diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000..011c056bb
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,8 @@
+# Reformat code te be PSR-2 compatible
+93cc82c4bf42cea403e1acaab201338bea304b6e
+# Convert to short syntax (array)
+332030325fbad38a64c5e60980d3b14b6434d6dd
+# Convert to short syntax
+b0fcdfab1aecaeb620f75a83f15aa02bc25765a0
+# Fix codestyle
+0f91f32ecff52ef479addb0a5013342d59fe0697
diff --git a/.gitattributes b/.gitattributes
index 3e9092c68..705fb391d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,7 @@
# Ignore all test and documentation for archive
-/.github export-ignore
-/.gitattributes export-ignore
-/.scrutinizer.yml export-ignore
-/.travis.yml export-ignore
-/docs export-ignore
+/.github export-ignore
+/.git-blame-ignore-revs export-ignore
+/.gitattributes export-ignore
+/.scrutinizer.yml export-ignore
+/.travis.yml export-ignore
+/docs export-ignore
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 3d8d32c25..ea75bda5f 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -3,5 +3,5 @@ Contributing to Yii2
- [Report an issue](https://github.com/yiisoft/yii2/blob/master/docs/internals/report-an-issue.md)
- [Translate documentation or messages](https://github.com/yiisoft/yii2/blob/master/docs/internals/translation-workflow.md)
-- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
+- [Give us feedback or start a design discussion](https://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
- [Contribute to the core code or fix bugs](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..692239301
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+open_collective: yiisoft
+tidelift: "packagist/yiisoft/yii2-app-basic"
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 52ec8692f..a2ee92439 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -9,6 +9,6 @@
| Q | A
| ---------------- | ---
-| Yii vesion |
+| Yii version |
| PHP version |
| Operating system |
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 000000000..405acca4e
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,6 @@
+# Security Policy
+
+Please use the [security issue form](https://www.yiiframework.com/security) to report to us any security issue you find in Yii.
+DO NOT use the issue tracker or discuss it in the public forum as it will cause more damage than help.
+
+Please note that as a non-commercial OpenSource project we are not able to pay bounties at the moment.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..a5beac653
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,83 @@
+on:
+ - pull_request
+ - push
+
+name: build
+
+jobs:
+ tests:
+ name: PHP ${{ matrix.php }} - ${{ matrix.os }}
+
+ env:
+ extensions: dom, json, gd, imagick
+ key: cache-v4
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+ - windows-latest
+
+ php:
+ - "7.4"
+ - "8.0"
+ - "8.1"
+ - "8.2"
+ - "8.3"
+ - "8.4"
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: Setup cache environment
+ id: cache-env
+ uses: shivammathur/cache-extensions@v1
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ${{ env.extensions }}
+ key: ${{ env.key }}
+
+ - name: Cache extensions
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.cache-env.outputs.dir }}
+ key: ${{ steps.cache-env.outputs.key }}
+ restore-keys: ${{ steps.cache-env.outputs.key }}
+
+ - name: Install PHP with extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ${{ env.extensions }}
+ ini-values: date.timezone='UTC'
+
+ - name: Determine composer cache directory on Linux
+ if: matrix.os == 'ubuntu-latest'
+ run: |
+ echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
+
+ - name: Determine composer cache directory on Windows
+ if: matrix.os == 'windows-latest'
+ run: |
+ echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" >> $GITHUB_ENV
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.cache-env.outputs.dir }}
+ key: php${{ matrix.php }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php }}-composer-${{ matrix.dependencies }}-
+
+ - name: Install dependencies with composer php PHP [5.6 - 8.0]
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
+
+ - name: Run tests with codeception
+ run: |
+ sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" config/web.php
+ php -S 127.0.0.1:8080 -t public > ./runtime/yii.log 2>&1 &
+ vendor/bin/codecept run
+ shell: bash
diff --git a/.gitignore b/.gitignore
index 5bd9be80b..05fb29d1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
# phpstorm project files
.idea
+# visual studio code project files
+.vscode
+
# netbeans project files
nbproject
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1b996428c..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-language: php
-
-php:
- - 5.4
- - 5.5
- - 5.6
- - 7.0
- - 7.1
-# - hhvm
-
-# faster builds on new travis setup not using sudo
-sudo: false
-
-# cache vendor dirs
-cache:
- directories:
- - $HOME/.composer/cache
-
-install:
- - travis_retry composer self-update && composer --version
- - travis_retry composer update --dev --prefer-dist --no-interaction
- # install php extensions
- - |
- if (php --version | grep -i HipHop > /dev/null); then
- echo "Skipping imagick and gmagick tests on HHVM"
- else
- pear config-set preferred_state beta
- printf "\n" | pecl install imagick
- # gmagick is not installed on travis currently
- #printf "\n" | pecl install gmagick
- fi
-# setup application:
- - |
- sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" config/web.php
-
-script:
- - |
- php -S localhost:8080 -t web > /dev/null 2>&1 &
- vendor/bin/codecept run
diff --git a/LICENSE.md b/LICENSE.md
index e98f03df8..ee872b9ab 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,3 @@
-The Yii framework is free software. It is released under the terms of
-the following BSD License.
-
Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
All rights reserved.
diff --git a/README.md b/README.md
index 1caaca9af..981a7f9d9 100644
--- a/README.md
+++ b/README.md
@@ -6,16 +6,16 @@
-Yii 2 Basic Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
+Yii 2 Basic Project Template is a skeleton [Yii 2](https://www.yiiframework.com/) application best for
rapidly creating small projects.
The template contains the basic features including user login/logout and a contact page.
It includes all commonly used configurations that would allow you to focus on adding new
features to your application.
-[](https://packagist.org/packages/yiisoft/yii2-app-basic)
-[](https://packagist.org/packages/yiisoft/yii2-app-basic)
-[](https://travis-ci.org/yiisoft/yii2-app-basic)
+[](https://packagist.org/packages/yiisoft/yii2-app-basic)
+[](https://packagist.org/packages/yiisoft/yii2-app-basic)
+[](https://github.com/yiisoft/yii2-app-basic/actions?query=workflow%3Abuild)
DIRECTORY STRUCTURE
-------------------
@@ -37,7 +37,7 @@ DIRECTORY STRUCTURE
REQUIREMENTS
------------
-The minimum requirement by this project template that your Web server supports PHP 5.4.0.
+The minimum requirement by this project template that your Web server supports PHP 7.4.
INSTALLATION
@@ -45,13 +45,13 @@ INSTALLATION
### Install via Composer
-If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions
-at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix).
+If you do not have [Composer](https://getcomposer.org/), you may install it by following the instructions
+at [getcomposer.org](https://getcomposer.org/doc/00-intro.md#installation-nix).
You can then install this project template using the following command:
~~~
-php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
+composer create-project --prefer-dist yiisoft/yii2-app-basic basic
~~~
Now you should be able to access the application through the following URL, assuming `basic` is the directory
@@ -63,7 +63,7 @@ http://localhost/basic/web/
### Install from an Archive File
-Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to
+Extract the archive file downloaded from [yiiframework.com](https://www.yiiframework.com/download/) to
a directory named `basic` that is directly under the Web root.
Set cookie validation key in `config/web.php` file to some random secret string:
@@ -82,6 +82,29 @@ http://localhost/basic/web/
~~~
+### Install with Docker
+
+Update your vendor packages
+
+ docker-compose run --rm php composer update --prefer-dist
+
+Run the installation triggers (creating cookie validation code)
+
+ docker-compose run --rm php composer install
+
+Start the container
+
+ docker-compose up -d
+
+You can then access the application through the following URL:
+
+ http://127.0.0.1:8000
+
+**NOTES:**
+- Minimum required Docker engine version `17.04` for development (see [Performance tuning for volume mounts](https://docs.docker.com/docker-for-mac/osxfs-caching/))
+- The default configuration uses a host-volume in your home directory `.docker-composer` for composer caches
+
+
CONFIGURATION
-------------
@@ -108,8 +131,8 @@ return [
TESTING
-------
-Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](http://codeception.com/).
-By default there are 3 test suites:
+Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](https://codeception.com/).
+By default, there are 3 test suites:
- `unit`
- `functional`
@@ -132,7 +155,7 @@ To execute acceptance tests do the following:
1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration
-2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured
+2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full-featured
version of Codeception
3. Update dependencies with Composer
@@ -141,7 +164,7 @@ To execute acceptance tests do the following:
composer update
```
-4. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it:
+4. Download [Selenium Server](https://www.seleniumhq.org/download/) and launch it:
```
java -jar ~/selenium-server-standalone-x.xx.x.jar
@@ -163,7 +186,7 @@ To execute acceptance tests do the following:
docker run --net=host selenium/standalone-firefox:2.53.0
```
-5. (Optional) Create `yii2_basic_tests` database and update it by applying migrations if you have them.
+5. (Optional) Create `yii2basic_test` database and update it by applying migrations if you have them.
```
tests/bin/yii migrate
@@ -198,13 +221,13 @@ to collect code coverage. You can run your tests and collect coverage with the f
```
#collect coverage for all tests
-vendor/bin/codecept run -- --coverage-html --coverage-xml
+vendor/bin/codecept run --coverage --coverage-html --coverage-xml
#collect coverage only for unit tests
-vendor/bin/codecept run unit -- --coverage-html --coverage-xml
+vendor/bin/codecept run unit --coverage --coverage-html --coverage-xml
#collect coverage for unit and functional tests
-vendor/bin/codecept run functional,unit -- --coverage-html --coverage-xml
+vendor/bin/codecept run functional,unit --coverage --coverage-html --coverage-xml
```
You can see code coverage output under the `tests/_output` directory.
diff --git a/Vagrantfile b/Vagrantfile
index 163b5c256..258aea601 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,18 +1,31 @@
require 'yaml'
require 'fileutils'
+required_plugins_installed = nil
required_plugins = %w( vagrant-hostmanager vagrant-vbguest )
required_plugins.each do |plugin|
- exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
+ unless Vagrant.has_plugin? plugin
+ system "vagrant plugin install #{plugin}"
+ required_plugins_installed = true
+ end
+end
+
+# IF plugin[s] was just installed - restart required
+if required_plugins_installed
+ # Get CLI command[s] and call again
+ system 'vagrant' + ARGV.to_s.gsub(/\[\"|\", \"|\"\]/, ' ')
+ exit
end
domains = {
- app: 'yii2basic.dev'
+ app: 'yii2basic.test'
}
+vagrantfile_dir_path = File.dirname(__FILE__)
+
config = {
- local: './vagrant/config/vagrant-local.yml',
- example: './vagrant/config/vagrant-local.example.yml'
+ local: vagrantfile_dir_path + '/vagrant/config/vagrant-local.yml',
+ example: vagrantfile_dir_path + '/vagrant/config/vagrant-local.example.yml'
}
# copy config from example if local config not exists
@@ -29,7 +42,7 @@ end
# vagrant configurate
Vagrant.configure(2) do |config|
# select the box
- config.vm.box = 'bento/ubuntu-16.04'
+ config.vm.box = 'bento/ubuntu-18.04'
# should we ask about box updates?
config.vm.box_check_update = options['box_check_update']
@@ -70,7 +83,7 @@ Vagrant.configure(2) do |config|
# config.vbguest.auto_update = false
# provisioners
- config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
+ config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone'], options['ip']]
config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
diff --git a/assets/AppAsset.php b/assets/AppAsset.php
index 47932b165..d9d4cc430 100644
--- a/assets/AppAsset.php
+++ b/assets/AppAsset.php
@@ -1,8 +1,9 @@
=5.4.0",
- "yiisoft/yii2": "~2.0.13",
- "yiisoft/yii2-bootstrap": "~2.0.0",
- "yiisoft/yii2-swiftmailer": "~2.0.0"
+ "php": ">=7.4.0",
+ "yiisoft/yii2": "~2.0.45",
+ "yiisoft/yii2-bootstrap5": "~2.0.2",
+ "yiisoft/yii2-symfonymailer": "~2.0.3"
},
"require-dev": {
- "yiisoft/yii2-debug": "~2.0.0",
- "yiisoft/yii2-gii": "~2.0.0",
+ "yiisoft/yii2-debug": "~2.1.0",
+ "yiisoft/yii2-gii": "~2.2.0",
"yiisoft/yii2-faker": "~2.0.0",
-
- "codeception/base": "^2.2.3",
- "codeception/verify": "~0.3.1",
- "codeception/specify": "~0.4.3"
+ "codeception/codeception": "^5.0.0 || ^4.0",
+ "codeception/lib-innerbrowser": "^4.0 || ^3.0 || ^1.1",
+ "codeception/module-asserts": "^3.0 || ^1.1",
+ "codeception/module-yii2": "^1.1",
+ "codeception/module-filesystem": "^3.0 || ^2.0 || ^1.1",
+ "codeception/verify": "^3.0 || ^2.2"
},
"config": {
+ "allow-plugins": {
+ "yiisoft/yii2-composer" : true
+ },
"process-timeout": 1800,
"fxp-asset": {
"enabled": false
diff --git a/config/__autocomplete.php b/config/__autocomplete.php
new file mode 100644
index 000000000..e5e1c00d7
--- /dev/null
+++ b/config/__autocomplete.php
@@ -0,0 +1,35 @@
+ [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
+ '@tests' => '@app/tests',
],
'components' => [
'cache' => [
@@ -42,6 +43,14 @@
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
+ // configuration adjustments for 'dev' environment
+ // requires version `2.1.21` of yii2-debug module
+ $config['bootstrap'][] = 'debug';
+ $config['modules']['debug'] = [
+ 'class' => 'yii\debug\Module',
+ // uncomment the following to add your IP if you are not connecting from localhost.
+ //'allowedIPs' => ['127.0.0.1', '::1'],
+ ];
}
return $config;
diff --git a/config/params.php b/config/params.php
index 6ebf2792b..981c621ac 100644
--- a/config/params.php
+++ b/config/params.php
@@ -2,4 +2,6 @@
return [
'adminEmail' => 'admin@example.com',
+ 'senderEmail' => 'noreply@example.com',
+ 'senderName' => 'Example.com mailer',
];
diff --git a/config/test.php b/config/test.php
index f95bc031e..fb5e2929e 100644
--- a/config/test.php
+++ b/config/test.php
@@ -1,4 +1,5 @@
[
'db' => $db,
'mailer' => [
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@app/mail',
+ // send all mails to a file by default.
'useFileTransport' => true,
+ 'messageClass' => 'yii\symfonymailer\Message'
],
'assetManager' => [
'basePath' => __DIR__ . '/../web/assets',
diff --git a/config/test_db.php b/config/test_db.php
index 5d213e135..f10835fe1 100644
--- a/config/test_db.php
+++ b/config/test_db.php
@@ -1,6 +1,7 @@
'site/error',
],
'mailer' => [
- 'class' => 'yii\swiftmailer\Mailer',
- // send all mails to a file by default. You have to set
- // 'useFileTransport' to false and configure a transport
- // for the mailer to send real emails.
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@app/mail',
+ // send all mails to a file by default.
'useFileTransport' => true,
],
'log' => [
diff --git a/controllers/SiteController.php b/controllers/SiteController.php
index 1a84f9cfb..67c3f50f8 100644
--- a/controllers/SiteController.php
+++ b/controllers/SiteController.php
@@ -13,13 +13,13 @@
class SiteController extends Controller
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
- 'class' => AccessControl::className(),
+ 'class' => AccessControl::class,
'only' => ['logout'],
'rules' => [
[
@@ -30,7 +30,7 @@ public function behaviors()
],
],
'verbs' => [
- 'class' => VerbFilter::className(),
+ 'class' => VerbFilter::class,
'actions' => [
'logout' => ['post'],
],
@@ -39,7 +39,7 @@ public function behaviors()
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function actions()
{
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 000000000..86be3bd0d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,9 @@
+version: '2'
+services:
+ php:
+ image: yiisoftware/yii2-php:7.4-apache
+ volumes:
+ - ~/.composer-docker/cache:/root/.composer/cache:delegated
+ - ./:/app:delegated
+ ports:
+ - '8000:80'
diff --git a/mail/layouts/html.php b/mail/layouts/html.php
index bddbc6129..95732cdfa 100644
--- a/mail/layouts/html.php
+++ b/mail/layouts/html.php
@@ -1,9 +1,9 @@
beginPage() ?>
diff --git a/mail/layouts/text.php b/mail/layouts/text.php
new file mode 100644
index 000000000..0873d7728
--- /dev/null
+++ b/mail/layouts/text.php
@@ -0,0 +1,13 @@
+beginPage();
+$this->beginBody();
+echo $content;
+$this->endBody();
+$this->endPage();
diff --git a/models/ContactForm.php b/models/ContactForm.php
index 0b13cb05d..f001d2192 100644
--- a/models/ContactForm.php
+++ b/models/ContactForm.php
@@ -52,7 +52,8 @@ public function contact($email)
if ($this->validate()) {
Yii::$app->mailer->compose()
->setTo($email)
- ->setFrom([$this->email => $this->name])
+ ->setFrom([Yii::$app->params['senderEmail'] => Yii::$app->params['senderName']])
+ ->setReplyTo([$this->email => $this->name])
->setSubject($this->subject)
->setTextBody($this->body)
->send();
diff --git a/models/LoginForm.php b/models/LoginForm.php
index cc6af264c..5304eecf4 100644
--- a/models/LoginForm.php
+++ b/models/LoginForm.php
@@ -8,7 +8,7 @@
/**
* LoginForm is the model behind the login form.
*
- * @property User|null $user This property is read-only.
+ * @property-read User|null $user
*
*/
class LoginForm extends Model
@@ -60,7 +60,7 @@ public function validatePassword($attribute, $params)
public function login()
{
if ($this->validate()) {
- return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
+ return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
}
return false;
}
diff --git a/models/User.php b/models/User.php
index 768bddd62..2e3fb25ed 100644
--- a/models/User.php
+++ b/models/User.php
@@ -29,7 +29,7 @@ class User extends \yii\base\BaseObject implements \yii\web\IdentityInterface
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public static function findIdentity($id)
{
@@ -37,7 +37,7 @@ public static function findIdentity($id)
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public static function findIdentityByAccessToken($token, $type = null)
{
@@ -68,7 +68,7 @@ public static function findByUsername($username)
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function getId()
{
@@ -76,7 +76,7 @@ public function getId()
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function getAuthKey()
{
@@ -84,7 +84,7 @@ public function getAuthKey()
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function validateAuthKey($authKey)
{
diff --git a/requirements.php b/requirements.php
index 91a0fb097..db69a36ee 100644
--- a/requirements.php
+++ b/requirements.php
@@ -1,4 +1,5 @@
'Memcache extension',
'mandatory' => false,
'condition' => extension_loaded('memcache') || extension_loaded('memcached'),
- 'by' => 'MemCache',
- 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : ''
+ 'by' => 'MemCache',
+ 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : ''
),
// CAPTCHA:
array(
'name' => 'GD PHP extension with FreeType support',
'mandatory' => false,
'condition' => $gdOK,
- 'by' => 'Captcha',
+ 'by' => 'Captcha',
'memo' => $gdMemo,
),
array(
'name' => 'ImageMagick PHP extension with PNG support',
'mandatory' => false,
'condition' => $imagickOK,
- 'by' => 'Captcha',
+ 'by' => 'Captcha',
'memo' => $imagickMemo,
),
// PHP ini :
@@ -153,8 +154,10 @@
'name' => 'APC extension',
'mandatory' => false,
'condition' => extension_loaded('apc'),
- 'by' => 'ApcCache',
+ 'by' => 'ApcCache',
);
}
-$requirementsChecker->checkYii()->check($requirements)->render();
+$result = $requirementsChecker->checkYii()->check($requirements)->getResult();
+$requirementsChecker->render();
+exit($result['summary']['errors'] === 0 ? 0 : 1);
diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php
index 131da42af..4b8424f73 100644
--- a/tests/_bootstrap.php
+++ b/tests/_bootstrap.php
@@ -1,6 +1,7 @@
amOnPage(Url::toRoute('/site/contact'));
}
-
+
public function contactPageWorks(AcceptanceTester $I)
{
$I->wantTo('ensure that contact page works');
@@ -25,7 +25,7 @@ public function contactFormCanBeSubmitted(AcceptanceTester $I)
$I->fillField('#contactform-verifycode', 'testme');
$I->click('contact-button');
-
+
$I->wait(2); // wait for button to be clicked
$I->dontSeeElement('#contact-form');
diff --git a/tests/acceptance/HomeCest.php b/tests/acceptance/HomeCest.php
index e65df16ae..98fb6b9f7 100644
--- a/tests/acceptance/HomeCest.php
+++ b/tests/acceptance/HomeCest.php
@@ -6,13 +6,13 @@ class HomeCest
{
public function ensureThatHomePageWorks(AcceptanceTester $I)
{
- $I->amOnPage(Url::toRoute('/site/index'));
+ $I->amOnPage(Url::toRoute('/site/index'));
$I->see('My Company');
-
+
$I->seeLink('About');
$I->click('About');
$I->wait(2); // wait for page to be opened
-
+
$I->see('This is the About page.');
}
}
diff --git a/tests/bin/yii b/tests/bin/yii
index 4923537fb..39df4013d 100755
--- a/tests/bin/yii
+++ b/tests/bin/yii
@@ -3,9 +3,9 @@
/**
* Yii console bootstrap file.
*
- * @link http://www.yiiframework.com/
+ * @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
- * @license http://www.yiiframework.com/license/
+ * @license https://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
diff --git a/tests/bin/yii.bat b/tests/bin/yii.bat
index d516b3a19..ce14c92bc 100644
--- a/tests/bin/yii.bat
+++ b/tests/bin/yii.bat
@@ -4,9 +4,9 @@ rem -------------------------------------------------------------
rem Yii command line bootstrap script for Windows.
rem
rem @author Qiang Xue
-rem @link http://www.yiiframework.com/
+rem @link https://www.yiiframework.com/
rem @copyright Copyright (c) 2008 Yii Software LLC
-rem @license http://www.yiiframework.com/license/
+rem @license https://www.yiiframework.com/license/
rem -------------------------------------------------------------
@setlocal
diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml
index 374c6df45..9d8cf149c 100644
--- a/tests/functional.suite.yml
+++ b/tests/functional.suite.yml
@@ -6,8 +6,9 @@
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
#basic/web/index.php
-class_name: FunctionalTester
+actor: FunctionalTester
modules:
enabled:
- Filesystem
- Yii2
+ - Asserts
diff --git a/tests/functional/ContactFormCest.php b/tests/functional/ContactFormCest.php
index ad8167865..f1ccaf18f 100644
--- a/tests/functional/ContactFormCest.php
+++ b/tests/functional/ContactFormCest.php
@@ -1,15 +1,15 @@
amOnPage(['site/contact']);
+ $I->amOnRoute('site/contact');
}
public function openContactPage(\FunctionalTester $I)
{
- $I->see('Contact', 'h1');
+ $I->see('Contact', 'h1');
}
public function submitEmptyForm(\FunctionalTester $I)
@@ -38,7 +38,7 @@ public function submitFormWithIncorrectEmail(\FunctionalTester $I)
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
- $I->dontSee('The verification code is incorrect', '.help-inline');
+ $I->dontSee('The verification code is incorrect', '.help-inline');
}
public function submitFormSuccessfully(\FunctionalTester $I)
@@ -52,6 +52,6 @@ public function submitFormSuccessfully(\FunctionalTester $I)
]);
$I->seeEmailIsSent();
$I->dontSeeElement('#contact-form');
- $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
+ $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
}
}
diff --git a/tests/functional/LoginFormCest.php b/tests/functional/LoginFormCest.php
index 7a83a27d6..a1545a706 100644
--- a/tests/functional/LoginFormCest.php
+++ b/tests/functional/LoginFormCest.php
@@ -10,7 +10,6 @@ public function _before(\FunctionalTester $I)
public function openLoginPage(\FunctionalTester $I)
{
$I->see('Login', 'h1');
-
}
// demonstrates `amLoggedInAs` method
@@ -54,6 +53,6 @@ public function loginSuccessfully(\FunctionalTester $I)
'LoginForm[password]' => 'admin',
]);
$I->see('Logout (admin)');
- $I->dontSeeElement('form#login-form');
+ $I->dontSeeElement('form#login-form');
}
-}
\ No newline at end of file
+}
diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml
index b1efaba99..c14e49c37 100644
--- a/tests/unit.suite.yml
+++ b/tests/unit.suite.yml
@@ -3,9 +3,9 @@
# suite for unit (internal) tests.
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
-class_name: UnitTester
+actor: UnitTester
modules:
enabled:
- Asserts
- Yii2:
- part: [orm, email]
\ No newline at end of file
+ part: [orm, email, fixtures]
diff --git a/tests/unit/models/ContactFormTest.php b/tests/unit/models/ContactFormTest.php
index 384889762..1bb1bb2d0 100644
--- a/tests/unit/models/ContactFormTest.php
+++ b/tests/unit/models/ContactFormTest.php
@@ -1,10 +1,12 @@
model = $this->getMockBuilder('app\models\ContactForm')
- ->setMethods(['validate'])
- ->getMock();
-
- $this->model->expects($this->once())
- ->method('validate')
- ->will($this->returnValue(true));
+ $model = new ContactForm();
- $this->model->attributes = [
+ $model->attributes = [
'name' => 'Tester',
'email' => 'tester@example.com',
'subject' => 'very important letter subject',
'body' => 'body of current message',
+ 'verifyCode' => 'testme',
];
- expect_that($this->model->contact('admin@example.com'));
+ verify($model->contact('admin@example.com'))->notEmpty();
// using Yii2 module actions to check email was sent
$this->tester->seeEmailIsSent();
+ /** @var MessageInterface $emailMessage */
$emailMessage = $this->tester->grabLastSentEmail();
- expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
- expect($emailMessage->getTo())->hasKey('admin@example.com');
- expect($emailMessage->getFrom())->hasKey('tester@example.com');
- expect($emailMessage->getSubject())->equals('very important letter subject');
- expect($emailMessage->toString())->contains('body of current message');
+ verify($emailMessage)->instanceOf('yii\mail\MessageInterface');
+ verify($emailMessage->getTo())->arrayHasKey('admin@example.com');
+ verify($emailMessage->getFrom())->arrayHasKey('noreply@example.com');
+ verify($emailMessage->getReplyTo())->arrayHasKey('tester@example.com');
+ verify($emailMessage->getSubject())->equals('very important letter subject');
+ verify($emailMessage->toString())->stringContainsString('body of current message');
}
}
diff --git a/tests/unit/models/LoginFormTest.php b/tests/unit/models/LoginFormTest.php
index 4a15dc9c5..6f96c2377 100644
--- a/tests/unit/models/LoginFormTest.php
+++ b/tests/unit/models/LoginFormTest.php
@@ -1,6 +1,6 @@
'not_existing_password',
]);
- expect_not($this->model->login());
- expect_that(\Yii::$app->user->isGuest);
+ verify($this->model->login())->false();
+ verify(\Yii::$app->user->isGuest)->true();
}
public function testLoginWrongPassword()
@@ -31,9 +31,9 @@ public function testLoginWrongPassword()
'password' => 'wrong_password',
]);
- expect_not($this->model->login());
- expect_that(\Yii::$app->user->isGuest);
- expect($this->model->errors)->hasKey('password');
+ verify($this->model->login())->false();
+ verify(\Yii::$app->user->isGuest)->true();
+ verify($this->model->errors)->arrayHasKey('password');
}
public function testLoginCorrect()
@@ -43,9 +43,8 @@ public function testLoginCorrect()
'password' => 'demo',
]);
- expect_that($this->model->login());
- expect_not(\Yii::$app->user->isGuest);
- expect($this->model->errors)->hasntKey('password');
+ verify($this->model->login())->true();
+ verify(\Yii::$app->user->isGuest)->false();
+ verify($this->model->errors)->arrayHasNotKey('password');
}
-
}
diff --git a/tests/unit/models/UserTest.php b/tests/unit/models/UserTest.php
index fc26450bf..3db9772a3 100644
--- a/tests/unit/models/UserTest.php
+++ b/tests/unit/models/UserTest.php
@@ -1,6 +1,6 @@
username)->equals('admin');
+ verify($user = User::findIdentity(100))->notEmpty();
+ verify($user->username)->equals('admin');
- expect_not(User::findIdentity(999));
+ verify(User::findIdentity(999))->empty();
}
public function testFindUserByAccessToken()
{
- expect_that($user = User::findIdentityByAccessToken('100-token'));
- expect($user->username)->equals('admin');
+ verify($user = User::findIdentityByAccessToken('100-token'))->notEmpty();
+ verify($user->username)->equals('admin');
- expect_not(User::findIdentityByAccessToken('non-existing'));
+ verify(User::findIdentityByAccessToken('non-existing'))->empty();
}
public function testFindUserByUsername()
{
- expect_that($user = User::findByUsername('admin'));
- expect_not(User::findByUsername('not-admin'));
+ verify($user = User::findByUsername('admin'))->notEmpty();
+ verify(User::findByUsername('not-admin'))->empty();
}
/**
* @depends testFindUserByUsername
*/
- public function testValidateUser($user)
+ public function testValidateUser()
{
$user = User::findByUsername('admin');
- expect_that($user->validateAuthKey('test100key'));
- expect_not($user->validateAuthKey('test102key'));
+ verify($user->validateAuthKey('test100key'))->notEmpty();
+ verify($user->validateAuthKey('test102key'))->empty();
- expect_that($user->validatePassword('admin'));
- expect_not($user->validatePassword('123456'));
+ verify($user->validatePassword('admin'))->notEmpty();
+ verify($user->validatePassword('123456'))->empty();
}
-
}
diff --git a/tests/unit/widgets/AlertTest.php b/tests/unit/widgets/AlertTest.php
new file mode 100644
index 000000000..af2db5d21
--- /dev/null
+++ b/tests/unit/widgets/AlertTest.php
@@ -0,0 +1,263 @@
+session->setFlash('error', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleErrorMessages()
+ {
+ $firstMessage = 'This is the first error message';
+ $secondMessage = 'This is the second error message';
+
+ Yii::$app->session->setFlash('error', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleDangerMessage()
+ {
+ $message = 'This is a danger message';
+
+ Yii::$app->session->setFlash('danger', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleDangerMessages()
+ {
+ $firstMessage = 'This is the first danger message';
+ $secondMessage = 'This is the second danger message';
+
+ Yii::$app->session->setFlash('danger', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleSuccessMessage()
+ {
+ $message = 'This is a success message';
+
+ Yii::$app->session->setFlash('success', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-success');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleSuccessMessages()
+ {
+ $firstMessage = 'This is the first danger message';
+ $secondMessage = 'This is the second danger message';
+
+ Yii::$app->session->setFlash('success', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-success');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleInfoMessage()
+ {
+ $message = 'This is an info message';
+
+ Yii::$app->session->setFlash('info', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-info');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleInfoMessages()
+ {
+ $firstMessage = 'This is the first info message';
+ $secondMessage = 'This is the second info message';
+
+ Yii::$app->session->setFlash('info', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-info');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleWarningMessage()
+ {
+ $message = 'This is a warning message';
+
+ Yii::$app->session->setFlash('warning', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-warning');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ }
+
+ public function testMultipleWarningMessages()
+ {
+ $firstMessage = 'This is the first warning message';
+ $secondMessage = 'This is the second warning message';
+
+ Yii::$app->session->setFlash('warning', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-warning');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ }
+
+ public function testSingleMixedMessages()
+ {
+ $errorMessage = 'This is an error message';
+ $dangerMessage = 'This is a danger message';
+ $successMessage = 'This is a success message';
+ $infoMessage = 'This is a info message';
+ $warningMessage = 'This is a warning message';
+
+ Yii::$app->session->setFlash('error', $errorMessage);
+ Yii::$app->session->setFlash('danger', $dangerMessage);
+ Yii::$app->session->setFlash('success', $successMessage);
+ Yii::$app->session->setFlash('info', $infoMessage);
+ Yii::$app->session->setFlash('warning', $warningMessage);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($errorMessage);
+ verify($renderingResult)->stringContainsString($dangerMessage);
+ verify($renderingResult)->stringContainsString($successMessage);
+ verify($renderingResult)->stringContainsString($infoMessage);
+ verify($renderingResult)->stringContainsString($warningMessage);
+
+ verify($renderingResult)->stringContainsString('alert-danger');
+ verify($renderingResult)->stringContainsString('alert-success');
+ verify($renderingResult)->stringContainsString('alert-info');
+ verify($renderingResult)->stringContainsString('alert-warning');
+ }
+
+ public function testMultipleMixedMessages()
+ {
+ $firstErrorMessage = 'This is the first error message';
+ $secondErrorMessage = 'This is the second error message';
+ $firstDangerMessage = 'This is the first danger message';
+ $secondDangerMessage = 'This is the second';
+ $firstSuccessMessage = 'This is the first success message';
+ $secondSuccessMessage = 'This is the second success message';
+ $firstInfoMessage = 'This is the first info message';
+ $secondInfoMessage = 'This is the second info message';
+ $firstWarningMessage = 'This is the first warning message';
+ $secondWarningMessage = 'This is the second warning message';
+
+ Yii::$app->session->setFlash('error', [$firstErrorMessage, $secondErrorMessage]);
+ Yii::$app->session->setFlash('danger', [$firstDangerMessage, $secondDangerMessage]);
+ Yii::$app->session->setFlash('success', [$firstSuccessMessage, $secondSuccessMessage]);
+ Yii::$app->session->setFlash('info', [$firstInfoMessage, $secondInfoMessage]);
+ Yii::$app->session->setFlash('warning', [$firstWarningMessage, $secondWarningMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstErrorMessage);
+ verify($renderingResult)->stringContainsString($secondErrorMessage);
+ verify($renderingResult)->stringContainsString($firstDangerMessage);
+ verify($renderingResult)->stringContainsString($secondDangerMessage);
+ verify($renderingResult)->stringContainsString($firstSuccessMessage);
+ verify($renderingResult)->stringContainsString($secondSuccessMessage);
+ verify($renderingResult)->stringContainsString($firstInfoMessage);
+ verify($renderingResult)->stringContainsString($secondInfoMessage);
+ verify($renderingResult)->stringContainsString($firstWarningMessage);
+ verify($renderingResult)->stringContainsString($secondWarningMessage);
+
+ verify($renderingResult)->stringContainsString('alert-danger');
+ verify($renderingResult)->stringContainsString('alert-success');
+ verify($renderingResult)->stringContainsString('alert-info');
+ verify($renderingResult)->stringContainsString('alert-warning');
+ }
+
+ public function testFlashIntegrity()
+ {
+ $errorMessage = 'This is an error message';
+ $unrelatedMessage = 'This is a message that is not related to the alert widget';
+
+ Yii::$app->session->setFlash('error', $errorMessage);
+ Yii::$app->session->setFlash('unrelated', $unrelatedMessage);
+
+ Alert::widget();
+
+ // Simulate redirect
+ Yii::$app->session->close();
+ Yii::$app->session->open();
+
+ verify(Yii::$app->session->getFlash('error'))->empty();
+ verify(Yii::$app->session->getFlash('unrelated'))->equals($unrelatedMessage);
+ }
+}
diff --git a/vagrant/config/vagrant-local-example.yml b/vagrant/config/vagrant-local.example.yml
similarity index 100%
rename from vagrant/config/vagrant-local-example.yml
rename to vagrant/config/vagrant-local.example.yml
diff --git a/vagrant/nginx/app.conf b/vagrant/nginx/app.conf
index 08ec5bb35..1bfc0d583 100644
--- a/vagrant/nginx/app.conf
+++ b/vagrant/nginx/app.conf
@@ -6,7 +6,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
- server_name yii2basic.dev;
+ server_name yii2basic.test;
root /app/web/;
index index.php;
@@ -28,7 +28,7 @@ server {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_pass 127.0.0.1:9000;
- fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
+ fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
try_files $uri =404;
}
diff --git a/vagrant/provision/always-as-root.sh b/vagrant/provision/always-as-root.sh
index e5d8e33e1..17fb58421 100644
--- a/vagrant/provision/always-as-root.sh
+++ b/vagrant/provision/always-as-root.sh
@@ -13,6 +13,6 @@ function info {
info "Provision-script user: `whoami`"
info "Restart web-stack"
-service php7.0-fpm restart
+service php7.2-fpm restart
service nginx restart
-service mysql restart
\ No newline at end of file
+service mysql restart
diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh
index 12165b1c0..1d2917016 100644
--- a/vagrant/provision/once-as-root.sh
+++ b/vagrant/provision/once-as-root.sh
@@ -3,6 +3,7 @@
#== Import script args ==
timezone=$(echo "$1")
+readonly IP=$2
#== Bash helpers ==
@@ -21,9 +22,12 @@ export DEBIAN_FRONTEND=noninteractive
info "Configure timezone"
timedatectl set-timezone ${timezone} --no-ask-password
+info "Add the VM IP to the list of allowed IPs"
+awk -v ip=$IP -f /app/vagrant/provision/provision.awk /app/config/web.php
+
info "Prepare root password for MySQL"
-debconf-set-selections <<< "mariadb-server-10.0 mysql-server/root_password password \"''\""
-debconf-set-selections <<< "mariadb-server-10.0 mysql-server/root_password_again password \"''\""
+debconf-set-selections <<< 'mariadb-server mysql-server/root_password password'
+debconf-set-selections <<< 'mariadb-server mysql-server/root_password_again password'
echo "Done!"
info "Update OS software"
@@ -31,21 +35,21 @@ apt-get update
apt-get upgrade -y
info "Install additional software"
-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 mariadb-server-10.0 php.xdebug
+apt-get install -y php7.2-curl php7.2-cli php7.2-intl php7.2-mysqlnd php7.2-gd php7.2-fpm php7.2-mbstring php7.2-xml unzip nginx mariadb-server-10.1 php.xdebug
info "Configure MySQL"
-sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mariadb.conf.d/50-server.cnf
-mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''"
-mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'"
-mysql -uroot <<< "DROP USER 'root'@'localhost'"
-mysql -uroot <<< "FLUSH PRIVILEGES"
+sed -i 's/.*bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
+mysql <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''"
+mysql <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'"
+mysql <<< "DROP USER 'root'@'localhost'"
+mysql <<< 'FLUSH PRIVILEGES'
echo "Done!"
info "Configure PHP-FPM"
-sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
-sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
-sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf
-cat << EOF > /etc/php/7.0/mods-available/xdebug.ini
+sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.2/fpm/pool.d/www.conf
+sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.2/fpm/pool.d/www.conf
+sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.2/fpm/pool.d/www.conf
+cat << EOF > /etc/php/7.2/mods-available/xdebug.ini
zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_connect_back=1
@@ -62,10 +66,14 @@ info "Enabling site configuration"
ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf
echo "Done!"
-info "Initailize databases for MySQL"
-mysql -uroot <<< "CREATE DATABASE yii2basic"
-mysql -uroot <<< "CREATE DATABASE yii2basic_test"
+info "Removing default site configuration"
+rm /etc/nginx/sites-enabled/default
+echo "Done!"
+
+info "Initialize databases for MySQL"
+mysql <<< 'CREATE DATABASE yii2basic'
+mysql <<< 'CREATE DATABASE yii2basic_test'
echo "Done!"
info "Install composer"
-curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
\ No newline at end of file
+curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
diff --git a/vagrant/provision/provision.awk b/vagrant/provision/provision.awk
new file mode 100644
index 000000000..bcf44d3be
--- /dev/null
+++ b/vagrant/provision/provision.awk
@@ -0,0 +1,50 @@
+###
+# Modifying Yii2's files for Vagrant VM
+#
+# @author HA3IK
+# @version 1.0.0
+
+BEGIN {
+ print "AWK BEGINs its work:"
+ IGNORECASE = 1
+
+ # Correct IP - wildcard last octet
+ match(ip, /(([0-9]+\.)+)/, arr)
+ ip = arr[1] "*"
+}
+# BODY
+{
+ # Check if it's the same file
+ if (FILENAME != isFile["same"]){
+ msg = "- Work with: " FILENAME
+ # Close a previous file
+ close(isFile["same"])
+ # Delete previous data
+ delete isFile
+ # Save current file
+ isFile["same"] = FILENAME
+ # Define array index for the file
+ switch (FILENAME){
+ case /config\/web\.php$/:
+ isFile["IsConfWeb"] = 1
+ msg = msg " - add allowed IP: " ip
+ break
+ }
+ # Print the concatenated message for the file
+ print msg
+ }
+
+ # IF config/web.php
+ if (isFile["IsConfWeb"]){
+ # IF line has "allowedIPs" and doesn't has our IP
+ if (match($0, "allowedIPs") && !match($0, ip)){
+ match($0, /([^\]]+)(.+)/, arr)
+ $0 = sprintf("%s, '%s'%s", arr[1], ip, arr[2])
+ }
+ # Rewrite the file
+ print $0 > FILENAME
+ }
+}
+END {
+ print "AWK ENDs its work."
+}
diff --git a/views/layouts/main.php b/views/layouts/main.php
index 34649cf54..c204435c0 100644
--- a/views/layouts/main.php
+++ b/views/layouts/main.php
@@ -1,77 +1,79 @@
registerCsrfMetaTags();
+$this->registerMetaTag(['charset' => Yii::$app->charset], 'charset');
+$this->registerMetaTag(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1, shrink-to-fit=no']);
+$this->registerMetaTag(['name' => 'description', 'content' => $this->params['meta_description'] ?? '']);
+$this->registerMetaTag(['name' => 'keywords', 'content' => $this->params['meta_keywords'] ?? '']);
+$this->registerLinkTag(['rel' => 'icon', 'type' => 'image/x-icon', 'href' => Yii::getAlias('@web/favicon.ico')]);
?>
beginPage() ?>
-
+
-
-
-
- = Html::csrfMetaTags() ?>
= Html::encode($this->title) ?>
head() ?>
-
+
beginBody() ?>
-
+
+
- = Breadcrumbs::widget([
- 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
- ]) ?>
+ params['breadcrumbs'])): ?>
+ = Breadcrumbs::widget(['links' => $this->params['breadcrumbs']]) ?>
+
= Alert::widget() ?>
= $content ?>
-
+
-