root 7 роки тому
коміт
a0d2c3f41d
100 змінених файлів з 3986 додано та 0 видалено
  1. +3
    -0
      .bowerrc
  2. +33
    -0
      .gitignore
  3. +32
    -0
      LICENSE.md
  4. +54
    -0
      README.md
  5. +72
    -0
      Vagrantfile
  6. +23
    -0
      backend/assets/AppAsset.php
  7. +2
    -0
      backend/config/.gitignore
  8. +1
    -0
      backend/config/bootstrap.php
  9. +50
    -0
      backend/config/main.php
  10. +4
    -0
      backend/config/params.php
  11. +98
    -0
      backend/controllers/SiteController.php
  12. +1
    -0
      backend/models/.gitkeep
  13. +2
    -0
      backend/runtime/.gitignore
  14. +79
    -0
      backend/views/layouts/main.php
  15. +27
    -0
      backend/views/site/error.php
  16. +53
    -0
      backend/views/site/index.php
  17. +35
    -0
      backend/views/site/login.php
  18. +2
    -0
      backend/web/.gitignore
  19. +2
    -0
      backend/web/assets/.gitignore
  20. +111
    -0
      backend/web/css/site.css
  21. BIN
      backend/web/favicon.ico
  22. +2
    -0
      backend/web/robots.txt
  23. +2
    -0
      common/config/.gitignore
  24. +5
    -0
      common/config/bootstrap.php
  25. +9
    -0
      common/config/main.php
  26. +6
    -0
      common/config/params.php
  27. +22
    -0
      common/mail/layouts/html.php
  28. +12
    -0
      common/mail/layouts/text.php
  29. +15
    -0
      common/mail/passwordResetToken-html.php
  30. +12
    -0
      common/mail/passwordResetToken-text.php
  31. +78
    -0
      common/models/LoginForm.php
  32. +189
    -0
      common/models/User.php
  33. +81
    -0
      common/widgets/Alert.php
  34. +40
    -0
      composer.json
  35. +913
    -0
      composer.lock
  36. +2
    -0
      console/config/.gitignore
  37. +1
    -0
      console/config/bootstrap.php
  38. +25
    -0
      console/config/main.php
  39. +4
    -0
      console/config/params.php
  40. +0
    -0
      console/controllers/.gitkeep
  41. +33
    -0
      console/migrations/m130524_201442_init.php
  42. +1
    -0
      console/models/.gitkeep
  43. +2
    -0
      console/runtime/.gitignore
  44. +25
    -0
      environments/dev/backend/config/main-local.php
  45. +3
    -0
      environments/dev/backend/config/params-local.php
  46. +19
    -0
      environments/dev/backend/web/index-test.php
  47. +18
    -0
      environments/dev/backend/web/index.php
  48. +20
    -0
      environments/dev/common/config/main-local.php
  49. +3
    -0
      environments/dev/common/config/params-local.php
  50. +7
    -0
      environments/dev/console/config/main-local.php
  51. +3
    -0
      environments/dev/console/config/params-local.php
  52. +24
    -0
      environments/dev/frontend/config/main-local.php
  53. +3
    -0
      environments/dev/frontend/config/params-local.php
  54. +18
    -0
      environments/dev/frontend/web/index-test.php
  55. +18
    -0
      environments/dev/frontend/web/index.php
  56. +11
    -0
      environments/dev/tests/codeception/config/config-local.php
  57. +28
    -0
      environments/dev/yii
  58. +65
    -0
      environments/index.php
  59. +9
    -0
      environments/prod/backend/config/main-local.php
  60. +3
    -0
      environments/prod/backend/config/params-local.php
  61. +18
    -0
      environments/prod/backend/web/index.php
  62. +16
    -0
      environments/prod/common/config/main-local.php
  63. +3
    -0
      environments/prod/common/config/params-local.php
  64. +3
    -0
      environments/prod/console/config/main-local.php
  65. +3
    -0
      environments/prod/console/config/params-local.php
  66. +9
    -0
      environments/prod/frontend/config/main-local.php
  67. +3
    -0
      environments/prod/frontend/config/params-local.php
  68. +18
    -0
      environments/prod/frontend/web/index.php
  69. +11
    -0
      environments/prod/tests/codeception/config/config-local.php
  70. +28
    -0
      environments/prod/yii
  71. +23
    -0
      frontend/assets/AppAsset.php
  72. +2
    -0
      frontend/config/.gitignore
  73. +1
    -0
      frontend/config/bootstrap.php
  74. +49
    -0
      frontend/config/main.php
  75. +4
    -0
      frontend/config/params.php
  76. +213
    -0
      frontend/controllers/SiteController.php
  77. +60
    -0
      frontend/models/ContactForm.php
  78. +68
    -0
      frontend/models/PasswordResetRequestForm.php
  79. +64
    -0
      frontend/models/ResetPasswordForm.php
  80. +58
    -0
      frontend/models/SignupForm.php
  81. +2
    -0
      frontend/runtime/.gitignore
  82. +82
    -0
      frontend/views/layouts/main.php
  83. +16
    -0
      frontend/views/site/about.php
  84. +45
    -0
      frontend/views/site/contact.php
  85. +27
    -0
      frontend/views/site/error.php
  86. +53
    -0
      frontend/views/site/index.php
  87. +39
    -0
      frontend/views/site/login.php
  88. +31
    -0
      frontend/views/site/requestPasswordResetToken.php
  89. +31
    -0
      frontend/views/site/resetPassword.php
  90. +35
    -0
      frontend/views/site/signup.php
  91. +2
    -0
      frontend/web/.gitignore
  92. +2
    -0
      frontend/web/assets/.gitignore
  93. +111
    -0
      frontend/web/css/site.css
  94. BIN
      frontend/web/favicon.ico
  95. +2
    -0
      frontend/web/robots.txt
  96. +217
    -0
      init
  97. +20
    -0
      init.bat
  98. +132
    -0
      requirements.php
  99. +59
    -0
      tests/README.md
  100. +11
    -0
      tests/codeception.yml

+ 3
- 0
.bowerrc Переглянути файл

@@ -0,0 +1,3 @@
{
"directory" : "vendor/bower"
}

+ 33
- 0
.gitignore Переглянути файл

@@ -0,0 +1,33 @@
# yii console command
/yii

# phpstorm project files
.idea

# netbeans project files
nbproject

# zend studio for eclipse project files
.buildpath
.project
.settings

# windows thumbnail cache
Thumbs.db

# composer vendor dir
/vendor

# composer itself is not needed
composer.phar

# Mac DS_Store Files
.DS_Store

# phpunit itself is not needed
phpunit.phar
# local phpunit config
/phpunit.xml

# vagrant runtime
/.vagrant

+ 32
- 0
LICENSE.md Переглянути файл

@@ -0,0 +1,32 @@
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.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Yii Software LLC nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

+ 54
- 0
README.md Переглянути файл

@@ -0,0 +1,54 @@
Yii 2 Advanced Project Template
===============================

Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
developing complex Web applications with multiple tiers.

The template includes three tiers: front end, back end, and console, each of which
is a separate Yii application.

The template is designed to work in a team development environment. It supports
deploying the application in different environments.

Documentation is at [docs/guide/README.md](docs/guide/README.md).

