├── .bowerrc
├── .gitignore
├── LICENSE.md
├── README.md
├── Vagrantfile
├── api
├── common
│ └── models
│ │ └── User.php
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ ├── params.php
│ └── rules.php
├── modules
│ └── v1
│ │ ├── Module.php
│ │ ├── controllers
│ │ └── .gitkeep
│ │ └── models
│ │ └── .gitkeep
├── runtime
│ └── .gitignore
└── web
│ └── .gitignore
├── auth
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── clients.php
│ ├── main.php
│ ├── params.php
│ └── rules.php
├── controllers
│ ├── AccountController.php
│ ├── Controller.php
│ └── TokenController.php
├── mail
│ ├── layouts
│ │ ├── html.php
│ │ └── text.php
│ ├── passwordResetToken-html.php
│ └── passwordResetToken-text.php
├── models
│ ├── Client.php
│ ├── LoginForm.php
│ ├── SignupForm.php
│ └── User.php
├── runtime
│ └── .gitignore
└── web
│ └── .gitignore
├── backend
├── assets
│ └── AppAsset.php
├── codeception.yml
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ ├── params.php
│ └── test.php
├── controllers
│ └── SiteController.php
├── models
│ └── .gitkeep
├── runtime
│ └── .gitignore
├── tests
│ ├── _bootstrap.php
│ ├── _data
│ │ ├── .gitignore
│ │ └── login_data.php
│ ├── _output
│ │ └── .gitignore
│ ├── _support
│ │ ├── .gitignore
│ │ ├── FunctionalTester.php
│ │ └── UnitTester.php
│ ├── functional.suite.yml
│ ├── functional
│ │ ├── LoginCest.php
│ │ └── _bootstrap.php
│ ├── unit.suite.yml
│ └── unit
│ │ └── _bootstrap.php
├── views
│ ├── layouts
│ │ └── main.php
│ └── site
│ │ ├── error.php
│ │ ├── index.php
│ │ └── login.php
└── web
│ ├── .gitignore
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ └── favicon.ico
├── codeception.yml
├── common
├── codeception.yml
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ ├── params.php
│ └── test.php
├── fixtures
│ └── UserFixture.php
├── mail
│ ├── layouts
│ │ ├── html.php
│ │ └── text.php
│ ├── passwordResetToken-html.php
│ └── passwordResetToken-text.php
├── models
│ ├── LoginForm.php
│ ├── PasswordResetRequestForm.php
│ ├── ResetPasswordForm.php
│ ├── SignupForm.php
│ └── User.php
├── tests
│ ├── _bootstrap.php
│ ├── _data
│ │ └── user.php
│ ├── _output
│ │ └── .gitignore
│ ├── _support
│ │ ├── .gitignore
│ │ └── UnitTester.php
│ ├── unit.suite.yml
│ └── unit
│ │ └── models
│ │ └── LoginFormTest.php
└── widgets
│ └── Alert.php
├── composer.json
├── console
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ └── params.php
├── controllers
│ └── .gitkeep
├── migrations
│ └── m130524_201442_init.php
├── models
│ └── .gitkeep
└── runtime
│ └── .gitignore
├── environments
├── dev
│ ├── api
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ │ ├── runtime
│ │ │ └── schema-builder
│ │ │ │ └── data
│ │ │ │ ├── Migration.php
│ │ │ │ ├── Model.php
│ │ │ │ ├── RestCrud.php
│ │ │ │ ├── RestModule.php
│ │ │ │ └── Schema.php
│ │ └── web
│ │ │ ├── .htaccess
│ │ │ ├── assets
│ │ │ └── .gitignore
│ │ │ ├── index.php
│ │ │ └── robots.txt
│ ├── auth
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ │ └── web
│ │ │ ├── .htaccess
│ │ │ ├── index.php
│ │ │ └── robots.txt
│ ├── backend
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ ├── params-local.php
│ │ │ └── test-local.php
│ │ └── web
│ │ │ ├── index-test.php
│ │ │ ├── index.php
│ │ │ └── robots.txt
│ ├── common
│ │ └── config
│ │ │ ├── main-local.php
│ │ │ ├── params-local.php
│ │ │ └── test-local.php
│ ├── console
│ │ └── config
│ │ │ ├── main-local.php
│ │ │ └── params-local.php
│ ├── frontend
│ │ ├── config
│ │ │ ├── main-local.php
│ │ │ ├── params-local.php
│ │ │ └── test-local.php
│ │ └── web
│ │ │ ├── index-test.php
│ │ │ ├── index.php
│ │ │ └── robots.txt
│ ├── yii
│ ├── yii_test
│ └── yii_test.bat
├── index.php
└── prod
│ ├── api
│ ├── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ └── web
│ │ ├── .htaccess
│ │ ├── index.php
│ │ └── robots.txt
│ ├── auth
│ ├── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ └── web
│ │ ├── .htaccess
│ │ ├── index.php
│ │ └── robots.txt
│ ├── backend
│ ├── config
│ │ ├── main-local.php
│ │ └── params-local.php
│ └── web
│ │ ├── index.php
│ │ └── robots.txt
│ ├── 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
│ │ └── robots.txt
│ └── yii
├── frontend
├── assets
│ └── AppAsset.php
├── codeception.yml
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ ├── params.php
│ └── test.php
├── controllers
│ └── SiteController.php
├── models
│ └── ContactForm.php
├── runtime
│ └── .gitignore
├── tests
│ ├── _bootstrap.php
│ ├── _data
│ │ ├── login_data.php
│ │ └── user.php
│ ├── _output
│ │ └── .gitignore
│ ├── _support
│ │ ├── .gitignore
│ │ ├── FunctionalTester.php
│ │ └── UnitTester.php
│ ├── acceptance.suite.yml.example
│ ├── acceptance
│ │ ├── HomeCest.php
│ │ └── _bootstrap.php
│ ├── functional.suite.yml
│ ├── functional
│ │ ├── AboutCest.php
│ │ ├── ContactCest.php
│ │ ├── HomeCest.php
│ │ ├── LoginCest.php
│ │ ├── SignupCest.php
│ │ └── _bootstrap.php
│ ├── unit.suite.yml
│ └── unit
│ │ ├── _bootstrap.php
│ │ └── models
│ │ ├── ContactFormTest.php
│ │ ├── PasswordResetRequestFormTest.php
│ │ ├── ResetPasswordFormTest.php
│ │ └── SignupFormTest.php
├── views
│ ├── layouts
│ │ └── main.php
│ └── site
│ │ ├── about.php
│ │ ├── contact.php
│ │ ├── error.php
│ │ ├── index.php
│ │ ├── login.php
│ │ ├── requestPasswordResetToken.php
│ │ ├── resetPassword.php
│ │ └── signup.php
└── web
│ ├── .gitignore
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ └── favicon.ico
├── init
├── init.bat
├── requirements.php
├── vagrant
├── config
│ ├── .gitignore
│ └── vagrant-local.example.yml
├── nginx
│ ├── app.conf
│ └── log
│ │ └── .gitignore
└── provision
│ ├── always-as-root.sh
│ ├── once-as-root.sh
│ └── once-as-vagrant.sh
└── yii.bat
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory" : "vendor/bower-asset"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # yii console commands
2 | /yii
3 | /yii_test
4 | /yii_test.bat
5 |
6 | # phpstorm project files
7 | .idea
8 |
9 | # netbeans project files
10 | nbproject
11 |
12 | # zend studio for eclipse project files
13 | .buildpath
14 | .project
15 | .settings
16 |
17 | # windows thumbnail cache
18 | Thumbs.db
19 |
20 | # composer vendor dir
21 | /vendor
22 |
23 | # composer itself is not needed
24 | composer.phar
25 |
26 | # Mac DS_Store Files
27 | .DS_Store
28 |
29 | # phpunit itself is not needed
30 | phpunit.phar
31 | # local phpunit config
32 | /phpunit.xml
33 |
34 | # vagrant runtime
35 | /.vagrant
36 |
--------------------------------------------------------------------------------
/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 | yii2-app-builder
2 | ==============
3 | [](https://packagist.org/packages/tunecino/yii2-app-builder)
4 | [](https://packagist.org/packages/tunecino/yii2-app-builder)
5 |
6 |
7 | This is a fork of [yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced) template to which I have added the following:
8 |
9 | - :file_folder:`api` folder as implementation of [Yii2 RESTful API framework](http://www.yiiframework.com/doc-2.0/guide-rest-quick-start.html)
10 | - :file_folder:`auth` folder to provide access/refresh tokens as implementation of [OAuth 2.0](https://tools.ietf.org/html/rfc6749). *(documentation and examples to be added later)*
11 | - [tunecino/yii2-schema-builder](https://github.com/tunecino/yii2-schema-builder) extension to both `frontend` and `api` apps.
12 |
13 | The plan is to keep this fork up-to-date with official template while keep improving builder & RESTful related stuff.
14 |
15 | ## Installation
16 | If you do not have Composer, you may follow the instructions in the [Yii Guide](http://www.yiiframework.com/doc-2.0/guide-start-installation.html#installing-via-composer) or [getcomposer.org](https://getcomposer.org/) to install it.
17 |
18 | You can then install this project template using the following command:
19 | ```
20 | composer create-project --prefer-dist tunecino/yii2-app-builder your-app-name
21 | ```
22 | Once the command finish go inside the created folder and init the app on `dev` mode same as you usually do with the [advanced template](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-installation.md#preparing-application):
23 |
24 | ```
25 | cd your-app-name
26 | ./init
27 | ```
28 | Then create a new database and adjust related configurations in common/config/main-local.php. You may also need to set document roots of your web server as shown in the [4th step of the Preparing application section](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-installation.md#preparing-application) except that you'll also need to do the same for `api.dev` and `auth.dev`. Alternatively you can also use vagrant.
29 |
30 | ## Usage
31 | After installing the template, configuring DB and init the dev mode, go to either `frontend.dev/index.php?r=builder` or `api.dev/builder`, use the [GUI](https://github.com/tunecino/yii2-schema-builder) to prototype your app then hit that Generate button. If it says DONE, the preview link of each entity should lead you to a working app.
32 |
--------------------------------------------------------------------------------
/Vagrantfile:
--------------------------------------------------------------------------------
1 | require 'yaml'
2 | require 'fileutils'
3 |
4 | required_plugins = %w( vagrant-hostmanager vagrant-vbguest )
5 | required_plugins.each do |plugin|
6 | exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
7 | end
8 |
9 | domains = {
10 | frontend: 'y2aa-frontend.dev',
11 | backend: 'y2aa-backend.dev',
12 | api: 'y2aa-api.dev',
13 | auth: 'y2aa-auth.dev/ping'
14 | }
15 |
16 | config = {
17 | local: './vagrant/config/vagrant-local.yml',
18 | example: './vagrant/config/vagrant-local.example.yml'
19 | }
20 |
21 | # copy config from example if local config not exists
22 | FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
23 | # read config
24 | options = YAML.load_file config[:local]
25 |
26 | # check github token
27 | if options['github_token'].nil? || options['github_token'].to_s.length != 40
28 | puts "You must place REAL GitHub token into configuration:\n/yii2-app-advanced/vagrant/config/vagrant-local.yml"
29 | exit
30 | end
31 |
32 | # vagrant configurate
33 | Vagrant.configure(2) do |config|
34 | # select the box
35 | config.vm.box = 'bento/ubuntu-16.04'
36 |
37 | # should we ask about box updates?
38 | config.vm.box_check_update = options['box_check_update']
39 |
40 | config.vm.provider 'virtualbox' do |vb|
41 | # machine cpus count
42 | vb.cpus = options['cpus']
43 | # machine memory size
44 | vb.memory = options['memory']
45 | # machine name (for VirtualBox UI)
46 | vb.name = options['machine_name']
47 | end
48 |
49 | # machine name (for vagrant console)
50 | config.vm.define options['machine_name']
51 |
52 | # machine name (for guest machine console)
53 | config.vm.hostname = options['machine_name']
54 |
55 | # network settings
56 | config.vm.network 'private_network', ip: options['ip']
57 |
58 | # sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
59 | config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'
60 |
61 | # disable folder '/vagrant' (guest machine)
62 | config.vm.synced_folder '.', '/vagrant', disabled: true
63 |
64 | # hosts settings (host machine)
65 | config.vm.provision :hostmanager
66 | config.hostmanager.enabled = true
67 | config.hostmanager.manage_host = true
68 | config.hostmanager.ignore_private_ip = false
69 | config.hostmanager.include_offline = true
70 | config.hostmanager.aliases = domains.values
71 |
72 | # provisioners
73 | config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
74 | config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
75 | config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
76 |
77 | # post-install message (vagrant console)
78 | config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}\nApi URL: http://#{domains[:api]}\nAuth URL: http://#{domains[:auth]}"
79 | end
80 |
--------------------------------------------------------------------------------
/api/common/models/User.php:
--------------------------------------------------------------------------------
1 | cache->get($token);
15 | return ($user_id) ? new static(['id' => $user_id]) : null;
16 | }
17 | }
--------------------------------------------------------------------------------
/api/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
3 | test-local.php
4 |
--------------------------------------------------------------------------------
/api/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | 'app-api',
12 | 'basePath' => dirname(__DIR__),
13 | 'controllerNamespace' => 'api\controllers',
14 | 'bootstrap' => ['log'],
15 | 'modules' => [
16 | 'v1' => [
17 | 'basePath' => '@api/modules/v1',
18 | 'class' => 'api\modules\v1\Module'
19 | ]
20 | ],
21 | 'components' => [
22 | 'request' => [
23 | 'parsers' => [
24 | 'application/json' => 'yii\web\JsonParser',
25 | ]
26 | ],
27 | 'user' => [
28 | 'identityClass' => 'api\common\models\User',
29 | 'enableSession' => false,
30 | 'enableAutoLogin' => false,
31 | 'loginUrl' => null,
32 | ],
33 | 'log' => [
34 | 'traceLevel' => YII_DEBUG ? 3 : 0,
35 | 'targets' => [
36 | [
37 | 'class' => 'yii\log\FileTarget',
38 | 'levels' => ['error', 'warning'],
39 | ],
40 | ],
41 | ],
42 | 'urlManager' => [
43 | 'enablePrettyUrl' => true,
44 | 'enableStrictParsing' => true,
45 | 'showScriptName' => false,
46 | 'rules' => $rules,
47 | ],
48 | ],
49 | 'params' => $params,
50 | ];
51 |
--------------------------------------------------------------------------------
/api/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/api/config/rules.php:
--------------------------------------------------------------------------------
1 | [
4 | 'id' => 'public_web',
5 | 'secret' => null,
6 | 'resetUrl' => 'http://example.com/account-recovery/',
7 | 'emailTokenLifeTime' => 3600, // 1 hour
8 | 'refreshTokenLifeTime' => [
9 | 'default' => 28800, // 8 hours
10 | 'remember' => 157784630, // ~ 5 years
11 | ],
12 | 'accessTokenLifeTime' => [
13 | 'default' => 300, // 5 minutes
14 | 'remember' => 1800, // 30 minutes
15 | ]
16 | ],
17 | ];
--------------------------------------------------------------------------------
/auth/config/main.php:
--------------------------------------------------------------------------------
1 | 'app-auth',
13 | 'basePath' => dirname(__DIR__),
14 | 'controllerNamespace' => 'auth\controllers',
15 | 'bootstrap' => ['log'],
16 | 'modules' => [],
17 | 'components' => [
18 | 'request' => [
19 | 'parsers' => [
20 | 'application/json' => 'yii\web\JsonParser',
21 | ]
22 | ],
23 | 'user' => [
24 | 'identityClass' => 'auth\models\User',
25 | 'enableSession' => false,
26 | 'enableAutoLogin' => false,
27 | 'loginUrl' => null,
28 | ],
29 | 'client' => [
30 | 'class' => 'auth\models\Client',
31 | 'dataList' => $clients,
32 | ],
33 | 'log' => [
34 | 'traceLevel' => YII_DEBUG ? 3 : 0,
35 | 'targets' => [
36 | [
37 | 'class' => 'yii\log\FileTarget',
38 | 'levels' => ['error', 'warning'],
39 | ],
40 | ],
41 | ],
42 | 'urlManager' => [
43 | 'enablePrettyUrl' => true,
44 | 'enableStrictParsing' => true,
45 | 'showScriptName' => false,
46 | 'rules' => $rules,
47 | ],
48 | ],
49 | 'params' => $params,
50 | ];
51 |
--------------------------------------------------------------------------------
/auth/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/auth/config/rules.php:
--------------------------------------------------------------------------------
1 | 'yii\rest\UrlRule',
5 | 'controller' => ['ping' => 'account'],
6 | 'patterns' => [
7 | 'GET,HEAD' => 'ping',
8 | 'OPTIONS' => 'options',
9 | ]
10 | ],
11 | [
12 | 'class' => 'yii\rest\UrlRule',
13 | 'controller' => ['account' => 'account'],
14 | 'patterns' => [
15 | 'POST login' => 'login',
16 | 'POST signup' => 'signup',
17 | 'POST req-reset-pass' => 'request-password-reset',
18 | 'POST reset-pass' => 'reset-password',
19 | // OPTTIONS VERBS
20 | 'OPTIONS login' => 'options',
21 | 'OPTIONS signup' => 'options',
22 | 'OPTIONS req-reset-pass' => 'options',
23 | 'OPTIONS reset-pass' => 'options',
24 | ]
25 | ],
26 | [
27 | 'class' => 'yii\rest\UrlRule',
28 | 'controller' => ['token' => 'token'],
29 | 'patterns' => [
30 | 'POST revoke' => 'revoke',
31 | 'POST refresh' => 'refresh',
32 | // OPTTIONS VERBS
33 | 'OPTIONS revoke' => 'options',
34 | 'OPTIONS refresh' => 'options',
35 | ]
36 | ],
37 | ];
--------------------------------------------------------------------------------
/auth/controllers/AccountController.php:
--------------------------------------------------------------------------------
1 | load(Yii::$app->request->bodyParams, '');
23 |
24 | if ($auth = $model->login()) {
25 | return [
26 | 'user' => [
27 | 'name' => Yii::$app->user->identity->username,
28 | 'email' => Yii::$app->user->identity->email,
29 | ],
30 | 'grant' => [
31 | 'refresh_token' => $auth['refresh_token'],
32 | 'access_token' => $auth['access_token'],
33 | 'expires_at' => time() + Yii::$app->client->accessExpiry,
34 | ]
35 | ];
36 | }
37 |
38 | if ($model->hasErrors() === false) {
39 | throw new ServerErrorHttpException('Failed for unknown reason.');
40 | }
41 |
42 | return $model;
43 | }
44 |
45 | public function actionSignup()
46 | {
47 | $model = new SignupForm();
48 | $model->load(Yii::$app->request->bodyParams, '');
49 |
50 | if ($auth = $model->signup()) {
51 | return [
52 | 'user' => [
53 | 'name' => Yii::$app->user->identity->username,
54 | 'email' => Yii::$app->user->identity->email,
55 | ],
56 | 'grant' => [
57 | 'refresh_token' => $auth['refresh_token'],
58 | 'access_token' => $auth['access_token'],
59 | 'expires_at' => time() + Yii::$app->client->accessExpiry,
60 | ]
61 | ];
62 | }
63 |
64 | if ($model->hasErrors() === false) {
65 | throw new ServerErrorHttpException('Failed for unknown reason.');
66 | }
67 |
68 | return $model;
69 | }
70 |
71 | public function actionRequestPasswordReset()
72 | {
73 | $model = new PasswordResetRequestForm();
74 |
75 | if ($model->load(Yii::$app->request->bodyParams, '') && $model->validate()) {
76 | if ($model->sendEmail() === false) {
77 | throw new ServerErrorHttpException('Sorry, we are unable to reset password for provided email.');
78 | }
79 | return ['message' => 'Check your email for further instructions.'];
80 | }
81 |
82 | return $model;
83 | }
84 |
85 | public function actionResetPassword()
86 | {
87 | $token = ArrayHelper::getValue(Yii::$app->request->bodyParams, 'token');
88 |
89 | try {
90 | $model = new ResetPasswordForm($token);
91 | } catch (InvalidParamException $e) {
92 | throw new BadRequestHttpException($e->getMessage());
93 | }
94 |
95 | if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->validate() && $model->resetPassword()) {
96 | return ['success' => 'New password was saved.'];
97 | }
98 |
99 | return $model;
100 | }
101 |
102 | }
--------------------------------------------------------------------------------
/auth/controllers/Controller.php:
--------------------------------------------------------------------------------
1 | \yii\filters\Cors::className(),
24 | 'cors' => [
25 | 'Origin' => ['*'],
26 | 'Access-Control-Allow-Origin' => ['*'],
27 | 'Access-Control-Request-Method' => $this->verbs(),
28 | 'Access-Control-Request-Headers' => ['*'],
29 | 'Access-Control-Allow-Credentials' => true,
30 | 'Access-Control-Max-Age' => 86400
31 | ],
32 | ];
33 | return $behaviors;
34 | }
35 |
36 | /**
37 | * @inheritdoc
38 | */
39 | public function beforeAction($action)
40 | {
41 | if ($action->id !== 'options' && $action->id !== 'ping') {
42 | $params = Yii::$app->request->bodyParams;
43 | if (Yii::$app->client->loadClient($params) === false) {
44 | throw new BadRequestHttpException('Unknown requester');
45 | }
46 | }
47 | return parent::beforeAction($action);
48 | }
49 |
50 | /**
51 | * Ping action should respond to /ping uri for test proposes and to confirm REST availability.
52 | */
53 | public function actionPing()
54 | {
55 | return 'pong';
56 | }
57 |
58 | /**
59 | * Responds to the OPTIONS request.
60 | * @param string $id
61 | */
62 | public function actionOptions()
63 | {
64 | if (Yii::$app->getRequest()->getMethod() !== 'OPTIONS') {
65 | Yii::$app->getResponse()->setStatusCode(405);
66 | }
67 |
68 | Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $this->verbs()));
69 | }
70 |
71 | /**
72 | * @inheritdoc
73 | */
74 | protected function verbs()
75 | {
76 | return ['GET', 'HEAD', 'POST', 'OPTIONS'];
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/auth/controllers/TokenController.php:
--------------------------------------------------------------------------------
1 | HttpBearerAuth::className(),
25 | 'except' => ['options'],
26 | ];
27 | return $behaviors;
28 | }
29 |
30 | public function actionRefresh()
31 | {
32 | $access_token = User::generateAccessToken();
33 | if ($access_token === false) {
34 | throw new ServerErrorHttpException('Failed for unknown reason.');
35 | }
36 |
37 | return [
38 | 'token' => [
39 | 'access_token' => $access_token,
40 | 'expires_at' => time() + Yii::$app->client->accessExpiry,
41 | ]
42 | ];
43 | }
44 |
45 | public function actionRevoke()
46 | {
47 | $access_token = ArrayHelper::getValue(Yii::$app->request->bodyParams, 'access_token');
48 | if ($access_token) User::revokeAccessToken($access_token);
49 |
50 | $refresh_token = substr(Yii::$app->request->headers->get('Authorization'), 7);
51 | $auth = User::findOne(['refresh_token' => $refresh_token]);
52 | if ($auth && $auth->delete() === false) {
53 | throw new ServerErrorHttpException('Failed for unknown reason.');
54 | }
55 |
56 | Yii::$app->getResponse()->setStatusCode(204);
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/auth/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 |
--------------------------------------------------------------------------------
/auth/mail/layouts/text.php:
--------------------------------------------------------------------------------
1 |
9 |
10 | beginPage() ?>
11 | beginBody() ?>
12 | = $content ?>
13 | endBody() ?>
14 | endPage() ?>
15 |
--------------------------------------------------------------------------------
/auth/mail/passwordResetToken-html.php:
--------------------------------------------------------------------------------
1 | client->resetUrl . $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 |
--------------------------------------------------------------------------------
/auth/mail/passwordResetToken-text.php:
--------------------------------------------------------------------------------
1 | client->resetUrl . $user->password_reset_token;
7 | ?>
8 | Hello = $user->username ?>,
9 |
10 | Follow the link below to reset your password:
11 |
12 | = $resetLink ?>
13 |
--------------------------------------------------------------------------------
/auth/models/Client.php:
--------------------------------------------------------------------------------
1 | dataList)) {
26 | throw new InvalidConfigException('At least one client should be defined under "'.self::class.'::$dataList".');
27 | }
28 | }
29 |
30 | public function rules()
31 | {
32 | return [
33 | ['client_id', 'required'],
34 | ['client_id', 'filter', 'filter' => 'trim'],
35 | ['client_id', 'in', 'range' => ArrayHelper::getColumn($this->dataList, 'id'), 'strict' => true],
36 | ['remember', 'boolean', 'falseValue'=> 'false', 'trueValue'=> 'true'],
37 | ['client_secret', 'validateClient', 'skipOnEmpty' => false],
38 | ];
39 | }
40 |
41 | public function validateClient($attribute, $params)
42 | {
43 | $client = $this->findClient($this->client_id);
44 |
45 | if ($client === null || $this->validateSecret() === false) {
46 | $this->addError($attribute, 'Invalid client.');
47 | }
48 | }
49 |
50 |
51 | /* internal methods */
52 |
53 | protected function getClient()
54 | {
55 | if ($this->_client === null) {
56 | $this->_client = $this->findClient($this->client_id);
57 | }
58 | return $this->_client;
59 | }
60 |
61 | protected function findClient($id)
62 | {
63 | foreach ($this->dataList as $client) {
64 | if ($id && ArrayHelper::getValue($client, 'id') === $id) return $client;
65 | }
66 | return null;
67 | }
68 |
69 | protected function validateSecret()
70 | {
71 | $secret = ArrayHelper::getValue($this->client, 'secret');
72 | return ($secret === null) ? true : Yii::$app->security->compareString($secret, $this->client_secret);
73 | }
74 |
75 |
76 | /* public methods */
77 |
78 | public function loadClient($params)
79 | {
80 | return $this->load($params,'') && $this->validate();
81 | }
82 |
83 | public function getId()
84 | {
85 | return ArrayHelper::getValue($this->client, 'id');
86 | }
87 |
88 | public function getAccessExpiry()
89 | {
90 | return $this->remember
91 | ? ArrayHelper::getValue($this->client, 'accessTokenLifeTime.remember')
92 | : ArrayHelper::getValue($this->client, 'accessTokenLifeTime.default');
93 | }
94 |
95 | public function getRefreshExpiry()
96 | {
97 | return $this->remember
98 | ? ArrayHelper::getValue($this->client, 'refreshTokenLifeTime.remember')
99 | : ArrayHelper::getValue($this->client, 'refreshTokenLifeTime.default');
100 | }
101 |
102 | public function getEmailExpiry()
103 | {
104 | return ArrayHelper::getValue($this->client, 'emailTokenLifeTime');
105 | }
106 |
107 | public function getResetUrl()
108 | {
109 | return ArrayHelper::getValue($this->client, 'resetUrl');
110 | }
111 |
112 | }
--------------------------------------------------------------------------------
/auth/models/LoginForm.php:
--------------------------------------------------------------------------------
1 | validate()) {
18 | $user = $this->getUser();
19 |
20 | $auth = new authUser;
21 | $auth->user_id = $user->id;
22 | $auth->client_id = Yii::$app->client->id;
23 | $auth->long_term = (Yii::$app->client->remember === 'true');
24 | $auth->generateRefreshToken();
25 |
26 | if ($auth->save() && Yii::$app->getUser()->login($user) && $access_token = $auth->generateAccessToken()) {
27 | return [
28 | 'access_token' => $access_token,
29 | 'refresh_token' => $auth->refresh_token,
30 | ];
31 | }
32 | }
33 |
34 | return null;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/auth/models/SignupForm.php:
--------------------------------------------------------------------------------
1 | validate()) {
19 | $user = new commonUser;
20 | $user->username = $this->username;
21 | $user->email = $this->email;
22 | $user->setPassword($this->password);
23 | $user->generateAuthKey();
24 |
25 | if ($user->save()) {
26 | $auth = new authUser;
27 | $auth->user_id = $user->id;
28 | $auth->client_id = Yii::$app->client->id;
29 | $auth->long_term = (Yii::$app->client->remember === 'true');
30 | $auth->generateRefreshToken();
31 |
32 | if ($auth->save() && Yii::$app->getUser()->login($user) && $access_token = $auth->generateAccessToken()) {
33 | return [
34 | 'access_token' => $access_token,
35 | 'refresh_token' => $auth->refresh_token,
36 | ];
37 | }
38 | }
39 | }
40 |
41 | return null;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/auth/models/User.php:
--------------------------------------------------------------------------------
1 | $id, 'status' => \common\models\User::STATUS_ACTIVE]);
39 | }
40 |
41 | /**
42 | * @inheritdoc
43 | */
44 | public static function findIdentityByAccessToken($token, $type = null)
45 | {
46 | $auth = static::findOne(['refresh_token' => $token]);
47 | return ($auth && $auth->isValid()) ? static::findIdentity($auth->user_id) : null;
48 | }
49 |
50 | /**
51 | * Validates Refresh Token LifeTime
52 | */
53 | public function isValid()
54 | {
55 | return time() < ($this->created_at + Yii::$app->client->refreshExpiry);
56 | }
57 |
58 | /**
59 | * @inheritdoc
60 | */
61 | public function getId()
62 | {
63 | return $this->user_id;
64 | }
65 |
66 | /**
67 | * @inheritdoc
68 | */
69 | public function getAuthKey()
70 | {
71 | throw new NotSupportedException('"getAuthKey" is not implemented.');
72 | }
73 |
74 | /**
75 | * @inheritdoc
76 | */
77 | public function validateAuthKey($authKey)
78 | {
79 | throw new NotSupportedException('"validateAuthKey" is not implemented.');
80 | }
81 |
82 | /**
83 | * Generates Refresh Token
84 | */
85 | public function generateRefreshToken()
86 | {
87 | $this->refresh_token = Yii::$app->security->generateRandomString();
88 | }
89 |
90 | /**
91 | * Generates Access Token and stores it in app's cache
92 | */
93 | public static function generateAccessToken()
94 | {
95 | $access_token = Yii::$app->security->generateRandomString();
96 |
97 | $cached = Yii::$app->cache->add(
98 | $access_token,
99 | Yii::$app->user->id,
100 | Yii::$app->client->accessExpiry
101 | );
102 |
103 | return $cached ? $access_token : false;
104 | }
105 |
106 | /**
107 | * Revokes Access Token and stores it in app's cache
108 | */
109 | public static function revokeAccessToken($access_token)
110 | {
111 | return Yii::$app->cache->delete($access_token);
112 | }
113 |
114 | }
--------------------------------------------------------------------------------
/auth/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/auth/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 | /robots.txt
4 | /.htaccess
5 |
--------------------------------------------------------------------------------
/backend/assets/AppAsset.php:
--------------------------------------------------------------------------------
1 | 'app-backend',
11 | 'basePath' => dirname(__DIR__),
12 | 'controllerNamespace' => 'backend\controllers',
13 | 'bootstrap' => ['log'],
14 | 'modules' => [],
15 | 'components' => [
16 | 'request' => [
17 | 'csrfParam' => '_csrf-backend',
18 | ],
19 | 'user' => [
20 | 'identityClass' => 'common\models\User',
21 | 'enableAutoLogin' => true,
22 | 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
23 | ],
24 | 'session' => [
25 | // this is the name of the session cookie used for login on the backend
26 | 'name' => 'advanced-backend',
27 | ],
28 | 'log' => [
29 | 'traceLevel' => YII_DEBUG ? 3 : 0,
30 | 'targets' => [
31 | [
32 | 'class' => 'yii\log\FileTarget',
33 | 'levels' => ['error', 'warning'],
34 | ],
35 | ],
36 | ],
37 | 'errorHandler' => [
38 | 'errorAction' => 'site/error',
39 | ],
40 | /*
41 | 'urlManager' => [
42 | 'enablePrettyUrl' => true,
43 | 'showScriptName' => false,
44 | 'rules' => [
45 | ],
46 | ],
47 | */
48 | ],
49 | 'params' => $params,
50 | ];
51 |
--------------------------------------------------------------------------------
/backend/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/backend/config/test.php:
--------------------------------------------------------------------------------
1 | 'app-backend-tests',
4 | 'components' => [
5 | 'assetManager' => [
6 | 'basePath' => __DIR__ . '/../web/assets',
7 | ],
8 | 'urlManager' => [
9 | 'showScriptName' => true,
10 | ],
11 | ],
12 | ];
13 |
--------------------------------------------------------------------------------
/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 | /**
57 | * Displays homepage.
58 | *
59 | * @return string
60 | */
61 | public function actionIndex()
62 | {
63 | return $this->render('index');
64 | }
65 |
66 | /**
67 | * Login action.
68 | *
69 | * @return string
70 | */
71 | public function actionLogin()
72 | {
73 | if (!Yii::$app->user->isGuest) {
74 | return $this->goHome();
75 | }
76 |
77 | $model = new LoginForm();
78 | if ($model->load(Yii::$app->request->post()) && $model->login()) {
79 | return $this->goBack();
80 | } else {
81 | return $this->render('login', [
82 | 'model' => $model,
83 | ]);
84 | }
85 | }
86 |
87 | /**
88 | * Logout action.
89 | *
90 | * @return string
91 | */
92 | public function actionLogout()
93 | {
94 | Yii::$app->user->logout();
95 |
96 | return $this->goHome();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/backend/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/backend/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/backend/tests/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'erau',
5 | 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI',
6 | // password_0
7 | 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne',
8 | 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490',
9 | 'created_at' => '1392559490',
10 | 'updated_at' => '1392559490',
11 | 'email' => 'sfriesen@jenkins.info',
12 | ],
13 | ];
14 |
--------------------------------------------------------------------------------
/backend/tests/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/backend/tests/_support/.gitignore:
--------------------------------------------------------------------------------
1 | _generated
2 |
--------------------------------------------------------------------------------
/backend/tests/_support/FunctionalTester.php:
--------------------------------------------------------------------------------
1 | [
25 | 'class' => UserFixture::className(),
26 | 'dataFile' => codecept_data_dir() . 'login_data.php'
27 | ]
28 | ];
29 | }
30 |
31 | /**
32 | * @param FunctionalTester $I
33 | */
34 | public function loginUser(FunctionalTester $I)
35 | {
36 | $I->amOnPage('/site/login');
37 | $I->fillField('Username', 'erau');
38 | $I->fillField('Password', 'password_0');
39 | $I->click('login-button');
40 |
41 | $I->see('Logout (erau)', 'form button[type=submit]');
42 | $I->dontSeeLink('Login');
43 | $I->dontSeeLink('Signup');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/backend/tests/functional/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'davert']);
9 | * ```
10 | *
11 | * In Cests
12 | *
13 | * ```php
14 | * \Codeception\Util\Fixtures::get('user1');
15 | * ```
16 | */
--------------------------------------------------------------------------------
/backend/tests/unit.suite.yml:
--------------------------------------------------------------------------------
1 | class_name: UnitTester
2 |
--------------------------------------------------------------------------------
/backend/tests/unit/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'davert']);
9 | * ```
10 | *
11 | * In Tests
12 | *
13 | * ```php
14 | * \Codeception\Util\Fixtures::get('user1');
15 | * ```
16 | */
17 |
--------------------------------------------------------------------------------
/backend/views/layouts/main.php:
--------------------------------------------------------------------------------
1 |
15 | beginPage() ?>
16 |
17 |
18 |
19 |
20 |
21 |
22 | = Html::csrfMetaTags() ?>
23 | = Html::encode($this->title) ?>
24 | head() ?>
25 |
26 |
27 | beginBody() ?>
28 |
29 |
30 | Yii::$app->name,
33 | 'brandUrl' => Yii::$app->homeUrl,
34 | 'options' => [
35 | 'class' => 'navbar-inverse navbar-fixed-top',
36 | ],
37 | ]);
38 | $menuItems = [
39 | ['label' => 'Home', 'url' => ['/site/index']],
40 | ];
41 | if (Yii::$app->user->isGuest) {
42 | $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
43 | } else {
44 | $menuItems[] = '
'
45 | . Html::beginForm(['/site/logout'], 'post')
46 | . Html::submitButton(
47 | 'Logout (' . Yii::$app->user->identity->username . ')',
48 | ['class' => 'btn btn-link logout']
49 | )
50 | . Html::endForm()
51 | . '';
52 | }
53 | echo Nav::widget([
54 | 'options' => ['class' => 'navbar-nav navbar-right'],
55 | 'items' => $menuItems,
56 | ]);
57 | NavBar::end();
58 | ?>
59 |
60 |
61 | = Breadcrumbs::widget([
62 | 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
63 | ]) ?>
64 | = Alert::widget() ?>
65 | = $content ?>
66 |
67 |
68 |
69 |
76 |
77 | endBody() ?>
78 |
79 |
80 | endPage() ?>
81 |
--------------------------------------------------------------------------------
/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';
6 | ?>
7 |
8 |
9 |
10 |
Congratulations!
11 |
12 |
You have successfully created your Yii-powered application.
13 |
14 |
Get started with Yii
15 |
16 |
17 |
18 |
19 |
20 |
21 |
Heading
22 |
23 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
24 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
25 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
26 | fugiat nulla pariatur.
27 |
28 |
Yii Documentation »
29 |
30 |
31 |
Heading
32 |
33 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
34 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
35 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
36 | fugiat nulla pariatur.
37 |
38 |
Yii Forum »
39 |
40 |
41 |
Heading
42 |
43 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
44 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
45 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
46 | fugiat nulla pariatur.
47 |
48 |
Yii Extensions »
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/backend/views/site/login.php:
--------------------------------------------------------------------------------
1 | title = 'Login';
11 | $this->params['breadcrumbs'][] = $this->title;
12 | ?>
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
Please fill out the following fields to login:
17 |
18 |
19 |
20 | 'login-form']); ?>
21 |
22 | = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
23 |
24 | = $form->field($model, 'password')->passwordInput() ?>
25 |
26 | = $form->field($model, 'rememberMe')->checkbox() ?>
27 |
28 |
29 | = Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/backend/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 | /robots.txt
4 |
--------------------------------------------------------------------------------
/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 td {
76 | white-space: nowrap;
77 | }
78 |
79 | .grid-view .filters input,
80 | .grid-view .filters select {
81 | min-width: 50px;
82 | }
83 |
84 | .hint-block {
85 | display: block;
86 | margin-top: 5px;
87 | color: #999;
88 | }
89 |
90 | .error-summary {
91 | color: #a94442;
92 | background: #fdf7f7;
93 | border-left: 3px solid #eed3d7;
94 | padding: 10px 20px;
95 | margin: 0 0 15px 0;
96 | }
97 |
98 | /* align the logout "link" (button in form) of the navbar */
99 | .nav li > form > button.logout {
100 | padding: 15px;
101 | border: none;
102 | }
103 |
104 | @media(max-width:767px) {
105 | .nav li > form > button.logout {
106 | display:block;
107 | text-align: left;
108 | width: 100%;
109 | padding: 10px 15px;
110 | }
111 | }
112 |
113 | .nav > li > form > button.logout:focus,
114 | .nav > li > form > button.logout:hover {
115 | text-decoration: none;
116 | }
117 |
118 | .nav > li > form > button.logout:focus {
119 | outline: none;
120 | }
121 |
--------------------------------------------------------------------------------
/backend/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tunecino/yii2-app-builder/1dc82b976a891972294b0684bc9e76323ea9d121/backend/web/favicon.ico
--------------------------------------------------------------------------------
/codeception.yml:
--------------------------------------------------------------------------------
1 | # global codeception file to run tests from all apps
2 | include:
3 | - common
4 | - frontend
5 | - backend
6 | paths:
7 | log: console/runtime/logs
8 | settings:
9 | colors: true
--------------------------------------------------------------------------------
/common/codeception.yml:
--------------------------------------------------------------------------------
1 | namespace: common\tests
2 | actor: Tester
3 | paths:
4 | tests: tests
5 | log: tests/_output
6 | data: tests/_data
7 | helpers: tests/_support
8 | settings:
9 | bootstrap: _bootstrap.php
10 | colors: true
11 | memory_limit: 1024M
12 | modules:
13 | config:
14 | Yii2:
15 | configFile: 'config/test-local.php'
16 |
--------------------------------------------------------------------------------
/common/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
3 | test-local.php
4 |
--------------------------------------------------------------------------------
/common/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | [
4 | '@bower' => '@vendor/bower-asset',
5 | '@npm' => '@vendor/npm-asset',
6 | ],
7 | 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
8 | 'components' => [
9 | 'cache' => [
10 | 'class' => 'yii\caching\FileCache',
11 | ],
12 | ],
13 | ];
14 |
--------------------------------------------------------------------------------
/common/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | 'supportEmail' => 'support@example.com',
5 | 'user.passwordResetTokenExpire' => 3600,
6 | ];
7 |
--------------------------------------------------------------------------------
/common/config/test.php:
--------------------------------------------------------------------------------
1 | 'app-common-tests',
4 | 'basePath' => dirname(__DIR__),
5 | 'components' => [
6 | 'user' => [
7 | 'class' => 'yii\web\User',
8 | 'identityClass' => 'common\models\User',
9 | ],
10 | ],
11 | ];
12 |
--------------------------------------------------------------------------------
/common/fixtures/UserFixture.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 |
9 |
10 | beginPage() ?>
11 | beginBody() ?>
12 | = $content ?>
13 | endBody() ?>
14 | endPage() ?>
15 |
--------------------------------------------------------------------------------
/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 bool 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 | }
61 |
62 | return false;
63 | }
64 |
65 | /**
66 | * Finds user by [[username]]
67 | *
68 | * @return User|null
69 | */
70 | protected function getUser()
71 | {
72 | if ($this->_user === null) {
73 | $this->_user = User::findByUsername($this->username);
74 | }
75 |
76 | return $this->_user;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/common/models/PasswordResetRequestForm.php:
--------------------------------------------------------------------------------
1 | '\common\models\User',
27 | 'filter' => ['status' => User::STATUS_ACTIVE],
28 | 'message' => 'There is no user with this email address.'
29 | ],
30 | ];
31 | }
32 |
33 | /**
34 | * Sends an email with a link, for resetting the password.
35 | *
36 | * @return bool whether the email was send
37 | */
38 | public function sendEmail()
39 | {
40 | /* @var $user User */
41 | $user = User::findOne([
42 | 'status' => User::STATUS_ACTIVE,
43 | 'email' => $this->email,
44 | ]);
45 |
46 | if (!$user) {
47 | return false;
48 | }
49 |
50 | if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
51 | $user->generatePasswordResetToken();
52 | if (!$user->save()) {
53 | return false;
54 | }
55 | }
56 |
57 | return Yii::$app
58 | ->mailer
59 | ->compose(
60 | ['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'],
61 | ['user' => $user]
62 | )
63 | ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
64 | ->setTo($this->email)
65 | ->setSubject('Password reset for ' . Yii::$app->name)
66 | ->send();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/common/models/ResetPasswordForm.php:
--------------------------------------------------------------------------------
1 | _user = User::findByPasswordResetToken($token);
34 | if (!$this->_user) {
35 | throw new InvalidParamException('Wrong password reset token.');
36 | }
37 | parent::__construct($config);
38 | }
39 |
40 | /**
41 | * @inheritdoc
42 | */
43 | public function rules()
44 | {
45 | return [
46 | ['password', 'required'],
47 | ['password', 'string', 'min' => 6],
48 | ];
49 | }
50 |
51 | /**
52 | * Resets password.
53 | *
54 | * @return bool if password was reset.
55 | */
56 | public function resetPassword()
57 | {
58 | $user = $this->_user;
59 | $user->setPassword($this->password);
60 | $user->removePasswordResetToken();
61 |
62 | return $user->save(false);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/common/models/SignupForm.php:
--------------------------------------------------------------------------------
1 | '\common\models\User', 'message' => 'This username has already been taken.'],
26 | ['username', 'string', 'min' => 2, 'max' => 255],
27 |
28 | ['email', 'trim'],
29 | ['email', 'required'],
30 | ['email', 'email'],
31 | ['email', 'string', 'max' => 255],
32 | ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
33 |
34 | ['password', 'required'],
35 | ['password', 'string', 'min' => 6],
36 | ];
37 | }
38 |
39 | /**
40 | * Signs user up.
41 | *
42 | * @return User|null the saved model or null if saving fails
43 | */
44 | public function signup()
45 | {
46 | if (!$this->validate()) {
47 | return null;
48 | }
49 |
50 | $user = new User();
51 | $user->username = $this->username;
52 | $user->email = $this->email;
53 | $user->setPassword($this->password);
54 | $user->generateAuthKey();
55 |
56 | return $user->save() ? $user : null;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/common/models/User.php:
--------------------------------------------------------------------------------
1 | self::STATUS_ACTIVE],
55 | ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
56 | ];
57 | }
58 |
59 | /**
60 | * @inheritdoc
61 | */
62 | public static function findIdentity($id)
63 | {
64 | return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
65 | }
66 |
67 | /**
68 | * @inheritdoc
69 | */
70 | public static function findIdentityByAccessToken($token, $type = null)
71 | {
72 | throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
73 | }
74 |
75 | /**
76 | * Finds user by username
77 | *
78 | * @param string $username
79 | * @return static|null
80 | */
81 | public static function findByUsername($username)
82 | {
83 | return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
84 | }
85 |
86 | /**
87 | * Finds user by password reset token
88 | *
89 | * @param string $token password reset token
90 | * @return static|null
91 | */
92 | public static function findByPasswordResetToken($token)
93 | {
94 | if (!static::isPasswordResetTokenValid($token)) {
95 | return null;
96 | }
97 |
98 | return static::findOne([
99 | 'password_reset_token' => $token,
100 | 'status' => self::STATUS_ACTIVE,
101 | ]);
102 | }
103 |
104 | /**
105 | * Finds out if password reset token is valid
106 | *
107 | * @param string $token password reset token
108 | * @return bool
109 | */
110 | public static function isPasswordResetTokenValid($token)
111 | {
112 | if (empty($token)) {
113 | return false;
114 | }
115 |
116 | $timestamp = (int) substr($token, strrpos($token, '_') + 1);
117 | $expire = Yii::$app->params['user.passwordResetTokenExpire'];
118 | return $timestamp + $expire >= time();
119 | }
120 |
121 | /**
122 | * @inheritdoc
123 | */
124 | public function getId()
125 | {
126 | return $this->getPrimaryKey();
127 | }
128 |
129 | /**
130 | * @inheritdoc
131 | */
132 | public function getAuthKey()
133 | {
134 | return $this->auth_key;
135 | }
136 |
137 | /**
138 | * @inheritdoc
139 | */
140 | public function validateAuthKey($authKey)
141 | {
142 | return $this->getAuthKey() === $authKey;
143 | }
144 |
145 | /**
146 | * Validates password
147 | *
148 | * @param string $password password to validate
149 | * @return bool if password provided is valid for current user
150 | */
151 | public function validatePassword($password)
152 | {
153 | return Yii::$app->security->validatePassword($password, $this->password_hash);
154 | }
155 |
156 | /**
157 | * Generates password hash from password and sets it to the model
158 | *
159 | * @param string $password
160 | */
161 | public function setPassword($password)
162 | {
163 | $this->password_hash = Yii::$app->security->generatePasswordHash($password);
164 | }
165 |
166 | /**
167 | * Generates "remember me" authentication key
168 | */
169 | public function generateAuthKey()
170 | {
171 | $this->auth_key = Yii::$app->security->generateRandomString();
172 | }
173 |
174 | /**
175 | * Generates new password reset token
176 | */
177 | public function generatePasswordResetToken()
178 | {
179 | $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
180 | }
181 |
182 | /**
183 | * Removes password reset token
184 | */
185 | public function removePasswordResetToken()
186 | {
187 | $this->password_reset_token = null;
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/common/tests/_bootstrap.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 |
--------------------------------------------------------------------------------
/common/tests/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/common/tests/_support/.gitignore:
--------------------------------------------------------------------------------
1 | _generated
2 |
--------------------------------------------------------------------------------
/common/tests/_support/UnitTester.php:
--------------------------------------------------------------------------------
1 | [
26 | 'class' => UserFixture::className(),
27 | 'dataFile' => codecept_data_dir() . 'user.php'
28 | ]
29 | ];
30 | }
31 |
32 | public function testLoginNoUser()
33 | {
34 | $model = new LoginForm([
35 | 'username' => 'not_existing_username',
36 | 'password' => 'not_existing_password',
37 | ]);
38 |
39 | expect('model should not login user', $model->login())->false();
40 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
41 | }
42 |
43 | public function testLoginWrongPassword()
44 | {
45 | $model = new LoginForm([
46 | 'username' => 'bayer.hudson',
47 | 'password' => 'wrong_password',
48 | ]);
49 |
50 | expect('model should not login user', $model->login())->false();
51 | expect('error message should be set', $model->errors)->hasKey('password');
52 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
53 | }
54 |
55 | public function testLoginCorrect()
56 | {
57 | $model = new LoginForm([
58 | 'username' => 'bayer.hudson',
59 | 'password' => 'password_0',
60 | ]);
61 |
62 | expect('model should login user', $model->login())->true();
63 | expect('error message should not be set', $model->errors)->hasntKey('password');
64 | expect('user should be logged in', Yii::$app->user->isGuest)->false();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/common/widgets/Alert.php:
--------------------------------------------------------------------------------
1 | session->setFlash('error', 'This is the message');
12 | * Yii::$app->session->setFlash('success', 'This is the message');
13 | * Yii::$app->session->setFlash('info', 'This is the message');
14 | * ```
15 | *
16 | * Multiple messages could be set as follows:
17 | *
18 | * ```php
19 | * Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']);
20 | * ```
21 | *
22 | * @author Kartik Visweswaran
23 | * @author Alexander Makarov
24 | */
25 | class Alert extends \yii\bootstrap\Widget
26 | {
27 | /**
28 | * @var array the alert types configuration for the flash messages.
29 | * This array is setup as $key => $value, where:
30 | * - key: the name of the session flash variable
31 | * - value: the bootstrap alert type (i.e. danger, success, info, warning)
32 | */
33 | public $alertTypes = [
34 | 'error' => 'alert-danger',
35 | 'danger' => 'alert-danger',
36 | 'success' => 'alert-success',
37 | 'info' => 'alert-info',
38 | 'warning' => 'alert-warning'
39 | ];
40 | /**
41 | * @var array the options for rendering the close button tag.
42 | * Array will be passed to [[\yii\bootstrap\Alert::closeButton]].
43 | */
44 | public $closeButton = [];
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function run()
50 | {
51 | $session = Yii::$app->session;
52 | $flashes = $session->getAllFlashes();
53 | $appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : '';
54 |
55 | foreach ($flashes as $type => $flash) {
56 | if (!isset($this->alertTypes[$type])) {
57 | continue;
58 | }
59 |
60 | foreach ((array) $flash as $i => $message) {
61 | echo \yii\bootstrap\Alert::widget([
62 | 'body' => $message,
63 | 'closeButton' => $this->closeButton,
64 | 'options' => array_merge($this->options, [
65 | 'id' => $this->getId() . '-' . $type . '-' . $i,
66 | 'class' => $this->alertTypes[$type] . $appendClass,
67 | ]),
68 | ]);
69 | }
70 |
71 | $session->removeFlash($type);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tunecino/yii2-app-builder",
3 | "description": "Fork of Yii 2 Advanced Project Template With RESTful API, OAuth 2.0 and Schema Builder",
4 | "keywords": ["yii2", "framework", "advanced", "project template", "builder", "rest", "bearer", "rest authentication"],
5 | "type": "project",
6 | "license": "BSD-3-Clause",
7 | "support": {
8 | "issues": "https://github.com/tunecino/yii2-app-builder/issues",
9 | "wiki": "https://github.com/tunecino/yii2-app-builder/wiki",
10 | "source": "https://github.com/tunecino/yii2-app-builder"
11 | },
12 | "minimum-stability": "dev",
13 | "require": {
14 | "php": ">=5.4.0",
15 | "yiisoft/yii2": "~2.0.6",
16 | "yiisoft/yii2-bootstrap": "~2.0.0",
17 | "yiisoft/yii2-swiftmailer": "~2.0.0 || ~2.1.0",
18 | "tunecino/yii2-schema-builder": "*"
19 | },
20 | "require-dev": {
21 | "yiisoft/yii2-debug": "~2.0.0",
22 | "yiisoft/yii2-gii": "~2.0.0",
23 | "yiisoft/yii2-faker": "~2.0.0",
24 | "codeception/base": "^2.2.3",
25 | "codeception/verify": "~0.3.1"
26 | },
27 | "config": {
28 | "process-timeout": 1800
29 | },
30 | "repositories": [
31 | {
32 | "type": "composer",
33 | "url": "https://asset-packagist.org"
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/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 | 'aliases' => [
15 | '@bower' => '@vendor/bower-asset',
16 | '@npm' => '@vendor/npm-asset',
17 | ],
18 | 'controllerMap' => [
19 | 'fixture' => [
20 | 'class' => 'yii\console\controllers\FixtureController',
21 | 'namespace' => 'common\fixtures',
22 | ],
23 | ],
24 | 'components' => [
25 | 'log' => [
26 | 'targets' => [
27 | [
28 | 'class' => 'yii\log\FileTarget',
29 | 'levels' => ['error', 'warning'],
30 | ],
31 | ],
32 | ],
33 | ],
34 | 'params' => $params,
35 | ];
36 |
--------------------------------------------------------------------------------
/console/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/console/controllers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tunecino/yii2-app-builder/1dc82b976a891972294b0684bc9e76323ea9d121/console/controllers/.gitkeep
--------------------------------------------------------------------------------
/console/migrations/m130524_201442_init.php:
--------------------------------------------------------------------------------
1 | db->driverName === 'mysql') {
11 | // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
12 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
13 | }
14 |
15 | $this->createTable('user', [
16 | 'id' => $this->primaryKey(),
17 | 'username' => $this->string()->notNull()->unique(),
18 | 'auth_key' => $this->string(32)->notNull(),
19 | 'password_hash' => $this->string()->notNull(),
20 | 'password_reset_token' => $this->string()->unique(),
21 | 'email' => $this->string()->notNull()->unique(),
22 | 'status' => $this->smallInteger()->notNull()->defaultValue(10),
23 | 'created_at' => $this->integer()->notNull(),
24 | 'updated_at' => $this->integer()->notNull(),
25 | ], $tableOptions);
26 |
27 | $this->createTable('auth', [
28 | 'id' => $this->primaryKey(),
29 | 'user_id' => $this->integer()->notNull(),
30 | 'refresh_token' => $this->string(32)->notNull()->unique(),
31 | 'long_term' => $this->boolean()->notNull()->defaultValue(0),
32 | 'client_id' => $this->string()->notNull(),
33 | 'created_at' => $this->integer()->notNull(),
34 | 'updated_at' => $this->integer()->notNull(),
35 | ], $tableOptions);
36 |
37 | $this->addForeignKey('fk-auth-user_id-user-id', 'auth', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
38 | }
39 |
40 | public function down()
41 | {
42 | $this->dropTable('auth');
43 | $this->dropTable('user');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/console/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/console/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/environments/dev/api/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'] = [
16 | 'class' => 'yii\debug\Module',
17 | ];
18 |
19 | $config['bootstrap'][] = 'gii';
20 | $config['modules']['gii'] = [
21 | 'class' => 'yii\gii\Module',
22 | 'generators' => [
23 | 'rest-module' => [
24 | 'class' => 'tunecino\builder\extra\gii\restModule\Generator', // custom generator class
25 | ],
26 | 'rest-crud' => [
27 | 'class' => 'tunecino\builder\extra\gii\restCrud\Generator', // custom generator class
28 | ],
29 | ],
30 | ];
31 |
32 | $config['bootstrap'][] = 'builder';
33 | $config['modules']['builder'] = [
34 | 'class' => 'tunecino\builder\Module',
35 | 'yiiScript' => dirname(dirname(__DIR__)) . '/yii',
36 | 'previewUrlCallback' => function($entity) {
37 | $moduleName = $entity->schema->moduleID ? $entity->schema->moduleID . '/' : '';
38 | return \yii\helpers\Url::toRoute( '/' . $moduleName . \yii\helpers\Inflector::pluralize($entity->name) , true);
39 | },
40 | 'commands' => [
41 | [
42 | 'class' => 'tunecino\builder\generators\migration\Generator',
43 | ],
44 |
45 | // run default app migration scripts if any
46 | 'yii migrate/up --interactive=0',
47 |
48 | [
49 | 'class' => 'tunecino\builder\generators\restModule\Generator', // custom generator class
50 | 'defaultAttributes' => [
51 | 'generateAsModule' => true,
52 | 'moduleNamespace' => 'api\modules',
53 | ],
54 | ],
55 | [
56 | 'class' => 'tunecino\builder\generators\model\Generator',
57 | 'defaultAttributes' => [
58 | 'ns' => 'api\modules\v1\models',
59 | 'queryNs' => 'api\modules\v1\models',
60 | ],
61 | ],
62 | [
63 | 'class' => 'tunecino\builder\generators\restCrud\Generator', // custom generator class
64 | 'defaultAttributes' => [
65 | 'modelNamespace' => 'api\modules\v1\models',
66 | 'controllerNamespace' => 'api\modules\v1\controllers',
67 | 'baseControllerClass' => 'yii\rest\ActiveController',
68 | ],
69 | ],
70 | function($schema) {
71 | $moduleName = $schema->moduleID ? $schema->moduleID . '/' : '';
72 | $ctrlNames = \yii\helpers\ArrayHelper::getColumn($schema->entities,'name');
73 | $controllers = '';
74 | for ($i=0; $i < count($ctrlNames); $i++) {
75 | $controllers .= $moduleName . $ctrlNames[$i];
76 | if ($i+1 < count($ctrlNames)) $controllers .= ',';
77 | }
78 | return 'yii builder/helpers/add-rest-rules-to-file @api/config/rules.php ' . $controllers;
79 | }
80 | ],
81 | ];
82 | }
83 |
84 | return $config;
85 |
--------------------------------------------------------------------------------
/environments/dev/api/config/params-local.php:
--------------------------------------------------------------------------------
1 | [
5 | 'appconfig' => '',
6 | 'template' => 'default',
7 | 'enableI18N' => '0',
8 | 'messageCategory' => 'app',
9 | 'db' => 'db',
10 | 'migrationTable' => '{{%migration}}',
11 | 'migrationPath' => '@runtime/schema-builder/migrations',
12 | 'templateFile' => '@yii/views/migration.php',
13 | 'useTablePrefix' => '0',
14 | 'schema_id' => '595e8678a13d2',
15 | 'id' => '595e8678a28cf',
16 | ],
17 | ];
--------------------------------------------------------------------------------
/environments/dev/api/runtime/schema-builder/data/Model.php:
--------------------------------------------------------------------------------
1 | [
5 | 'appconfig' => '',
6 | 'template' => 'default',
7 | 'enableI18N' => '0',
8 | 'messageCategory' => 'app',
9 | 'db' => 'db',
10 | 'ns' => 'api\\modules\\v1\\models',
11 | 'baseClass' => 'yii\\db\\ActiveRecord',
12 | 'generateRelations' => 'all',
13 | 'useSchemaName' => '1',
14 | 'generateQuery' => '0',
15 | 'queryNs' => 'api\\modules\\v1\\models',
16 | 'queryClass' => '',
17 | 'queryBaseClass' => 'yii\\db\\ActiveQuery',
18 | 'useTablePrefix' => false,
19 | 'schema_id' => '595e8678a13d2',
20 | 'id' => '595e8678a2dc6',
21 | ],
22 | ];
--------------------------------------------------------------------------------
/environments/dev/api/runtime/schema-builder/data/RestCrud.php:
--------------------------------------------------------------------------------
1 | [
5 | 'appconfig' => '',
6 | 'template' => 'default',
7 | 'enableI18N' => '0',
8 | 'messageCategory' => 'app',
9 | 'baseControllerClass' => 'yii\\rest\\ActiveController',
10 | 'modelNamespace' => 'api\\modules\\v1\\models',
11 | 'controllerNamespace' => 'api\\modules\\v1\\controllers',
12 | 'searchModelNamespace' => '',
13 | 'schema_id' => '595e8678a13d2',
14 | 'id' => '595e8678a3163',
15 | ],
16 | ];
--------------------------------------------------------------------------------
/environments/dev/api/runtime/schema-builder/data/RestModule.php:
--------------------------------------------------------------------------------
1 | [
5 | 'appconfig' => '',
6 | 'template' => 'default',
7 | 'enableI18N' => '0',
8 | 'messageCategory' => 'app',
9 | 'generateAsModule' => '1',
10 | 'moduleNamespace' => 'api\\modules',
11 | 'schema_id' => '595e8678a13d2',
12 | 'id' => '595e8678a2b32',
13 | ],
14 | ];
--------------------------------------------------------------------------------
/environments/dev/api/runtime/schema-builder/data/Schema.php:
--------------------------------------------------------------------------------
1 | [
5 | 'name' => 'v1',
6 | 'id' => '595e8678a13d2',
7 | 'isModule' => '1',
8 | ],
9 | ];
--------------------------------------------------------------------------------
/environments/dev/api/web/.htaccess:
--------------------------------------------------------------------------------
1 | Options +FollowSymLinks
2 | IndexIgnore */*
3 |
4 | RewriteEngine on
5 |
6 | # if a directory or a file exists, use it directly
7 | RewriteCond %{REQUEST_FILENAME} !-f
8 | RewriteCond %{REQUEST_FILENAME} !-d
9 |
10 | # otherwise forward it to index.php
11 | RewriteRule . index.php
--------------------------------------------------------------------------------
/environments/dev/api/web/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/environments/dev/api/web/index.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/dev/api/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/environments/dev/auth/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 | 'mailer' => [
10 | 'class' => 'yii\swiftmailer\Mailer',
11 | 'viewPath' => '@auth/mail',
12 | // send all mails to a file by default. You have to set
13 | // 'useFileTransport' to false and configure a transport
14 | // for the mailer to send real emails.
15 | 'useFileTransport' => true,
16 | ],
17 | ],
18 | ];
19 |
20 | if (!YII_ENV_TEST) {
21 | // configuration adjustments for 'dev' environment
22 | $config['bootstrap'][] = 'debug';
23 | $config['modules']['debug'] = [
24 | 'class' => 'yii\debug\Module',
25 | ];
26 | }
27 |
28 | return $config;
29 |
--------------------------------------------------------------------------------
/environments/dev/auth/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/dev/auth/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/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'] = [
16 | 'class' => 'yii\debug\Module',
17 | ];
18 |
19 | $config['bootstrap'][] = 'gii';
20 | $config['modules']['gii'] = [
21 | 'class' => 'yii\gii\Module',
22 | ];
23 |
24 | $config['bootstrap'][] = 'builder';
25 | $config['modules']['builder'] = [
26 | 'class' => 'tunecino\builder\Module',
27 | 'yiiScript' => dirname(dirname(__DIR__)) . '/yii',
28 | 'commands' => [
29 | [
30 | 'class' => 'tunecino\builder\generators\migration\Generator'
31 | ],
32 |
33 | // run default app migration scripts if any
34 | 'yii migrate/up --interactive=0',
35 |
36 | [
37 | 'class' => 'tunecino\builder\generators\model\Generator',
38 | 'defaultAttributes' => [
39 | 'ns' => 'backend\models',
40 | 'queryNs' => 'backend\models',
41 | ],
42 | ],
43 | [
44 | 'class' => 'tunecino\builder\generators\crud\Generator',
45 | 'defaultAttributes' => [
46 | 'baseViewPath' => '@backend/views',
47 | 'modelNamespace' => 'backend\models',
48 | 'controllerNamespace' => 'backend\controllers',
49 | ],
50 | ]
51 | ],
52 | ];
53 | }
54 |
55 | return $config;
56 |
--------------------------------------------------------------------------------
/environments/dev/backend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/dev/backend/web/index.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/dev/backend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/environments/dev/common/config/main-local.php:
--------------------------------------------------------------------------------
1 | [
4 | 'db' => [
5 | 'class' => 'yii\db\Connection',
6 | 'dsn' => 'mysql:host=127.0.0.1;dbname=yii2advanced',
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 | [
8 | 'db' => [
9 | 'dsn' => 'mysql:host=localhost;dbname=yii2advanced_test',
10 | ]
11 | ],
12 | ]
13 | );
14 |
--------------------------------------------------------------------------------
/environments/dev/console/config/main-local.php:
--------------------------------------------------------------------------------
1 | ['gii', 'builder'],
4 | 'modules' => [
5 | 'gii' => [
6 | 'class' => 'yii\gii\Module',
7 | 'generators' => [
8 | 'rest-module' => [
9 | 'class' => 'tunecino\builder\extra\gii\restModule\Generator', // custom generator class
10 | ],
11 | 'rest-crud' => [
12 | 'class' => 'tunecino\builder\extra\gii\restCrud\Generator', // custom generator class
13 | ],
14 | ],
15 | ],
16 | 'builder' => 'tunecino\builder\Module',
17 | ],
18 | ];
--------------------------------------------------------------------------------
/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'] = [
16 | 'class' => 'yii\debug\Module',
17 | ];
18 |
19 | $config['bootstrap'][] = 'gii';
20 | $config['modules']['gii'] = [
21 | 'class' => 'yii\gii\Module',
22 | ];
23 |
24 | $config['bootstrap'][] = 'builder';
25 | $config['modules']['builder'] = [
26 | 'class' => 'tunecino\builder\Module',
27 | 'yiiScript' => dirname(dirname(__DIR__)) . '/yii',
28 | 'commands' => [
29 | [
30 | 'class' => 'tunecino\builder\generators\migration\Generator'
31 | ],
32 |
33 | // run default app migration scripts if any
34 | 'yii migrate/up --interactive=0',
35 |
36 | [
37 | 'class' => 'tunecino\builder\generators\model\Generator',
38 | 'defaultAttributes' => [
39 | 'ns' => 'frontend\models',
40 | 'queryNs' => 'frontend\models',
41 | ],
42 | ],
43 | [
44 | 'class' => 'tunecino\builder\generators\crud\Generator',
45 | 'defaultAttributes' => [
46 | 'baseViewPath' => '@frontend/views',
47 | 'modelNamespace' => 'frontend\models',
48 | 'controllerNamespace' => 'frontend\controllers',
49 | ],
50 | ]
51 | ],
52 | ];
53 | }
54 |
55 | return $config;
56 |
--------------------------------------------------------------------------------
/environments/dev/frontend/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
19 |
--------------------------------------------------------------------------------
/environments/dev/frontend/web/index.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/dev/frontend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/environments/dev/yii:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
28 | exit($exitCode);
29 |
--------------------------------------------------------------------------------
/environments/dev/yii_test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
27 | exit($exitCode);
28 |
--------------------------------------------------------------------------------
/environments/dev/yii_test.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_test" %*
19 |
20 | @endlocal
21 |
--------------------------------------------------------------------------------
/environments/index.php:
--------------------------------------------------------------------------------
1 | [
11 | * 'path' => 'directory storing the local files',
12 | * 'skipFiles' => [
13 | * // list of files that should only copied once and skipped if they already exist
14 | * ],
15 | * 'setWritable' => [
16 | * // list of directories that should be set writable
17 | * ],
18 | * 'setExecutable' => [
19 | * // list of files that should be set executable
20 | * ],
21 | * 'setCookieValidationKey' => [
22 | * // list of config files that need to be inserted with automatically generated cookie validation keys
23 | * ],
24 | * 'createSymlink' => [
25 | * // list of symlinks to be created. Keys are symlinks, and values are the targets.
26 | * ],
27 | * ],
28 | * ];
29 | * ```
30 | */
31 | return [
32 | 'Development' => [
33 | 'path' => 'dev',
34 | 'setWritable' => [
35 | 'backend/runtime',
36 | 'backend/web/assets',
37 | 'frontend/runtime',
38 | 'frontend/web/assets',
39 | 'api/runtime',
40 | /**
41 | * assets for temporary use in dev mode to render web based extensions like yii2-debug or gii.
42 | * It shouldn't exist in production mode as it shouldn't be needed by REST apps.
43 | */
44 | 'api/web/assets',
45 | 'auth/runtime',
46 | ],
47 | 'setExecutable' => [
48 | 'yii',
49 | 'yii_test',
50 | ],
51 | 'setCookieValidationKey' => [
52 | 'backend/config/main-local.php',
53 | 'frontend/config/main-local.php',
54 | 'api/config/main-local.php',
55 | 'auth/config/main-local.php',
56 | ],
57 | ],
58 | 'Production' => [
59 | 'path' => 'prod',
60 | 'setWritable' => [
61 | 'backend/runtime',
62 | 'backend/web/assets',
63 | 'frontend/runtime',
64 | 'frontend/web/assets',
65 | 'api/runtime',
66 | 'auth/runtime',
67 | ],
68 | 'setExecutable' => [
69 | 'yii',
70 | ],
71 | 'setCookieValidationKey' => [
72 | 'backend/config/main-local.php',
73 | 'frontend/config/main-local.php',
74 | 'api/config/main-local.php',
75 | 'auth/config/main-local.php',
76 | ],
77 | ],
78 | ];
79 |
--------------------------------------------------------------------------------
/environments/prod/api/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/api/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/prod/api/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/environments/prod/auth/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 | 'mailer' => [
9 | 'class' => 'yii\swiftmailer\Mailer',
10 | 'viewPath' => '@auth/mail',
11 | ],
12 | ],
13 | ];
14 |
--------------------------------------------------------------------------------
/environments/prod/auth/config/params-local.php:
--------------------------------------------------------------------------------
1 | run();
18 |
--------------------------------------------------------------------------------
/environments/prod/auth/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/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();
18 |
--------------------------------------------------------------------------------
/environments/prod/backend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/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();
18 |
--------------------------------------------------------------------------------
/environments/prod/frontend/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Allow: /
--------------------------------------------------------------------------------
/environments/prod/yii:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
28 | exit($exitCode);
29 |
--------------------------------------------------------------------------------
/frontend/assets/AppAsset.php:
--------------------------------------------------------------------------------
1 | 'app-frontend',
11 | 'basePath' => dirname(__DIR__),
12 | 'bootstrap' => ['log'],
13 | 'controllerNamespace' => 'frontend\controllers',
14 | 'components' => [
15 | 'request' => [
16 | 'csrfParam' => '_csrf-frontend',
17 | ],
18 | 'user' => [
19 | 'identityClass' => 'common\models\User',
20 | 'enableAutoLogin' => true,
21 | 'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
22 | ],
23 | 'session' => [
24 | // this is the name of the session cookie used for login on the frontend
25 | 'name' => 'advanced-frontend',
26 | ],
27 | 'log' => [
28 | 'traceLevel' => YII_DEBUG ? 3 : 0,
29 | 'targets' => [
30 | [
31 | 'class' => 'yii\log\FileTarget',
32 | 'levels' => ['error', 'warning'],
33 | ],
34 | ],
35 | ],
36 | 'errorHandler' => [
37 | 'errorAction' => 'site/error',
38 | ],
39 | /*
40 | 'urlManager' => [
41 | 'enablePrettyUrl' => true,
42 | 'showScriptName' => false,
43 | 'rules' => [
44 | ],
45 | ],
46 | */
47 | ],
48 | 'params' => $params,
49 | ];
50 |
--------------------------------------------------------------------------------
/frontend/config/params.php:
--------------------------------------------------------------------------------
1 | 'admin@example.com',
4 | ];
5 |
--------------------------------------------------------------------------------
/frontend/config/test.php:
--------------------------------------------------------------------------------
1 | 'app-frontend-tests',
4 | 'components' => [
5 | 'assetManager' => [
6 | 'basePath' => __DIR__ . '/../web/assets',
7 | ],
8 | 'urlManager' => [
9 | 'showScriptName' => true,
10 | ],
11 | ],
12 | ];
13 |
--------------------------------------------------------------------------------
/frontend/controllers/SiteController.php:
--------------------------------------------------------------------------------
1 | [
28 | 'class' => AccessControl::className(),
29 | 'only' => ['logout', 'signup'],
30 | 'rules' => [
31 | [
32 | 'actions' => ['signup'],
33 | 'allow' => true,
34 | 'roles' => ['?'],
35 | ],
36 | [
37 | 'actions' => ['logout'],
38 | 'allow' => true,
39 | 'roles' => ['@'],
40 | ],
41 | ],
42 | ],
43 | 'verbs' => [
44 | 'class' => VerbFilter::className(),
45 | 'actions' => [
46 | 'logout' => ['post'],
47 | ],
48 | ],
49 | ];
50 | }
51 |
52 | /**
53 | * @inheritdoc
54 | */
55 | public function actions()
56 | {
57 | return [
58 | 'error' => [
59 | 'class' => 'yii\web\ErrorAction',
60 | ],
61 | 'captcha' => [
62 | 'class' => 'yii\captcha\CaptchaAction',
63 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
64 | ],
65 | ];
66 | }
67 |
68 | /**
69 | * Displays homepage.
70 | *
71 | * @return mixed
72 | */
73 | public function actionIndex()
74 | {
75 | return $this->render('index');
76 | }
77 |
78 | /**
79 | * Logs in a user.
80 | *
81 | * @return mixed
82 | */
83 | public function actionLogin()
84 | {
85 | if (!Yii::$app->user->isGuest) {
86 | return $this->goHome();
87 | }
88 |
89 | $model = new LoginForm();
90 | if ($model->load(Yii::$app->request->post()) && $model->login()) {
91 | return $this->goBack();
92 | } else {
93 | return $this->render('login', [
94 | 'model' => $model,
95 | ]);
96 | }
97 | }
98 |
99 | /**
100 | * Logs out the current user.
101 | *
102 | * @return mixed
103 | */
104 | public function actionLogout()
105 | {
106 | Yii::$app->user->logout();
107 |
108 | return $this->goHome();
109 | }
110 |
111 | /**
112 | * Displays contact page.
113 | *
114 | * @return mixed
115 | */
116 | public function actionContact()
117 | {
118 | $model = new ContactForm();
119 | if ($model->load(Yii::$app->request->post()) && $model->validate()) {
120 | if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
121 | Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
122 | } else {
123 | Yii::$app->session->setFlash('error', 'There was an error sending your message.');
124 | }
125 |
126 | return $this->refresh();
127 | } else {
128 | return $this->render('contact', [
129 | 'model' => $model,
130 | ]);
131 | }
132 | }
133 |
134 | /**
135 | * Displays about page.
136 | *
137 | * @return mixed
138 | */
139 | public function actionAbout()
140 | {
141 | return $this->render('about');
142 | }
143 |
144 | /**
145 | * Signs user up.
146 | *
147 | * @return mixed
148 | */
149 | public function actionSignup()
150 | {
151 | $model = new SignupForm();
152 | if ($model->load(Yii::$app->request->post())) {
153 | if ($user = $model->signup()) {
154 | if (Yii::$app->getUser()->login($user)) {
155 | return $this->goHome();
156 | }
157 | }
158 | }
159 |
160 | return $this->render('signup', [
161 | 'model' => $model,
162 | ]);
163 | }
164 |
165 | /**
166 | * Requests password reset.
167 | *
168 | * @return mixed
169 | */
170 | public function actionRequestPasswordReset()
171 | {
172 | $model = new PasswordResetRequestForm();
173 | if ($model->load(Yii::$app->request->post()) && $model->validate()) {
174 | if ($model->sendEmail()) {
175 | Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
176 |
177 | return $this->goHome();
178 | } else {
179 | Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.');
180 | }
181 | }
182 |
183 | return $this->render('requestPasswordResetToken', [
184 | 'model' => $model,
185 | ]);
186 | }
187 |
188 | /**
189 | * Resets password.
190 | *
191 | * @param string $token
192 | * @return mixed
193 | * @throws BadRequestHttpException
194 | */
195 | public function actionResetPassword($token)
196 | {
197 | try {
198 | $model = new ResetPasswordForm($token);
199 | } catch (InvalidParamException $e) {
200 | throw new BadRequestHttpException($e->getMessage());
201 | }
202 |
203 | if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
204 | Yii::$app->session->setFlash('success', 'New password saved.');
205 |
206 | return $this->goHome();
207 | }
208 |
209 | return $this->render('resetPassword', [
210 | 'model' => $model,
211 | ]);
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/frontend/models/ContactForm.php:
--------------------------------------------------------------------------------
1 | 'Verification Code',
42 | ];
43 | }
44 |
45 | /**
46 | * Sends an email to the specified email address using the information collected by this model.
47 | *
48 | * @param string $email the target email address
49 | * @return bool whether the email was sent
50 | */
51 | public function sendEmail($email)
52 | {
53 | return Yii::$app->mailer->compose()
54 | ->setTo($email)
55 | ->setFrom([$this->email => $this->name])
56 | ->setSubject($this->subject)
57 | ->setTextBody($this->body)
58 | ->send();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/frontend/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/frontend/tests/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'erau',
5 | 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI',
6 | // password_0
7 | 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne',
8 | 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490',
9 | 'created_at' => '1392559490',
10 | 'updated_at' => '1392559490',
11 | 'email' => 'sfriesen@jenkins.info',
12 | ],
13 | ];
14 |
--------------------------------------------------------------------------------
/frontend/tests/_data/user.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 |
--------------------------------------------------------------------------------
/frontend/tests/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/frontend/tests/_support/.gitignore:
--------------------------------------------------------------------------------
1 | _generated
2 |
--------------------------------------------------------------------------------
/frontend/tests/_support/FunctionalTester.php:
--------------------------------------------------------------------------------
1 | see($message, '.help-block');
27 | }
28 |
29 | public function dontSeeValidationError($message)
30 | {
31 | $this->dontSee($message, '.help-block');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/frontend/tests/_support/UnitTester.php:
--------------------------------------------------------------------------------
1 | amOnPage(Url::toRoute('/site/index'));
12 | $I->see('My Application');
13 |
14 | $I->seeLink('About');
15 | $I->click('About');
16 | $I->wait(2); // wait for page to be opened
17 |
18 | $I->see('This is the About page.');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/tests/acceptance/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'davert']);
9 | * ```
10 | *
11 | * In Cept
12 | *
13 | * ```php
14 | * \Codeception\Util\Fixtures::get('user1');
15 | * ```
16 | */
--------------------------------------------------------------------------------
/frontend/tests/functional.suite.yml:
--------------------------------------------------------------------------------
1 | class_name: FunctionalTester
2 | modules:
3 | enabled:
4 | - Filesystem
5 | - Yii2
6 |
--------------------------------------------------------------------------------
/frontend/tests/functional/AboutCest.php:
--------------------------------------------------------------------------------
1 | amOnRoute('site/about');
11 | $I->see('About', 'h1');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/tests/functional/ContactCest.php:
--------------------------------------------------------------------------------
1 | amOnPage(['site/contact']);
13 | }
14 |
15 | public function checkContact(FunctionalTester $I)
16 | {
17 | $I->see('Contact', 'h1');
18 | }
19 |
20 | public function checkContactSubmitNoData(FunctionalTester $I)
21 | {
22 | $I->submitForm('#contact-form', []);
23 | $I->see('Contact', 'h1');
24 | $I->seeValidationError('Name cannot be blank');
25 | $I->seeValidationError('Email cannot be blank');
26 | $I->seeValidationError('Subject cannot be blank');
27 | $I->seeValidationError('Body cannot be blank');
28 | $I->seeValidationError('The verification code is incorrect');
29 | }
30 |
31 | public function checkContactSubmitNotCorrectEmail(FunctionalTester $I)
32 | {
33 | $I->submitForm('#contact-form', [
34 | 'ContactForm[name]' => 'tester',
35 | 'ContactForm[email]' => 'tester.email',
36 | 'ContactForm[subject]' => 'test subject',
37 | 'ContactForm[body]' => 'test content',
38 | 'ContactForm[verifyCode]' => 'testme',
39 | ]);
40 | $I->seeValidationError('Email is not a valid email address.');
41 | $I->dontSeeValidationError('Name cannot be blank');
42 | $I->dontSeeValidationError('Subject cannot be blank');
43 | $I->dontSeeValidationError('Body cannot be blank');
44 | $I->dontSeeValidationError('The verification code is incorrect');
45 | }
46 |
47 | public function checkContactSubmitCorrectData(FunctionalTester $I)
48 | {
49 | $I->submitForm('#contact-form', [
50 | 'ContactForm[name]' => 'tester',
51 | 'ContactForm[email]' => 'tester@example.com',
52 | 'ContactForm[subject]' => 'test subject',
53 | 'ContactForm[body]' => 'test content',
54 | 'ContactForm[verifyCode]' => 'testme',
55 | ]);
56 | $I->seeEmailIsSent();
57 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/frontend/tests/functional/HomeCest.php:
--------------------------------------------------------------------------------
1 | amOnPage(\Yii::$app->homeUrl);
12 | $I->see('My Application');
13 | $I->seeLink('About');
14 | $I->click('About');
15 | $I->see('This is the About page.');
16 | }
17 | }
--------------------------------------------------------------------------------
/frontend/tests/functional/LoginCest.php:
--------------------------------------------------------------------------------
1 | [
21 | 'class' => UserFixture::className(),
22 | 'dataFile' => codecept_data_dir() . 'login_data.php'
23 | ]
24 | ];
25 | }
26 |
27 | public function _before(FunctionalTester $I)
28 | {
29 | $I->amOnRoute('site/login');
30 | }
31 |
32 | protected function formParams($login, $password)
33 | {
34 | return [
35 | 'LoginForm[username]' => $login,
36 | 'LoginForm[password]' => $password,
37 | ];
38 | }
39 |
40 | public function checkEmpty(FunctionalTester $I)
41 | {
42 | $I->submitForm('#login-form', $this->formParams('', ''));
43 | $I->seeValidationError('Username cannot be blank.');
44 | $I->seeValidationError('Password cannot be blank.');
45 | }
46 |
47 | public function checkWrongPassword(FunctionalTester $I)
48 | {
49 | $I->submitForm('#login-form', $this->formParams('admin', 'wrong'));
50 | $I->seeValidationError('Incorrect username or password.');
51 | }
52 |
53 | public function checkValidLogin(FunctionalTester $I)
54 | {
55 | $I->submitForm('#login-form', $this->formParams('erau', 'password_0'));
56 | $I->see('Logout (erau)', 'form button[type=submit]');
57 | $I->dontSeeLink('Login');
58 | $I->dontSeeLink('Signup');
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/frontend/tests/functional/SignupCest.php:
--------------------------------------------------------------------------------
1 | amOnRoute('site/signup');
15 | }
16 |
17 | public function signupWithEmptyFields(FunctionalTester $I)
18 | {
19 | $I->see('Signup', 'h1');
20 | $I->see('Please fill out the following fields to signup:');
21 | $I->submitForm($this->formId, []);
22 | $I->seeValidationError('Username cannot be blank.');
23 | $I->seeValidationError('Email cannot be blank.');
24 | $I->seeValidationError('Password cannot be blank.');
25 |
26 | }
27 |
28 | public function signupWithWrongEmail(FunctionalTester $I)
29 | {
30 | $I->submitForm(
31 | $this->formId, [
32 | 'SignupForm[username]' => 'tester',
33 | 'SignupForm[email]' => 'ttttt',
34 | 'SignupForm[password]' => 'tester_password',
35 | ]
36 | );
37 | $I->dontSee('Username cannot be blank.', '.help-block');
38 | $I->dontSee('Password cannot be blank.', '.help-block');
39 | $I->see('Email is not a valid email address.', '.help-block');
40 | }
41 |
42 | public function signupSuccessfully(FunctionalTester $I)
43 | {
44 | $I->submitForm($this->formId, [
45 | 'SignupForm[username]' => 'tester',
46 | 'SignupForm[email]' => 'tester.email@example.com',
47 | 'SignupForm[password]' => 'tester_password',
48 | ]);
49 |
50 | $I->seeRecord('common\models\User', [
51 | 'username' => 'tester',
52 | 'email' => 'tester.email@example.com',
53 | ]);
54 |
55 | $I->see('Logout (tester)', 'form button[type=submit]');
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/frontend/tests/functional/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'davert']);
9 | * ```
10 | *
11 | * In Cests
12 | *
13 | * ```php
14 | * \Codeception\Util\Fixtures::get('user1');
15 | * ```
16 | */
--------------------------------------------------------------------------------
/frontend/tests/unit.suite.yml:
--------------------------------------------------------------------------------
1 | class_name: UnitTester
2 | modules:
3 | enabled:
4 | - Yii2:
5 | part: [orm, email, fixtures]
6 | - Asserts
7 |
--------------------------------------------------------------------------------
/frontend/tests/unit/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 'davert']);
9 | * ```
10 | *
11 | * In Tests
12 | *
13 | * ```php
14 | * \Codeception\Util\Fixtures::get('user1');
15 | * ```
16 | */
17 |
--------------------------------------------------------------------------------
/frontend/tests/unit/models/ContactFormTest.php:
--------------------------------------------------------------------------------
1 | attributes = [
14 | 'name' => 'Tester',
15 | 'email' => 'tester@example.com',
16 | 'subject' => 'very important letter subject',
17 | 'body' => 'body of current message',
18 | ];
19 |
20 | expect_that($model->sendEmail('admin@example.com'));
21 |
22 | // using Yii2 module actions to check email was sent
23 | $this->tester->seeEmailIsSent();
24 |
25 | $emailMessage = $this->tester->grabLastSentEmail();
26 | expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
27 | expect($emailMessage->getTo())->hasKey('admin@example.com');
28 | expect($emailMessage->getFrom())->hasKey('tester@example.com');
29 | expect($emailMessage->getSubject())->equals('very important letter subject');
30 | expect($emailMessage->toString())->contains('body of current message');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/frontend/tests/unit/models/PasswordResetRequestFormTest.php:
--------------------------------------------------------------------------------
1 | tester->haveFixtures([
21 | 'user' => [
22 | 'class' => UserFixture::className(),
23 | 'dataFile' => codecept_data_dir() . 'user.php'
24 | ]
25 | ]);
26 | }
27 |
28 | public function testSendMessageWithWrongEmailAddress()
29 | {
30 | $model = new PasswordResetRequestForm();
31 | $model->email = 'not-existing-email@example.com';
32 | expect_not($model->sendEmail());
33 | }
34 |
35 | public function testNotSendEmailsToInactiveUser()
36 | {
37 | $user = $this->tester->grabFixture('user', 1);
38 | $model = new PasswordResetRequestForm();
39 | $model->email = $user['email'];
40 | expect_not($model->sendEmail());
41 | }
42 |
43 | public function testSendEmailSuccessfully()
44 | {
45 | $userFixture = $this->tester->grabFixture('user', 0);
46 |
47 | $model = new PasswordResetRequestForm();
48 | $model->email = $userFixture['email'];
49 | $user = User::findOne(['password_reset_token' => $userFixture['password_reset_token']]);
50 |
51 | expect_that($model->sendEmail());
52 | expect_that($user->password_reset_token);
53 |
54 | $emailMessage = $this->tester->grabLastSentEmail();
55 | expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
56 | expect($emailMessage->getTo())->hasKey($model->email);
57 | expect($emailMessage->getFrom())->hasKey(Yii::$app->params['supportEmail']);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/frontend/tests/unit/models/ResetPasswordFormTest.php:
--------------------------------------------------------------------------------
1 | tester->haveFixtures([
19 | 'user' => [
20 | 'class' => UserFixture::className(),
21 | 'dataFile' => codecept_data_dir() . 'user.php'
22 | ],
23 | ]);
24 | }
25 |
26 | public function testResetWrongToken()
27 | {
28 | $this->tester->expectException('yii\base\InvalidParamException', function() {
29 | new ResetPasswordForm('');
30 | });
31 |
32 | $this->tester->expectException('yii\base\InvalidParamException', function() {
33 | new ResetPasswordForm('notexistingtoken_1391882543');
34 | });
35 | }
36 |
37 | public function testResetCorrectToken()
38 | {
39 | $user = $this->tester->grabFixture('user', 0);
40 | $form = new ResetPasswordForm($user['password_reset_token']);
41 | expect_that($form->resetPassword());
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/frontend/tests/unit/models/SignupFormTest.php:
--------------------------------------------------------------------------------
1 | tester->haveFixtures([
18 | 'user' => [
19 | 'class' => UserFixture::className(),
20 | 'dataFile' => codecept_data_dir() . 'user.php'
21 | ]
22 | ]);
23 | }
24 |
25 | public function testCorrectSignup()
26 | {
27 | $model = new SignupForm([
28 | 'username' => 'some_username',
29 | 'email' => 'some_email@example.com',
30 | 'password' => 'some_password',
31 | ]);
32 |
33 | $user = $model->signup();
34 |
35 | expect($user)->isInstanceOf('common\models\User');
36 |
37 | expect($user->username)->equals('some_username');
38 | expect($user->email)->equals('some_email@example.com');
39 | expect($user->validatePassword('some_password'))->true();
40 | }
41 |
42 | public function testNotCorrectSignup()
43 | {
44 | $model = new SignupForm([
45 | 'username' => 'troy.becker',
46 | 'email' => 'nicolas.dianna@hotmail.com',
47 | 'password' => 'some_password',
48 | ]);
49 |
50 | expect_not($model->signup());
51 | expect_that($model->getErrors('username'));
52 | expect_that($model->getErrors('email'));
53 |
54 | expect($model->getFirstError('username'))
55 | ->equals('This username has already been taken.');
56 | expect($model->getFirstError('email'))
57 | ->equals('This email address has already been taken.');
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/frontend/views/layouts/main.php:
--------------------------------------------------------------------------------
1 |
15 | beginPage() ?>
16 |
17 |
18 |
19 |
20 |
21 |
22 | = Html::csrfMetaTags() ?>
23 | = Html::encode($this->title) ?>
24 | head() ?>
25 |
26 |
27 | beginBody() ?>
28 |
29 |
30 | Yii::$app->name,
33 | 'brandUrl' => Yii::$app->homeUrl,
34 | 'options' => [
35 | 'class' => 'navbar-inverse navbar-fixed-top',
36 | ],
37 | ]);
38 | $menuItems = [
39 | ['label' => 'Home', 'url' => ['/site/index']],
40 | ['label' => 'About', 'url' => ['/site/about']],
41 | ['label' => 'Contact', 'url' => ['/site/contact']],
42 | ];
43 | if (Yii::$app->user->isGuest) {
44 | $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];
45 | $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
46 | } else {
47 | $menuItems[] = '
'
48 | . Html::beginForm(['/site/logout'], 'post')
49 | . Html::submitButton(
50 | 'Logout (' . Yii::$app->user->identity->username . ')',
51 | ['class' => 'btn btn-link logout']
52 | )
53 | . Html::endForm()
54 | . '';
55 | }
56 | echo Nav::widget([
57 | 'options' => ['class' => 'navbar-nav navbar-right'],
58 | 'items' => $menuItems,
59 | ]);
60 | NavBar::end();
61 | ?>
62 |
63 |
64 | = Breadcrumbs::widget([
65 | 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
66 | ]) ?>
67 | = Alert::widget() ?>
68 | = $content ?>
69 |
70 |
71 |
72 |
79 |
80 | endBody() ?>
81 |
82 |
83 | endPage() ?>
84 |
--------------------------------------------------------------------------------
/frontend/views/site/about.php:
--------------------------------------------------------------------------------
1 | title = 'About';
8 | $this->params['breadcrumbs'][] = $this->title;
9 | ?>
10 |
11 |
= Html::encode($this->title) ?>
12 |
13 |
This is the About page. You may modify the following file to customize its content:
14 |
15 |
= __FILE__ ?>
16 |
17 |
--------------------------------------------------------------------------------
/frontend/views/site/contact.php:
--------------------------------------------------------------------------------
1 | title = 'Contact';
12 | $this->params['breadcrumbs'][] = $this->title;
13 | ?>
14 |
46 |
--------------------------------------------------------------------------------
/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/views/site/index.php:
--------------------------------------------------------------------------------
1 | title = 'My Yii Application';
6 | ?>
7 |
8 |
9 |
10 |
Congratulations!
11 |
12 |
You have successfully created your Yii-powered application.
13 |
14 |
Get started with Yii
15 |
16 |
17 |
18 |
19 |
20 |
21 |
Heading
22 |
23 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
24 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
25 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
26 | fugiat nulla pariatur.
27 |
28 |
Yii Documentation »
29 |
30 |
31 |
Heading
32 |
33 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
34 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
35 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
36 | fugiat nulla pariatur.
37 |
38 |
Yii Forum »
39 |
40 |
41 |
Heading
42 |
43 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
44 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
45 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
46 | fugiat nulla pariatur.
47 |
48 |
Yii Extensions »
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/frontend/views/site/login.php:
--------------------------------------------------------------------------------
1 | title = 'Login';
11 | $this->params['breadcrumbs'][] = $this->title;
12 | ?>
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
Please fill out the following fields to login:
17 |
18 |
19 |
20 | 'login-form']); ?>
21 |
22 | = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
23 |
24 | = $form->field($model, 'password')->passwordInput() ?>
25 |
26 | = $form->field($model, 'rememberMe')->checkbox() ?>
27 |
28 |
29 | If you forgot your password you can = Html::a('reset it', ['site/request-password-reset']) ?>.
30 |
31 |
32 |
33 | = Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/frontend/views/site/requestPasswordResetToken.php:
--------------------------------------------------------------------------------
1 | title = 'Request password reset';
11 | $this->params['breadcrumbs'][] = $this->title;
12 | ?>
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
Please fill out your email. A link to reset password will be sent there.
17 |
18 |
19 |
20 | 'request-password-reset-form']); ?>
21 |
22 | = $form->field($model, 'email')->textInput(['autofocus' => true]) ?>
23 |
24 |
25 | = Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/frontend/views/site/resetPassword.php:
--------------------------------------------------------------------------------
1 | title = 'Reset password';
11 | $this->params['breadcrumbs'][] = $this->title;
12 | ?>
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
Please choose your new password:
17 |
18 |
19 |
20 | 'reset-password-form']); ?>
21 |
22 | = $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>
23 |
24 |
25 | = Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/frontend/views/site/signup.php:
--------------------------------------------------------------------------------
1 | title = 'Signup';
11 | $this->params['breadcrumbs'][] = $this->title;
12 | ?>
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
Please fill out the following fields to signup:
17 |
18 |
19 |
20 | 'form-signup']); ?>
21 |
22 | = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
23 |
24 | = $form->field($model, 'email') ?>
25 |
26 | = $form->field($model, 'password')->passwordInput() ?>
27 |
28 |
29 | = Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/frontend/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 | /robots.txt
4 |
--------------------------------------------------------------------------------
/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: "\e151";
53 | }
54 |
55 | a.desc:after {
56 | content: "\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 td {
76 | white-space: nowrap;
77 | }
78 |
79 | .grid-view .filters input,
80 | .grid-view .filters select {
81 | min-width: 50px;
82 | }
83 |
84 | .hint-block {
85 | display: block;
86 | margin-top: 5px;
87 | color: #999;
88 | }
89 |
90 | .error-summary {
91 | color: #a94442;
92 | background: #fdf7f7;
93 | border-left: 3px solid #eed3d7;
94 | padding: 10px 20px;
95 | margin: 0 0 15px 0;
96 | }
97 |
98 | /* align the logout "link" (button in form) of the navbar */
99 | .nav li > form > button.logout {
100 | padding: 15px;
101 | border: none;
102 | }
103 |
104 | @media(max-width:767px) {
105 | .nav li > form > button.logout {
106 | display:block;
107 | text-align: left;
108 | width: 100%;
109 | padding: 10px 15px;
110 | }
111 | }
112 |
113 | .nav > li > form > button.logout:focus,
114 | .nav > li > form > button.logout:hover {
115 | text-decoration: none;
116 | }
117 |
118 | .nav > li > form > button.logout:focus {
119 | outline: none;
120 | }
121 |
--------------------------------------------------------------------------------
/frontend/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tunecino/yii2-app-builder/1dc82b976a891972294b0684bc9e76323ea9d121/frontend/web/favicon.ico
--------------------------------------------------------------------------------
/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 | if (isset($env['skipFiles'])) {
69 | $skipFiles = $env['skipFiles'];
70 | array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; });
71 | $files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists')));
72 | }
73 | $all = false;
74 | foreach ($files as $file) {
75 | if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
76 | break;
77 | }
78 | }
79 |
80 | $callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink'];
81 | foreach ($callbacks as $callback) {
82 | if (!empty($env[$callback])) {
83 | $callback($root, $env[$callback]);
84 | }
85 | }
86 |
87 | echo "\n ... initialization completed.\n\n";
88 |
89 | function getFileList($root, $basePath = '')
90 | {
91 | $files = [];
92 | $handle = opendir($root);
93 | while (($path = readdir($handle)) !== false) {
94 | if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') {
95 | continue;
96 | }
97 | $fullPath = "$root/$path";
98 | $relativePath = $basePath === '' ? $path : "$basePath/$path";
99 | if (is_dir($fullPath)) {
100 | $files = array_merge($files, getFileList($fullPath, $relativePath));
101 | } else {
102 | $files[] = $relativePath;
103 | }
104 | }
105 | closedir($handle);
106 | return $files;
107 | }
108 |
109 | function copyFile($root, $source, $target, &$all, $params)
110 | {
111 | if (!is_file($root . '/' . $source)) {
112 | echo " skip $target ($source not exist)\n";
113 | return true;
114 | }
115 | if (is_file($root . '/' . $target)) {
116 | if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
117 | echo " unchanged $target\n";
118 | return true;
119 | }
120 | if ($all) {
121 | echo " overwrite $target\n";
122 | } else {
123 | echo " exist $target\n";
124 | echo " ...overwrite? [Yes|No|All|Quit] ";
125 |
126 |
127 | $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
128 | if (!strncasecmp($answer, 'q', 1)) {
129 | return false;
130 | } else {
131 | if (!strncasecmp($answer, 'y', 1)) {
132 | echo " overwrite $target\n";
133 | } else {
134 | if (!strncasecmp($answer, 'a', 1)) {
135 | echo " overwrite $target\n";
136 | $all = true;
137 | } else {
138 | echo " skip $target\n";
139 | return true;
140 | }
141 | }
142 | }
143 | }
144 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
145 | return true;
146 | }
147 | echo " generate $target\n";
148 | @mkdir(dirname($root . '/' . $target), 0777, true);
149 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
150 | return true;
151 | }
152 |
153 | function getParams()
154 | {
155 | $rawParams = [];
156 | if (isset($_SERVER['argv'])) {
157 | $rawParams = $_SERVER['argv'];
158 | array_shift($rawParams);
159 | }
160 |
161 | $params = [];
162 | foreach ($rawParams as $param) {
163 | if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
164 | $name = $matches[1];
165 | $params[$name] = isset($matches[3]) ? $matches[3] : true;
166 | } else {
167 | $params[] = $param;
168 | }
169 | }
170 | return $params;
171 | }
172 |
173 | function setWritable($root, $paths)
174 | {
175 | foreach ($paths as $writable) {
176 | if (is_dir("$root/$writable")) {
177 | if (@chmod("$root/$writable", 0777)) {
178 | echo " chmod 0777 $writable\n";
179 | } else {
180 | printError("Operation chmod not permitted for directory $writable.");
181 | }
182 | } else {
183 | printError("Directory $writable does not exist.");
184 | }
185 | }
186 | }
187 |
188 | function setExecutable($root, $paths)
189 | {
190 | foreach ($paths as $executable) {
191 | if (file_exists("$root/$executable")) {
192 | if (@chmod("$root/$executable", 0755)) {
193 | echo " chmod 0755 $executable\n";
194 | } else {
195 | printError("Operation chmod not permitted for $executable.");
196 | }
197 | } else {
198 | printError("$executable does not exist.");
199 | }
200 | }
201 | }
202 |
203 | function setCookieValidationKey($root, $paths)
204 | {
205 | foreach ($paths as $file) {
206 | echo " generate cookie validation key in $file\n";
207 | $file = $root . '/' . $file;
208 | $length = 32;
209 | $bytes = openssl_random_pseudo_bytes($length);
210 | $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
211 | $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
212 | file_put_contents($file, $content);
213 | }
214 | }
215 |
216 | function createSymlink($root, $links)
217 | {
218 | foreach ($links as $link => $target) {
219 | //first removing folders to avoid errors if the folder already exists
220 | @rmdir($root . "/" . $link);
221 | //next removing existing symlink in order to update the target
222 | if (is_link($root . "/" . $link)) {
223 | @unlink($root . "/" . $link);
224 | }
225 | if (@symlink($root . "/" . $target, $root . "/" . $link)) {
226 | echo " symlink $root/$target $root/$link\n";
227 | } else {
228 | printError("Cannot create symlink $root/$target $root/$link.");
229 | }
230 | }
231 | }
232 |
233 | /**
234 | * Prints error message.
235 | * @param string $message message
236 | */
237 | function printError($message)
238 | {
239 | echo "\n " . formatMessage("Error. $message", ['fg-red']) . " \n";
240 | }
241 |
242 | /**
243 | * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream.
244 | *
245 | * - windows without ansicon
246 | * - not tty consoles
247 | *
248 | * @return boolean true if the stream supports ANSI colors, otherwise false.
249 | */
250 | function ansiColorsSupported()
251 | {
252 | return DIRECTORY_SEPARATOR === '\\'
253 | ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'
254 | : function_exists('posix_isatty') && @posix_isatty(STDOUT);
255 | }
256 |
257 | /**
258 | * Get ANSI code of style.
259 | * @param string $name style name
260 | * @return integer ANSI code of style.
261 | */
262 | function getStyleCode($name)
263 | {
264 | $styles = [
265 | 'bold' => 1,
266 | 'fg-black' => 30,
267 | 'fg-red' => 31,
268 | 'fg-green' => 32,
269 | 'fg-yellow' => 33,
270 | 'fg-blue' => 34,
271 | 'fg-magenta' => 35,
272 | 'fg-cyan' => 36,
273 | 'fg-white' => 37,
274 | 'bg-black' => 40,
275 | 'bg-red' => 41,
276 | 'bg-green' => 42,
277 | 'bg-yellow' => 43,
278 | 'bg-blue' => 44,
279 | 'bg-magenta' => 45,
280 | 'bg-cyan' => 46,
281 | 'bg-white' => 47,
282 | ];
283 | return $styles[$name];
284 | }
285 |
286 | /**
287 | * Formats message using styles if STDOUT supports it.
288 | * @param string $message message
289 | * @param string[] $styles styles
290 | * @return string formatted message.
291 | */
292 | function formatMessage($message, $styles)
293 | {
294 | if (empty($styles) || !ansiColorsSupported()) {
295 | return $message;
296 | }
297 |
298 | return sprintf("\x1b[%sm", implode(';', array_map('getStyleCode', $styles))) . $message . "\x1b[0m";
299 | }
300 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/vagrant/config/.gitignore:
--------------------------------------------------------------------------------
1 | # local configuration
2 | vagrant-local.yml
--------------------------------------------------------------------------------
/vagrant/config/vagrant-local.example.yml:
--------------------------------------------------------------------------------
1 | # Your personal GitHub token
2 | github_token:
3 | # Read more: https://github.com/blog/1509-personal-api-tokens
4 | # You can generate it here: https://github.com/settings/tokens
5 |
6 | # Guest OS timezone
7 | timezone: Europe/London
8 |
9 | # Are we need check box updates for every 'vagrant up'?
10 | box_check_update: false
11 |
12 | # Virtual machine name
13 | machine_name: y2aa
14 |
15 | # Virtual machine IP
16 | ip: 192.168.83.137
17 |
18 | # Virtual machine CPU cores number
19 | cpus: 1
20 |
21 | # Virtual machine RAM
22 | memory: 1024
23 |
--------------------------------------------------------------------------------
/vagrant/nginx/app.conf:
--------------------------------------------------------------------------------
1 | server {
2 | charset utf-8;
3 | client_max_body_size 128M;
4 | sendfile off;
5 |
6 | listen 80; ## listen for ipv4
7 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
8 |
9 | server_name y2aa-frontend.dev;
10 | root /app/frontend/web/;
11 | index index.php;
12 |
13 | access_log /app/vagrant/nginx/log/frontend-access.log;
14 | error_log /app/vagrant/nginx/log/frontend-error.log;
15 |
16 | location / {
17 | # Redirect everything that isn't a real file to index.php
18 | try_files $uri $uri/ /index.php$is_args$args;
19 | }
20 |
21 | # uncomment to avoid processing of calls to non-existing static files by Yii
22 | #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
23 | # try_files $uri =404;
24 | #}
25 | #error_page 404 /404.html;
26 |
27 | location ~ \.php$ {
28 | include fastcgi_params;
29 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
30 | #fastcgi_pass 127.0.0.1:9000;
31 | fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
32 | try_files $uri =404;
33 | }
34 |
35 | location ~ /\.(ht|svn|git) {
36 | deny all;
37 | }
38 | }
39 |
40 | server {
41 | charset utf-8;
42 | client_max_body_size 128M;
43 | sendfile off;
44 |
45 | listen 80; ## listen for ipv4
46 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
47 |
48 | server_name y2aa-backend.dev;
49 | root /app/backend/web/;
50 | index index.php;
51 |
52 | access_log /app/vagrant/nginx/log/backend-access.log;
53 | error_log /app/vagrant/nginx/log/backend-error.log;
54 |
55 | location / {
56 | # Redirect everything that isn't a real file to index.php
57 | try_files $uri $uri/ /index.php$is_args$args;
58 | }
59 |
60 | # uncomment to avoid processing of calls to non-existing static files by Yii
61 | #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
62 | # try_files $uri =404;
63 | #}
64 | #error_page 404 /404.html;
65 |
66 | location ~ \.php$ {
67 | include fastcgi_params;
68 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
69 | #fastcgi_pass 127.0.0.1:9000;
70 | fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
71 | try_files $uri =404;
72 | }
73 |
74 | location ~ /\.(ht|svn|git) {
75 | deny all;
76 | }
77 | }
78 |
79 | server {
80 | charset utf-8;
81 | client_max_body_size 128M;
82 | sendfile off;
83 |
84 | listen 80; ## listen for ipv4
85 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
86 |
87 | server_name y2aa-api.dev;
88 | root /app/api/web/;
89 | index index.php;
90 |
91 | access_log /app/vagrant/nginx/log/api-access.log;
92 | error_log /app/vagrant/nginx/log/api-error.log;
93 |
94 | location / {
95 | # Redirect everything that isn't a real file to index.php
96 | try_files $uri $uri/ /index.php$is_args$args;
97 | }
98 |
99 | # uncomment to avoid processing of calls to non-existing static files by Yii
100 | #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
101 | # try_files $uri =404;
102 | #}
103 | #error_page 404 /404.html;
104 |
105 | location ~ \.php$ {
106 | include fastcgi_params;
107 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
108 | #fastcgi_pass 127.0.0.1:9000;
109 | fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
110 | try_files $uri =404;
111 | }
112 |
113 | location ~ /\.(ht|svn|git) {
114 | deny all;
115 | }
116 | }
117 |
118 | server {
119 | charset utf-8;
120 | client_max_body_size 128M;
121 | sendfile off;
122 |
123 | listen 80; ## listen for ipv4
124 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
125 |
126 | server_name y2aa-auth.dev;
127 | root /app/auth/web/;
128 | index index.php;
129 |
130 | access_log /app/vagrant/nginx/log/auth-access.log;
131 | error_log /app/vagrant/nginx/log/auth-error.log;
132 |
133 | location / {
134 | # Redirect everything that isn't a real file to index.php
135 | try_files $uri $uri/ /index.php$is_args$args;
136 | }
137 |
138 | # uncomment to avoid processing of calls to non-existing static files by Yii
139 | #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
140 | # try_files $uri =404;
141 | #}
142 | #error_page 404 /404.html;
143 |
144 | location ~ \.php$ {
145 | include fastcgi_params;
146 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
147 | #fastcgi_pass 127.0.0.1:9000;
148 | fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
149 | try_files $uri =404;
150 | }
151 |
152 | location ~ /\.(ht|svn|git) {
153 | deny all;
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/vagrant/nginx/log/.gitignore:
--------------------------------------------------------------------------------
1 | # nginx logs
2 | backend-access.log
3 | backend-error.log
4 | frontend-access.log
5 | frontend-error.log
6 | api-access.log
7 | api-error.log
8 | auth-access.log
9 | auth-error.log
--------------------------------------------------------------------------------
/vagrant/provision/always-as-root.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #== Bash helpers ==
4 |
5 | function info {
6 | echo " "
7 | echo "--> $1"
8 | echo " "
9 | }
10 |
11 | #== Provision script ==
12 |
13 | info "Provision-script user: `whoami`"
14 |
15 | info "Restart web-stack"
16 | service php7.0-fpm restart
17 | service nginx restart
18 | service mysql restart
--------------------------------------------------------------------------------
/vagrant/provision/once-as-root.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #== Import script args ==
4 |
5 | timezone=$(echo "$1")
6 |
7 | #== Bash helpers ==
8 |
9 | function info {
10 | echo " "
11 | echo "--> $1"
12 | echo " "
13 | }
14 |
15 | #== Provision script ==
16 |
17 | info "Provision-script user: `whoami`"
18 |
19 | export DEBIAN_FRONTEND=noninteractive
20 |
21 | info "Configure timezone"
22 | timedatectl set-timezone ${timezone} --no-ask-password
23 |
24 | info "Prepare root password for MySQL"
25 | debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass password \"''\""
26 | debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass password \"''\""
27 | echo "Done!"
28 |
29 | info "Update OS software"
30 | apt-get update
31 | apt-get upgrade -y
32 |
33 | info "Install additional software"
34 | apt-get install -y php7.0-curl php7.0-cli php7.0-intl php7.0-mysqlnd php7.0-gd php7.0-fpm php7.0-mbstring php7.0-xml unzip nginx mysql-server-5.7 php.xdebug
35 |
36 | info "Configure MySQL"
37 | sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf
38 | mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''"
39 | mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'"
40 | mysql -uroot <<< "DROP USER 'root'@'localhost'"
41 | mysql -uroot <<< "FLUSH PRIVILEGES"
42 | echo "Done!"
43 |
44 | info "Configure PHP-FPM"
45 | sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
46 | sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
47 | sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
48 | cat << EOF > /etc/php/7.0/mods-available/xdebug.ini
49 | zend_extension=xdebug.so
50 | xdebug.remote_enable=1
51 | xdebug.remote_connect_back=1
52 | xdebug.remote_port=9000
53 | xdebug.remote_autostart=1
54 | EOF
55 | echo "Done!"
56 |
57 | info "Configure NGINX"
58 | sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf
59 | echo "Done!"
60 |
61 | info "Enabling site configuration"
62 | ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf
63 | echo "Done!"
64 |
65 | info "Initailize databases for MySQL"
66 | mysql -uroot <<< "CREATE DATABASE yii2advanced"
67 | mysql -uroot <<< "CREATE DATABASE yii2advanced_test"
68 | echo "Done!"
69 |
70 | info "Install composer"
71 | curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
--------------------------------------------------------------------------------
/vagrant/provision/once-as-vagrant.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #== Import script args ==
4 |
5 | github_token=$(echo "$1")
6 |
7 | #== Bash helpers ==
8 |
9 | function info {
10 | echo " "
11 | echo "--> $1"
12 | echo " "
13 | }
14 |
15 | #== Provision script ==
16 |
17 | info "Provision-script user: `whoami`"
18 |
19 | info "Configure composer"
20 | composer config --global github-oauth.github.com ${github_token}
21 | echo "Done!"
22 |
23 | info "Install project dependencies"
24 | cd /app
25 | composer --no-progress --prefer-dist install
26 |
27 | info "Init project"
28 | ./init --env=Development --overwrite=y
29 |
30 | info "Apply migrations"
31 | ./yii migrate --interactive=0
32 | ./yii_test migrate --interactive=0
33 |
34 | info "Create bash-alias 'app' for vagrant user"
35 | echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases
36 |
37 | info "Enabling colorized prompt for guest console"
38 | sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc
39 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------