├── .bowerrc
├── .env-dist
├── .gitignore
├── LICENSE.md
├── README.md
├── Vagrantfile
├── backend
├── assets
│ └── AppAsset.php
├── codeception.yml
├── components
│ └── AdminAccessControl.php
├── config
│ ├── .gitignore
│ ├── bootstrap.php
│ ├── main.php
│ ├── params.php
│ └── test.php
├── controllers
│ ├── BaseAdminController.php
│ ├── EmailFormController.php
│ ├── LogController.php
│ └── SiteController.php
├── models
│ ├── .gitkeep
│ ├── EmailFormSearch.php
│ ├── Log.php
│ └── LogSearch.php
├── 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
│ ├── email-form
│ │ ├── _form.php
│ │ ├── _search.php
│ │ ├── create.php
│ │ ├── index.php
│ │ ├── update.php
│ │ └── view.php
│ ├── layouts
│ │ ├── main-login.php
│ │ └── main.php
│ ├── log
│ │ ├── index.php
│ │ └── view.php
│ └── site
│ │ ├── error.php
│ │ └── index.php
└── web
│ ├── .gitignore
│ ├── .htaccess
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ ├── favicon.ico
│ └── img
│ └── 128x128.png
├── 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
├── messages
│ ├── config.php
│ └── ru-RU
│ │ ├── app-backend.php
│ │ ├── app-forms.php
│ │ └── app-model.php
├── models
│ ├── EmailForm.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
│ ├── M180422195051Insert_adminus.php
│ ├── m180422_170849_create_email_form_table.php
│ └── m180430_141650_cache.php
├── models
│ └── .gitkeep
└── runtime
│ └── .gitignore
├── db
└── docker-entrypoint-initdb.d
│ ├── .gitignore
│ └── createdb.sql.example
├── docker-compose.yml
├── environments
├── dev
│ ├── 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
│ ├── 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
│ └── urls.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
│ ├── .htaccess
│ ├── assets
│ └── .gitignore
│ ├── css
│ └── site.css
│ └── favicon.ico
├── init
├── init.bat
├── nginx
├── Dockerfile
├── gzip.conf
├── nginx.conf
└── run.sh
├── package.json
├── php
├── Dockerfile-alpine
├── Dockerfile-debian
└── image-files
│ ├── etc
│ └── apache2
│ │ └── sites-available
│ │ └── 000-default.conf
│ ├── root
│ └── .bashrc
│ └── usr
│ └── local
│ ├── bin
│ ├── composer
│ └── docker-php-entrypoint
│ └── etc
│ └── php
│ └── conf.d
│ ├── base.ini
│ └── xdebug.ini
├── postcss.config.js
├── requirements.php
├── vagrant
├── config
│ ├── .gitignore
│ └── vagrant-local.example.yml
├── nginx
│ ├── app.conf
│ └── log
│ │ └── .gitignore
└── provision
│ ├── always-as-root.sh
│ ├── common.sh
│ ├── once-as-root.sh
│ └── once-as-vagrant.sh
└── yii.bat
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory" : "vendor/bower-asset"
3 | }
4 |
--------------------------------------------------------------------------------
/.env-dist:
--------------------------------------------------------------------------------
1 | ## Built image name
2 | PHP_IMAGE_NAME=local/yii2-php
3 | PHP_IMAGE_VERSION_SUFFIX=
4 |
5 | ## PHP-fpm & nginx
6 | COMPOSE_PROJECT_NAME=yii2fpm
7 | COMPOSE_FILE=docker-compose.yml
8 | DOCKERFILE_FLAVOUR=debian
9 | PHP_BASE_IMAGE_VERSION=7.3-fpm
10 |
11 | ## Runtime settings
12 | # Xdebug (calling the xdebug.remote_host on 9005 port)
13 | PHP_ENABLE_XDEBUG=0
14 |
--------------------------------------------------------------------------------
/.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 | /node_modules
37 | /db/data
38 |
39 | .env
40 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The Yii App is free software. It is released under the terms of
2 | the following BSD License.
3 |
4 | Copyright © 2018 by Akiraz
5 | All rights are not 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 Fast Simple Advanced App [](https://packagist.org/packages/akiraz2/yii2-app) [](https://packagist.org/packages/akiraz2/yii2-app)
2 |
3 | Yii2-app is Fast and Ready-to-production advanced project template.
4 |
5 | Dockerized, for development (mysql, nginx, php-fpm)
6 |
7 | Please, [enable php intl extension](http://php.net/manual/en/intl.installation.php) for better work.
8 |
9 | Default, the template includes three tiers: `frontend`, `backend`, and `console`, each of which is a separate Yii application.
10 |
11 | > **NOTE:** Template is in initial development. Anything may change at any time.
12 |
13 |
14 | ## Features
15 | * Gentelella Admin template is beautiful and simple bootstrap, compatible with yii2 assets: [yiister/yii2-gentelella](https://github.com/yiister/yii2-gentelella), [Demo](https://colorlib.com/polygon/gentelella/)
16 | * Yii2 User is strong and proved user-module with many features: [dektrium/yii2-user](https://github.com/dektrium/yii2-user) (login `adminus`, password `adminus`)
17 | * Frontend and Backend User Controllers are filtered (by `dektrium/yii2-user`)
18 | * File or DB cache, but I recommend Redis Cache - it is really fast
19 | * Yii2 queue (DB table `queue`), but you can use *Redis-queue* or other [yii2-queue docs](https://github.com/yiisoft/yii2-queue/blob/master/docs/guide/README.md)
20 | * Queue Manager with backend (`/queuemanager/default/index`) using [ignatenkovnikita/yii2-queuemanager](https://github.com/ignatenkovnikita/yii2-queuemanager)
21 | * Log DB Target with backend (`/log/index`) - simply view log messages
22 | * .htaccess - config for **pretty urls** (rewrite index.php), *may be later add nginx config*
23 | * **UrlManagerFrontend** for backend app (all url rules in file `frontend/config/urls.php`, hostInfo in `common/config/params.php`)
24 | * i18n translations in `common/messages` with config (current only English and Russian, language translation are welcome!)
25 | * ContactForm in frontend app is improved: [himiklab/yii2-recaptcha-widget](https://github.com/himiklab/yii2-recaptcha-widget),
26 | all email are saved to DB (`common/models/EmailForm` Model), optionally send message to Viber messenger via bot
27 | (install requirements [Bogdaan/viber-bot-php](https://github.com/Bogdaan/viber-bot-php) and config, uncomment code in Model)
28 | * Gii generator:
29 | 1. added **yii2-queue** Jobs generator
30 | 2. yii2 migration generator (from existing table) [Insolita/yii2-migrik](https://github.com/Insolita/yii2-migrik)
31 | 3. [schmunk42/yii2-giiant](https://github.com/schmunk42/yii2-giiant) - really steroid, but in development with bugs
32 |
33 |
34 | ## Available modules
35 | These modules can be easy installed to Yii2-App using Composer:
36 |
37 | * Yii2 Super Blog Module (semantic, seo): [akiraz2/yii2-blog](https://github.com/akiraz2/yii2-blog)
38 | * Yii2 many web-statictic counters (all-in-one) *(yandex, google, own db-counter)*: [akiraz2/yii2-stat](https://github.com/akiraz2/yii2-stat)
39 | * yii2 opengraph component: [dragonjet/yii2-opengraph](https://github.com/dragonjet/yii2-opengraph)
40 | * yii2 settings (db+cache): [yii2mod/yii2-settings](https://github.com/yii2mod/yii2-settings)
41 | * etc...
42 |
43 |
44 | ## Installation
45 | Yii2-app template can be installed using composer. Run following command to download and install Yii2-app:
46 | ```
47 | composer create-project --prefer-dist akiraz2/yii2-app my-site
48 | ```
49 | After installation run `init`
50 |
51 | ## Docker
52 | Install yii2-app using [Docker](https://www.docker.com):
53 |
54 | 0. run command to create project
55 | ```
56 | docker run --rm --interactive --tty \
57 | --volume $PWD:/app \
58 | --volume ${COMPOSER_HOME:-$HOME/.composer}:/tmp \
59 | composer create-project --prefer-dist akiraz2/yii2-app my-site
60 | ```
61 | 1. copy `.env-dist` to `.env`, configure if needed. You can change DB from mysql to postgresql - just change docker-compose.yml (and common/config/main-local.php after init)
62 | 2. copy `/mysql/docker-entrypoint-initdb.d/createdb.sql.example` to `createdb.sql` if you have ready DB (so dont run migrations)
63 | 3. `docker-compose build` (you can configure Docker PHP in /php/Dockerfile-debian before building, for example, add mongodb)
64 | 4. `docker-compose up -d`
65 | 5. `docker-compose exec php bash`, in terminal run `composer install`, then `php init`, then run other migrations (see next)
66 | 6. open [http://localhost:8100](http://localhost:8100) to test frontend (backend is on [http://localhost:8200](localhost:8200))
67 |
68 | Access to Console App: `docker-compose exec php bash` and `php yii mycommand/action`
69 |
70 | ### Migrations
71 |
72 | > **NOTE:** Make sure that you have properly configured `db` application component and run the following command
73 |
74 | ```
75 | php yii migrate/up --migrationPath=@vendor/dektrium/yii2-user/migrations
76 | php yii migrate --migrationPath=@yii/log/migrations/
77 | php yii migrate --migrationPath=vendor/ignatenkovnikita/yii2-queuemanager/migrations/
78 | php yii migrate/up
79 | ```
80 |
81 | ### Default User Credentials
82 | login: `adminus`
83 | password: `adminus`
84 |
85 | ### Web server config
86 |
87 | For newbies, I will recommend reading these instructions [yiisoft/yii2-app-advanced/start-installation.md](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-installation.md) (apache, nginx, etc\hosts
88 |
89 | ## Development
90 |
91 | ### Messages
92 | Change in `common/config/main.php`
93 | ```
94 | 'language' => 'ru-RU',
95 | 'sourceLanguage' => 'en-US',
96 | ```
97 |
98 | Add your language in `common/messages/config.php`
99 | ```
100 | 'languages' => [
101 | 'ru-RU',
102 | ],
103 | ```
104 | In shell
105 | ```
106 | php yii message/extract common/messages/config.php
107 | ```
108 |
109 | ## Support
110 |
111 | If you have any questions or problems with Yii2-App you can ask them directly
112 | by using following email address: `akiraz@bk.ru`.
113 |
114 |
115 | ## Contributing
116 |
117 | If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.
118 | +PSR-2 style coding.
119 |
120 | I can apply patch, PR in 2-3 days! If not, please write me `akiraz@bk.ru`
121 |
122 | ## Licensing
123 |
124 | Yii2-App is released under the BSD License. See the bundled [LICENSE.md](LICENSE.md)
125 | for details.
126 |
--------------------------------------------------------------------------------
/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.test',
11 | backend: 'y2aa-backend.test'
12 | }
13 |
14 | config = {
15 | local: './vagrant/config/vagrant-local.yml',
16 | example: './vagrant/config/vagrant-local.example.yml'
17 | }
18 |
19 | # copy config from example if local config not exists
20 | FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
21 | # read config
22 | options = YAML.load_file config[:local]
23 |
24 | # check github token
25 | if options['github_token'].nil? || options['github_token'].to_s.length != 40
26 | puts "You must place REAL GitHub token into configuration:\n/yii2-app-advanced/vagrant/config/vagrant-local.yml"
27 | exit
28 | end
29 |
30 | # vagrant configurate
31 | Vagrant.configure(2) do |config|
32 | # select the box
33 | config.vm.box = 'bento/ubuntu-16.04'
34 |
35 | # should we ask about box updates?
36 | config.vm.box_check_update = options['box_check_update']
37 |
38 | config.vm.provider 'virtualbox' do |vb|
39 | # machine cpus count
40 | vb.cpus = options['cpus']
41 | # machine memory size
42 | vb.memory = options['memory']
43 | # machine name (for VirtualBox UI)
44 | vb.name = options['machine_name']
45 | end
46 |
47 | # machine name (for vagrant console)
48 | config.vm.define options['machine_name']
49 |
50 | # machine name (for guest machine console)
51 | config.vm.hostname = options['machine_name']
52 |
53 | # network settings
54 | config.vm.network 'private_network', ip: options['ip']
55 |
56 | # sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
57 | config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'
58 |
59 | # disable folder '/vagrant' (guest machine)
60 | config.vm.synced_folder '.', '/vagrant', disabled: true
61 |
62 | # hosts settings (host machine)
63 | config.vm.provision :hostmanager
64 | config.hostmanager.enabled = true
65 | config.hostmanager.manage_host = true
66 | config.hostmanager.ignore_private_ip = false
67 | config.hostmanager.include_offline = true
68 | config.hostmanager.aliases = domains.values
69 |
70 | # provisioners
71 | config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
72 | config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
73 | config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
74 |
75 | # post-install message (vagrant console)
76 | config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}"
77 | end
78 |
--------------------------------------------------------------------------------
/backend/assets/AppAsset.php:
--------------------------------------------------------------------------------
1 | rules[] =[
18 | 'allow' => true,
19 | 'roles' => ['@'],
20 | 'matchCallback' => function () {
21 | return \Yii::$app->user->identity->getIsAdmin();
22 | }
23 | ];
24 | parent::init(); // TODO: Change the autogenerated stub
25 | }
26 | }
--------------------------------------------------------------------------------
/backend/config/.gitignore:
--------------------------------------------------------------------------------
1 | main-local.php
2 | params-local.php
3 | test-local.php
4 |
--------------------------------------------------------------------------------
/backend/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | 'app-backend',
11 | 'basePath' => dirname(__DIR__),
12 | 'controllerNamespace' => 'backend\controllers',
13 | 'bootstrap' => ['log'],
14 | 'modules' => [
15 | 'user' => [
16 | // following line will restrict access to profile, recovery, registration and settings controllers from backend
17 | 'as backend' => 'dektrium\user\filters\BackendFilter',
18 | 'controllerMap' => [
19 | 'security' => [
20 | 'class' => 'dektrium\user\controllers\SecurityController',
21 | 'layout' => '//main-login',
22 | ],
23 | ],
24 | ],
25 | 'queuemanager' => [
26 | 'class' => \ignatenkovnikita\queuemanager\QueueManager::class
27 | ]
28 | ],
29 | 'components' => [
30 | 'request' => [
31 | 'csrfParam' => '_csrf-backend',
32 | ],
33 | /*'user' => [
34 | 'identityClass' => 'common\models\User',
35 | 'enableAutoLogin' => true,
36 | 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
37 | ],*/
38 | 'session' => [
39 | // this is the name of the session cookie used for login on the backend
40 | 'name' => 'advanced-backend',
41 | ],
42 | 'errorHandler' => [
43 | 'errorAction' => 'site/error',
44 | ],
45 | 'urlManager' => [
46 | 'enablePrettyUrl' => true,
47 | 'showScriptName' => false,
48 | 'rules' => [
49 | ],
50 | ],
51 | ],
52 | 'params' => $params,
53 | ];
54 |
--------------------------------------------------------------------------------
/backend/config/params.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/BaseAdminController.php:
--------------------------------------------------------------------------------
1 | [
26 | 'class' => VerbFilter::class,
27 | 'actions' => [
28 | 'delete' => ['POST'],
29 | ],
30 | ],
31 | 'access' => [
32 | 'class' => AdminAccessControl::class,
33 | ],
34 | ];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/backend/controllers/EmailFormController.php:
--------------------------------------------------------------------------------
1 | search(Yii::$app->request->queryParams);
31 |
32 | return $this->render('index', [
33 | 'searchModel' => $searchModel,
34 | 'dataProvider' => $dataProvider,
35 | ]);
36 | }
37 |
38 | /**
39 | * Displays a single EmailForm model.
40 | * @param integer $id
41 | * @return mixed
42 | */
43 | public function actionView($id)
44 | {
45 | return $this->render('view', [
46 | 'model' => $this->findModel($id),
47 | ]);
48 | }
49 |
50 | /**
51 | * Creates a new EmailForm model.
52 | * If creation is successful, the browser will be redirected to the 'view' page.
53 | * @return mixed
54 | */
55 | public function actionCreate()
56 | {
57 | $model = new EmailForm();
58 |
59 | if ($model->load(Yii::$app->request->post()) && $model->save()) {
60 | return $this->redirect(['view', 'id' => $model->id]);
61 | } else {
62 | return $this->render('create', [
63 | 'model' => $model,
64 | ]);
65 | }
66 | }
67 |
68 | /**
69 | * Updates an existing EmailForm model.
70 | * If update is successful, the browser will be redirected to the 'view' page.
71 | * @param integer $id
72 | * @return mixed
73 | */
74 | public function actionUpdate($id)
75 | {
76 | $model = $this->findModel($id);
77 |
78 | if ($model->load(Yii::$app->request->post()) && $model->save()) {
79 | return $this->redirect(['view', 'id' => $model->id]);
80 | } else {
81 | return $this->render('update', [
82 | 'model' => $model,
83 | ]);
84 | }
85 | }
86 |
87 | /**
88 | * Deletes an existing EmailForm model.
89 | * If deletion is successful, the browser will be redirected to the 'index' page.
90 | * @param integer $id
91 | * @return mixed
92 | */
93 | public function actionDelete($id)
94 | {
95 | $this->findModel($id)->delete();
96 |
97 | return $this->redirect(['index']);
98 | }
99 |
100 | /**
101 | * Finds the EmailForm model based on its primary key value.
102 | * If the model is not found, a 404 HTTP exception will be thrown.
103 | * @param integer $id
104 | * @return EmailForm the loaded model
105 | * @throws NotFoundHttpException if the model cannot be found
106 | */
107 | protected function findModel($id)
108 | {
109 | if (($model = EmailForm::findOne($id)) !== null) {
110 | return $model;
111 | } else {
112 | throw new NotFoundHttpException('The requested page does not exist.');
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/backend/controllers/LogController.php:
--------------------------------------------------------------------------------
1 | search(Yii::$app->request->queryParams);
25 | if (strcasecmp(Yii::$app->request->method, 'delete') == 0) {
26 | Log::deleteAll($dataProvider->query->where);
27 | return $this->refresh();
28 | }
29 | $dataProvider->sort = [
30 | 'defaultOrder' => ['log_time' => SORT_DESC]
31 | ];
32 | return $this->render('index', [
33 | 'searchModel' => $searchModel,
34 | 'dataProvider' => $dataProvider,
35 | ]);
36 | }
37 |
38 | /**
39 | * Displays a single Log model.
40 | * @param integer $id
41 | * @return mixed
42 | */
43 | public function actionView($id) {
44 | return $this->render('view', [
45 | 'model' => $this->findModel($id),
46 | ]);
47 | }
48 |
49 | /**
50 | * Deletes an existing Log model.
51 | * If deletion is successful, the browser will be redirected to the 'index' page.
52 | * @param integer $id
53 | * @return mixed
54 | */
55 | public function actionDelete($id) {
56 | $this->findModel($id)->delete();
57 |
58 | return $this->redirect(['index']);
59 | }
60 |
61 | /**
62 | * Finds the Log model based on its primary key value.
63 | * If the model is not found, a 404 HTTP exception will be thrown.
64 | * @param integer $id
65 | * @return Log the loaded model
66 | * @throws NotFoundHttpException if the model cannot be found
67 | */
68 | protected function findModel($id) {
69 | if (($model = Log::findOne($id)) !== null) {
70 | return $model;
71 | } else {
72 | throw new NotFoundHttpException('The requested page does not exist.');
73 | }
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/backend/controllers/SiteController.php:
--------------------------------------------------------------------------------
1 | [
21 | 'class' => AccessControl::class,
22 | 'rules' => [
23 | [
24 | 'actions' => ['login', 'error'],
25 | 'allow' => true,
26 | ],
27 | [
28 | 'actions' => ['logout', 'index'],
29 | 'allow' => true,
30 | 'roles' => ['@'],
31 | ],
32 | ],
33 | ],
34 | 'verbs' => [
35 | 'class' => VerbFilter::class,
36 | 'actions' => [
37 | 'logout' => ['post'],
38 | ],
39 | ],
40 | ];
41 | }
42 |
43 | /**
44 | * {@inheritdoc}
45 | */
46 | public function actions()
47 | {
48 | return [
49 | 'error' => [
50 | 'class' => 'yii\web\ErrorAction',
51 | ],
52 | ];
53 | }
54 |
55 | /**
56 | * Displays homepage.
57 | *
58 | * @return string
59 | */
60 | public function actionIndex()
61 | {
62 | return $this->render('index');
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/backend/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/backend/models/EmailFormSearch.php:
--------------------------------------------------------------------------------
1 | $query,
56 | ]);
57 |
58 | $this->load($params);
59 |
60 | if (!$this->validate()) {
61 | // uncomment the following line if you do not want to return any records when validation fails
62 | // $query->where('0=1');
63 | return $dataProvider;
64 | }
65 |
66 | // grid filtering conditions
67 | $query->andFilterWhere([
68 | 'id' => $this->id,
69 | 'user_id' => $this->user_id,
70 | 'status' => $this->status,
71 | 'created_at' => $this->created_at,
72 | 'send_at' => $this->send_at,
73 | ]);
74 |
75 | $query->andFilterWhere(['like', 'setToEmail', $this->setToEmail])
76 | ->andFilterWhere(['like', 'setToName', $this->setToName])
77 | ->andFilterWhere(['like', 'setFromEmail', $this->setFromEmail])
78 | ->andFilterWhere(['like', 'setFromName', $this->setFromName])
79 | ->andFilterWhere(['like', 'subject', $this->subject])
80 | ->andFilterWhere(['like', 'textBody', $this->textBody])
81 | ->andFilterWhere(['like', 'status_text', $this->status_text]);
82 |
83 | return $dataProvider;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/backend/models/Log.php:
--------------------------------------------------------------------------------
1 | 255],
43 | ];
44 | }
45 |
46 | /**
47 | * @inheritdoc
48 | */
49 | public function attributeLabels()
50 | {
51 | return [
52 | 'id' => 'ID',
53 | 'level' => 'Level',
54 | 'category' => 'Category',
55 | 'log_time' => 'Log Time',
56 | 'prefix' => 'Prefix',
57 | 'message' => 'Message',
58 | ];
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/backend/models/LogSearch.php:
--------------------------------------------------------------------------------
1 | $query,
57 | ]);
58 |
59 | $this->load($params);
60 |
61 | if (!$this->validate()) {
62 | // uncomment the following line if you do not want to return any records when validation fails
63 | // $query->where('0=1');
64 | return $dataProvider;
65 | }
66 |
67 | // grid filtering conditions
68 | $query->andFilterWhere([
69 | 'id' => $this->id,
70 | 'level' => $this->level,
71 | 'log_time' => $this->log_time,
72 | ]);
73 |
74 | $query->andFilterWhere(['like', 'category', $this->category])
75 | ->andFilterWhere(['like', 'prefix', $this->prefix])
76 | ->andFilterWhere(['like', 'message', $this->message]);
77 |
78 | return $dataProvider;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/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 | [
24 | 'class' => UserFixture::className(),
25 | 'dataFile' => codecept_data_dir() . 'login_data.php'
26 | ]
27 | ];
28 | }
29 |
30 | /**
31 | * @param FunctionalTester $I
32 | */
33 | public function loginUser(FunctionalTester $I)
34 | {
35 | $I->amOnPage('/site/login');
36 | $I->fillField('Username', 'erau');
37 | $I->fillField('Password', 'password_0');
38 | $I->click('login-button');
39 |
40 | $I->see('Logout (erau)', 'form button[type=submit]');
41 | $I->dontSeeLink('Login');
42 | $I->dontSeeLink('Signup');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/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 | suite_namespace: backend\tests\unit
2 | actor: UnitTester
3 |
--------------------------------------------------------------------------------
/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/email-form/_form.php:
--------------------------------------------------------------------------------
1 |
16 |
17 |
44 |
--------------------------------------------------------------------------------
/backend/views/email-form/_search.php:
--------------------------------------------------------------------------------
1 |
16 |
17 |
56 |
--------------------------------------------------------------------------------
/backend/views/email-form/create.php:
--------------------------------------------------------------------------------
1 | title = 'Create Email Form';
16 | $this->params['breadcrumbs'][] = ['label' => 'Email Forms', 'url' => ['index']];
17 | $this->params['breadcrumbs'][] = $this->title;
18 | ?>
19 |
20 |
21 |
= Html::encode($this->title) ?>
22 |
23 | = $this->render('_form', [
24 | 'model' => $model,
25 | ]) ?>
26 |
27 |
28 |
--------------------------------------------------------------------------------
/backend/views/email-form/index.php:
--------------------------------------------------------------------------------
1 | title = 'Email Forms';
17 | $this->params['breadcrumbs'][] = $this->title;
18 | ?>
19 |
55 |
--------------------------------------------------------------------------------
/backend/views/email-form/update.php:
--------------------------------------------------------------------------------
1 | title = 'Update Email Form: ' . $model->id;
15 | $this->params['breadcrumbs'][] = ['label' => 'Email Forms', 'url' => ['index']];
16 | $this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
17 | $this->params['breadcrumbs'][] = 'Update';
18 | ?>
19 |
20 |
21 |
= Html::encode($this->title) ?>
22 |
23 | = $this->render('_form', [
24 | 'model' => $model,
25 | ]) ?>
26 |
27 |
28 |
--------------------------------------------------------------------------------
/backend/views/email-form/view.php:
--------------------------------------------------------------------------------
1 | title = $model->id;
16 | $this->params['breadcrumbs'][] = ['label' => 'Email Forms', 'url' => ['index']];
17 | $this->params['breadcrumbs'][] = $this->title;
18 | ?>
19 |
53 |
--------------------------------------------------------------------------------
/backend/views/layouts/main-login.php:
--------------------------------------------------------------------------------
1 |
18 | beginPage() ?>
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | = Html::csrfMetaTags() ?>
27 | = Html::encode($this->title) ?>
28 | head() ?>
29 |
30 |
34 |
35 |
36 | beginBody() ?>
37 | = $content ?>
38 | endBody() ?>
39 |
40 |
41 | endPage() ?>
42 |
--------------------------------------------------------------------------------
/backend/views/layouts/main.php:
--------------------------------------------------------------------------------
1 |
13 | beginPage(); ?>
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | = Html::csrfMetaTags() ?>
22 | = Html::encode($this->title) ?>
23 | head() ?>
24 |
25 |
29 |
30 |
31 | beginBody(); ?>
32 |
33 |
34 |
35 |
36 |
114 |
115 |
116 |
117 |
118 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | params['h1'])): ?>
199 |
200 |
201 |
= $this->params['h1'] ?>
202 |
203 |
213 |
214 |
215 |
216 |
217 | = $content ?>
218 |
219 |
220 |
221 |
228 |
229 |
230 |
231 |
232 |
233 |
239 |
240 | endBody(); ?>
241 |
242 |
243 | endPage(); ?>
244 |
--------------------------------------------------------------------------------
/backend/views/log/index.php:
--------------------------------------------------------------------------------
1 | title = 'Logs';
17 | $this->params['breadcrumbs'][] = $this->title;
18 | ?>
19 |
20 |
21 |
= Html::encode($this->title) ?>
22 |
23 | 'btn btn-danger', 'data-method' => 'delete']) ?>
24 |
25 | =
26 | GridView::widget([
27 | 'dataProvider' => $dataProvider,
28 | 'filterModel' => $searchModel,
29 | 'columns' => [
30 | ['class' => 'yii\grid\SerialColumn'],
31 | [
32 | 'attribute' => 'level',
33 | 'value' => function ($model) {
34 | return \yii\log\Logger::getLevelName($model->level);
35 | },
36 | 'filter' => [
37 | \yii\log\Logger::LEVEL_ERROR => 'error',
38 | \yii\log\Logger::LEVEL_WARNING => 'warning',
39 | \yii\log\Logger::LEVEL_INFO => 'info',
40 | \yii\log\Logger::LEVEL_TRACE => 'trace',
41 | \yii\log\Logger::LEVEL_PROFILE_BEGIN => 'profile begin',
42 | \yii\log\Logger::LEVEL_PROFILE_END => 'profile end'
43 | ]
44 | ],
45 | 'category',
46 | 'prefix',
47 | [
48 | 'attribute' => 'log_time',
49 | 'format' => 'datetime',
50 | 'value' => function ($model) {
51 | return (int) $model->log_time;
52 | }
53 | ],
54 | [
55 | 'class' => 'yii\grid\ActionColumn',
56 | 'template' => '{view}{delete}'
57 | ]
58 | ],
59 | ]);
60 | ?>
61 |
62 |
--------------------------------------------------------------------------------
/backend/views/log/view.php:
--------------------------------------------------------------------------------
1 | title = 'Error '.$model->id;
14 | $this->params['breadcrumbs'][] = ['label' => 'System Logs', 'url' => ['index']];
15 | $this->params['breadcrumbs'][] = $this->title;
16 | ?>
17 |
18 |
19 |
20 | $model->id], ['class' => 'btn btn-danger', 'data'=>['method'=>'post']]) ?>
21 |
22 |
23 | $model,
25 | 'attributes' => [
26 | 'id',
27 | 'level',
28 | 'category',
29 | [
30 | 'attribute' => 'log_time',
31 | 'format' => 'datetime',
32 | 'value' => (int) $model->log_time
33 | ],
34 | 'prefix:ntext',
35 | [
36 | 'attribute'=>'message',
37 | 'format'=>'raw',
38 | 'value'=>Html::tag('pre', $model->message, ['style'=>'white-space: pre-wrap'])
39 | ],
40 | ],
41 | ]) ?>
42 | message; ?>
43 |
--------------------------------------------------------------------------------
/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 = \Yii::t('app-backend', 'Dashboard');
6 | ?>
7 |
8 |
9 |
10 |
Total Users
11 |
2500
12 |
4% From last Week
13 |
14 |
15 |
Average Time
16 |
123.50
17 |
3% From last Week
18 |
19 |
20 |
Total Males
21 |
2,500
22 |
34% From last Week
23 |
24 |
25 |
Total Females
26 |
4,567
27 |
12% From last Week
28 |
29 |
30 |
Total Collections
31 |
2,315
32 |
34% From last Week
33 |
34 |
35 |
Total Connections
36 |
7,325
37 |
34% From last Week
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/backend/web/.gitignore:
--------------------------------------------------------------------------------
1 | /index.php
2 | /index-test.php
3 | /robots.txt
4 |
--------------------------------------------------------------------------------
/backend/web/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 |
3 | # Если запрашиваемая в URL директория или файл существуют обращаемся к ним напрямую
4 | RewriteCond %{REQUEST_FILENAME} !-f
5 | RewriteCond %{REQUEST_FILENAME} !-d
6 | # Если нет - перенаправляем запрос на index.php
7 | RewriteRule . index.php
--------------------------------------------------------------------------------
/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/akiraz2/yii2-app/7466c9625cfc066a9ed38fa01a570528dcd126d6/backend/web/favicon.ico
--------------------------------------------------------------------------------
/backend/web/img/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akiraz2/yii2-app/7466c9625cfc066a9ed38fa01a570528dcd126d6/backend/web/img/128x128.png
--------------------------------------------------------------------------------
/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_suffix: Tester
3 | paths:
4 | tests: tests
5 | output: tests/_output
6 | data: tests/_data
7 | support: 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 | 'en-US',
5 | 'sourceLanguage' => 'en-US',
6 | 'aliases' => [
7 | '@bower' => '@vendor/bower-asset',
8 | '@npm' => '@vendor/npm-asset',
9 | ],
10 | 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
11 | 'components' => [
12 | 'formatter' => [
13 | 'class' => 'yii\i18n\Formatter',
14 | 'nullDisplay' => '-',
15 | 'defaultTimeZone' => 'Europe/Moscow',
16 | 'locale' => 'ru-RU',
17 | 'thousandSeparator' => ' ',
18 | 'decimalSeparator' => '.',
19 | // must enable php intl extension for \NumberFormatter
20 | /*'numberFormatterOptions' => [
21 | \NumberFormatter::MIN_FRACTION_DIGITS => 0,
22 | \NumberFormatter::MAX_FRACTION_DIGITS => 0,
23 | ]*/
24 | ],
25 | 'cache' => [
26 | 'class' => yii\caching\FileCache::class,
27 | // 'class' => yii\caching\DbCache::class,
28 | // 'cacheTable' => '{{%cache}}',
29 | /*'class' => \yii\redis\Cache::class,
30 | 'redis' => [
31 | 'hostname' => 'localhost',
32 | 'port' => 6379,
33 | 'database' => 0,
34 | ]*/
35 | ],
36 | 'log' => [
37 | 'traceLevel' => YII_DEBUG ? 3 : 0,
38 | 'targets' => [
39 | [
40 | 'class' => 'yii\log\DbTarget',
41 | 'levels' => ['error', 'warning'],
42 | ],
43 | ],
44 | ],
45 | 'urlManagerFrontend' => [
46 | 'class' => \yii\web\UrlManager::class,
47 | 'enablePrettyUrl' => true,
48 | 'showScriptName' => false,
49 | 'hostInfo' => $hostinfo['frontendHost'],
50 | 'rules' => require __DIR__.'/../../frontend/config/urls.php',
51 | ],
52 | 'i18n' => [
53 | 'translations' => [
54 | 'app*' => [
55 | 'class' => 'yii\i18n\PhpMessageSource',
56 | 'basePath' => '@common/messages',
57 | ],
58 | 'giiant' => [
59 | 'class' => 'yii\i18n\PhpMessageSource',
60 | ],
61 | 'cruds' => [
62 | 'class' => 'yii\i18n\PhpMessageSource',
63 | //'basePath' => '@common/messages',
64 | ],
65 | ],
66 | ],
67 | 'queue' => [
68 | 'class' => \yii\queue\sync\Queue::class,
69 | 'handle' => false, // whether tasks should be executed immediately
70 | ],
71 | // 'queue' => [
72 | // 'class' => \yii\queue\db\Queue::class,
73 | // 'db' => 'db', // DB connection component or its config
74 | // 'tableName' => '{{%queue}}', // Table name
75 | // 'channel' => 'default', // Queue channel key
76 | // 'mutex' => \yii\mutex\MysqlMutex::class, // Mutex used to sync queries
77 | // 'as log' => \yii\queue\LogBehavior::class,
78 | // 'as quuemanager' => \ignatenkovnikita\queuemanager\behaviors\QueueManagerBehavior::class
79 | // // Other driver options
80 | // ],
81 | ],
82 | 'modules' => [
83 | 'user' => [
84 | 'class' => 'dektrium\user\Module',
85 | 'enableUnconfirmedLogin' => false,
86 | 'confirmWithin' => 21600,
87 | 'cost' => 12,
88 | 'admins' => ['adminus'],
89 | 'modelMap' => [
90 | 'User' => 'common\models\User',
91 | ],
92 | ],
93 | ],
94 | ];
95 |
--------------------------------------------------------------------------------
/common/config/params.php:
--------------------------------------------------------------------------------
1 | 'akiraz@bk.ru',
4 | 'supportEmail' => 'akiraz@bk.ru',
5 | 'user.passwordResetTokenExpire' => 3600,
6 | 'frontendHost' => 'https://website/',
7 | ];
8 |
--------------------------------------------------------------------------------
/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 | 'request' => [
11 | 'cookieValidationKey' => 'test',
12 | ],
13 | ],
14 | ];
15 |
--------------------------------------------------------------------------------
/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/messages/config.php:
--------------------------------------------------------------------------------
1 | null,
14 | 'interactive' => true,
15 | 'help' => null,
16 | 'sourcePath' => '@common/../',
17 | 'messagePath' => '@common/messages',
18 | 'languages' => [
19 | 'ru-RU',
20 | ],
21 | 'translator' => 'Yii::t',
22 | 'sort' => false,
23 | 'overwrite' => true,
24 | 'removeUnused' => false,
25 | 'markUnused' => true,
26 | 'except' => [
27 | '.svn',
28 | '.git',
29 | '.gitignore',
30 | '.gitkeep',
31 | '.hgignore',
32 | '.hgkeep',
33 | '/vendor',
34 | '/BaseYii.php',
35 | '/node_modules',
36 | '/vagrant',
37 | '*test*',
38 | '*fixture*',
39 | 'environments'
40 | ],
41 | 'only' => [
42 | '*.php',
43 | ],
44 | 'format' => 'php',
45 | /*'db' => 'db',
46 | 'sourceMessageTable' => '{{%source_message}}',
47 | 'messageTable' => '{{%message}}',*/
48 | 'catalog' => 'messages',
49 | 'ignoreCategories' => [],
50 | 'phpFileHeader' => '',
51 | 'phpDocBlock' => null,
52 | ];
53 |
--------------------------------------------------------------------------------
/common/messages/ru-RU/app-backend.php:
--------------------------------------------------------------------------------
1 | 'Административное',
21 | 'Dashboard' => 'Панель управления',
22 | 'General' => 'Главное',
23 | 'Guest' => 'Гость',
24 | 'Welcome' => 'Привет',
25 | ];
26 |
--------------------------------------------------------------------------------
/common/messages/ru-RU/app-forms.php:
--------------------------------------------------------------------------------
1 | 'Удалить',
21 | 'Update' => 'Обновить',
22 | ];
23 |
--------------------------------------------------------------------------------
/common/messages/ru-RU/app-model.php:
--------------------------------------------------------------------------------
1 | 'Менеджер очереди',
21 | 'Email Form' => 'Email Form',
22 | 'Log' => 'Лог',
23 | 'Log out' => 'Выход',
24 | 'Message' => 'Сообщение',
25 | 'Phone' => 'Телефон',
26 | 'Profile' => 'Профиль',
27 | 'Users' => 'Пользователи',
28 | 'Verification Code' => 'Код верификации',
29 | ];
30 |
--------------------------------------------------------------------------------
/common/models/EmailForm.php:
--------------------------------------------------------------------------------
1 | 255],
46 | ];
47 | }
48 |
49 | /**
50 | * @inheritdoc
51 | */
52 | public function attributeLabels()
53 | {
54 | return [
55 | 'id' => 'ID',
56 | 'user_id' => 'User ID',
57 | 'setToName' => 'Имя получателя',
58 | 'setFromName' => 'Имя отправителя',
59 | 'setToEmail' => 'Email получателя',
60 | 'setFromEmail' => 'Email отправителя',
61 | 'subject' => 'Тема',
62 | 'textBody' => 'Сообщение',
63 | 'created_at' => 'Дата создания',
64 | 'status' => 'Статус',
65 | ];
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/common/models/User.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 | [
27 | 'class' => UserFixture::className(),
28 | 'dataFile' => codecept_data_dir() . 'user.php'
29 | ]
30 | ];
31 | }
32 |
33 | public function testLoginNoUser()
34 | {
35 | $model = new LoginForm([
36 | 'username' => 'not_existing_username',
37 | 'password' => 'not_existing_password',
38 | ]);
39 |
40 | expect('model should not login user', $model->login())->false();
41 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
42 | }
43 |
44 | public function testLoginWrongPassword()
45 | {
46 | $model = new LoginForm([
47 | 'username' => 'bayer.hudson',
48 | 'password' => 'wrong_password',
49 | ]);
50 |
51 | expect('model should not login user', $model->login())->false();
52 | expect('error message should be set', $model->errors)->hasKey('password');
53 | expect('user should not be logged in', Yii::$app->user->isGuest)->true();
54 | }
55 |
56 | public function testLoginCorrect()
57 | {
58 | $model = new LoginForm([
59 | 'username' => 'bayer.hudson',
60 | 'password' => 'password_0',
61 | ]);
62 |
63 | expect('model should login user', $model->login())->true();
64 | expect('error message should not be set', $model->errors)->hasntKey('password');
65 | expect('user should be logged in', Yii::$app->user->isGuest)->false();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/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 | /**
48 | * {@inheritdoc}
49 | */
50 | public function run()
51 | {
52 | $session = Yii::$app->session;
53 | $flashes = $session->getAllFlashes();
54 | $appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : '';
55 |
56 | foreach ($flashes as $type => $flash) {
57 | if (!isset($this->alertTypes[$type])) {
58 | continue;
59 | }
60 |
61 | foreach ((array) $flash as $i => $message) {
62 | echo \yii\bootstrap\Alert::widget([
63 | 'body' => $message,
64 | 'closeButton' => $this->closeButton,
65 | 'options' => array_merge($this->options, [
66 | 'id' => $this->getId() . '-' . $type . '-' . $i,
67 | 'class' => $this->alertTypes[$type] . $appendClass,
68 | ]),
69 | ]);
70 | }
71 |
72 | $session->removeFlash($type);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "akiraz2/yii2-app",
3 | "description": "Yii2 my advanced project template (Redis-cache, DB-queue, gentelella-admin, dektrium-user, DB-log)",
4 | "keywords": ["yii2", "framework", "advanced", "project template"],
5 | "homepage": "https://github.com/akiraz2/yii2-app",
6 | "type": "project",
7 | "license": "BSD-3-Clause",
8 | "support": {
9 | "source": "https://github.com/akiraz2/yii2-app"
10 | },
11 | "minimum-stability": "stable",
12 | "require": {
13 | "php": ">=7.0.0",
14 | "yiisoft/yii2": "~2.0.14",
15 | "yiisoft/yii2-bootstrap": "~2.0.0",
16 | "yiisoft/yii2-swiftmailer": "~2.0.0 || ~2.1.0",
17 | "dektrium/yii2-user": "dev-master",
18 | "yiister/yii2-gentelella": "~1.0",
19 | "yiisoft/yii2-redis": "^2.0",
20 | "yiisoft/yii2-queue": "^2.0",
21 | "himiklab/yii2-recaptcha-widget": "^1.2",
22 | "ignatenkovnikita/yii2-queuemanager": "dev-master",
23 | "yiisoft/yii2-jui": "^2.0",
24 | "schmunk42/yii2-giiant": "@dev"
25 | },
26 | "require-dev": {
27 | "yiisoft/yii2-debug": "~2.0.0",
28 | "yiisoft/yii2-gii": "~2.0.0",
29 | "yiisoft/yii2-faker": "~2.0.0",
30 | "codeception/base": "^2.2.3",
31 | "codeception/verify": "~0.3.1",
32 | "insolita/yii2-migration-generator": "~2.3"
33 | },
34 | "config": {
35 | "process-timeout": 1800,
36 | "fxp-asset": {
37 | "enabled": false
38 | }
39 | },
40 | "repositories": [
41 | {
42 | "type": "composer",
43 | "url": "https://asset-packagist.org"
44 | }
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/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', 'queue'],
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 | 'migrate' => [
24 | 'class' => 'yii\console\controllers\MigrateController',
25 | //'migrationPath' => null,
26 | 'migrationNamespaces' => [
27 | //'console\migrations',
28 | 'yii\queue\db\migrations',
29 | ],
30 | ],
31 | ],
32 | 'components' => [
33 | ],
34 | 'params' => $params,
35 | ];
36 |
--------------------------------------------------------------------------------
/console/config/params.php:
--------------------------------------------------------------------------------
1 | insert('{{%user}}', [
16 | 'id' => 1,
17 | 'username' => 'adminus',
18 | 'email' => 'admin@admin.ru',
19 | 'password_hash' => '$2y$12$BJu3H91IIWNKhcmfK7QnkeUUB90FTEl4xb12cVvWAuV6dJXGho8JS',
20 | 'auth_key' => 'vYghSpiPCeP60_jCLo9hIVrGlFUMY3xJ',
21 | 'confirmed_at' => '1524426563',
22 | 'created_at' => '1524426563',
23 | 'updated_at' => '1524426563',
24 | 'flags' => '0',
25 | ]);
26 |
27 | $this->insert('{{%profile}}', [
28 | 'user_id' => '1'
29 | ]);
30 | }
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | public function safeDown()
36 | {
37 | $this->delete('{{%user}}', ['id' => 1]);
38 | $this->delete('{{%profile}}', ['id' => 1]);
39 |
40 | return true;
41 | }
42 |
43 | /*
44 | // Use up()/down() to run migration code without a transaction.
45 | public function up()
46 | {
47 |
48 | }
49 |
50 | public function down()
51 | {
52 | echo "M180422195051Insert_adminus cannot be reverted.\n";
53 |
54 | return false;
55 | }
56 | */
57 | }
58 |
--------------------------------------------------------------------------------
/console/migrations/m180422_170849_create_email_form_table.php:
--------------------------------------------------------------------------------
1 | createTable('{{%email_form}}', [
16 | 'id' => $this->primaryKey(),
17 | 'user_id' => $this->integer(11),
18 | 'setToEmail' => $this->string(100),
19 | 'setToName' => $this->string(100),
20 | 'setFromEmail' => $this->string(100),
21 | 'setFromName' => $this->string(100),
22 | 'subject' => $this->string(255),
23 | 'textBody' => $this->text()->notNull(),
24 | 'status' => $this->tinyInteger(4)->defaultValue(0),
25 | 'created_at' => $this->timestamp(),
26 | 'status_text' => $this->text(),
27 | 'send_at' => $this->dateTime()
28 | ], $this->tableOptions);
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function safeDown()
35 | {
36 | $this->dropTable('{{%email_form}}');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/console/migrations/m180430_141650_cache.php:
--------------------------------------------------------------------------------
1 | db = 'db';
12 | parent::init();
13 | }
14 |
15 | public function safeUp()
16 | {
17 | $this->createTable('{{%cache}}',[
18 | 'id'=> $this->char(128)->notNull(),
19 | 'expire'=> $this->integer(11)->null()->defaultValue(null),
20 | 'data'=> $this->binary()->null()->defaultValue(null),
21 | ], $this->tableOptions);
22 |
23 | $this->addPrimaryKey('pk_on_cache','{{%cache}}',['id']);
24 | }
25 |
26 | public function safeDown()
27 | {
28 | $this->dropPrimaryKey('pk_on_cache','{{%cache}}');
29 | $this->dropTable('{{%cache}}');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/console/models/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/console/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/db/docker-entrypoint-initdb.d/.gitignore:
--------------------------------------------------------------------------------
1 | *.sql
2 |
--------------------------------------------------------------------------------
/db/docker-entrypoint-initdb.d/createdb.sql.example:
--------------------------------------------------------------------------------
1 | #
2 | # Copy createdb.sql.example to createdb.sql
3 | # then uncomment then set database name and username to create you need databases
4 | #
5 | # example: .env MYSQL_USER=appuser and needed db name is myshop_db
6 | #
7 | # CREATE DATABASE IF NOT EXISTS `myshop_db` ;
8 | # GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ;
9 | #
10 | #
11 | # this sql script will auto run when the mysql container starts and the $DATA_PATH_HOST/mysql not found.
12 | #
13 | # if your $DATA_PATH_HOST/mysql exists and you do not want to delete it, you can run by manual execution:
14 | #
15 | # docker-compose exec mysql bash
16 | # mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql
17 | #
18 | CREATE DATABASE IF NOT EXISTS `dbname` COLLATE 'utf8_general_ci' ;
19 | GRANT ALL ON `dbname`.* TO 'username'@'%' ;
20 |
21 | FLUSH PRIVILEGES ;
22 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | web:
4 | build:
5 | dockerfile: Dockerfile
6 | context: 'nginx'
7 | ports:
8 | - '8100:80'
9 | - '8200:81'
10 | volumes:
11 | # Application testing
12 | - ./frontend/web:/app/frontend/web:delegated
13 | - ./backend/web:/app/backend/web:delegated
14 | links:
15 | - php
16 | php:
17 | build:
18 | dockerfile: Dockerfile-${DOCKERFILE_FLAVOUR}
19 | context: 'php'
20 | args:
21 | - PHP_BASE_IMAGE_VERSION=${PHP_BASE_IMAGE_VERSION}
22 | image: ${PHP_IMAGE_NAME}:${PHP_BASE_IMAGE_VERSION}${PHP_IMAGE_VERSION_SUFFIX}
23 | environment:
24 | - GITHUB_API_TOKEN=${GITHUB_API_TOKEN}
25 | - PHP_ENABLE_XDEBUG
26 | - TEST_RUNTIME_PATH=/tmp/runtime
27 | volumes:
28 | - ./:/app:delegated
29 | # Composer cache
30 | - ~/.composer/cache:/root/.composer/cache:delegated
31 | links:
32 | - db
33 | db:
34 | image: mysql:5.7
35 | environment:
36 | MYSQL_ROOT_PASSWORD: root
37 | MYSQL_USER: username
38 | MYSQL_PASSWORD: password
39 | MYSQL_DATABASE: yii2advanced
40 | volumes:
41 | - ./db/data:/var/lib/mysql
42 | - ./db/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
43 |
44 | # db:
45 | # image: postgres:13-alpine
46 | # environment:
47 | # POSTGRES_USER: username
48 | # POSTGRES_PASSWORD: password
49 | # POSTGRES_DB: yii2advanced
50 | # volumes:
51 | # - ./db/data:/var/lib/postgresql/data
52 | # - ./db/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
53 |
--------------------------------------------------------------------------------
/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 | 'allowedIPs' => ['*']
18 | ];
19 |
20 | $config['bootstrap'][] = 'gii';
21 | $config['modules']['gii'] = [
22 | 'class' => 'yii\gii\Module',
23 | 'allowedIPs' => ['*'],
24 | 'generators' => [
25 | 'job' => [
26 | 'class' => \yii\queue\gii\Generator::class,
27 | ],
28 | ],
29 | ];
30 | }
31 |
32 | return $config;
33 |
--------------------------------------------------------------------------------
/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' => 'pgsql:host=db;dbname=yii2advanced',
7 | 'dsn' => 'mysql:host=db;dbname=yii2advanced',
8 | 'username' => 'username',
9 | 'password' => 'password',
10 | 'charset' => 'utf8',
11 | ],
12 | 'mailer' => [
13 | 'class' => 'yii\swiftmailer\Mailer',
14 | 'viewPath' => '@common/mail',
15 | // send all mails to a file by default. You have to set
16 | // 'useFileTransport' to false and configure a transport
17 | // for the mailer to send real emails.
18 | 'useFileTransport' => true,
19 | ],
20 | ],
21 | ];
22 |
--------------------------------------------------------------------------------
/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'],
4 | 'modules' => [
5 | 'gii' => 'yii\gii\Module',
6 | ],
7 | ];
8 |
--------------------------------------------------------------------------------
/environments/dev/console/config/params-local.php:
--------------------------------------------------------------------------------
1 | [
5 | 'request' => [
6 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
7 | 'cookieValidationKey' => '',
8 | ],
9 | ],
10 | ];
11 |
12 | if (!YII_ENV_TEST) {
13 | // configuration adjustments for 'dev' environment
14 | $config['bootstrap'][] = 'debug';
15 | $config['modules']['debug'] = [
16 | 'class' => 'yii\debug\Module',
17 | 'allowedIPs' => ['*']
18 | ];
19 |
20 | $config['bootstrap'][] = 'gii';
21 | $config['modules']['gii'] = [
22 | 'class' => 'yii\gii\Module',
23 | 'allowedIPs' => ['*']
24 | ];
25 | }
26 |
27 | return $config;
28 |
--------------------------------------------------------------------------------
/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();
24 | exit($exitCode);
25 |
--------------------------------------------------------------------------------
/environments/dev/yii_test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
23 | exit($exitCode);
24 |
--------------------------------------------------------------------------------
/environments/dev/yii_test.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem -------------------------------------------------------------
4 | rem Yii command line bootstrap script for Windows.
5 | rem -------------------------------------------------------------
6 |
7 | @setlocal
8 |
9 | set YII_PATH=%~dp0
10 |
11 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
12 |
13 | "%PHP_COMMAND%" "%YII_PATH%yii_test" %*
14 |
15 | @endlocal
16 |
--------------------------------------------------------------------------------
/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 | ],
40 | 'setExecutable' => [
41 | 'yii',
42 | 'yii_test',
43 | ],
44 | 'setCookieValidationKey' => [
45 | 'backend/config/main-local.php',
46 | 'frontend/config/main-local.php',
47 | ],
48 | ],
49 | 'Production' => [
50 | 'path' => 'prod',
51 | 'setWritable' => [
52 | 'backend/runtime',
53 | 'backend/web/assets',
54 | 'frontend/runtime',
55 | 'frontend/web/assets',
56 | ],
57 | 'setExecutable' => [
58 | 'yii',
59 | ],
60 | 'setCookieValidationKey' => [
61 | 'backend/config/main-local.php',
62 | 'frontend/config/main-local.php',
63 | ],
64 | ],
65 | ];
66 |
--------------------------------------------------------------------------------
/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();
24 | exit($exitCode);
25 |
--------------------------------------------------------------------------------
/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 | 'errorHandler' => [
28 | 'errorAction' => 'site/error',
29 | ],
30 | 'reCaptcha' => [
31 | 'name' => 'reCaptcha',
32 | 'class' => 'himiklab\yii2\recaptcha\ReCaptcha',
33 | 'siteKey' => 'your siteKey',
34 | 'secret' => 'your secret key',
35 | ],
36 | 'urlManager' => [
37 | 'enablePrettyUrl' => true,
38 | 'showScriptName' => false,
39 | 'rules' => require 'urls.php',
40 | ],
41 | ],
42 | 'params' => $params,
43 | 'modules' => [
44 | 'user' => [
45 | // following line will restrict access to admin controller from frontend application
46 | 'as frontend' => 'dektrium\user\filters\FrontendFilter',
47 | ],
48 | ],
49 | ];
50 |
--------------------------------------------------------------------------------
/frontend/config/params.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/config/urls.php:
--------------------------------------------------------------------------------
1 | [
22 | 'class' => 'yii\web\ErrorAction',
23 | ],
24 | 'captcha' => [
25 | 'class' => 'yii\captcha\CaptchaAction',
26 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
27 | ],
28 | ];
29 | }
30 |
31 | /**
32 | * Displays homepage.
33 | *
34 | * @return mixed
35 | */
36 | public function actionIndex()
37 | {
38 | return $this->render('index');
39 | }
40 |
41 | /**
42 | * Displays contact page.
43 | *
44 | * @return mixed
45 | */
46 | public function actionContact()
47 | {
48 | $model = new ContactForm();
49 | if ($model->load(Yii::$app->request->post()) && $model->validate()) {
50 | if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
51 | Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
52 | } else {
53 | Yii::$app->session->setFlash('error', 'There was an error sending your message.');
54 | }
55 |
56 | return $this->refresh();
57 | } else {
58 | return $this->render('contact', [
59 | 'model' => $model,
60 | ]);
61 | }
62 | }
63 |
64 | /**
65 | * Displays about page.
66 | *
67 | * @return mixed
68 | */
69 | public function actionAbout()
70 | {
71 | return $this->render('about');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/frontend/models/ContactForm.php:
--------------------------------------------------------------------------------
1 | 'contact'],
35 | ['phone', 'required', 'on' => 'callback'],
36 | [['message'], 'required'],
37 | [['email', 'message', 'phone'], 'filter', 'filter' => 'strip_tags'],
38 | ['email', 'email'],
39 | [['message'], 'string', 'min' => 25, 'on' => 'contact'],
40 | [['message'], 'string', 'min' => 5, 'on' => 'callback'],
41 | ['phone', 'string', 'min' => 10],
42 | [['verifyCode'], ReCaptchaValidator::class]
43 |
44 | ];
45 | }
46 |
47 | /**
48 | * @inheritdoc
49 | */
50 | public function attributeLabels()
51 | {
52 | return [
53 | 'phone' => Yii::t('app-model', 'Phone'),
54 | 'message' => Yii::t('app-model', 'Message'),
55 | 'verifyCode' => Yii::t('app-model', 'Verification Code')
56 | ];
57 | }
58 |
59 | /**
60 | * @return array
61 | */
62 | public function scenarios()
63 | {
64 | $scenarios = parent::scenarios();
65 | $scenarios['contact'] = ['email', 'message', 'phone', 'verifyCode'];
66 | $scenarios['callback'] = ['email', 'message', 'phone', 'verifyCode'];
67 | return $scenarios;
68 | }
69 |
70 | /**
71 | * Sends an email to the specified email address using the information collected by this model.
72 | *
73 | * @param string $email the target email address
74 | * @return bool whether the email was sent
75 | */
76 | public function sendEmail($email)
77 | {
78 | $contact_form= new EmailForm();
79 |
80 | if(isset(Yii::$app->user) && !Yii::$app->user->isGuest)
81 | $contact_form->user_id= Yii::$app->user->id;
82 |
83 | $this->message= $this->message. '
84 |
85 | Email: '.$this->email . '
86 | '.Yii::t('app-model', 'Phone').': '.$this->phone;
87 |
88 | $contact_form->textBody=$this->message;
89 | $contact_form->subject="From contacts Page";
90 | $contact_form->setToEmail=$this->email? $this->email: Yii::$app->params['adminEmail'];
91 | $contact_form->setToName=$this->email? $this->email: Yii::$app->params['adminEmail'];
92 | $contact_form->setFromEmail=Yii::$app->params['supportEmail'];
93 | $contact_form->setFromName=Yii::$app->name;
94 | $contact_form->save();
95 |
96 | $result = Yii::$app->mailer->compose()
97 | ->setTo($email)
98 | ->setFrom([Yii::$app->params['supportEmail'] => 'С контактов'])
99 | ->setSubject(Yii::$app->name)
100 | ->setTextBody($this->message)
101 | ->send();
102 | //$result = mail ( Yii::$app->params['adminEmail'], 'Заявка с сайта', $this->message);
103 |
104 | //$this->sendViber($this->message);
105 |
106 | $contact_form->status=$result;
107 | $contact_form->save();
108 |
109 | return $result;
110 | }
111 |
112 | /**
113 | * Send messages via Viber messenger
114 | *
115 | * requirements:
116 | * composer require bogdaan/viber-bot-php
117 | * composer require yii2mod/yii2-settings
118 | * and then Config !
119 | *
120 | * @param $message
121 | * @return bool
122 | *
123 | public function sendViber($message) {
124 | $settings = Yii::$app->settings;
125 | $apiKey = $settings->get('ViberForm', 'apiKey');
126 | $finance_list = explode(';',$settings->get('ViberForm', 'finance'));
127 |
128 | if(!$apiKey || !count($finance_list))
129 | return false;
130 |
131 | $botSender = new Sender([
132 | 'name' => $settings->get('ViberForm', 'botName'),
133 | 'avatar' => 'https://developers.viber.com/img/favicon.ico',
134 | ]);
135 |
136 | $bot = null;
137 | try {
138 | // create bot instance
139 | $bot = new Bot(['token' => $apiKey]);
140 |
141 | for($i=0; $igetClient()->sendMessage(
145 | (new \Viber\Api\Message\Text())
146 | ->setSender($botSender)
147 | ->setReceiver($user_id)
148 | ->setText($message)
149 | );
150 | }
151 |
152 | return true;
153 |
154 | } catch (\Exception $e) {
155 | Yii::warning('Exception: '. $e->getMessage());
156 | if ($bot) {
157 | //Yii::warning('Actual sign: ' . $bot->getSignHeaderValue());
158 | //Yii::warning('Actual body: ' . $bot->getInputBody());
159 | }
160 | return false;
161 | }
162 | }*/
163 | }
164 |
--------------------------------------------------------------------------------
/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 | suite_namespace: frontend\tests\functional
2 | actor: FunctionalTester
3 | modules:
4 | enabled:
5 | - Filesystem
6 | - Yii2
7 |
--------------------------------------------------------------------------------
/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 | suite_namespace: frontend\tests\unit
2 | actor: UnitTester
3 | modules:
4 | enabled:
5 | - Yii2:
6 | part: [orm, email, fixtures]
7 | - Asserts
8 |
--------------------------------------------------------------------------------
/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' => ['/user/register']];
45 | $menuItems[] = ['label' => 'Login', 'url' => ['/user/login']];
46 | } else {
47 | $menuItems[] = '
'
48 | . Html::beginForm(['/user/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/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 |
3 | # Если запрашиваемая в URL директория или файл существуют обращаемся к ним напрямую
4 | RewriteCond %{REQUEST_FILENAME} !-f
5 | RewriteCond %{REQUEST_FILENAME} !-d
6 | # Если нет - перенаправляем запрос на index.php
7 | RewriteRule . index.php
--------------------------------------------------------------------------------
/frontend/web/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/frontend/web/css/site.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | .wrap {
7 | min-height: 100%;
8 | height: auto;
9 | margin: 0 auto -60px;
10 | padding: 0 0 60px;
11 | }
12 |
13 | .wrap > .container {
14 | padding: 70px 15px 20px;
15 | }
16 |
17 | .footer {
18 | height: 60px;
19 | background-color: #f5f5f5;
20 | border-top: 1px solid #ddd;
21 | padding-top: 20px;
22 | }
23 |
24 | .jumbotron {
25 | text-align: center;
26 | background-color: transparent;
27 | }
28 |
29 | .jumbotron .btn {
30 | font-size: 21px;
31 | padding: 14px 24px;
32 | }
33 |
34 | .not-set {
35 | color: #c55;
36 | font-style: italic;
37 | }
38 |
39 | /* add sorting icons to gridview sort links */
40 | a.asc:after, a.desc:after {
41 | position: relative;
42 | top: 1px;
43 | display: inline-block;
44 | font-family: 'Glyphicons Halflings';
45 | font-style: normal;
46 | font-weight: normal;
47 | line-height: 1;
48 | padding-left: 5px;
49 | }
50 |
51 | a.asc:after {
52 | content: "\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/akiraz2/yii2-app/7466c9625cfc066a9ed38fa01a570528dcd126d6/frontend/web/favicon.ico
--------------------------------------------------------------------------------
/init:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | $name) {
26 | echo " [$i] $name\n";
27 | }
28 | echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] ';
29 | $answer = trim(fgets(STDIN));
30 |
31 | if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) {
32 | echo "\n Quit initialization.\n";
33 | exit(0);
34 | }
35 |
36 | if (isset($envNames[$answer])) {
37 | $envName = $envNames[$answer];
38 | }
39 | } else {
40 | $envName = $params['env'];
41 | }
42 |
43 | if (!in_array($envName, $envNames)) {
44 | $envsList = implode(', ', $envNames);
45 | echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n";
46 | exit(2);
47 | }
48 |
49 | $env = $envs[$envName];
50 |
51 | if (empty($params['env'])) {
52 | echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] ";
53 | $answer = trim(fgets(STDIN));
54 | if (strncasecmp($answer, 'y', 1)) {
55 | echo "\n Quit initialization.\n";
56 | exit(0);
57 | }
58 | }
59 |
60 | echo "\n Start initialization ...\n\n";
61 | $files = getFileList("$root/environments/{$env['path']}");
62 | if (isset($env['skipFiles'])) {
63 | $skipFiles = $env['skipFiles'];
64 | array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; });
65 | $files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists')));
66 | }
67 | $all = false;
68 | foreach ($files as $file) {
69 | if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
70 | break;
71 | }
72 | }
73 |
74 | $callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink'];
75 | foreach ($callbacks as $callback) {
76 | if (!empty($env[$callback])) {
77 | $callback($root, $env[$callback]);
78 | }
79 | }
80 |
81 | echo "\n ... initialization completed.\n\n";
82 |
83 | function getFileList($root, $basePath = '')
84 | {
85 | $files = [];
86 | $handle = opendir($root);
87 | while (($path = readdir($handle)) !== false) {
88 | if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') {
89 | continue;
90 | }
91 | $fullPath = "$root/$path";
92 | $relativePath = $basePath === '' ? $path : "$basePath/$path";
93 | if (is_dir($fullPath)) {
94 | $files = array_merge($files, getFileList($fullPath, $relativePath));
95 | } else {
96 | $files[] = $relativePath;
97 | }
98 | }
99 | closedir($handle);
100 | return $files;
101 | }
102 |
103 | function copyFile($root, $source, $target, &$all, $params)
104 | {
105 | if (!is_file($root . '/' . $source)) {
106 | echo " skip $target ($source not exist)\n";
107 | return true;
108 | }
109 | if (is_file($root . '/' . $target)) {
110 | if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
111 | echo " unchanged $target\n";
112 | return true;
113 | }
114 | if ($all) {
115 | echo " overwrite $target\n";
116 | } else {
117 | echo " exist $target\n";
118 | echo " ...overwrite? [Yes|No|All|Quit] ";
119 |
120 |
121 | $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
122 | if (!strncasecmp($answer, 'q', 1)) {
123 | return false;
124 | } else {
125 | if (!strncasecmp($answer, 'y', 1)) {
126 | echo " overwrite $target\n";
127 | } else {
128 | if (!strncasecmp($answer, 'a', 1)) {
129 | echo " overwrite $target\n";
130 | $all = true;
131 | } else {
132 | echo " skip $target\n";
133 | return true;
134 | }
135 | }
136 | }
137 | }
138 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
139 | return true;
140 | }
141 | echo " generate $target\n";
142 | @mkdir(dirname($root . '/' . $target), 0777, true);
143 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
144 | return true;
145 | }
146 |
147 | function getParams()
148 | {
149 | $rawParams = [];
150 | if (isset($_SERVER['argv'])) {
151 | $rawParams = $_SERVER['argv'];
152 | array_shift($rawParams);
153 | }
154 |
155 | $params = [];
156 | foreach ($rawParams as $param) {
157 | if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
158 | $name = $matches[1];
159 | $params[$name] = isset($matches[3]) ? $matches[3] : true;
160 | } else {
161 | $params[] = $param;
162 | }
163 | }
164 | return $params;
165 | }
166 |
167 | function setWritable($root, $paths)
168 | {
169 | foreach ($paths as $writable) {
170 | if (is_dir("$root/$writable")) {
171 | if (@chmod("$root/$writable", 0777)) {
172 | echo " chmod 0777 $writable\n";
173 | } else {
174 | printError("Operation chmod not permitted for directory $writable.");
175 | }
176 | } else {
177 | printError("Directory $writable does not exist.");
178 | }
179 | }
180 | }
181 |
182 | function setExecutable($root, $paths)
183 | {
184 | foreach ($paths as $executable) {
185 | if (file_exists("$root/$executable")) {
186 | if (@chmod("$root/$executable", 0755)) {
187 | echo " chmod 0755 $executable\n";
188 | } else {
189 | printError("Operation chmod not permitted for $executable.");
190 | }
191 | } else {
192 | printError("$executable does not exist.");
193 | }
194 | }
195 | }
196 |
197 | function setCookieValidationKey($root, $paths)
198 | {
199 | foreach ($paths as $file) {
200 | echo " generate cookie validation key in $file\n";
201 | $file = $root . '/' . $file;
202 | $length = 32;
203 | $bytes = openssl_random_pseudo_bytes($length);
204 | $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
205 | $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
206 | file_put_contents($file, $content);
207 | }
208 | }
209 |
210 | function createSymlink($root, $links)
211 | {
212 | foreach ($links as $link => $target) {
213 | //first removing folders to avoid errors if the folder already exists
214 | @rmdir($root . "/" . $link);
215 | //next removing existing symlink in order to update the target
216 | if (is_link($root . "/" . $link)) {
217 | @unlink($root . "/" . $link);
218 | }
219 | if (@symlink($root . "/" . $target, $root . "/" . $link)) {
220 | echo " symlink $root/$target $root/$link\n";
221 | } else {
222 | printError("Cannot create symlink $root/$target $root/$link.");
223 | }
224 | }
225 | }
226 |
227 | /**
228 | * Prints error message.
229 | * @param string $message message
230 | */
231 | function printError($message)
232 | {
233 | echo "\n " . formatMessage("Error. $message", ['fg-red']) . " \n";
234 | }
235 |
236 | /**
237 | * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream.
238 | *
239 | * - windows without ansicon
240 | * - not tty consoles
241 | *
242 | * @return boolean true if the stream supports ANSI colors, otherwise false.
243 | */
244 | function ansiColorsSupported()
245 | {
246 | return DIRECTORY_SEPARATOR === '\\'
247 | ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'
248 | : function_exists('posix_isatty') && @posix_isatty(STDOUT);
249 | }
250 |
251 | /**
252 | * Get ANSI code of style.
253 | * @param string $name style name
254 | * @return integer ANSI code of style.
255 | */
256 | function getStyleCode($name)
257 | {
258 | $styles = [
259 | 'bold' => 1,
260 | 'fg-black' => 30,
261 | 'fg-red' => 31,
262 | 'fg-green' => 32,
263 | 'fg-yellow' => 33,
264 | 'fg-blue' => 34,
265 | 'fg-magenta' => 35,
266 | 'fg-cyan' => 36,
267 | 'fg-white' => 37,
268 | 'bg-black' => 40,
269 | 'bg-red' => 41,
270 | 'bg-green' => 42,
271 | 'bg-yellow' => 43,
272 | 'bg-blue' => 44,
273 | 'bg-magenta' => 45,
274 | 'bg-cyan' => 46,
275 | 'bg-white' => 47,
276 | ];
277 | return $styles[$name];
278 | }
279 |
280 | /**
281 | * Formats message using styles if STDOUT supports it.
282 | * @param string $message message
283 | * @param string[] $styles styles
284 | * @return string formatted message.
285 | */
286 | function formatMessage($message, $styles)
287 | {
288 | if (empty($styles) || !ansiColorsSupported()) {
289 | return $message;
290 | }
291 |
292 | return sprintf("\x1b[%sm", implode(';', array_map('getStyleCode', $styles))) . $message . "\x1b[0m";
293 | }
294 |
--------------------------------------------------------------------------------
/init.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem -------------------------------------------------------------
4 | rem Yii command line init script for Windows.
5 | rem -------------------------------------------------------------
6 |
7 | @setlocal
8 |
9 | set YII_PATH=%~dp0
10 |
11 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
12 |
13 | "%PHP_COMMAND%" "%YII_PATH%init" %*
14 |
15 | @endlocal
16 |
--------------------------------------------------------------------------------
/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx:1.19-alpine
2 | COPY nginx.conf /etc/nginx/nginx.conf
3 |
--------------------------------------------------------------------------------
/nginx/gzip.conf:
--------------------------------------------------------------------------------
1 | gzip on;
2 | gzip_proxied any;
3 | gzip_types text/plain text/xml text/css application/javascript application/x-javascript;
4 | gzip_vary on;
5 | gzip_disable "MSIE [1-6]\.(?!.*SV1)";
6 |
--------------------------------------------------------------------------------
/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | user nginx;
2 | worker_processes 1;
3 |
4 | error_log /var/log/nginx/error.log warn;
5 | pid /var/run/nginx.pid;
6 |
7 | events {
8 | worker_connections 1024;
9 | }
10 |
11 |
12 | http {
13 | include /etc/nginx/mime.types;
14 | default_type application/octet-stream;
15 |
16 | log_format main '$remote_addr - $remote_user [$time_local] "$request" '
17 | '$status $body_bytes_sent "$http_referer" '
18 | '"$http_user_agent" "$http_x_forwarded_for"';
19 |
20 | log_format logstash_json '{ "@timestamp": "$time_iso8601", '
21 | '"@fields": { '
22 | '"remote_addr": "$remote_addr", '
23 | '"remote_user": "$remote_user", '
24 | '"body_bytes_sent": "$body_bytes_sent", '
25 | '"request_time": "$request_time", '
26 | '"status": "$status", '
27 | '"request": "$request", '
28 | '"request_method": "$request_method", '
29 | '"http_x_forwarded_for": "$http_x_forwarded_for", '
30 | '"http_referrer": "$http_referer", '
31 | '"http_user_agent": "$http_user_agent" } }';
32 |
33 | access_log /var/log/nginx/access.log logstash_json;
34 |
35 | sendfile on;
36 | #tcp_nopush on;
37 |
38 | keepalive_timeout 65;
39 |
40 | #gzip on;
41 |
42 | server {
43 | charset utf-8;
44 | client_max_body_size 512M;
45 | server_name localhost;
46 |
47 | listen 80;
48 |
49 | root /app/frontend/web;
50 | index index.php;
51 |
52 | location / {
53 | # Redirect everything that isn't a real file to index.php
54 | try_files $uri $uri/ /index.php?$args;
55 | }
56 |
57 | # uncomment to avoid processing of calls to non-existing static files by Yii
58 | location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
59 | try_files $uri =404;
60 | }
61 |
62 | location ~ \.php$ {
63 | include /etc/nginx/fastcgi_params;
64 | fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
65 | fastcgi_pass php:9000;
66 | try_files $uri =404;
67 | }
68 |
69 | location ~ /\.(ht|svn|git) {
70 | deny all;
71 | }
72 | }
73 |
74 | server {
75 | charset utf-8;
76 | client_max_body_size 512M;
77 | server_name localhost;
78 |
79 | listen 81;
80 |
81 | root /app/backend/web;
82 | index index.php;
83 |
84 | location / {
85 | # Redirect everything that isn't a real file to index.php
86 | try_files $uri $uri/ /index.php?$args;
87 | }
88 |
89 | # uncomment to avoid processing of calls to non-existing static files by Yii
90 | location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
91 | try_files $uri =404;
92 | }
93 |
94 | location ~ \.php$ {
95 | include /etc/nginx/fastcgi_params;
96 | fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
97 | fastcgi_pass php:9000;
98 | try_files $uri =404;
99 | }
100 |
101 | location ~ /\.(ht|svn|git) {
102 | deny all;
103 | }
104 | }
105 |
106 | include /etc/nginx/conf.d/*.conf;
107 | }
108 |
--------------------------------------------------------------------------------
/nginx/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Fail on any error
4 | set -o errexit
5 |
6 | # Example of using environment variable in configuration at runtime
7 | if [ ! -n "$NGINX_ERROR_LOG_LEVEL" ] ; then
8 | NGINX_ERROR_LOG_LEVEL="warn"
9 | fi
10 | sed -i "s|\${NGINX_ERROR_LOG_LEVEL}|${NGINX_ERROR_LOG_LEVEL}|" /etc/nginx/nginx.conf
11 |
12 | if [ ! -n "$SERVER_NAME" ] ; then
13 | SERVER_NAME="app"
14 | fi
15 | sed -i "s|\${SERVER_NAME}|${SERVER_NAME}|" /etc/nginx/nginx.conf
16 |
17 | if [ ! -n "$FASTCGI_PASS_HOST" ] ; then
18 | FASTCGI_PASS_HOST="phpfpm"
19 | fi
20 | sed -i "s|\${FASTCGI_PASS_HOST}|${FASTCGI_PASS_HOST}|" /etc/nginx/nginx.conf
21 |
22 | # Run nginx
23 | nginx -g 'daemon off;'
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Yii2 app",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "postcss.config.js",
6 | "dependencies": {},
7 | "devDependencies": {
8 | "autoprefixer": "^8.2.0",
9 | "css-mqpacker": "^6.0.2",
10 | "postcss-cssnext": "^3.1.0",
11 | "postcss-focus": "^3.0.0",
12 | "postcss-import": "^11.1.0",
13 | "postcss-nested": "^3.0.0",
14 | "postcss-nested-ancestors": "^2.0.0",
15 | "postcss-scss": "^1.0.4",
16 | "postcss-size": "^2.0.0"
17 | },
18 | "scripts": {
19 | "test": "echo \"Error: no test specified\" && exit 1"
20 | },
21 | "author": "",
22 | "license": "ISC"
23 | }
24 |
--------------------------------------------------------------------------------
/php/Dockerfile-alpine:
--------------------------------------------------------------------------------
1 | # PHP Docker image for Yii 2.0 Framework runtime
2 | # ==============================================
3 |
4 | ARG PHP_BASE_IMAGE_VERSION
5 | FROM php:${PHP_BASE_IMAGE_VERSION}
6 |
7 | # Install system packages & PHP extensions required for Yii 2.0 Framework
8 | RUN apk --update --virtual build-deps add \
9 | autoconf \
10 | make \
11 | gcc \
12 | g++ \
13 | libtool \
14 | icu-dev \
15 | curl-dev \
16 | freetype-dev \
17 | imagemagick-dev \
18 | pcre-dev \
19 | postgresql-dev \
20 | libjpeg-turbo-dev \
21 | libpng-dev \
22 | libxml2-dev && \
23 | apk add \
24 | git \
25 | curl \
26 | bash \
27 | bash-completion \
28 | icu \
29 | imagemagick \
30 | pcre \
31 | freetype \
32 | libintl \
33 | libjpeg-turbo \
34 | libpng \
35 | libltdl \
36 | libxml2 \
37 | mysql-client \
38 | postgresql && \
39 | docker-php-ext-configure gd \
40 | --with-gd \
41 | --with-freetype-dir=/usr/include/ \
42 | --with-png-dir=/usr/include/ \
43 | --with-jpeg-dir=/usr/include/ && \
44 | docker-php-ext-configure bcmath && \
45 | docker-php-ext-install \
46 | soap \
47 | zip \
48 | curl \
49 | bcmath \
50 | exif \
51 | gd \
52 | iconv \
53 | intl \
54 | mbstring \
55 | opcache \
56 | pdo_mysql \
57 | pdo_pgsql && \
58 | pecl install \
59 | imagick \
60 | mongodb && \
61 | apk del \
62 | build-deps
63 |
64 | RUN echo "extension=imagick.so" > /usr/local/etc/php/conf.d/pecl-imagick.ini && \
65 | echo "extension=mongodb.so" > /usr/local/etc/php/conf.d/pecl-mongodb.ini
66 |
67 |
68 | # Configure version constraints
69 | ENV PHP_ENABLE_XDEBUG=0 \
70 | PATH=/app:/app/vendor/bin:/root/.composer/vendor/bin:$PATH \
71 | TERM=linux \
72 | VERSION_PRESTISSIMO_PLUGIN=^0.3.7 \
73 | COMPOSER_ALLOW_SUPERUSER=1
74 |
75 | # Add configuration files
76 | COPY image-files/ /
77 |
78 | # Add GITHUB_API_TOKEN support for composer
79 | RUN chmod 700 \
80 | /usr/local/bin/docker-php-entrypoint \
81 | /usr/local/bin/composer
82 |
83 | # Install composer
84 | RUN curl -sS https://getcomposer.org/installer | php -- \
85 | --filename=composer.phar \
86 | --install-dir=/usr/local/bin && \
87 | composer clear-cache
88 |
89 | # Install composer plugins
90 | RUN composer global require --optimize-autoloader \
91 | "hirak/prestissimo:${VERSION_PRESTISSIMO_PLUGIN}" && \
92 | composer global dumpautoload --optimize && \
93 | composer clear-cache
94 |
95 | # Application environment
96 | WORKDIR /app
97 |
--------------------------------------------------------------------------------
/php/Dockerfile-debian:
--------------------------------------------------------------------------------
1 | # PHP Docker image for Yii 2.0 Framework runtime
2 | # ==============================================
3 |
4 | ARG PHP_BASE_IMAGE_VERSION
5 | FROM php:${PHP_BASE_IMAGE_VERSION}
6 |
7 | # Install system packages for PHP extensions recommended for Yii 2.0 Framework
8 | ENV DEBIAN_FRONTEND=noninteractive
9 | RUN apt-get update && \
10 | apt-get -y install \
11 | gnupg2 && \
12 | apt-key update && \
13 | apt-get update && \
14 | apt-get -y install \
15 | g++ \
16 | git \
17 | curl \
18 | imagemagick \
19 | libcurl3-dev \
20 | libicu-dev \
21 | libfreetype6-dev \
22 | libjpeg-dev \
23 | libjpeg62-turbo-dev \
24 | libmagickwand-dev \
25 | libpq-dev \
26 | libpng-dev \
27 | libxml2-dev \
28 | libzip-dev \
29 | zlib1g-dev \
30 | default-mysql-client \
31 | openssh-client \
32 | nano \
33 | mc \
34 | unzip \
35 | libcurl4-openssl-dev \
36 | libssl-dev \
37 | --no-install-recommends && \
38 | apt-get clean && \
39 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
40 |
41 | # Install PHP extensions required for Yii 2.0 Framework
42 | RUN docker-php-ext-configure gd \
43 | --with-freetype-dir=/usr/include/ \
44 | --with-png-dir=/usr/include/ \
45 | --with-jpeg-dir=/usr/include/ && \
46 | docker-php-ext-configure bcmath && \
47 | docker-php-ext-install \
48 | soap \
49 | zip \
50 | curl \
51 | bcmath \
52 | exif \
53 | gd \
54 | iconv \
55 | intl \
56 | mbstring \
57 | opcache \
58 | pdo_mysql \
59 | pdo_pgsql
60 |
61 | # Install PECL extensions
62 | # see http://stackoverflow.com/a/8154466/291573) for usage of `printf`
63 | RUN printf "\n" | pecl install \
64 | imagick && \
65 | #mongodb && \
66 | docker-php-ext-enable \
67 | imagick
68 | #mongodb
69 |
70 | # Check if Xdebug extension need to be compiled
71 | RUN cd /tmp && \
72 | git clone git://github.com/xdebug/xdebug.git && \
73 | cd xdebug && \
74 | git checkout 2.7.2 && \
75 | phpize && \
76 | ./configure --enable-xdebug && \
77 | make && \
78 | make install && \
79 | rm -rf /tmp/xdebug
80 |
81 | # Environment settings
82 | ENV PHP_USER_ID=33 \
83 | PHP_ENABLE_XDEBUG=0 \
84 | PATH=/app:/app/vendor/bin:/root/.composer/vendor/bin:$PATH \
85 | TERM=linux \
86 | VERSION_PRESTISSIMO_PLUGIN=^0.3.7 \
87 | COMPOSER_ALLOW_SUPERUSER=1
88 |
89 | # Add configuration files
90 | COPY image-files/ /
91 |
92 | # Add GITHUB_API_TOKEN support for composer
93 | RUN chmod 700 \
94 | /usr/local/bin/docker-php-entrypoint \
95 | /usr/local/bin/composer
96 |
97 | # Install composer
98 | RUN curl -sS https://getcomposer.org/installer | php -- \
99 | --filename=composer.phar \
100 | --install-dir=/usr/local/bin && \
101 | composer clear-cache
102 |
103 | # Install composer plugins
104 | #RUN composer global require --optimize-autoloader \
105 | # "hirak/prestissimo:${VERSION_PRESTISSIMO_PLUGIN}" && \
106 | # composer global dumpautoload --optimize && \
107 | # composer clear-cache
108 |
109 | # Enable mod_rewrite for images with apache
110 | RUN if command -v a2enmod >/dev/null 2>&1; then \
111 | a2enmod rewrite headers \
112 | ;fi
113 |
114 | # Install Yii framework bash autocompletion
115 | RUN curl -L https://raw.githubusercontent.com/yiisoft/yii2/master/contrib/completion/bash/yii \
116 | -o /etc/bash_completion.d/yii
117 |
118 | # Application environment
119 | WORKDIR /app
120 |
--------------------------------------------------------------------------------
/php/image-files/etc/apache2/sites-available/000-default.conf:
--------------------------------------------------------------------------------
1 |
2 | Options Indexes FollowSymLinks
3 | AllowOverride All
4 | Require all granted
5 |
6 |
7 |
8 | # The ServerName directive sets the request scheme, hostname and port that
9 | # the server uses to identify itself. This is used when creating
10 | # redirection URLs. In the context of virtual hosts, the ServerName
11 | # specifies what hostname must appear in the request's Host: header to
12 | # match this virtual host. For the default virtual host (this file) this
13 | # value is not decisive as it is used as a last resort host regardless.
14 | # However, you must set it for any further virtual host explicitly.
15 | #ServerName www.example.com
16 |
17 | ServerAdmin webmaster@localhost
18 | DocumentRoot /app/web
19 |
20 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
21 | # error, crit, alert, emerg.
22 | # It is also possible to configure the loglevel for particular
23 | # modules, e.g.
24 | #LogLevel info ssl:warn
25 |
26 | ErrorLog ${APACHE_LOG_DIR}/error.log
27 | CustomLog ${APACHE_LOG_DIR}/access.log combined
28 |
29 | # For most configuration files from conf-available/, which are
30 | # enabled or disabled at a global level, it is possible to
31 | # include a line for only one particular virtual host. For example the
32 | # following line enables the CGI configuration for this host only
33 | # after it has been globally disabled with "a2disconf".
34 | #Include conf-available/serve-cgi-bin.conf
35 |
36 |
--------------------------------------------------------------------------------
/php/image-files/root/.bashrc:
--------------------------------------------------------------------------------
1 | cat <<'MSG'
2 | _ _ __ _
3 | (_|_)/ _| | |
4 | _ _ _ _| |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
5 | | | | | | | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
6 | | |_| | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
7 | \__, |_|_|_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
8 | __/ |
9 | |___/
10 |
11 | MSG
12 |
13 | echo "PHP version: ${PHP_VERSION}"
14 |
15 | if ! shopt -oq posix; then
16 | if [ -f /usr/share/bash-completion/bash_completion ]; then
17 | . /usr/share/bash-completion/bash_completion
18 | elif [ -f /etc/bash_completion.d/yii ]; then
19 | . /etc/bash_completion.d/yii
20 | fi
21 | fi
22 |
--------------------------------------------------------------------------------
/php/image-files/usr/local/bin/composer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if [ -n "${GITHUB_API_TOKEN}" ]
6 | then
7 | composer.phar config -g github-oauth.github.com ${GITHUB_API_TOKEN}
8 | fi
9 |
10 | composer.phar "$@"
--------------------------------------------------------------------------------
/php/image-files/usr/local/bin/docker-php-entrypoint:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | # Set permissions based on ENV variable (debian only)
5 | if [ -x "$(command -v usermod)" ] ; then
6 | usermod -u ${PHP_USER_ID} www-data
7 | fi
8 |
9 | # Enable xdebug by ENV variable
10 | if [ 0 -ne "${PHP_ENABLE_XDEBUG:-0}" ] ; then
11 | docker-php-ext-enable xdebug
12 | echo "Enabled xdebug"
13 | fi
14 |
15 | export PS1="\e[0;35mphd \e[0;37m\u container \h \e[0;32m\w \e[0;0m\n$ "
16 |
17 | # first arg is `-f` or `--some-option`
18 | if [ "${1#-}" != "$1" ]; then
19 | if [ -x "$(command -v apache2-foreground)" ]; then
20 | set -- apache2-foreground "$@"
21 | elif [ -x "$(command -v php-fpm)" ]; then
22 | set -- php-fpm "$@"
23 | else
24 | set -- php "$@"
25 | fi
26 | fi
27 |
28 | exec "$@"
29 |
--------------------------------------------------------------------------------
/php/image-files/usr/local/etc/php/conf.d/base.ini:
--------------------------------------------------------------------------------
1 | ; Required timezone
2 | date.timezone = UTC
3 |
4 | ; General settings
5 | memory_limit=128M
6 | max_execution_time=30
7 | sys_temp_dir=/tmp
8 | upload_max_filesize=512M
9 | upload_tmp_dir=/tmp
10 | post_max_size=512M
11 |
12 | ; Security, Debug & Logs
13 | expose_php=off
14 | cgi.fix_pathinfo=0
15 | log_errors=on
16 | error_reporting=E_ALL
17 | html_errors=on
18 | xdebug.default_enable=off
19 |
20 | ; Opcache
21 | opcache.memory_consumption=128
22 | opcache.interned_strings_buffer=8
23 | opcache.max_accelerated_files=4000
24 | ;opcache.validate_timestamps=off
25 | opcache.fast_shutdown=0
26 | opcache.enable_cli=1
27 |
28 | ; PHP language options
29 | short_open_tag=0
--------------------------------------------------------------------------------
/php/image-files/usr/local/etc/php/conf.d/xdebug.ini:
--------------------------------------------------------------------------------
1 | ;zend_extension=xdebug.so
2 | xdebug.remote_enable=1
3 | xdebug.remote_autostart=1
4 | xdebug.remote_connect_back=0
5 | ;;; if you are on macOS, use host.docker.internal to identify the host machine, due to a network limitation on mac (https://docs.docker.com/docker-for-mac/networking/#port-mapping)
6 | ;;; otherwise find host ip
7 | xdebug.remote_host=host.docker.internal
8 | ;;; avoid standard port (9000) conflicts using 9005 port
9 | xdebug.remote_port=9005
10 | xdebug.idekey=PHPStorm
11 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | require('postcss-import')(),
4 | require('postcss-cssnext')(),
5 | require('postcss-nested-ancestors')(),
6 | require('postcss-nested')(),
7 | //require('css-mqpacker')(),
8 | //require('postcss-focus')()
9 | ]
10 | }
--------------------------------------------------------------------------------
/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.test;
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.test;
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 |
--------------------------------------------------------------------------------
/vagrant/nginx/log/.gitignore:
--------------------------------------------------------------------------------
1 | # nginx logs
2 | backend-access.log
3 | backend-error.log
4 | frontend-access.log
5 | frontend-error.log
--------------------------------------------------------------------------------
/vagrant/provision/always-as-root.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source /app/vagrant/provision/common.sh
4 |
5 | #== Provision script ==
6 |
7 | info "Provision-script user: `whoami`"
8 |
9 | info "Restart web-stack"
10 | service php7.0-fpm restart
11 | service nginx restart
12 | service mysql restart
--------------------------------------------------------------------------------
/vagrant/provision/common.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #== Bash helpers ==
4 |
5 | function info {
6 | echo " "
7 | echo "--> $1"
8 | echo " "
9 | }
10 |
--------------------------------------------------------------------------------
/vagrant/provision/once-as-root.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source /app/vagrant/provision/common.sh
4 |
5 | #== Import script args ==
6 |
7 | timezone=$(echo "$1")
8 |
9 | #== Provision script ==
10 |
11 | info "Provision-script user: `whoami`"
12 |
13 | export DEBIAN_FRONTEND=noninteractive
14 |
15 | info "Configure timezone"
16 | timedatectl set-timezone ${timezone} --no-ask-password
17 |
18 | info "Prepare root password for MySQL"
19 | debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass password \"''\""
20 | debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass password \"''\""
21 | echo "Done!"
22 |
23 | info "Update OS software"
24 | apt-get update
25 | apt-get upgrade -y
26 |
27 | info "Install additional software"
28 | 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
29 |
30 | info "Configure MySQL"
31 | sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf
32 | mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''"
33 | mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'"
34 | mysql -uroot <<< "DROP USER 'root'@'localhost'"
35 | mysql -uroot <<< "FLUSH PRIVILEGES"
36 | echo "Done!"
37 |
38 | info "Configure PHP-FPM"
39 | sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
40 | sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
41 | sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
42 | cat << EOF > /etc/php/7.0/mods-available/xdebug.ini
43 | zend_extension=xdebug.so
44 | xdebug.remote_enable=1
45 | xdebug.remote_connect_back=1
46 | xdebug.remote_port=9000
47 | xdebug.remote_autostart=1
48 | EOF
49 | echo "Done!"
50 |
51 | info "Configure NGINX"
52 | sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf
53 | echo "Done!"
54 |
55 | info "Enabling site configuration"
56 | ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf
57 | echo "Done!"
58 |
59 | info "Initailize databases for MySQL"
60 | mysql -uroot <<< "CREATE DATABASE yii2advanced"
61 | mysql -uroot <<< "CREATE DATABASE yii2advanced_test"
62 | echo "Done!"
63 |
64 | info "Install composer"
65 | 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 | source /app/vagrant/provision/common.sh
4 |
5 | #== Import script args ==
6 |
7 | github_token=$(echo "$1")
8 |
9 | #== Provision script ==
10 |
11 | info "Provision-script user: `whoami`"
12 |
13 | info "Configure composer"
14 | composer config --global github-oauth.github.com ${github_token}
15 | echo "Done!"
16 |
17 | info "Install project dependencies"
18 | cd /app
19 | composer --no-progress --prefer-dist install
20 |
21 | info "Init project"
22 | ./init --env=Development --overwrite=y
23 |
24 | info "Apply migrations"
25 | ./yii migrate --interactive=0
26 | ./yii_test migrate --interactive=0
27 |
28 | info "Create bash-alias 'app' for vagrant user"
29 | echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases
30 |
31 | info "Enabling colorized prompt for guest console"
32 | sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc
33 |
--------------------------------------------------------------------------------
/yii.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem -------------------------------------------------------------
4 | rem Yii command line bootstrap script for Windows.
5 | rem -------------------------------------------------------------
6 |
7 | @setlocal
8 |
9 | set YII_PATH=%~dp0
10 |
11 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
12 |
13 | "%PHP_COMMAND%" "%YII_PATH%yii" %*
14 |
15 | @endlocal
16 |
--------------------------------------------------------------------------------