[![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2-app-advanced/v/stable.png)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Total Downloads](https://poser.pugx.org/yiisoft/yii2-app-advanced/downloads.png)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Build Status](https://travis-ci.org/yiisoft/yii2-app-advanced.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-advanced)

DIRECTORY STRUCTURE
-------------------

```
common
config/ contains shared configurations
mail/ contains view files for e-mails
models/ contains model classes used in both backend and frontend
console
config/ contains console configurations
controllers/ contains console controllers (commands)
migrations/ contains database migrations
models/ contains console-specific model classes
runtime/ contains files generated during runtime
backend
assets/ contains application assets such as JavaScript and CSS
config/ contains backend configurations
controllers/ contains Web controller classes
models/ contains backend-specific model classes
runtime/ contains files generated during runtime
views/ contains view files for the Web application
web/ contains the entry script and Web resources
frontend
assets/ contains application assets such as JavaScript and CSS
config/ contains frontend configurations
controllers/ contains Web controller classes
models/ contains frontend-specific model classes
runtime/ contains files generated during runtime
views/ contains view files for the Web application
web/ contains the entry script and Web resources
widgets/ contains frontend widgets
vendor/ contains dependent 3rd-party packages
environments/ contains environment-based overrides
tests contains various tests for the advanced application
codeception/ contains tests developed with Codeception PHP Testing Framework
```

+ 72
- 0
Vagrantfile Переглянути файл

@@ -0,0 +1,72 @@
require 'yaml'
require 'fileutils'

domains = {
frontend: 'y2aa-frontend.dev',
backend: 'y2aa-backend.dev'
}

config = {
local: './vagrant/config/vagrant-local.yml',
example: './vagrant/config/vagrant-local.example.yml'
}

# copy config from example if local config not exists
FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
# read config
options = YAML.load_file config[:local]

# check github token
if options['github_token'].nil? || options['github_token'].to_s.length != 40
puts "You must place REAL GitHub token into configuration:\n/yii2-app-advancded/vagrant/config/vagrant-local.yml"
exit
end

# vagrant configurate
Vagrant.configure(2) do |config|
# select the box
config.vm.box = 'ubuntu/trusty64'

# should we ask about box updates?
config.vm.box_check_update = options['box_check_update']

config.vm.provider 'virtualbox' do |vb|
# machine cpus count
vb.cpus = options['cpus']
# machine memory size
vb.memory = options['memory']
# machine name (for VirtualBox UI)
vb.name = options['machine_name']
end

# machine name (for vagrant console)
config.vm.define options['machine_name']

# machine name (for guest machine console)
config.vm.hostname = options['machine_name']

# network settings
config.vm.network 'private_network', ip: options['ip']

# sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'

# disable folder '/vagrant' (guest machine)
config.vm.synced_folder '.', '/vagrant', disabled: true

# hosts settings (host machine)
config.vm.provision :hostmanager
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.ignore_private_ip = false
config.hostmanager.include_offline = true
config.hostmanager.aliases = domains.values

# provisioners
config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
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'

# post-install message (vagrant console)
config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}"
end

+ 23
- 0
backend/assets/AppAsset.php Переглянути файл

@@ -0,0 +1,23 @@
<?php

namespace backend\assets;

use yii\web\AssetBundle;

/**
* Main backend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}

+ 2
- 0
backend/config/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
main-local.php
params-local.php

+ 1
- 0
backend/config/bootstrap.php Переглянути файл

@@ -0,0 +1 @@
<?php

+ 50
- 0
backend/config/main.php Переглянути файл

@@ -0,0 +1,50 @@
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);

return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'request' => [
'csrfParam' => '_csrf-backend',
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
],
'session' => [
// this is the name of the session cookie used for login on the backend
'name' => 'advanced-backend',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
/*
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
*/
],
'params' => $params,
];

+ 4
- 0
backend/config/params.php Переглянути файл

@@ -0,0 +1,4 @@
<?php
return [
'adminEmail' => '[email protected]',
];

+ 98
- 0
backend/controllers/SiteController.php Переглянути файл

@@ -0,0 +1,98 @@
<?php
namespace backend\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;

/**
* Site controller
*/
class SiteController extends Controller
{
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}

/**
* @inheritdoc
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}

/**
* Displays homepage.
*
* @return string
*/
public function actionIndex()
{
return $this->render('index');
}

/**
* Login action.
*
* @return string
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}

$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}

/**
* Logout action.
*
* @return string
*/
public function actionLogout()
{
Yii::$app->user->logout();

return $this->goHome();
}
}

+ 1
- 0
backend/models/.gitkeep Переглянути файл

@@ -0,0 +1 @@
*

+ 2
- 0
backend/runtime/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
*
!.gitignore

+ 79
- 0
backend/views/layouts/main.php Переглянути файл

@@ -0,0 +1,79 @@
<?php

/* @var $this \yii\web\View */
/* @var $content string */

use backend\assets\AppAsset;
use yii\helpers\Html;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use common\widgets\Alert;

AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>

<div class="wrap">
<?php
NavBar::begin([
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-fixed-top',
],
]);
$menuItems = [
['label' => 'Home', 'url' => ['/site/index']],
];
if (Yii::$app->user->isGuest) {
$menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
$menuItems[] = '<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-link']
)
. Html::endForm()
. '</li>';
}
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $menuItems,
]);
NavBar::end();
?>

<div class="container">
<?= Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<?= Alert::widget() ?>
<?= $content ?>
</div>
</div>

<footer class="footer">
<div class="container">
<p class="pull-left">&copy; My Company <?= date('Y') ?></p>

<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</footer>

<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

+ 27
- 0
backend/views/site/error.php Переглянути файл

@@ -0,0 +1,27 @@
<?php

/* @var $this yii\web\View */
/* @var $name string */
/* @var $message string */
/* @var $exception Exception */

use yii\helpers\Html;

$this->title = $name;
?>
<div class="site-error">

<h1><?= Html::encode($this->title) ?></h1>

<div class="alert alert-danger">
<?= nl2br(Html::encode($message)) ?>
</div>

<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>

</div>

+ 53
- 0
backend/views/site/index.php Переглянути файл

@@ -0,0 +1,53 @@
<?php

/* @var $this yii\web\View */

$this->title = 'My Yii Application';
?>
<div class="site-index">

<div class="jumbotron">
<h1>Congratulations!</h1>

<p class="lead">You have successfully created your Yii-powered application.</p>

<p><a class="btn btn-lg btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p>
</div>

<div class="body-content">

<div class="row">
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions &raquo;</a></p>
</div>
</div>

</div>
</div>

+ 35
- 0
backend/views/site/login.php Переглянути файл

@@ -0,0 +1,35 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \common\models\LoginForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-login">
<h1><?= Html::encode($this->title) ?></h1>

<p>Please fill out the following fields to login:</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

<?= $form->field($model, 'password')->passwordInput() ?>

<?= $form->field($model, 'rememberMe')->checkbox() ?>

<div class="form-group">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

+ 2
- 0
backend/web/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
/index.php
/index-test.php

+ 2
- 0
backend/web/assets/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
*
!.gitignore

+ 111
- 0
backend/web/css/site.css Переглянути файл

@@ -0,0 +1,111 @@
html,
body {
height: 100%;
}

.wrap {
min-height: 100%;
height: auto;
margin: 0 auto -60px;
padding: 0 0 60px;
}

.wrap > .container {
padding: 70px 15px 20px;
}

.footer {
height: 60px;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
padding-top: 20px;
}

.jumbotron {
text-align: center;
background-color: transparent;
}

.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}

.not-set {
color: #c55;
font-style: italic;
}

/* add sorting icons to gridview sort links */
a.asc:after, a.desc:after {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
padding-left: 5px;
}

a.asc:after {
content: /*"\e113"*/ "\e151";
}

a.desc:after {
content: /*"\e114"*/ "\e152";
}

.sort-numerical a.asc:after {
content: "\e153";
}

.sort-numerical a.desc:after {
content: "\e154";
}

.sort-ordinal a.asc:after {
content: "\e155";
}

.sort-ordinal a.desc:after {
content: "\e156";
}

.grid-view td {
white-space: nowrap;
}

.grid-view .filters input,
.grid-view .filters select {
min-width: 50px;
}

.hint-block {
display: block;
margin-top: 5px;
color: #999;
}

.error-summary {
color: #a94442;
background: #fdf7f7;
border-left: 3px solid #eed3d7;
padding: 10px 20px;
margin: 0 0 15px 0;
}

/* align the logout "link" (button in form) of the navbar */
.nav > li > form {
padding: 8px;
}

@media(max-width:768px) {
.nav li > form {
padding: 3px;
}
}

.nav > li > form > button:hover {
text-decoration: none;
}

BIN
backend/web/favicon.ico Переглянути файл

Перед Після

+ 2
- 0
backend/web/robots.txt Переглянути файл

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /

+ 2
- 0
common/config/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
main-local.php
params-local.php

+ 5
- 0
common/config/bootstrap.php Переглянути файл

@@ -0,0 +1,5 @@
<?php
Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');

+ 9
- 0
common/config/main.php Переглянути файл

@@ -0,0 +1,9 @@
<?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
],
];

+ 6
- 0
common/config/params.php Переглянути файл

@@ -0,0 +1,6 @@
<?php
return [
'adminEmail' => '[email protected]',
'supportEmail' => '[email protected]',
'user.passwordResetTokenExpire' => 3600,
];

+ 22
- 0
common/mail/layouts/html.php Переглянути файл

