@@ -0,0 +1,3 @@ | |||
{ | |||
"directory" : "vendor/bower" | |||
} |
@@ -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 |
@@ -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. |
@@ -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). | |||
[](https://packagist.org/packages/yiisoft/yii2-app-advanced) | |||
[](https://packagist.org/packages/yiisoft/yii2-app-advanced) | |||
[](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 | |||
``` |
@@ -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 |
@@ -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', | |||
]; | |||
} |
@@ -0,0 +1,2 @@ | |||
main-local.php | |||
params-local.php |
@@ -0,0 +1 @@ | |||
<?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, | |||
]; |
@@ -0,0 +1,4 @@ | |||
<?php | |||
return [ | |||
'adminEmail' => 'admin@example.com', | |||
]; |
@@ -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(); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
* |
@@ -0,0 +1,2 @@ | |||
* | |||
!.gitignore |
@@ -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">© My Company <?= date('Y') ?></p> | |||
<p class="pull-right"><?= Yii::powered() ?></p> | |||
</div> | |||
</footer> | |||
<?php $this->endBody() ?> | |||
</body> | |||
</html> | |||
<?php $this->endPage() ?> |
@@ -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> |
@@ -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 »</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 »</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 »</a></p> | |||
</div> | |||
</div> | |||
</div> | |||
</div> |
@@ -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> |
@@ -0,0 +1,2 @@ | |||
/index.php | |||
/index-test.php |
@@ -0,0 +1,2 @@ | |||
* | |||
!.gitignore |
@@ -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; | |||
} |
@@ -0,0 +1,2 @@ | |||
User-agent: * | |||
Disallow: / |
@@ -0,0 +1,2 @@ | |||
main-local.php | |||
params-local.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'); |
@@ -0,0 +1,9 @@ | |||
<?php | |||
return [ | |||
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', | |||
'components' => [ | |||
'cache' => [ | |||
'class' => 'yii\caching\FileCache', | |||
], | |||
], | |||
]; |
@@ -0,0 +1,6 @@ | |||
<?php | |||
return [ | |||
'adminEmail' => 'admin@example.com', | |||
'supportEmail' => 'support@example.com', | |||
'user.passwordResetTokenExpire' => 3600, | |||
]; |
@@ -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() ?> |
@@ -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() ?> |
@@ -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> |
@@ -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 ?> |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 <kartikv2@gmail.com> | |||
* @author Alexander Makarov <sam@rmcreative.ru> | |||
*/ | |||
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); | |||
} | |||
} | |||
} | |||
} |
@@ -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" | |||
} | |||
} |
@@ -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": "mail@cebe.cc", | |||
"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": "admin@htmlpurifier.org", | |||
"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": "fabien@symfony.com" | |||
} | |||
], | |||
"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": "qiang.xue@gmail.com", | |||
"homepage": "http://www.yiiframework.com/", | |||
"role": "Founder and project lead" | |||
}, | |||
{ | |||
"name": "Alexander Makarov", | |||
"email": "sam@rmcreative.ru", | |||
"homepage": "http://rmcreative.ru/", | |||
"role": "Core framework development" | |||
}, | |||
{ | |||
"name": "Maurizio Domba", | |||
"homepage": "http://mdomba.info/", | |||
"role": "Core framework development" | |||
}, | |||
{ | |||
"name": "Carsten Brandt", | |||
"email": "mail@cebe.cc", | |||
"homepage": "http://cebe.cc/", | |||
"role": "Core framework development" | |||
}, | |||
{ | |||
"name": "Timur Ruziev", | |||
"email": "resurtm@gmail.com", | |||
"homepage": "http://resurtm.com/", | |||
"role": "Core framework development" | |||
}, | |||
{ | |||
"name": "Paul Klimov", | |||
"email": "klimov.paul@gmail.com", | |||
"role": "Core framework development" | |||
}, | |||
{ | |||
"name": "Dmitry Naumenko", | |||
"email": "d.naumenko.a@gmail.com", | |||
"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": "qiang.xue@gmail.com" | |||
} | |||
], | |||
"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": "qiang.xue@gmail.com" | |||
} | |||
], | |||
"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": "klimov.paul@gmail.com" | |||
} | |||
], | |||
"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": "mark.github@yandex.ru" | |||
} | |||
], | |||
"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": "qiang.xue@gmail.com" | |||
} | |||
], | |||
"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": "mark.github@yandex.ru" | |||
} | |||
], | |||
"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": "qiang.xue@gmail.com" | |||
} | |||
], | |||
"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": [] | |||
} |
@@ -0,0 +1,2 @@ | |||
main-local.php | |||
params-local.php |
@@ -0,0 +1 @@ | |||
<?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, | |||
]; |
@@ -0,0 +1,4 @@ | |||
<?php | |||
return [ | |||
'adminEmail' => 'admin@example.com', | |||
]; |
@@ -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}}'); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
* |
@@ -0,0 +1,2 @@ | |||
* | |||
!.gitignore |
@@ -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; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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(); |
@@ -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(); |
@@ -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, | |||
], | |||
], | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -0,0 +1,7 @@ | |||
<?php | |||
return [ | |||
'bootstrap' => ['gii'], | |||
'modules' => [ | |||
'gii' => 'yii\gii\Module', | |||
], | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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(); |
@@ -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(); |
@@ -0,0 +1,11 @@ | |||
<?php | |||
return [ | |||
'components' => [ | |||
'db' => [ | |||
'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', | |||
'username' => 'root', | |||
'password' => '', | |||
'charset' => 'utf8', | |||
], | |||
], | |||
]; |
@@ -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); |
@@ -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', | |||
], | |||
], | |||
]; |
@@ -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' => '', | |||
], | |||
], | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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(); |
@@ -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', | |||
], | |||
], | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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' => '', | |||
], | |||
], | |||
]; |
@@ -0,0 +1,3 @@ | |||
<?php | |||
return [ | |||
]; |
@@ -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(); |
@@ -0,0 +1,11 @@ | |||
<?php | |||
return [ | |||
'components' => [ | |||
'db' => [ | |||
'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', | |||
'username' => 'root', | |||
'password' => '', | |||
'charset' => 'utf8', | |||
], | |||
], | |||
]; |
@@ -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); |
@@ -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', | |||
]; | |||
} |
@@ -0,0 +1,2 @@ | |||
main-local.php | |||
params-local.php |
@@ -0,0 +1 @@ | |||
<?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, | |||
]; |
@@ -0,0 +1,4 @@ | |||
<?php | |||
return [ | |||
'adminEmail' => 'admin@example.com', | |||
]; |
@@ -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, | |||
]); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -0,0 +1,2 @@ | |||
* | |||
!.gitignore |
@@ -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">© My Company <?= date('Y') ?></p> | |||
<p class="pull-right"><?= Yii::powered() ?></p> | |||
</div> | |||
</footer> | |||
<?php $this->endBody() ?> | |||
</body> | |||
</html> | |||
<?php $this->endPage() ?> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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 »</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 »</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 »</a></p> | |||
</div> | |||
</div> | |||
</div> | |||
</div> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -0,0 +1,2 @@ | |||
/index.php | |||
/index-test.php |
@@ -0,0 +1,2 @@ | |||
* | |||
!.gitignore |
@@ -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; | |||
} |
@@ -0,0 +1,2 @@ | |||
User-agent: * | |||
Disallow: |
@@ -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 <sam@rmcreative.ru> | |||
* | |||
* @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); | |||
} | |||
} |
@@ -0,0 +1,20 @@ | |||
@echo off | |||
rem ------------------------------------------------------------- | |||
rem Yii command line init script for Windows. | |||
rem | |||
rem @author Qiang Xue <qiang.xue@gmail.com> | |||
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 |
@@ -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(); |
@@ -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`. |
@@ -0,0 +1,11 @@ | |||
include: | |||
- codeception/common | |||
- codeception/console | |||
- codeception/backend | |||
- codeception/frontend | |||
paths: | |||
log: codeception/_output | |||
settings: | |||
colors: true |