@@ -0,0 +1,22 @@
<?php
use yii\helpers\Html;

/* @var $this \yii\web\View view component instance */
/* @var $message \yii\mail\MessageInterface the message being composed */
/* @var $content string main view render result */
?>
<?php $this->beginPage() ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?= Yii::$app->charset ?>" />
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<?= $content ?>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

+ 12
- 0
common/mail/layouts/text.php Переглянути файл

@@ -0,0 +1,12 @@
<?php
use yii\helpers\Html;

/* @var $this \yii\web\View view component instance */
/* @var $message \yii\mail\MessageInterface the message being composed */
/* @var $content string main view render result */
?>
<?php $this->beginPage() ?>
<?php $this->beginBody() ?>
<?= $content ?>
<?php $this->endBody() ?>
<?php $this->endPage() ?>

+ 15
- 0
common/mail/passwordResetToken-html.php Переглянути файл

@@ -0,0 +1,15 @@
<?php
use yii\helpers\Html;

/* @var $this yii\web\View */
/* @var $user common\models\User */

$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
?>
<div class="password-reset">
<p>Hello <?= Html::encode($user->username) ?>,</p>

<p>Follow the link below to reset your password:</p>

<p><?= Html::a(Html::encode($resetLink), $resetLink) ?></p>
</div>

+ 12
- 0
common/mail/passwordResetToken-text.php Переглянути файл

@@ -0,0 +1,12 @@
<?php

/* @var $this yii\web\View */
/* @var $user common\models\User */

$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
?>
Hello <?= $user->username ?>,

Follow the link below to reset your password:

<?= $resetLink ?>

+ 78
- 0
common/models/LoginForm.php Переглянути файл

@@ -0,0 +1,78 @@
<?php
namespace common\models;

use Yii;
use yii\base\Model;

/**
* Login form
*/
class LoginForm extends Model
{
public $username;
public $password;
public $rememberMe = true;

private $_user;


/**
* @inheritdoc
*/
public function rules()
{
return [
// username and password are both required
[['username', 'password'], 'required'],
// rememberMe must be a boolean value
['rememberMe', 'boolean'],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}

/**
* Validates the password.
* This method serves as the inline validation for password.
*
* @param string $attribute the attribute currently being validated
* @param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Incorrect username or password.');
}
}
}

/**
* Logs in a user using the provided username and password.
*
* @return boolean whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}

/**
* Finds user by [[username]]
*
* @return User|null
*/
protected function getUser()
{
if ($this->_user === null) {
$this->_user = User::findByUsername($this->username);
}

return $this->_user;
}
}

+ 189
- 0
common/models/User.php Переглянути файл

@@ -0,0 +1,189 @@
<?php
namespace common\models;

use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

/**
* User model
*
* @property integer $id
* @property string $username
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property string $auth_key
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;


/**
* @inheritdoc
*/
public static function tableName()
{
return '{{%user}}';
}

/**
* @inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}

/**
* @inheritdoc
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}

/**
* @inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}

/**
* @inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}

/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}

/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}

return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}

/**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}

$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}

/**
* @inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}

/**
* @inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}

/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}

/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}

/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}

/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}

/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}

/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}

+ 81
- 0
common/widgets/Alert.php Переглянути файл

@@ -0,0 +1,81 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace common\widgets;

use Yii;

/**
* Alert widget renders a message from session flash. All flash messages are displayed
* in the sequence they were assigned using setFlash. You can set message as following:
*
* ```php
* Yii::$app->session->setFlash('error', 'This is the message');
* Yii::$app->session->setFlash('success', 'This is the message');
* Yii::$app->session->setFlash('info', 'This is the message');
* ```
*
* Multiple messages could be set as follows:
*
* ```php
* Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']);
* ```
*
* @author Kartik Visweswaran <[email protected]>
* @author Alexander Makarov <[email protected]>
*/
class Alert extends \yii\bootstrap\Widget
{
/**
* @var array the alert types configuration for the flash messages.
* This array is setup as $key => $value, where:
* - $key is the name of the session flash variable
* - $value is the bootstrap alert type (i.e. danger, success, info, warning)
*/
public $alertTypes = [
'error' => 'alert-danger',
'danger' => 'alert-danger',
'success' => 'alert-success',
'info' => 'alert-info',
'warning' => 'alert-warning'
];
/**
* @var array the options for rendering the close button tag.
*/
public $closeButton = [];


public function init()
{
parent::init();

$session = Yii::$app->session;
$flashes = $session->getAllFlashes();
$appendCss = isset($this->options['class']) ? ' ' . $this->options['class'] : '';

foreach ($flashes as $type => $data) {
if (isset($this->alertTypes[$type])) {
$data = (array) $data;
foreach ($data as $i => $message) {
/* initialize css class for each alert box */
$this->options['class'] = $this->alertTypes[$type] . $appendCss;

/* assign unique id to each alert box */
$this->options['id'] = $this->getId() . '-' . $type . '-' . $i;

echo \yii\bootstrap\Alert::widget([
'body' => $message,
'closeButton' => $this->closeButton,
'options' => $this->options,
]);
}

$session->removeFlash($type);
}
}
}
}

+ 40
- 0
composer.json Переглянути файл

@@ -0,0 +1,40 @@
{
"name": "yiisoft/yii2-app-advanced",
"description": "Yii 2 Advanced Project Template",
"keywords": ["yii2", "framework", "advanced", "project template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "stable",
"require": {
"php": ">=5.4.0",
"yiisoft/yii2": ">=2.0.6",
"yiisoft/yii2-bootstrap": "*",
"yiisoft/yii2-swiftmailer": "*"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-gii": "*",
"yiisoft/yii2-faker": "*"
},
"config": {
"process-timeout": 1800
},
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
},
"scripts": {
"post-install-cmd": "php init --env=Development --overwrite=n"
}
}

+ 913
- 0
composer.lock Переглянути файл

@@ -0,0 +1,913 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "914f9194a4d021de88b285b03e683984",
"content-hash": "e1929a97e872bdbaacc8530468eccb67",
"packages": [
{
"name": "bower-asset/bootstrap",
"version": "v3.3.7",
"source": {
"type": "git",
"url": "https://github.com/twbs/bootstrap.git",
"reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"shasum": ""
},
"require": {
"bower-asset/jquery": ">=1.9.1,<4.0"
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": [
"less/bootstrap.less",
"dist/js/bootstrap.js"
],
"bower-asset-ignore": [
"/.*",
"_config.yml",
"CNAME",
"composer.json",
"CONTRIBUTING.md",
"docs",
"js/tests",
"test-infra"
]
},
"license": [
"MIT"
],
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"keywords": [
"css",
"framework",
"front-end",
"js",
"less",
"mobile-first",
"responsive",
"web"
]
},
{
"name": "bower-asset/jquery",
"version": "2.2.4",
"source": {
"type": "git",
"url": "https://github.com/jquery/jquery-dist.git",
"reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jquery/jquery-dist/zipball/c0185ab7c75aab88762c5aae780b9d83b80eda72",
"reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72",
"shasum": ""
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": "dist/jquery.js",
"bower-asset-ignore": [
"package.json"
]
},
"license": [
"MIT"
],
"keywords": [
"browser",
"javascript",
"jquery",
"library"
]
},
{
"name": "bower-asset/jquery.inputmask",
"version": "3.2.7",
"source": {
"type": "git",
"url": "https://github.com/RobinHerbots/jquery.inputmask.git",
"reference": "5a72c563b502b8e05958a524cdfffafe9987be38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/5a72c563b502b8e05958a524cdfffafe9987be38",
"reference": "5a72c563b502b8e05958a524cdfffafe9987be38",
"shasum": ""
},
"require": {
"bower-asset/jquery": ">=1.7"
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": [
"./dist/inputmask/inputmask.js"
],
"bower-asset-ignore": [
"**/*",
"!dist/*",
"!dist/inputmask/*",
"!dist/min/*",
"!dist/min/inputmask/*",
"!extra/bindings/*",
"!extra/dependencyLibs/*",
"!extra/phone-codes/*"
]
},
"license": [
"http://opensource.org/licenses/mit-license.php"
],
"description": "jquery.inputmask is a jquery plugin which create an input mask.",
"keywords": [
"form",
"input",
"inputmask",
"jquery",
"mask",
"plugins"
]
},
{
"name": "bower-asset/punycode",
"version": "v1.3.2",
"source": {
"type": "git",
"url": "https://github.com/bestiejs/punycode.js.git",
"reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
"reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3",
"shasum": ""
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": "punycode.js",
"bower-asset-ignore": [
"coverage",
"tests",
".*",
"component.json",
"Gruntfile.js",
"node_modules",
"package.json"
]
}
},
{
"name": "bower-asset/yii2-pjax",
"version": "v2.0.6",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/jquery-pjax.git",
"reference": "60728da6ade5879e807a49ce59ef9a72039b8978"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978",
"reference": "60728da6ade5879e807a49ce59ef9a72039b8978",
"shasum": ""
},
"require": {
"bower-asset/jquery": ">=1.8"
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": "./jquery.pjax.js",
"bower-asset-ignore": [
".travis.yml",
"Gemfile",
"Gemfile.lock",
"CONTRIBUTING.md",
"vendor/",
"script/",
"test/"
]
},
"license": [
"MIT"
]
},
{
"name": "cebe/markdown",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/cebe/markdown.git",
"reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2",
"reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2",
"shasum": ""
},
"require": {
"lib-pcre": "*",
"php": ">=5.4.0"
},
"require-dev": {
"cebe/indent": "*",
"facebook/xhprof": "*@dev",
"phpunit/phpunit": "4.1.*"
},
"bin": [
"bin/markdown"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"cebe\\markdown\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Carsten Brandt",
"email": "[email protected]",
"homepage": "http://cebe.cc/",
"role": "Creator"
}
],
"description": "A super fast, highly extensible markdown parser for PHP",
"homepage": "https://github.com/cebe/markdown#readme",
"keywords": [
"extensible",
"fast",
"gfm",
"markdown",
"markdown-extra"
],
"time": "2015-03-06 05:28:07"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.8.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2",
"reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [
"library/HTMLPurifier.composer.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "[email protected]",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"time": "2016-07-16 12:58:58"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.3",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"mockery/mockery": "~0.9.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
},
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "[email protected]"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.org",
"keywords": [
"email",
"mail",
"mailer"
],
"time": "2016-07-08 11:51:25"
},
{
"name": "yiisoft/yii2",
"version": "2.0.9",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-framework.git",
"reference": "2b75151ea60e1fd820046416eee2e89c3dda1133"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/2b75151ea60e1fd820046416eee2e89c3dda1133",
"reference": "2b75151ea60e1fd820046416eee2e89c3dda1133",
"shasum": ""
},
"require": {
"bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
"bower-asset/jquery.inputmask": "~3.2.2",
"bower-asset/punycode": "1.3.*",
"bower-asset/yii2-pjax": "~2.0.1",
"cebe/markdown": "~1.0.0 | ~1.1.0",
"ext-ctype": "*",
"ext-mbstring": "*",
"ezyang/htmlpurifier": "~4.6",
"lib-pcre": "*",
"php": ">=5.4.0",
"yiisoft/yii2-composer": "~2.0.4"
},
"bin": [
"yii"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Qiang Xue",
"email": "[email protected]",
"homepage": "http://www.yiiframework.com/",
"role": "Founder and project lead"
},
{
"name": "Alexander Makarov",
"email": "[email protected]",
"homepage": "http://rmcreative.ru/",
"role": "Core framework development"
},
{
"name": "Maurizio Domba",
"homepage": "http://mdomba.info/",
"role": "Core framework development"
},
{
"name": "Carsten Brandt",
"email": "[email protected]",
"homepage": "http://cebe.cc/",
"role": "Core framework development"
},
{
"name": "Timur Ruziev",
"email": "[email protected]",
"homepage": "http://resurtm.com/",
"role": "Core framework development"
},
{
"name": "Paul Klimov",
"email": "[email protected]",
"role": "Core framework development"
},
{
"name": "Dmitry Naumenko",
"email": "[email protected]",
"role": "Core framework development"
}
],
"description": "Yii PHP Framework Version 2",
"homepage": "http://www.yiiframework.com/",
"keywords": [
"framework",
"yii2"
],
"time": "2016-07-11 13:36:42"
},
{
"name": "yiisoft/yii2-bootstrap",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-bootstrap.git",
"reference": "3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5",
"reference": "3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5",
"shasum": ""
},
"require": {
"bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*",
"yiisoft/yii2": ">=2.0.6"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
},
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
},
"autoload": {
"psr-4": {
"yii\\bootstrap\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Qiang Xue",
"email": "[email protected]"
}
],
"description": "The Twitter Bootstrap extension for the Yii framework",
"keywords": [
"bootstrap",
"yii2"
],
"time": "2016-03-17 03:29:28"
},
{
"name": "yiisoft/yii2-composer",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-composer.git",
"reference": "7452fd908a5023b8bb5ea1b123a174ca080de464"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464",
"reference": "7452fd908a5023b8bb5ea1b123a174ca080de464",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0"
},
"type": "composer-plugin",
"extra": {
"class": "yii\\composer\\Plugin",
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\composer\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Qiang Xue",
"email": "[email protected]"
}
],
"description": "The composer plugin for Yii extension installer",
"keywords": [
"composer",
"extension installer",
"yii2"
],
"time": "2016-02-06 00:49:24"
},
{
"name": "yiisoft/yii2-swiftmailer",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-swiftmailer.git",
"reference": "e2c6315caff30a9271a7afad4d684627721dc69a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/e2c6315caff30a9271a7afad4d684627721dc69a",
"reference": "e2c6315caff30a9271a7afad4d684627721dc69a",
"shasum": ""
},
"require": {
"swiftmailer/swiftmailer": "~5.0",
"yiisoft/yii2": ">=2.0.4"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\swiftmailer\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Paul Klimov",
"email": "[email protected]"
}
],
"description": "The SwiftMailer integration for the Yii framework",
"keywords": [
"email",
"mail",
"mailer",
"swift",
"swiftmailer",
"yii2"
],
"time": "2016-03-17 03:58:49"
}
],
"packages-dev": [
{
"name": "bower-asset/typeahead.js",
"version": "v0.11.1",
"source": {
"type": "git",
"url": "https://github.com/twitter/typeahead.js.git",
"reference": "588440f66559714280628a4f9799f0c4eb880a4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twitter/typeahead.js/zipball/588440f66559714280628a4f9799f0c4eb880a4a",
"reference": "588440f66559714280628a4f9799f0c4eb880a4a",
"shasum": ""
},
"require": {
"bower-asset/jquery": ">=1.7"
},
"require-dev": {
"bower-asset/jasmine-ajax": "~1.3.1",
"bower-asset/jasmine-jquery": "~1.5.2",
"bower-asset/jquery": "~1.7"
},
"type": "bower-asset-library",
"extra": {
"bower-asset-main": "dist/typeahead.bundle.js"
}
},
{
"name": "fzaninotto/faker",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/fzaninotto/Faker.git",
"reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44f9a286a04b80c76a4e5fb7aad8bb539b920123",
"reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123",
"shasum": ""
},
"require": {
"php": "^5.3.3|^7.0"
},
"require-dev": {
"ext-intl": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~1.5"
},
"type": "library",
"extra": {
"branch-alias": []
},
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"time": "2016-04-29 12:21:54"
},
{
"name": "phpspec/php-diff",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/php-diff.git",
"reference": "0464787bfa7cd13576c5a1e318709768798bec6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/php-diff/zipball/0464787bfa7cd13576c5a1e318709768798bec6a",
"reference": "0464787bfa7cd13576c5a1e318709768798bec6a",
"shasum": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Diff": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Chris Boulton",
"homepage": "http://github.com/chrisboulton"
}
],
"description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
"time": "2016-04-07 12:29:16"
},
{
"name": "yiisoft/yii2-codeception",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-codeception.git",
"reference": "c916a36d09fc128b05a374e7922bc56854334d56"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/c916a36d09fc128b05a374e7922bc56854334d56",
"reference": "c916a36d09fc128b05a374e7922bc56854334d56",
"shasum": ""
},
"require": {
"yiisoft/yii2": ">=2.0.4"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\codeception\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Mark Jebri",
"email": "[email protected]"
}
],
"description": "The Codeception integration for the Yii framework",
"keywords": [
"codeception",
"yii2"
],
"time": "2016-03-17 03:41:26"
},
{
"name": "yiisoft/yii2-debug",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-debug.git",
"reference": "55ed2e853ed8050a34415f63a4da84f88a56f895"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/55ed2e853ed8050a34415f63a4da84f88a56f895",
"reference": "55ed2e853ed8050a34415f63a4da84f88a56f895",
"shasum": ""
},
"require": {
"yiisoft/yii2": ">=2.0.4",
"yiisoft/yii2-bootstrap": "*"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\debug\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Qiang Xue",
"email": "[email protected]"
}
],
"description": "The debugger extension for the Yii framework",
"keywords": [
"debug",
"debugger",
"yii2"
],
"time": "2016-03-17 03:50:19"
},
{
"name": "yiisoft/yii2-faker",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-faker.git",
"reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/b88ca69ee226a3610b2c26c026c3203d7ac50f6c",
"reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c",
"shasum": ""
},
"require": {
"fzaninotto/faker": "*",
"yiisoft/yii2": "*"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\faker\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Mark Jebri",
"email": "[email protected]"
}
],
"description": "Fixture generator. The Faker integration for the Yii framework.",
"keywords": [
"Fixture",
"faker",
"yii2"
],
"time": "2015-03-01 06:22:44"
},
{
"name": "yiisoft/yii2-gii",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-gii.git",
"reference": "1bd6df6804ca077ec022587905a0d43eb286f507"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/1bd6df6804ca077ec022587905a0d43eb286f507",
"reference": "1bd6df6804ca077ec022587905a0d43eb286f507",
"shasum": ""
},
"require": {
"bower-asset/typeahead.js": "0.10.* | ~0.11.0",
"phpspec/php-diff": ">=1.0.2",
"yiisoft/yii2": ">=2.0.4",
"yiisoft/yii2-bootstrap": "~2.0"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
},
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
},
"autoload": {
"psr-4": {
"yii\\gii\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Qiang Xue",
"email": "[email protected]"
}
],
"description": "The Gii extension for the Yii framework",
"keywords": [
"code generator",
"gii",
"yii2"
],
"time": "2016-03-18 14:09:46"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.4.0"
},
"platform-dev": []
}

+ 2
- 0
console/config/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
main-local.php
params-local.php

+ 1
- 0
console/config/bootstrap.php Переглянути файл

@@ -0,0 +1 @@
<?php

+ 25
- 0
console/config/main.php Переглянути файл

@@ -0,0 +1,25 @@
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);

return [
'id' => 'app-console',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'console\controllers',
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
],
'params' => $params,
];

+ 4
- 0
console/config/params.php Переглянути файл

@@ -0,0 +1,4 @@
<?php
return [
'adminEmail' => '[email protected]',
];

+ 0
- 0
console/controllers/.gitkeep Переглянути файл


+ 33
- 0
console/migrations/m130524_201442_init.php Переглянути файл

@@ -0,0 +1,33 @@
<?php

use yii\db\Migration;

class m130524_201442_init extends Migration
{
public function up()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}

$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),

'status' => $this->smallInteger()->notNull()->defaultValue(10),
'created_at' => $this->integer()->notNull(),
'updated_at' => $this->integer()->notNull(),
], $tableOptions);
}

public function down()
{
$this->dropTable('{{%user}}');
}
}

+ 1
- 0
console/models/.gitkeep Переглянути файл

@@ -0,0 +1 @@
*

+ 2
- 0
console/runtime/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
*
!.gitignore

+ 25
- 0
environments/dev/backend/config/main-local.php Переглянути файл

@@ -0,0 +1,25 @@
<?php

$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];

if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];

$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}

return $config;

+ 3
- 0
environments/dev/backend/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 19
- 0
environments/dev/backend/web/index-test.php Переглянути файл

@@ -0,0 +1,19 @@
<?php

// NOTE: Make sure this file is not accessible when deployed to production
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) {
die('You are not allowed to access this file.');
}

defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');


$config = require(__DIR__ . '/../../tests/codeception/config/backend/acceptance.php');

(new yii\web\Application($config))->run();

+ 18
- 0
environments/dev/backend/web/index.php Переглянути файл

@@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);

$application = new yii\web\Application($config);
$application->run();

+ 20
- 0
environments/dev/common/config/main-local.php Переглянути файл

@@ -0,0 +1,20 @@
<?php
return [
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@common/mail',
// 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.
'useFileTransport' => true,
],
],
];

+ 3
- 0
environments/dev/common/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 7
- 0
environments/dev/console/config/main-local.php Переглянути файл

@@ -0,0 +1,7 @@
<?php
return [
'bootstrap' => ['gii'],
'modules' => [
'gii' => 'yii\gii\Module',
],
];

+ 3
- 0
environments/dev/console/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 24
- 0
environments/dev/frontend/config/main-local.php Переглянути файл

@@ -0,0 +1,24 @@
<?php

$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];

if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}

return $config;

+ 3
- 0
environments/dev/frontend/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 18
- 0
environments/dev/frontend/web/index-test.php Переглянути файл

@@ -0,0 +1,18 @@
<?php

// NOTE: Make sure this file is not accessible when deployed to production
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) {
die('You are not allowed to access this file.');
}

defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = require(__DIR__ . '/../../tests/codeception/config/frontend/acceptance.php');

(new yii\web\Application($config))->run();

+ 18
- 0
environments/dev/frontend/web/index.php Переглянути файл

@@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);

$application = new yii\web\Application($config);
$application->run();

+ 11
- 0
environments/dev/tests/codeception/config/config-local.php Переглянути файл

@@ -0,0 +1,11 @@
<?php
return [
'components' => [
'db' => [
'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
];

+ 28
- 0
environments/dev/yii Переглянути файл

@@ -0,0 +1,28 @@
#!/usr/bin/env php
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/common/config/bootstrap.php');
require(__DIR__ . '/console/config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/common/config/main.php'),
require(__DIR__ . '/common/config/main-local.php'),
require(__DIR__ . '/console/config/main.php'),
require(__DIR__ . '/console/config/main-local.php')
);

$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);

+ 65
- 0
environments/index.php Переглянути файл

@@ -0,0 +1,65 @@
<?php
/**
* The manifest of files that are local to specific environment.
* This file returns a list of environments that the application
* may be installed under. The returned data must be in the following
* format:
*
* ```php
* return [
* 'environment name' => [
* 'path' => 'directory storing the local files',
* 'skipFiles' => [
* // list of files that should only copied once and skipped if they already exist
* ],
* 'setWritable' => [
* // list of directories that should be set writable
* ],
* 'setExecutable' => [
* // list of files that should be set executable
* ],
* 'setCookieValidationKey' => [
* // list of config files that need to be inserted with automatically generated cookie validation keys
* ],
* 'createSymlink' => [
* // list of symlinks to be created. Keys are symlinks, and values are the targets.
* ],
* ],
* ];
* ```
*/
return [
'Development' => [
'path' => 'dev',
'setWritable' => [
'backend/runtime',
'backend/web/assets',
'frontend/runtime',
'frontend/web/assets',
],
'setExecutable' => [
'yii',
'tests/codeception/bin/yii',
],
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
],
],
'Production' => [
'path' => 'prod',
'setWritable' => [
'backend/runtime',
'backend/web/assets',
'frontend/runtime',
'frontend/web/assets',
],
'setExecutable' => [
'yii',
],
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
],
],
];

+ 9
- 0
environments/prod/backend/config/main-local.php Переглянути файл

@@ -0,0 +1,9 @@
<?php
return [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];

+ 3
- 0
environments/prod/backend/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 18
- 0
environments/prod/backend/web/index.php Переглянути файл

@@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);

$application = new yii\web\Application($config);
$application->run();

+ 16
- 0
environments/prod/common/config/main-local.php Переглянути файл

@@ -0,0 +1,16 @@
<?php
return [
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@common/mail',
],
],
];

+ 3
- 0
environments/prod/common/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 3
- 0
environments/prod/console/config/main-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 3
- 0
environments/prod/console/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 9
- 0
environments/prod/frontend/config/main-local.php Переглянути файл

@@ -0,0 +1,9 @@
<?php
return [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];

+ 3
- 0
environments/prod/frontend/config/params-local.php Переглянути файл

@@ -0,0 +1,3 @@
<?php
return [
];

+ 18
- 0
environments/prod/frontend/web/index.php Переглянути файл

@@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');

require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);

$application = new yii\web\Application($config);
$application->run();

+ 11
- 0
environments/prod/tests/codeception/config/config-local.php Переглянути файл

@@ -0,0 +1,11 @@
<?php
return [
'components' => [
'db' => [
'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
];

+ 28
- 0
environments/prod/yii Переглянути файл

@@ -0,0 +1,28 @@
#!/usr/bin/env php
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');

require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/common/config/bootstrap.php');
require(__DIR__ . '/console/config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/common/config/main.php'),
require(__DIR__ . '/common/config/main-local.php'),
require(__DIR__ . '/console/config/main.php'),
require(__DIR__ . '/console/config/main-local.php')
);

$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);

+ 23
- 0
frontend/assets/AppAsset.php Переглянути файл

@@ -0,0 +1,23 @@
<?php

namespace frontend\assets;

use yii\web\AssetBundle;

/**
* Main frontend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}

+ 2
- 0
frontend/config/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
main-local.php
params-local.php

+ 1
- 0
frontend/config/bootstrap.php Переглянути файл

@@ -0,0 +1 @@
<?php

+ 49
- 0
frontend/config/main.php Переглянути файл

@@ -0,0 +1,49 @@
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);

return [
'id' => 'app-frontend',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'request' => [
'csrfParam' => '_csrf-frontend',
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
],
'session' => [
// this is the name of the session cookie used for login on the frontend
'name' => 'advanced-frontend',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
/*
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
*/
],
'params' => $params,
];

+ 4
- 0
frontend/config/params.php Переглянути файл

@@ -0,0 +1,4 @@
<?php
return [
'adminEmail' => '[email protected]',
];

+ 213
- 0
frontend/controllers/SiteController.php Переглянути файл

@@ -0,0 +1,213 @@
<?php
namespace frontend\controllers;

use Yii;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\ContactForm;

/**
* Site controller
*/
class SiteController extends Controller
{
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}

/**
* @inheritdoc
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}

/**
* Displays homepage.
*
* @return mixed
*/
public function actionIndex()
{
return $this->render('index');
}

/**
* Logs in a user.
*
* @return mixed
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}

$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}

/**
* Logs out the current user.
*
* @return mixed
*/
public function actionLogout()
{
Yii::$app->user->logout();

return $this->goHome();
}

/**
* Displays contact page.
*
* @return mixed
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
} else {
Yii::$app->session->setFlash('error', 'There was an error sending email.');
}

return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}

/**
* Displays about page.
*
* @return mixed
*/
public function actionAbout()
{
return $this->render('about');
}

/**
* Signs user up.
*
* @return mixed
*/
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}

return $this->render('signup', [
'model' => $model,
]);
}

/**
* Requests password reset.
*
* @return mixed
*/
public function actionRequestPasswordReset()
{
$model = new PasswordResetRequestForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'Check your email for further instructions.');

return $this->goHome();
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.');
}
}

return $this->render('requestPasswordResetToken', [
'model' => $model,
]);
}

/**
* Resets password.
*
* @param string $token
* @return mixed
* @throws BadRequestHttpException
*/
public function actionResetPassword($token)
{
try {
$model = new ResetPasswordForm($token);
} catch (InvalidParamException $e) {
throw new BadRequestHttpException($e->getMessage());
}

if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
Yii::$app->session->setFlash('success', 'New password was saved.');

return $this->goHome();
}

return $this->render('resetPassword', [
'model' => $model,
]);
}
}

+ 60
- 0
frontend/models/ContactForm.php Переглянути файл

@@ -0,0 +1,60 @@
<?php

namespace frontend\models;

use Yii;
use yii\base\Model;

/**
* ContactForm is the model behind the contact form.
*/
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
public $verifyCode;


/**
* @inheritdoc
*/
public function rules()
{
return [
// name, email, subject and body are required
[['name', 'email', 'subject', 'body'], 'required'],
// email has to be a valid email address
['email', 'email'],
// verifyCode needs to be entered correctly
['verifyCode', 'captcha'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'verifyCode' => 'Verification Code',
];
}

/**
* Sends an email to the specified email address using the information collected by this model.
*
* @param string $email the target email address
* @return boolean whether the email was sent
*/
public function sendEmail($email)
{
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([$this->email => $this->name])
->setSubject($this->subject)
->setTextBody($this->body)
->send();
}
}

+ 68
- 0
frontend/models/PasswordResetRequestForm.php Переглянути файл

@@ -0,0 +1,68 @@
<?php
namespace frontend\models;

use Yii;
use yii\base\Model;
use common\models\User;

/**
* Password reset request form
*/
class PasswordResetRequestForm extends Model
{
public $email;


/**
* @inheritdoc
*/
public function rules()
{
return [
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'exist',
'targetClass' => '\common\models\User',
'filter' => ['status' => User::STATUS_ACTIVE],
'message' => 'There is no user with such email.'
],
];
}

/**
* Sends an email with a link, for resetting the password.
*
* @return boolean whether the email was send
*/
public function sendEmail()
{
/* @var $user User */
$user = User::findOne([
'status' => User::STATUS_ACTIVE,
'email' => $this->email,
]);

if (!$user) {
return false;
}
if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
$user->generatePasswordResetToken();
if (!$user->save()) {
return false;
}
}

return Yii::$app
->mailer
->compose(
['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'],
['user' => $user]
)
->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
->setTo($this->email)
->setSubject('Password reset for ' . Yii::$app->name)
->send();
}
}

+ 64
- 0
frontend/models/ResetPasswordForm.php Переглянути файл

@@ -0,0 +1,64 @@
<?php
namespace frontend\models;

use yii\base\Model;
use yii\base\InvalidParamException;
use common\models\User;

/**
* Password reset form
*/
class ResetPasswordForm extends Model
{
public $password;

/**
* @var \common\models\User
*/
private $_user;


/**
* Creates a form model given a token.
*
* @param string $token
* @param array $config name-value pairs that will be used to initialize the object properties
* @throws \yii\base\InvalidParamException if token is empty or not valid
*/
public function __construct($token, $config = [])
{
if (empty($token) || !is_string($token)) {
throw new InvalidParamException('Password reset token cannot be blank.');
}
$this->_user = User::findByPasswordResetToken($token);
if (!$this->_user) {
throw new InvalidParamException('Wrong password reset token.');
}
parent::__construct($config);
}

/**
* @inheritdoc
*/
public function rules()
{
return [
['password', 'required'],
['password', 'string', 'min' => 6],
];
}

/**
* Resets password.
*
* @return boolean if password was reset.
*/
public function resetPassword()
{
$user = $this->_user;
$user->setPassword($this->password);
$user->removePasswordResetToken();

return $user->save(false);
}
}

+ 58
- 0
frontend/models/SignupForm.php Переглянути файл

@@ -0,0 +1,58 @@
<?php
namespace frontend\models;

use yii\base\Model;
use common\models\User;

/**
* Signup form
*/
class SignupForm extends Model
{
public $username;
public $email;
public $password;


/**
* @inheritdoc
*/
public function rules()
{
return [
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],

['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],

['password', 'required'],
['password', 'string', 'min' => 6],
];
}

/**
* Signs user up.
*
* @return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
return $user->save() ? $user : null;
}
}

+ 2
- 0
frontend/runtime/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
*
!.gitignore

+ 82
- 0
frontend/views/layouts/main.php Переглянути файл

@@ -0,0 +1,82 @@
<?php

/* @var $this \yii\web\View */
/* @var $content string */

use yii\helpers\Html;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use frontend\assets\AppAsset;
use common\widgets\Alert;

AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>

<div class="wrap">
<?php
NavBar::begin([
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-fixed-top',
],
]);
$menuItems = [
['label' => 'Home', 'url' => ['/site/index']],
['label' => 'About', 'url' => ['/site/about']],
['label' => 'Contact', 'url' => ['/site/contact']],
];
if (Yii::$app->user->isGuest) {
$menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];
$menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
$menuItems[] = '<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-link']
)
. Html::endForm()
. '</li>';
}
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $menuItems,
]);
NavBar::end();
?>

<div class="container">
<?= Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<?= Alert::widget() ?>
<?= $content ?>
</div>
</div>

<footer class="footer">
<div class="container">
<p class="pull-left">&copy; My Company <?= date('Y') ?></p>

<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</footer>

<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

+ 16
- 0
frontend/views/site/about.php Переглянути файл

@@ -0,0 +1,16 @@
<?php

/* @var $this yii\web\View */

use yii\helpers\Html;

$this->title = 'About';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-about">
<h1><?= Html::encode($this->title) ?></h1>

<p>This is the About page. You may modify the following file to customize its content:</p>

<code><?= __FILE__ ?></code>
</div>

+ 45
- 0
frontend/views/site/contact.php Переглянути файл

@@ -0,0 +1,45 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\ContactForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;

$this->title = 'Contact';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-contact">
<h1><?= Html::encode($this->title) ?></h1>

<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>

<?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?>

<?= $form->field($model, 'email') ?>

<?= $form->field($model, 'subject') ?>

<?= $form->field($model, 'body')->textarea(['rows' => 6]) ?>

<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
]) ?>

<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>

</div>

+ 27
- 0
frontend/views/site/error.php Переглянути файл

@@ -0,0 +1,27 @@
<?php

/* @var $this yii\web\View */
/* @var $name string */
/* @var $message string */
/* @var $exception Exception */

use yii\helpers\Html;

$this->title = $name;
?>
<div class="site-error">

<h1><?= Html::encode($this->title) ?></h1>

<div class="alert alert-danger">
<?= nl2br(Html::encode($message)) ?>
</div>

<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>

</div>

+ 53
- 0
frontend/views/site/index.php Переглянути файл

@@ -0,0 +1,53 @@
<?php

/* @var $this yii\web\View */

$this->title = 'My Yii Application';
?>
<div class="site-index">

<div class="jumbotron">
<h1>Congratulations!</h1>

<p class="lead">You have successfully created your Yii-powered application.</p>

<p><a class="btn btn-lg btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p>
</div>

<div class="body-content">

<div class="row">
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>

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

<p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions &raquo;</a></p>
</div>
</div>

</div>
</div>

+ 39
- 0
frontend/views/site/login.php Переглянути файл

@@ -0,0 +1,39 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \common\models\LoginForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-login">
<h1><?= Html::encode($this->title) ?></h1>

<p>Please fill out the following fields to login:</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

<?= $form->field($model, 'password')->passwordInput() ?>

<?= $form->field($model, 'rememberMe')->checkbox() ?>

<div style="color:#999;margin:1em 0">
If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>.
</div>

<div class="form-group">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

+ 31
- 0
frontend/views/site/requestPasswordResetToken.php Переглянути файл

@@ -0,0 +1,31 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\PasswordResetRequestForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Request password reset';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-request-password-reset">
<h1><?= Html::encode($this->title) ?></h1>

<p>Please fill out your email. A link to reset password will be sent there.</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'request-password-reset-form']); ?>

<?= $form->field($model, 'email')->textInput(['autofocus' => true]) ?>

<div class="form-group">
<?= Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

+ 31
- 0
frontend/views/site/resetPassword.php Переглянути файл

@@ -0,0 +1,31 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\ResetPasswordForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Reset password';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-reset-password">
<h1><?= Html::encode($this->title) ?></h1>

<p>Please choose your new password:</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'reset-password-form']); ?>

<?= $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>

<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

+ 35
- 0
frontend/views/site/signup.php Переглянути файл

@@ -0,0 +1,35 @@
<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\SignupForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Signup';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-signup">
<h1><?= Html::encode($this->title) ?></h1>

<p>Please fill out the following fields to signup:</p>

<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>

<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

<?= $form->field($model, 'email') ?>

<?= $form->field($model, 'password')->passwordInput() ?>

<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

+ 2
- 0
frontend/web/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
/index.php
/index-test.php

+ 2
- 0
frontend/web/assets/.gitignore Переглянути файл

@@ -0,0 +1,2 @@
*
!.gitignore

+ 111
- 0
frontend/web/css/site.css Переглянути файл

@@ -0,0 +1,111 @@
html,
body {
height: 100%;
}

.wrap {
min-height: 100%;
height: auto;
margin: 0 auto -60px;
padding: 0 0 60px;
}

.wrap > .container {
padding: 70px 15px 20px;
}

.footer {
height: 60px;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
padding-top: 20px;
}

.jumbotron {
text-align: center;
background-color: transparent;
}

.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}

.not-set {
color: #c55;
font-style: italic;
}

/* add sorting icons to gridview sort links */
a.asc:after, a.desc:after {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
padding-left: 5px;
}

a.asc:after {
content: "\e151";
}

a.desc:after {
content: "\e152";
}

.sort-numerical a.asc:after {
content: "\e153";
}

.sort-numerical a.desc:after {
content: "\e154";
}

.sort-ordinal a.asc:after {
content: "\e155";
}

.sort-ordinal a.desc:after {
content: "\e156";
}

.grid-view td {
white-space: nowrap;
}

.grid-view .filters input,
.grid-view .filters select {
min-width: 50px;
}

.hint-block {
display: block;
margin-top: 5px;
color: #999;
}

.error-summary {
color: #a94442;
background: #fdf7f7;
border-left: 3px solid #eed3d7;
padding: 10px 20px;
margin: 0 0 15px 0;
}

/* align the logout "link" (button in form) of the navbar */
.nav > li > form {
padding: 8px;
}

@media(max-width:768px) {
.nav li > form {
padding: 3px;
}
}

.nav > li > form > button:hover {
text-decoration: none;
}

BIN
frontend/web/favicon.ico Переглянути файл

Перед Після

+ 2
- 0
frontend/web/robots.txt Переглянути файл

@@ -0,0 +1,2 @@
User-agent: *
Disallow:

+ 217
- 0
init Переглянути файл

@@ -0,0 +1,217 @@
#!/usr/bin/env php
<?php
/**
* Yii Application Initialization Tool
*
* In order to run in non-interactive mode:
*
* init --env=Development --overwrite=n
*
* @author Alexander Makarov <[email protected]>
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

if (!extension_loaded('openssl')) {
die('The OpenSSL PHP extension is required by Yii2.');
}

$params = getParams();
$root = str_replace('\\', '/', __DIR__);
$envs = require("$root/environments/index.php");
$envNames = array_keys($envs);

echo "Yii Application Initialization Tool v1.0\n\n";

$envName = null;
if (empty($params['env']) || $params['env'] === '1') {
echo "Which environment do you want the application to be initialized in?\n\n";
foreach ($envNames as $i => $name) {
echo " [$i] $name\n";
}
echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] ';
$answer = trim(fgets(STDIN));

if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) {
echo "\n Quit initialization.\n";
exit(0);
}

if (isset($envNames[$answer])) {
$envName = $envNames[$answer];
}
} else {
$envName = $params['env'];
}

if (!in_array($envName, $envNames)) {
$envsList = implode(', ', $envNames);
echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n";
exit(2);
}

$env = $envs[$envName];

if (empty($params['env'])) {
echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] ";
$answer = trim(fgets(STDIN));
if (strncasecmp($answer, 'y', 1)) {
echo "\n Quit initialization.\n";
exit(0);
}
}

echo "\n Start initialization ...\n\n";
$files = getFileList("$root/environments/{$env['path']}");
if (isset($env['skipFiles'])) {
$skipFiles = $env['skipFiles'];
array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; });
$files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists')));
}
$all = false;
foreach ($files as $file) {
if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
break;
}
}

$callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink'];
foreach ($callbacks as $callback) {
if (!empty($env[$callback])) {
$callback($root, $env[$callback]);
}
}

echo "\n ... initialization completed.\n\n";

function getFileList($root, $basePath = '')
{
$files = [];
$handle = opendir($root);
while (($path = readdir($handle)) !== false) {
if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') {
continue;
}
$fullPath = "$root/$path";
$relativePath = $basePath === '' ? $path : "$basePath/$path";
if (is_dir($fullPath)) {
$files = array_merge($files, getFileList($fullPath, $relativePath));
} else {
$files[] = $relativePath;
}
}
closedir($handle);
return $files;
}

function copyFile($root, $source, $target, &$all, $params)
{
if (!is_file($root . '/' . $source)) {
echo " skip $target ($source not exist)\n";
return true;
}
if (is_file($root . '/' . $target)) {
if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
echo " unchanged $target\n";
return true;
}
if ($all) {
echo " overwrite $target\n";
} else {
echo " exist $target\n";
echo " ...overwrite? [Yes|No|All|Quit] ";


$answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
if (!strncasecmp($answer, 'q', 1)) {
return false;
} else {
if (!strncasecmp($answer, 'y', 1)) {
echo " overwrite $target\n";
} else {
if (!strncasecmp($answer, 'a', 1)) {
echo " overwrite $target\n";
$all = true;
} else {
echo " skip $target\n";
return true;
}
}
}
}
file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
return true;
}
echo " generate $target\n";
@mkdir(dirname($root . '/' . $target), 0777, true);
file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
return true;
}

function getParams()
{
$rawParams = [];
if (isset($_SERVER['argv'])) {
$rawParams = $_SERVER['argv'];
array_shift($rawParams);
}

$params = [];
foreach ($rawParams as $param) {
if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
$name = $matches[1];
$params[$name] = isset($matches[3]) ? $matches[3] : true;
} else {
$params[] = $param;
}
}
return $params;
}

function setWritable($root, $paths)
{
foreach ($paths as $writable) {
if (is_dir("$root/$writable")) {
echo " chmod 0777 $writable\n";
@chmod("$root/$writable", 0777);
} else {
echo "\n Error. Directory $writable does not exist. \n";
}
}
}

function setExecutable($root, $paths)
{
foreach ($paths as $executable) {
echo " chmod 0755 $executable\n";
@chmod("$root/$executable", 0755);
}
}

function setCookieValidationKey($root, $paths)
{
foreach ($paths as $file) {
echo " generate cookie validation key in $file\n";
$file = $root . '/' . $file;
$length = 32;
$bytes = openssl_random_pseudo_bytes($length);
$key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
$content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
file_put_contents($file, $content);
}
}

function createSymlink($root, $links) {
foreach ($links as $link => $target) {
echo " symlink " . $root . "/" . $target . " " . $root . "/" . $link . "\n";
//first removing folders to avoid errors if the folder already exists
@rmdir($root . "/" . $link);
//next removing existing symlink in order to update the target
if (is_link($root . "/" . $link)) {
@unlink($root . "/" . $link);
}
@symlink($root . "/" . $target, $root . "/" . $link);
}
}

+ 20
- 0
init.bat Переглянути файл

@@ -0,0 +1,20 @@
@echo off

rem -------------------------------------------------------------
rem Yii command line init script for Windows.
rem
rem @author Qiang Xue <[email protected]>
rem @link http://www.yiiframework.com/
rem @copyright Copyright (c) 2008 Yii Software LLC
rem @license http://www.yiiframework.com/license/
rem -------------------------------------------------------------

@setlocal

set YII_PATH=%~dp0

if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe

"%PHP_COMMAND%" "%YII_PATH%init" %*

@endlocal

+ 132
- 0
requirements.php Переглянути файл

@@ -0,0 +1,132 @@
<?php
/**
* Application requirement checker script.
*
* In order to run this script use the following console command:
* php requirements.php
*
* In order to run this script from the web, you should copy it to the web root.
* If you are using Linux you can create a hard link instead, using the following command:
* ln requirements.php ../requirements.php
*/

// you may need to adjust this path to the correct Yii framework path
$frameworkPath = dirname(__FILE__) . '/vendor/yiisoft/yii2';

if (!is_dir($frameworkPath)) {
echo '<h1>Error</h1>';
echo '<p><strong>The path to yii framework seems to be incorrect.</strong></p>';
echo '<p>You need to install Yii framework via composer or adjust the framework path in file <abbr title="' . __FILE__ . '">' . basename(__FILE__) . '</abbr>.</p>';
echo '<p>Please refer to the <abbr title="' . dirname(__FILE__) . '/README.md">README</abbr> on how to install Yii.</p>';
}

require_once($frameworkPath . '/requirements/YiiRequirementChecker.php');
$requirementsChecker = new YiiRequirementChecker();

$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.';
$gdOK = $imagickOK = false;

if (extension_loaded('imagick')) {
$imagick = new Imagick();
$imagickFormats = $imagick->queryFormats('PNG');
if (in_array('PNG', $imagickFormats)) {
$imagickOK = true;
} else {
$imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.';
}
}

if (extension_loaded('gd')) {
$gdInfo = gd_info();
if (!empty($gdInfo['FreeType Support'])) {
$gdOK = true;
} else {
$gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.';
}
}

/**
* Adjust requirements according to your application specifics.
*/
$requirements = array(
// Database :
array(
'name' => 'PDO extension',
'mandatory' => true,
'condition' => extension_loaded('pdo'),
'by' => 'All DB-related classes',
),
array(
'name' => 'PDO SQLite extension',
'mandatory' => false,
'condition' => extension_loaded('pdo_sqlite'),
'by' => 'All DB-related classes',
'memo' => 'Required for SQLite database.',
),
array(
'name' => 'PDO MySQL extension',
'mandatory' => false,
'condition' => extension_loaded('pdo_mysql'),
'by' => 'All DB-related classes',
'memo' => 'Required for MySQL database.',
),
array(
'name' => 'PDO PostgreSQL extension',
'mandatory' => false,
'condition' => extension_loaded('pdo_pgsql'),
'by' => 'All DB-related classes',
'memo' => 'Required for PostgreSQL database.',
),
// Cache :
array(
'name' => 'Memcache extension',
'mandatory' => false,
'condition' => extension_loaded('memcache') || extension_loaded('memcached'),
'by' => '<a href="http://www.yiiframework.com/doc-2.0/yii-caching-memcache.html">MemCache</a>',
'memo' => extension_loaded('memcached') ? 'To use memcached set <a href="http://www.yiiframework.com/doc-2.0/yii-caching-memcache.html#$useMemcached-detail">MemCache::useMemcached</a> to <code>true</code>.' : ''
),
array(
'name' => 'APC extension',
'mandatory' => false,
'condition' => extension_loaded('apc'),
'by' => '<a href="http://www.yiiframework.com/doc-2.0/yii-caching-apccache.html">ApcCache</a>',
),
// CAPTCHA:
array(
'name' => 'GD PHP extension with FreeType support',
'mandatory' => false,
'condition' => $gdOK,
'by' => '<a href="http://www.yiiframework.com/doc-2.0/yii-captcha-captcha.html">Captcha</a>',
'memo' => $gdMemo,
),
array(
'name' => 'ImageMagick PHP extension with PNG support',
'mandatory' => false,
'condition' => $imagickOK,
'by' => '<a href="http://www.yiiframework.com/doc-2.0/yii-captcha-captcha.html">Captcha</a>',
'memo' => $imagickMemo,
),
// PHP ini :
'phpExposePhp' => array(
'name' => 'Expose PHP',
'mandatory' => false,
'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
'by' => 'Security reasons',
'memo' => '"expose_php" should be disabled at php.ini',
),
'phpAllowUrlInclude' => array(
'name' => 'PHP allow url include',
'mandatory' => false,
'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
'by' => 'Security reasons',
'memo' => '"allow_url_include" should be disabled at php.ini',
),
'phpSmtp' => array(
'name' => 'PHP mail SMTP',
'mandatory' => false,
'condition' => strlen(ini_get('SMTP')) > 0,
'by' => 'Email sending',
'memo' => 'PHP mail SMTP server required',
),
);
$requirementsChecker->checkYii()->check($requirements)->render();

+ 59
- 0
tests/README.md Переглянути файл

@@ -0,0 +1,59 @@
This directory contains various tests for the advanced applications.

Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/).

After creating and setting up the advanced application, follow these steps to prepare for the tests:

1. Install Codeception if it's not yet installed:

```
composer global require "codeception/codeception=2.1.*" "codeception/specify=*" "codeception/verify=*"
```

If you've never used Composer for global packages run `composer global status`. It should output:

```
Changed current directory to <directory>
```

Then add `<directory>/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command
line globally.

2. Install faker extension by running the following from template root directory where `composer.json` is:

```
composer require --dev yiisoft/yii2-faker:*
```

3. Create a database for tests, adjust the `components['db']` configuration in `tests/codeception/config/config-local.php`,
then update it by applying migrations:

```
codeception/bin/yii migrate
```

4. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in
webserver. In the root directory where `common`, `frontend` etc. are execute the following:

```
php -S localhost:8080
```

5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory:

```
# frontend tests
cd frontend
codecept build
codecept run
# backend tests
cd backend
codecept build
codecept run
# etc.
```

If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`.

+ 11
- 0
tests/codeception.yml Переглянути файл

@@ -0,0 +1,11 @@
include:
- codeception/common
- codeception/console
- codeception/backend
- codeception/frontend

paths:
log: codeception/_output

settings:
colors: true

Деякі файли не було показано, через те що забагато файлів було змінено

Завантаження…
Відмінити
Зберегти