diff --git a/.bowerrc b/.bowerrc
new file mode 100755
index 0000000..1669168
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory" : "vendor/bower"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..6ce6155
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,35 @@
+# yii console commands
+/yii
+/yii_test
+/yii_test.bat
+
+# 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
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100755
index 0000000..e98f03d
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,32 @@
+The Yii framework is free software. It is released under the terms of
+the following BSD License.
+
+Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Yii Software LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100755
index 0000000..4181f83
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,72 @@
+require 'yaml'
+require 'fileutils'
+
+domains = {
+ frontend: 'y2aa-frontend.dev',
+ backend: 'y2aa-backend.dev'
+}
+
+config = {
+ local: './vagrant/config/vagrant-local.yml',
+ example: './vagrant/config/vagrant-local.example.yml'
+}
+
+# copy config from example if local config not exists
+FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
+# read config
+options = YAML.load_file config[:local]
+
+# check github token
+if options['github_token'].nil? || options['github_token'].to_s.length != 40
+ puts "You must place REAL GitHub token into configuration:\n/yii2-app-advanced/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
diff --git a/backend/assets/AppAsset.php b/backend/assets/AppAsset.php
new file mode 100755
index 0000000..d85fd95
--- /dev/null
+++ b/backend/assets/AppAsset.php
@@ -0,0 +1,23 @@
+ '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,
+ 'enableStrictParsing' => false,
+ 'rules' => [
+ ],
+ ],
+ ],
+ 'params' => $params,
+];
diff --git a/backend/config/params.php b/backend/config/params.php
new file mode 100755
index 0000000..7f754b9
--- /dev/null
+++ b/backend/config/params.php
@@ -0,0 +1,4 @@
+ 'admin@example.com',
+];
diff --git a/backend/config/test.php b/backend/config/test.php
new file mode 100755
index 0000000..09536cf
--- /dev/null
+++ b/backend/config/test.php
@@ -0,0 +1,9 @@
+ 'app-backend-tests',
+ 'components' => [
+ 'assetManager' => [
+ 'basePath' => __DIR__ . '/../web/assets',
+ ],
+ ],
+];
diff --git a/backend/controllers/ModsController.php b/backend/controllers/ModsController.php
new file mode 100644
index 0000000..aaec55f
--- /dev/null
+++ b/backend/controllers/ModsController.php
@@ -0,0 +1,124 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all Mods models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new ModsSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Mods model.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Mods model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Mods();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Updates an existing Mods model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Deletes an existing Mods model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Mods model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param integer $id
+ * @return Mods the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Mods::findOne($id)) !== null) {
+ return $model;
+ } else {
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+ }
+}
diff --git a/backend/controllers/ShipController.php b/backend/controllers/ShipController.php
new file mode 100644
index 0000000..5f6b4f1
--- /dev/null
+++ b/backend/controllers/ShipController.php
@@ -0,0 +1,124 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all Ship models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new ShipSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Ship model.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Ship model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Ship();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Updates an existing Ship model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Deletes an existing Ship model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Ship model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param integer $id
+ * @return Ship the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Ship::findOne($id)) !== null) {
+ return $model;
+ } else {
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+ }
+}
diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php
new file mode 100755
index 0000000..9624dcc
--- /dev/null
+++ b/backend/controllers/SiteController.php
@@ -0,0 +1,98 @@
+ [
+ '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();
+ }
+}
diff --git a/backend/controllers/UserController.php b/backend/controllers/UserController.php
new file mode 100644
index 0000000..3bba264
--- /dev/null
+++ b/backend/controllers/UserController.php
@@ -0,0 +1,124 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all User models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new UserSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single User model.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new User model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new User();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Updates an existing User model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * Deletes an existing User model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param integer $id
+ * @return mixed
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the User model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param integer $id
+ * @return User the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = User::findOne($id)) !== null) {
+ return $model;
+ } else {
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+ }
+}
diff --git a/backend/models/.gitkeep b/backend/models/.gitkeep
new file mode 100755
index 0000000..72e8ffc
--- /dev/null
+++ b/backend/models/.gitkeep
@@ -0,0 +1 @@
+*
diff --git a/backend/models/ModsSearch.php b/backend/models/ModsSearch.php
new file mode 100644
index 0000000..fcc9801
--- /dev/null
+++ b/backend/models/ModsSearch.php
@@ -0,0 +1,73 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'ship_id' => $this->ship_id,
+ 'mod_gun' => $this->mod_gun,
+ 'mod_tower' => $this->mod_tower,
+ 'exp_gun' => $this->exp_gun,
+ 'exp_tower' => $this->exp_tower,
+ 'cost_gun' => $this->cost_gun,
+ 'cost_tower' => $this->cost_tower,
+ ]);
+
+ return $dataProvider;
+ }
+}
diff --git a/backend/models/ShipSearch.php b/backend/models/ShipSearch.php
new file mode 100644
index 0000000..4b55ce9
--- /dev/null
+++ b/backend/models/ShipSearch.php
@@ -0,0 +1,76 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'lvl' => $this->lvl,
+ 'stock_gun' => $this->stock_gun,
+ 'stock_tower' => $this->stock_tower,
+ 'mod_gun' => $this->mod_gun,
+ 'mod_tower' => $this->mod_tower,
+ 'strength' => $this->strength,
+ 'type' => $this->type,
+ ]);
+
+ $query->andFilterWhere(['like', 'name', $this->name]);
+
+ return $dataProvider;
+ }
+}
diff --git a/backend/models/UserSearch.php b/backend/models/UserSearch.php
new file mode 100644
index 0000000..eb125cf
--- /dev/null
+++ b/backend/models/UserSearch.php
@@ -0,0 +1,81 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'status' => $this->status,
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at,
+ 'win' => $this->win,
+ 'lose' => $this->lose,
+ 'draw' => $this->draw,
+ 'credits' => $this->credits,
+ 'battle_id' => $this->battle_id,
+ ]);
+
+ $query->andFilterWhere(['like', 'username', $this->username])
+ ->andFilterWhere(['like', 'auth_key', $this->auth_key])
+ ->andFilterWhere(['like', 'password_hash', $this->password_hash])
+ ->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token])
+ ->andFilterWhere(['like', 'email', $this->email]);
+
+ return $dataProvider;
+ }
+}
diff --git a/backend/runtime/.gitignore b/backend/runtime/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/backend/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/backend/tests/_bootstrap.php b/backend/tests/_bootstrap.php
new file mode 100755
index 0000000..83a1f26
--- /dev/null
+++ b/backend/tests/_bootstrap.php
@@ -0,0 +1,9 @@
+ 'erau',
+ 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI',
+ // password_0
+ 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne',
+ 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490',
+ 'created_at' => '1392559490',
+ 'updated_at' => '1392559490',
+ 'email' => 'sfriesen@jenkins.info',
+ ],
+];
diff --git a/backend/tests/_output/.gitignore b/backend/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/backend/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/backend/tests/_support/.gitignore b/backend/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/backend/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/backend/tests/_support/FunctionalTester.php b/backend/tests/_support/FunctionalTester.php
new file mode 100755
index 0000000..80a79ed
--- /dev/null
+++ b/backend/tests/_support/FunctionalTester.php
@@ -0,0 +1,25 @@
+haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'login_data.php'
+ ]
+ ]);
+ }
+ /**
+ * @param FunctionalTester $I
+ */
+ public function loginUser(FunctionalTester $I)
+ {
+ $I->amOnPage('/site/login');
+ $I->fillField('Username', 'erau');
+ $I->fillField('Password', 'password_0');
+ $I->click('login-button');
+
+ $I->see('Logout (erau)', 'form button[type=submit]');
+ $I->dontSeeLink('Login');
+ $I->dontSeeLink('Signup');
+ }
+}
diff --git a/backend/tests/functional/_bootstrap.php b/backend/tests/functional/_bootstrap.php
new file mode 100755
index 0000000..30ed54b
--- /dev/null
+++ b/backend/tests/functional/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/backend/tests/unit.suite.yml b/backend/tests/unit.suite.yml
new file mode 100755
index 0000000..1ba1eb4
--- /dev/null
+++ b/backend/tests/unit.suite.yml
@@ -0,0 +1 @@
+class_name: UnitTester
diff --git a/backend/tests/unit/_bootstrap.php b/backend/tests/unit/_bootstrap.php
new file mode 100755
index 0000000..e432ce5
--- /dev/null
+++ b/backend/tests/unit/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Tests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php
new file mode 100755
index 0000000..08628af
--- /dev/null
+++ b/backend/views/layouts/main.php
@@ -0,0 +1,82 @@
+
+beginPage() ?>
+
+
+
+
+
+ = Html::csrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+ 'My Company',
+ 'brandUrl' => Yii::$app->homeUrl,
+ 'options' => [
+ 'class' => 'navbar-inverse navbar-fixed-top',
+ ],
+ ]);
+ $menuItems = [
+ ['label' => 'Home', 'url' => ['/site/index']],
+ ['label' => 'Ships', 'url' => ['/ship']],
+ ['label' => 'Users', 'url' => ['/user']],
+ ['label' => 'Mods', 'url' => ['/mods']],
+ ];
+ if (Yii::$app->user->isGuest) {
+ $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
+ } else {
+ $menuItems[] = '
'
+ . Html::beginForm(['/site/logout'], 'post')
+ . Html::submitButton(
+ 'Logout (' . Yii::$app->user->identity->username . ')',
+ ['class' => 'btn btn-link logout']
+ )
+ . Html::endForm()
+ . '';
+ }
+ echo Nav::widget([
+ 'options' => ['class' => 'navbar-nav navbar-right'],
+ 'items' => $menuItems,
+ ]);
+ NavBar::end();
+ ?>
+
+
+ = Breadcrumbs::widget([
+ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
+ ]) ?>
+ = Alert::widget() ?>
+ = $content ?>
+
+
+
+
+
+endBody() ?>
+
+
+endPage() ?>
diff --git a/backend/views/mods/_form.php b/backend/views/mods/_form.php
new file mode 100644
index 0000000..8cf55db
--- /dev/null
+++ b/backend/views/mods/_form.php
@@ -0,0 +1,27 @@
+
+
+
diff --git a/backend/views/mods/_search.php b/backend/views/mods/_search.php
new file mode 100644
index 0000000..024587f
--- /dev/null
+++ b/backend/views/mods/_search.php
@@ -0,0 +1,41 @@
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'ship_id') ?>
+
+ = $form->field($model, 'mod_gun') ?>
+
+ = $form->field($model, 'mod_tower') ?>
+
+ = $form->field($model, 'exp_gun') ?>
+
+ field($model, 'exp_tower') ?>
+
+ field($model, 'cost_gun') ?>
+
+ field($model, 'cost_tower') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
+
+
+
+
+
diff --git a/backend/views/mods/create.php b/backend/views/mods/create.php
new file mode 100644
index 0000000..53a409a
--- /dev/null
+++ b/backend/views/mods/create.php
@@ -0,0 +1,21 @@
+title = 'Create Mods';
+$this->params['breadcrumbs'][] = ['label' => 'Mods', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/mods/index.php b/backend/views/mods/index.php
new file mode 100644
index 0000000..b577399
--- /dev/null
+++ b/backend/views/mods/index.php
@@ -0,0 +1,39 @@
+title = 'Mods';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+ render('_search', ['model' => $searchModel]); ?>
+
+
+ = Html::a('Create Mods', ['create'], ['class' => 'btn btn-success']) ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ // 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ //'id',
+ 'ship_id',
+ 'mod_gun',
+ 'mod_tower',
+ 'exp_gun',
+ 'exp_tower',
+ 'cost_gun',
+ 'cost_tower',
+
+ ['class' => 'yii\grid\ActionColumn'],
+ ],
+ ]); ?>
+
diff --git a/backend/views/mods/update.php b/backend/views/mods/update.php
new file mode 100644
index 0000000..f0fc517
--- /dev/null
+++ b/backend/views/mods/update.php
@@ -0,0 +1,21 @@
+title = 'Update Mods: ' . $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Mods', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/mods/view.php b/backend/views/mods/view.php
new file mode 100644
index 0000000..c579d97
--- /dev/null
+++ b/backend/views/mods/view.php
@@ -0,0 +1,42 @@
+title = $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Mods', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'ship_id',
+ 'mod_gun',
+ 'mod_tower',
+ 'exp_gun',
+ 'exp_tower',
+ 'cost_gun',
+ 'cost_tower',
+ ],
+ ]) ?>
+
+
diff --git a/backend/views/ship/_form.php b/backend/views/ship/_form.php
new file mode 100644
index 0000000..4dd9b72
--- /dev/null
+++ b/backend/views/ship/_form.php
@@ -0,0 +1,37 @@
+
+
+
diff --git a/backend/views/ship/_search.php b/backend/views/ship/_search.php
new file mode 100644
index 0000000..e18ee6a
--- /dev/null
+++ b/backend/views/ship/_search.php
@@ -0,0 +1,43 @@
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'name') ?>
+
+ = $form->field($model, 'lvl') ?>
+
+ = $form->field($model, 'stock_gun') ?>
+
+ = $form->field($model, 'stock_tower') ?>
+
+ field($model, 'mod_gun') ?>
+
+ field($model, 'mod_tower') ?>
+
+ field($model, 'strength') ?>
+
+ field($model, 'type') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
+
+
+
+
+
diff --git a/backend/views/ship/create.php b/backend/views/ship/create.php
new file mode 100644
index 0000000..c98e149
--- /dev/null
+++ b/backend/views/ship/create.php
@@ -0,0 +1,21 @@
+title = 'Create Ship';
+$this->params['breadcrumbs'][] = ['label' => 'Ships', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/ship/index.php b/backend/views/ship/index.php
new file mode 100644
index 0000000..2fee3f2
--- /dev/null
+++ b/backend/views/ship/index.php
@@ -0,0 +1,39 @@
+title = 'Ships';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+ render('_search', ['model' => $searchModel]); ?>
+
+
+ = Html::a('Create Ship', ['create'], ['class' => 'btn btn-success'], ['style' => 'width: 240px']) ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ //'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+ //'id',
+ 'name',
+ 'lvl',
+ 'stock_gun',
+ 'stock_tower',
+ 'mod_gun',
+ 'mod_tower',
+ 'strength',
+ 'type',
+
+ ['class' => 'yii\grid\ActionColumn'],
+ ],
+ ]); ?>
+
diff --git a/backend/views/ship/update.php b/backend/views/ship/update.php
new file mode 100644
index 0000000..9a35ea6
--- /dev/null
+++ b/backend/views/ship/update.php
@@ -0,0 +1,21 @@
+title = 'Update Ship: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Ships', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/ship/view.php b/backend/views/ship/view.php
new file mode 100644
index 0000000..8d2ea26
--- /dev/null
+++ b/backend/views/ship/view.php
@@ -0,0 +1,43 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Ships', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'name',
+ 'lvl',
+ 'stock_gun',
+ 'stock_tower',
+ 'mod_gun',
+ 'mod_tower',
+ 'strength',
+ 'type',
+ ],
+ ]) ?>
+
+
diff --git a/backend/views/site/error.php b/backend/views/site/error.php
new file mode 100755
index 0000000..0ba2574
--- /dev/null
+++ b/backend/views/site/error.php
@@ -0,0 +1,27 @@
+title = $name;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = nl2br(Html::encode($message)) ?>
+
+
+
+ The above error occurred while the Web server was processing your request.
+
+
+ Please contact us if you think this is a server error. Thank you.
+
+
+
diff --git a/backend/views/site/index.php b/backend/views/site/index.php
new file mode 100755
index 0000000..f780610
--- /dev/null
+++ b/backend/views/site/index.php
@@ -0,0 +1,53 @@
+title = 'My Yii Application';
+?>
+
+
+
+
Congratulations!
+
+
You have successfully created your Yii-powered application.
+
+
Get started with Yii
+
+
+
+
+
+
+
Heading
+
+
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.
+
+
Yii Documentation »
+
+
+
Heading
+
+
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.
+
+
Yii Forum »
+
+
+
Heading
+
+
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.
+
+
Yii Extensions »
+
+
+
+
+
diff --git a/backend/views/site/login.php b/backend/views/site/login.php
new file mode 100755
index 0000000..20f3f78
--- /dev/null
+++ b/backend/views/site/login.php
@@ -0,0 +1,35 @@
+title = 'Login';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out the following fields to login:
+
+
+
+ 'login-form']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+ = $form->field($model, 'rememberMe')->checkbox() ?>
+
+
+ = Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
+
+
+
+
+
+
diff --git a/backend/views/user/_form.php b/backend/views/user/_form.php
new file mode 100644
index 0000000..2fef732
--- /dev/null
+++ b/backend/views/user/_form.php
@@ -0,0 +1,23 @@
+
+
+
diff --git a/backend/views/user/_search.php b/backend/views/user/_search.php
new file mode 100644
index 0000000..b615465
--- /dev/null
+++ b/backend/views/user/_search.php
@@ -0,0 +1,53 @@
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'username') ?>
+
+ = $form->field($model, 'auth_key') ?>
+
+ = $form->field($model, 'password_hash') ?>
+
+ = $form->field($model, 'password_reset_token') ?>
+
+ field($model, 'email') ?>
+
+ field($model, 'status') ?>
+
+ field($model, 'created_at') ?>
+
+ field($model, 'updated_at') ?>
+
+ field($model, 'win') ?>
+
+ field($model, 'lose') ?>
+
+ field($model, 'draw') ?>
+
+ field($model, 'credits') ?>
+
+ field($model, 'battle_id') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
+
+
+
+
+
diff --git a/backend/views/user/create.php b/backend/views/user/create.php
new file mode 100644
index 0000000..a71baf7
--- /dev/null
+++ b/backend/views/user/create.php
@@ -0,0 +1,21 @@
+title = 'Create User';
+$this->params['breadcrumbs'][] = ['label' => 'Users', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/user/index.php b/backend/views/user/index.php
new file mode 100644
index 0000000..1b4d7fc
--- /dev/null
+++ b/backend/views/user/index.php
@@ -0,0 +1,45 @@
+title = 'Users';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+ render('_search', ['model' => $searchModel]); ?>
+
+
+ = Html::a('Create User', ['create'], ['class' => 'btn btn-success']) ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ //'id',
+ 'username',
+ //'auth_key',
+ //'password_hash',
+ //'password_reset_token',
+ // 'email:email',
+ // 'status',
+ // 'created_at',
+ // 'updated_at',
+ 'win',
+ 'lose',
+ 'draw',
+ 'credits',
+ 'battle_id',
+
+ ['class' => 'yii\grid\ActionColumn'],
+ ],
+ ]); ?>
+
diff --git a/backend/views/user/update.php b/backend/views/user/update.php
new file mode 100644
index 0000000..0dece80
--- /dev/null
+++ b/backend/views/user/update.php
@@ -0,0 +1,21 @@
+title = 'Update User: ' . $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Users', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/views/user/view.php b/backend/views/user/view.php
new file mode 100644
index 0000000..60e011e
--- /dev/null
+++ b/backend/views/user/view.php
@@ -0,0 +1,48 @@
+title = $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Users', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'username',
+ 'auth_key',
+ 'password_hash',
+ 'password_reset_token',
+ 'email:email',
+ 'status',
+ 'created_at',
+ 'updated_at',
+ 'win',
+ 'lose',
+ 'draw',
+ 'credits',
+ 'battle_id',
+ ],
+ ]) ?>
+
+
diff --git a/backend/web/.gitignore b/backend/web/.gitignore
new file mode 100755
index 0000000..25c74e6
--- /dev/null
+++ b/backend/web/.gitignore
@@ -0,0 +1,2 @@
+/index.php
+/index-test.php
diff --git a/backend/web/.htaccess b/backend/web/.htaccess
new file mode 100755
index 0000000..1426180
--- /dev/null
+++ b/backend/web/.htaccess
@@ -0,0 +1,10 @@
+Options +FollowSymLinks
+
+RewriteEngine on
+
+# if a directory or a file exists, use it directly
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+
+# otherwise forward it to index.php
+RewriteRule . index.php
diff --git a/backend/web/assets/.gitignore b/backend/web/assets/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/backend/web/assets/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/backend/web/css/site.css b/backend/web/css/site.css
new file mode 100755
index 0000000..a4573b8
--- /dev/null
+++ b/backend/web/css/site.css
@@ -0,0 +1,121 @@
+html,
+body {
+ height: 100%;
+ background: url('../../../frontend/web/img/bg.jpg');
+}
+
+.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 > button.logout {
+ padding: 15px;
+ border: none;
+}
+
+@media(max-width:767px) {
+ .nav li > form > button.logout {
+ display:block;
+ text-align: left;
+ width: 100%;
+ padding: 10px 15px;
+ }
+}
+
+.nav > li > form > button.logout:focus,
+.nav > li > form > button.logout:hover {
+ text-decoration: none;
+}
+
+.nav > li > form > button.logout:focus {
+ outline: none;
+}
diff --git a/backend/web/favicon.ico b/backend/web/favicon.ico
new file mode 100755
index 0000000..580ed73
Binary files /dev/null and b/backend/web/favicon.ico differ
diff --git a/backend/web/robots.txt b/backend/web/robots.txt
new file mode 100755
index 0000000..1f53798
--- /dev/null
+++ b/backend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/codeception.yml b/codeception.yml
new file mode 100755
index 0000000..af20104
--- /dev/null
+++ b/codeception.yml
@@ -0,0 +1,9 @@
+# global codeception file to run tests from all apps
+include:
+ - common
+ - frontend
+ - backend
+paths:
+ log: console/runtime/logs
+settings:
+ colors: true
\ No newline at end of file
diff --git a/common/codeception.yml b/common/codeception.yml
new file mode 100755
index 0000000..de5d76a
--- /dev/null
+++ b/common/codeception.yml
@@ -0,0 +1,15 @@
+namespace: common\tests
+actor: Tester
+paths:
+ tests: tests
+ log: tests/_output
+ data: tests/_data
+ helpers: tests/_support
+settings:
+ bootstrap: _bootstrap.php
+ colors: true
+ memory_limit: 1024M
+modules:
+ config:
+ Yii2:
+ configFile: 'config/test-local.php'
diff --git a/common/components/Combat.php b/common/components/Combat.php
new file mode 100644
index 0000000..3650072
--- /dev/null
+++ b/common/components/Combat.php
@@ -0,0 +1,203 @@
+session;
+ $session->open();
+ if (!isset($session['usershiphp']) && !isset($session['bothp'])) {
+ $session['usershiphp'] = $ship->strength;
+ $session['bothp'] = $ship->strength;
+ }
+
+ $playerdmg = $this->dmgPlayer($ship->ship_id, $ship->mod_gun);
+ $botdmg = $this->dmgBot($ship->ship_id);
+
+ switch ($type) {
+ case 1:
+ $i = rand(0,10);
+ if($i == 7) {
+ $adddmg = (($ship->strength)*0.3);
+ } else {
+ $adddmg = (($ship->strength)*0.1);
+ }
+ $session['bothp'] = $session['bothp'] - ceil(($this->shipTypePlayer($ship->type, $playerdmg) + $adddmg));
+ $session['usershiphp'] = $session['usershiphp'] - ceil(($this->shipTypeBot($ship->type, $botdmg) + $adddmg));
+ $log = Yii::t('app', 'You attacked the bot warship on -').''.ceil(($this->shipTypePlayer($ship->type, $playerdmg) + $adddmg)).'
';
+ $log .= Yii::t('app', 'Our warship were attacked by bot warship on -').''.ceil(($this->shipTypeBot($ship->type, $botdmg) + $adddmg)).'';
+ break;
+ case 2:
+ $adddmg = (($ship->strength)*0.1);
+ $session['bothp'] = $session['bothp'] - ceil(($this->shipTypePlayer($ship->strength, $playerdmg) + $adddmg));
+ $session['usershiphp'] = $session['usershiphp'] - ceil(($this->shipTypeBot($ship->strength, $botdmg) + $adddmg));
+ $log = Yii::t('app', 'You attacked the bot warship on -').''.ceil(($this->shipTypePlayer($ship->type, $playerdmg) + $adddmg)).'
';
+ $log .= Yii::t('app', 'Our warship were attacked by bot warship on -').''.ceil(($this->shipTypeBot($ship->type, $botdmg) + $adddmg)).'';
+ break;
+ case 3:
+ $adddmg = (($ship->strength)*0.1);
+ $session['bothp'] = $session['bothp'] - ceil(($this->shipTypePlayer($ship->strength, $playerdmg) + $adddmg));
+ $session['usershiphp'] = $session['usershiphp'] - ceil(($this->shipTypeBot($ship->strength, $botdmg) + $adddmg));
+ $log = Yii::t('app', 'You attacked the bot warship on -').''.ceil(($this->shipTypePlayer($ship->type, $playerdmg) + $adddmg)).'
';
+ $log .= Yii::t('app', 'Our warship were attacked by bot warship on -').''.ceil(($this->shipTypeBot($ship->type, $botdmg) + $adddmg)).'';
+ break;
+ case 4:
+ $i = rand(1,30);
+ if($i == 23) {
+ $adddmg = $ship->strength;
+ } else {
+ $adddmg = ceil(($ship->strength)*0.1);
+ }
+ $session['bothp'] = $session['bothp'] - ceil(($this->shipTypePlayer($ship->strength, $playerdmg) + $adddmg));
+ $session['usershiphp'] = $session['usershiphp'] - ceil(($this->shipTypeBot($ship->strength, $botdmg) + $adddmg));
+ $log = Yii::t('app', 'You attacked the bot warship on -').''.ceil(($this->shipTypePlayer($ship->type, $playerdmg) + $adddmg)).'
';
+ $log .= Yii::t('app', 'Our warship were attacked by bot warship on -').''.ceil(($this->shipTypeBot($ship->type, $botdmg) + $adddmg)).'';
+ break;
+ }
+ $this->writeLog($bid->bid, $log);
+ /*
+ * Cheking for state - HP;
+ */
+ if ($session['usershiphp'] <= 0) {
+ $bid->updateAll(['status' => 1], ['bid' => $bid->bid]);
+ unset($session['usershiphp']);
+ unset($session['bothp']);
+ unset($log);
+ unset($battleid);
+ $player->updateCounters(['lose' => 1]);
+ $player->updateAll(['battle_id' => 0], ['id' => Yii::$app->user->id]);
+ Controller::redirect('combat/lose');
+ } elseif ($session['bothp'] <= 0) {
+ $bid->updateAll(['status' => 1], ['bid' => $bid->bid]);
+ unset($session['usershiphp']);
+ unset($session['bothp']);
+ unset($log);
+ unset($battleid);
+ $ship->updateCounters(['exp' => $this->expirence($ship->ship_id)]);
+ $player->updateCounters(['win' => 1]);
+ $player->updateCounters(['credits' => +($this->giveMoney())]);
+ $player->updateAll(['battle_id' => 0], ['id' => Yii::$app->user->id]);
+ Controller::redirect('combat/win');
+ }
+
+ return [$session['usershiphp'], $session['bothp'], $ship, $player];
+
+ }
+
+ /**
+ * @param $user
+ * @param $item
+ * @return mixed
+ */
+ public function addHp($user, $item)
+ {
+ if(Yii::$app->request->post('gethp')) {
+ $user = $user + $item;
+ return $user;
+ }
+ }
+
+ /**
+ * Calculate damage for player;
+ */
+ public function dmgPlayer($id, $gun)
+ {
+ $playerdmg = (($id) * rand(80,90)) + ($gun) * 10;
+
+ return $playerdmg;
+ }
+
+ /**
+ * @param $id
+ * @return mixed
+ */
+ public function dmgBot($id)
+ {
+ $botdmg = ($id) * rand(80,10);
+
+ return $botdmg;
+ }
+
+ /**
+ * @param $id
+ * @return mixed
+ */
+ public function expirence($id)
+ {
+ $expirence = ($id*(10*$this->exp)+rand(10,20));
+
+ return $expirence;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function giveMoney()
+ {
+ $givemoney = (($this->credits)*100)+rand(0,50);
+
+ return $givemoney;
+ }
+
+ /**
+ * @param $bid
+ * @param $pdmg
+ */
+ public function writeLog($bid, $pdmg)
+ {
+ //$sql = "UPDATE `battles` SET `logs` = CONCAT(`logs`,'".$pdmg."') WHERE `bid` = $bid";
+ //$battles = Battles::findBySql($sql)->all();
+
+ $battleid = Battles::findOne(['bid' => $bid]);
+ $battleid->updateAll(['logs' => new \yii\db\Expression("CONCAT('".$pdmg."')")], ['bid' => $bid]);
+ }
+
+ /**
+ * @param $type
+ * @param $dmg
+ * @return mixed
+ */
+ public function shipTypePlayer($type, $dmg)
+ {
+ if($type == 3) {
+ $pdmg = $dmg - (rand(20, 30) * 1.5);
+ return $pdmg;
+ } elseif ($type == 2) {
+ $pdmg = $dmg + (rand(40, 50) * 1.5);
+ return $pdmg;
+ } else {
+ $pdmg = $dmg;
+ return $pdmg;
+ }
+ }
+
+ /**
+ * @param $type
+ * @param $dmg
+ * @return mixed
+ */
+ public function shipTypeBot($type, $dmg)
+ {
+ if($type == 3) {
+ $bdmg = $dmg - (rand(19, 32) * 1.4);
+ return $bdmg;
+ } elseif ($type == 2) {
+ $bdmg = $dmg + (rand(38, 50) * 1.5);
+ return $bdmg;
+ } else {
+ $bdmg = $dmg;
+ return $bdmg;
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/config/.gitignore b/common/config/.gitignore
new file mode 100755
index 0000000..42799dd
--- /dev/null
+++ b/common/config/.gitignore
@@ -0,0 +1,3 @@
+main-local.php
+params-local.php
+test-local.php
diff --git a/common/config/bootstrap.php b/common/config/bootstrap.php
new file mode 100755
index 0000000..93d0185
--- /dev/null
+++ b/common/config/bootstrap.php
@@ -0,0 +1,5 @@
+ dirname(dirname(__DIR__)) . '/vendor',
+ 'components' => [
+ 'cache' => [
+ 'class' => 'yii\caching\FileCache',
+ ],
+ 'Combat' => [
+ 'class' => 'common\components\Combat',
+ 'exp' => '10',
+ 'credits' => '0.5',
+ ],
+ ],
+];
diff --git a/common/config/params.php b/common/config/params.php
new file mode 100755
index 0000000..4ec9ba6
--- /dev/null
+++ b/common/config/params.php
@@ -0,0 +1,6 @@
+ 'admin@example.com',
+ 'supportEmail' => 'support@example.com',
+ 'user.passwordResetTokenExpire' => 3600,
+];
diff --git a/common/config/test.php b/common/config/test.php
new file mode 100755
index 0000000..c952c41
--- /dev/null
+++ b/common/config/test.php
@@ -0,0 +1,11 @@
+ 'app-common-tests',
+ 'basePath' => dirname(__DIR__),
+ 'components' => [
+ 'user' => [
+ 'class' => 'yii\web\User',
+ 'identityClass' => 'common\models\User',
+ ],
+ ],
+];
diff --git a/common/fixtures/User.php b/common/fixtures/User.php
new file mode 100755
index 0000000..d4b0f36
--- /dev/null
+++ b/common/fixtures/User.php
@@ -0,0 +1,9 @@
+
+beginPage() ?>
+
+
+
+
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+ beginBody() ?>
+ = $content ?>
+ endBody() ?>
+
+
+endPage() ?>
diff --git a/common/mail/layouts/text.php b/common/mail/layouts/text.php
new file mode 100755
index 0000000..aab1d5d
--- /dev/null
+++ b/common/mail/layouts/text.php
@@ -0,0 +1,14 @@
+
+
+beginPage() ?>
+beginBody() ?>
+= $content ?>
+endBody() ?>
+endPage() ?>
diff --git a/common/mail/passwordResetToken-html.php b/common/mail/passwordResetToken-html.php
new file mode 100755
index 0000000..f3daf49
--- /dev/null
+++ b/common/mail/passwordResetToken-html.php
@@ -0,0 +1,15 @@
+urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
+?>
+
+
Hello = Html::encode($user->username) ?>,
+
+
Follow the link below to reset your password:
+
+
= Html::a(Html::encode($resetLink), $resetLink) ?>
+
diff --git a/common/mail/passwordResetToken-text.php b/common/mail/passwordResetToken-text.php
new file mode 100755
index 0000000..244c0cb
--- /dev/null
+++ b/common/mail/passwordResetToken-text.php
@@ -0,0 +1,12 @@
+urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
+?>
+Hello = $user->username ?>,
+
+Follow the link below to reset your password:
+
+= $resetLink ?>
diff --git a/common/models/Battles.php b/common/models/Battles.php
new file mode 100644
index 0000000..cb81855
--- /dev/null
+++ b/common/models/Battles.php
@@ -0,0 +1,63 @@
+ true, 'targetClass' => User::className(), 'targetAttribute' => ['creator_id' => 'id']],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'logs' => 'Logs',
+ 'bid' => 'Bid',
+ 'creator_id' => 'Creator ID',
+ 'date' => 'Date',
+ 'status' => 'Status',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCreator()
+ {
+ return $this->hasOne(User::className(), ['id' => 'creator_id']);
+ }
+}
diff --git a/common/models/Items.php b/common/models/Items.php
new file mode 100644
index 0000000..c3fb4e4
--- /dev/null
+++ b/common/models/Items.php
@@ -0,0 +1,57 @@
+ 50],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'name' => 'Name',
+ 'hp' => 'Hp',
+ 'qnt' => 'Qnt',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getUserItems()
+ {
+ return $this->hasMany(UserItems::className(), ['item_id' => 'id']);
+ }
+}
diff --git a/common/models/LoginForm.php b/common/models/LoginForm.php
new file mode 100755
index 0000000..a4f6c6d
--- /dev/null
+++ b/common/models/LoginForm.php
@@ -0,0 +1,90 @@
+ Yii::t('app', 'username'),
+ 'password' => Yii::t('app', 'password'),
+ 'rememberMe' => Yii::t('app', 'rememberMe'),
+ ];
+ }
+
+ /**
+ * 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 bool 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;
+ }
+}
diff --git a/common/models/Mods.php b/common/models/Mods.php
new file mode 100644
index 0000000..b507c6d
--- /dev/null
+++ b/common/models/Mods.php
@@ -0,0 +1,59 @@
+ true, 'targetClass' => Ship::className(), 'targetAttribute' => ['ship_id' => 'id']],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'ship_id' => 'Ship ID',
+ 'mod_gun' => 'Mod Gun',
+ 'mod_tower' => 'Mod Tower',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getShip()
+ {
+ return $this->hasOne(Ship::className(), ['id' => 'ship_id']);
+ }
+}
diff --git a/common/models/Port.php b/common/models/Port.php
new file mode 100755
index 0000000..e99f8ec
--- /dev/null
+++ b/common/models/Port.php
@@ -0,0 +1,88 @@
+ true, 'targetClass' => \common\models\User::className(), 'targetAttribute' => ['user_id' => 'id']],
+ [['ship_id'], 'exist', 'skipOnError' => true, 'targetClass' => Ship::className(), 'targetAttribute' => ['ship_id' => 'id']],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'user_id' => 'User ID',
+ 'ship_id' => 'Ship ID',
+ 'exp' => 'Exp',
+ 'stock_gun' => 'Stock Gun',
+ 'stock_tower' => 'Stock Tower',
+ 'mod_gun' => 'Mod Gun',
+ 'mod_tower' => 'Mod Tower',
+ 'strength' => 'Strength',
+ 'type' => 'Type',
+ 'exp_gun' => 'Exp Gun',
+ 'exp_tower' => 'Exp Tower',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getUser()
+ {
+ return $this->hasOne(User::className(), ['id' => 'user_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getShip()
+ {
+ return $this->hasOne(Ship::className(), ['id' => 'ship_id']);
+ }
+}
diff --git a/common/models/Ship.php b/common/models/Ship.php
new file mode 100755
index 0000000..8b3ac8f
--- /dev/null
+++ b/common/models/Ship.php
@@ -0,0 +1,68 @@
+ 255],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'name' => 'Name',
+ 'lvl' => 'Lvl',
+ 'stock_gun' => 'Stock Gun',
+ 'stock_tower' => 'Stock Tower',
+ 'mod_gun' => 'Mod Gun',
+ 'mod_tower' => 'Mod Tower',
+ 'strength' => 'Strength',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPorts()
+ {
+ return $this->hasMany(Port::className(), ['ship_id' => 'id']);
+ }
+}
diff --git a/common/models/User.php b/common/models/User.php
new file mode 100755
index 0000000..d756436
--- /dev/null
+++ b/common/models/User.php
@@ -0,0 +1,222 @@
+ 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 bool
+ */
+ 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 bool 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;
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPorts()
+ {
+ return $this->hasMany(Port::className(), ['user_id' => 'id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getBattles()
+ {
+ return $this->hasMany(Battles::className(), ['creator_id' => 'id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getUserItems()
+ {
+ return $this->hasMany(UserItems::className(), ['user_id' => 'id']);
+ }
+}
diff --git a/common/models/UserItems.php b/common/models/UserItems.php
new file mode 100644
index 0000000..aa50c79
--- /dev/null
+++ b/common/models/UserItems.php
@@ -0,0 +1,69 @@
+ true, 'targetClass' => Items::className(), 'targetAttribute' => ['item_id' => 'id']],
+ [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'item_id' => 'Item ID',
+ 'user_id' => 'User ID',
+ 'qnt' => 'Qnt',
+ 'hp' => 'Hp',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getItem()
+ {
+ return $this->hasOne(Items::className(), ['id' => 'item_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getUser()
+ {
+ return $this->hasOne(User::className(), ['id' => 'user_id']);
+ }
+}
diff --git a/common/tests/_bootstrap.php b/common/tests/_bootstrap.php
new file mode 100755
index 0000000..d5a93de
--- /dev/null
+++ b/common/tests/_bootstrap.php
@@ -0,0 +1,9 @@
+ 'bayer.hudson',
+ 'auth_key' => 'HP187Mvq7Mmm3CTU80dLkGmni_FUH_lR',
+ //password_0
+ 'password_hash' => '$2y$13$EjaPFBnZOQsHdGuHI.xvhuDp1fHpo8hKRSk6yshqa9c5EG8s3C3lO',
+ 'password_reset_token' => 'ExzkCOaYc1L8IOBs4wdTGGbgNiG3Wz1I_1402312317',
+ 'created_at' => '1402312317',
+ 'updated_at' => '1402312317',
+ 'email' => 'nicole.paucek@schultz.info',
+ ],
+];
diff --git a/common/tests/_output/.gitignore b/common/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/common/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/common/tests/_support/.gitignore b/common/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/common/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/common/tests/_support/UnitTester.php b/common/tests/_support/UnitTester.php
new file mode 100755
index 0000000..91cb34f
--- /dev/null
+++ b/common/tests/_support/UnitTester.php
@@ -0,0 +1,25 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testLoginNoUser()
+ {
+ $model = new LoginForm([
+ 'username' => 'not_existing_username',
+ 'password' => 'not_existing_password',
+ ]);
+
+ expect('model should not login user', $model->login())->false();
+ expect('user should not be logged in', Yii::$app->user->isGuest)->true();
+ }
+
+ public function testLoginWrongPassword()
+ {
+ $model = new LoginForm([
+ 'username' => 'bayer.hudson',
+ 'password' => 'wrong_password',
+ ]);
+
+ expect('model should not login user', $model->login())->false();
+ expect('error message should be set', $model->errors)->hasKey('password');
+ expect('user should not be logged in', Yii::$app->user->isGuest)->true();
+ }
+
+ public function testLoginCorrect()
+ {
+ $model = new LoginForm([
+ 'username' => 'bayer.hudson',
+ 'password' => 'password_0',
+ ]);
+
+ expect('model should login user', $model->login())->true();
+ expect('error message should not be set', $model->errors)->hasntKey('password');
+ expect('user should be logged in', Yii::$app->user->isGuest)->false();
+ }
+}
diff --git a/common/widgets/Alert.php b/common/widgets/Alert.php
new file mode 100755
index 0000000..69f1c40
--- /dev/null
+++ b/common/widgets/Alert.php
@@ -0,0 +1,75 @@
+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
+ * @author Alexander Makarov
+ */
+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);
+ }
+ }
+ }
+}
diff --git a/composer.json b/composer.json
new file mode 100755
index 0000000..671cdf5
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,44 @@
+{
+ "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": "~2.0.0",
+ "yiisoft/yii2-swiftmailer": "~2.0.0",
+ "facebook/webdriver": "~1.0",
+ "codemix/yii2-localeurls": "^1.4"
+ },
+ "require-dev": {
+ "yiisoft/yii2-debug": "~2.0.0",
+ "yiisoft/yii2-gii": "~2.0.0",
+ "yiisoft/yii2-faker": "~2.0.0",
+
+ "codeception/base": "^2.2.3",
+ "codeception/verify": "~0.3.1"
+ },
+ "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"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100755
index 0000000..f0fe768
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,3138 @@
+{
+ "_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": "b8e446f48301bac06b4039ac394db092",
+ "content-hash": "d33d3619c3997f2e7ca8391a70e23551",
+ "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.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/RobinHerbots/Inputmask.git",
+ "reference": "8a882bc471ba4077c4f8ecbe3d9d61c7558f3ef2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/8a882bc471ba4077c4f8ecbe3d9d61c7558f3ef2",
+ "reference": "8a882bc471ba4077c4f8ecbe3d9d61c7558f3ef2",
+ "shasum": ""
+ },
+ "require": {
+ "bower-asset/jquery": ">=1.7"
+ },
+ "type": "bower-asset-library",
+ "extra": {
+ "bower-asset-main": [
+ "./dist/inputmask/inputmask.dependencyLib",
+ "./dist/inputmask/inputmask",
+ "./dist/inputmask/inputmask.extensions",
+ "./dist/inputmask/inputmask.date.extensions",
+ "./dist/inputmask/inputmask.numeric.extensions",
+ "./dist/inputmask/inputmask.phone.extensions",
+ "./dist/inputmask/inputmask.regex.extensions",
+ "./dist/inputmask/jquery.inputmask"
+ ],
+ "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.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cebe/markdown.git",
+ "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cebe/markdown/zipball/c30eb5e01fe021cc5bba2f9ee0eeef96d4931166",
+ "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166",
+ "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": "2016-09-14 20:40:20"
+ },
+ {
+ "name": "codemix/yii2-localeurls",
+ "version": "1.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/codemix/yii2-localeurls.git",
+ "reference": "785769af625d69430a11ec167b56eef47f933baf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/codemix/yii2-localeurls/zipball/785769af625d69430a11ec167b56eef47f933baf",
+ "reference": "785769af625d69430a11ec167b56eef47f933baf",
+ "shasum": ""
+ },
+ "require": {
+ "yiisoft/yii2": "*"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "codemix\\localeurls\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Härtl",
+ "email": "haertl.mike@gmail.com"
+ }
+ ],
+ "description": "Automatic locale/language management for URLs.",
+ "keywords": [
+ "i18n",
+ "locale",
+ "yii2"
+ ],
+ "time": "2017-02-24 10:38:34"
+ },
+ {
+ "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": "facebook/webdriver",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/facebook/php-webdriver.git",
+ "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/77300c4ab2025d4316635f592ec849ca7323bd8c",
+ "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": "^5.5 || ~7.0",
+ "symfony/process": "^2.8 || ^3.1"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^1.11",
+ "php-mock/php-mock-phpunit": "^1.1",
+ "phpunit/phpunit": "4.6.* || ~5.0",
+ "satooshi/php-coveralls": "^1.0",
+ "squizlabs/php_codesniffer": "^2.6"
+ },
+ "suggest": {
+ "phpdocumentor/phpdocumentor": "2.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Facebook\\WebDriver\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "description": "A PHP client for WebDriver",
+ "homepage": "https://github.com/facebook/php-webdriver",
+ "keywords": [
+ "facebook",
+ "php",
+ "selenium",
+ "webdriver"
+ ],
+ "time": "2017-01-13 15:48:08"
+ },
+ {
+ "name": "swiftmailer/swiftmailer",
+ "version": "v5.4.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/swiftmailer/swiftmailer.git",
+ "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
+ "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9.1",
+ "symfony/phpunit-bridge": "~3.2"
+ },
+ "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": "2017-02-13 07:52:53"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
+ "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Process Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-16 14:07:22"
+ },
+ {
+ "name": "yiisoft/yii2",
+ "version": "2.0.11.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-framework.git",
+ "reference": "ee996adec1dfd7babb67bd0c604f5bd6425fe5ab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/ee996adec1dfd7babb67bd0c604f5bd6425fe5ab",
+ "reference": "ee996adec1dfd7babb67bd0c604f5bd6425fe5ab",
+ "shasum": ""
+ },
+ "require": {
+ "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
+ "bower-asset/jquery.inputmask": "~3.2.2 | ~3.3.3",
+ "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"
+ },
+ {
+ "name": "Boudewijn Vahrmeijer",
+ "email": "info@dynasource.eu",
+ "homepage": "http://dynasource.eu",
+ "role": "Core framework development"
+ }
+ ],
+ "description": "Yii PHP Framework Version 2",
+ "homepage": "http://www.yiiframework.com/",
+ "keywords": [
+ "framework",
+ "yii2"
+ ],
+ "time": "2017-02-08 09:04:32"
+ },
+ {
+ "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.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-composer.git",
+ "reference": "3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2",
+ "reference": "3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "require-dev": {
+ "composer/composer": "^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-12-20 13:26:02"
+ },
+ {
+ "name": "yiisoft/yii2-swiftmailer",
+ "version": "2.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-swiftmailer.git",
+ "reference": "26b900767f1031ff3a4668dfa36c10595875f0a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/26b900767f1031ff3a4668dfa36c10595875f0a5",
+ "reference": "26b900767f1031ff3a4668dfa36c10595875f0a5",
+ "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-09-09 11:48:11"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "behat/gherkin",
+ "version": "v4.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Gherkin.git",
+ "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74",
+ "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.5|~5",
+ "symfony/phpunit-bridge": "~2.7|~3",
+ "symfony/yaml": "~2.3|~3"
+ },
+ "suggest": {
+ "symfony/yaml": "If you want to parse features, represented in YAML files"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Gherkin": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Gherkin DSL parser for PHP 5.3",
+ "homepage": "http://behat.org/",
+ "keywords": [
+ "BDD",
+ "Behat",
+ "Cucumber",
+ "DSL",
+ "gherkin",
+ "parser"
+ ],
+ "time": "2016-10-30 11:50:56"
+ },
+ {
+ "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": "codeception/base",
+ "version": "2.2.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/base.git",
+ "reference": "8d5f54ce583ceaa9627c2441e20bbd4873de50cc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/base/zipball/8d5f54ce583ceaa9627c2441e20bbd4873de50cc",
+ "reference": "8d5f54ce583ceaa9627c2441e20bbd4873de50cc",
+ "shasum": ""
+ },
+ "require": {
+ "behat/gherkin": "~4.4.0",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "guzzlehttp/psr7": "~1.0",
+ "php": ">=5.4.0 <8.0",
+ "phpunit/php-code-coverage": ">=2.2.4 <5.0",
+ "phpunit/phpunit": ">4.8.20 <6.0",
+ "sebastian/comparator": "~1.1",
+ "sebastian/diff": "^1.4",
+ "symfony/browser-kit": ">=2.7 <4.0",
+ "symfony/console": ">=2.7 <4.0",
+ "symfony/css-selector": ">=2.7 <4.0",
+ "symfony/dom-crawler": ">=2.7.5 <4.0",
+ "symfony/event-dispatcher": ">=2.7 <4.0",
+ "symfony/finder": ">=2.7 <4.0",
+ "symfony/yaml": ">=2.7 <4.0"
+ },
+ "require-dev": {
+ "codeception/specify": "~0.3",
+ "facebook/graph-sdk": "~5.3",
+ "flow/jsonpath": "~0.2",
+ "league/factory-muffin": "^3.0",
+ "league/factory-muffin-faker": "^1.0",
+ "mongodb/mongodb": "^1.0",
+ "monolog/monolog": "~1.8",
+ "pda/pheanstalk": "~3.0",
+ "php-amqplib/php-amqplib": "~2.4",
+ "predis/predis": "^1.0",
+ "squizlabs/php_codesniffer": "~2.0",
+ "vlucas/phpdotenv": "^2.4.0"
+ },
+ "suggest": {
+ "codeception/specify": "BDD-style code blocks",
+ "codeception/verify": "BDD-style assertions",
+ "flow/jsonpath": "For using JSONPath in REST module",
+ "league/factory-muffin": "For DataFactory module",
+ "league/factory-muffin-faker": "For Faker support in DataFactory module",
+ "phpseclib/phpseclib": "for SFTP option in FTP Module",
+ "symfony/phpunit-bridge": "For phpunit-bridge support"
+ },
+ "bin": [
+ "codecept"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": []
+ },
+ "autoload": {
+ "psr-4": {
+ "Codeception\\": "src\\Codeception",
+ "Codeception\\Extension\\": "ext"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert@mail.ua",
+ "homepage": "http://codegyre.com"
+ }
+ ],
+ "description": "BDD-style testing framework",
+ "homepage": "http://codeception.com/",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "acceptance testing",
+ "functional testing",
+ "unit testing"
+ ],
+ "time": "2017-02-04 02:16:42"
+ },
+ {
+ "name": "codeception/verify",
+ "version": "0.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Verify.git",
+ "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Verify/zipball/5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
+ "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/Codeception/function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert.php@mailican.com"
+ }
+ ],
+ "description": "BDD assertion library for PHPUnit",
+ "time": "2017-01-09 10:58:51"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3,<8.0-DEV"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2015-06-14 21:17:01"
+ },
+ {
+ "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": "guzzlehttp/psr7",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/0d6c7ca039329247e4f0f8f8f6506810e8248855",
+ "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-02-27 10:51:17"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+ "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "doctrine/collections": "1.*",
+ "phpunit/phpunit": "~4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "homepage": "https://github.com/myclabs/DeepCopy",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2017-01-26 22:05:40"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2015-12-27 11:43:31"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0@dev",
+ "phpdocumentor/type-resolver": "^0.2.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^4.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2016-09-30 07:12:33"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "time": "2016-11-25 06:54:22"
+ },
+ {
+ "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": "phpspec/prophecy",
+ "version": "v1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+ "sebastian/comparator": "^1.1|^2.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8 || ^5.6.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.6.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2017-03-02 20:05:34"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "4.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "09e2277d14ea467e5a984010f501343ef29ffc69"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69",
+ "reference": "09e2277d14ea467e5a984010f501343ef29ffc69",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-file-iterator": "^1.3",
+ "phpunit/php-text-template": "^1.2",
+ "phpunit/php-token-stream": "^1.4.2 || ^2.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/environment": "^1.3.2 || ^2.0",
+ "sebastian/version": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": "^2.1.4",
+ "phpunit/phpunit": "^5.7"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2017-03-01 09:12:17"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2016-10-03 07:40:28"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21 13:50:34"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2017-02-26 11:10:40"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.4.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2017-02-27 10:12:30"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "5.7.15",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "b99112aecc01f62acf3d81a3f59646700a1849e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b99112aecc01f62acf3d81a3f59646700a1849e5",
+ "reference": "b99112aecc01f62acf3d81a3f59646700a1849e5",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "~1.3",
+ "php": "^5.6 || ^7.0",
+ "phpspec/prophecy": "^1.6.2",
+ "phpunit/php-code-coverage": "^4.0.4",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^3.2",
+ "sebastian/comparator": "^1.2.4",
+ "sebastian/diff": "~1.2",
+ "sebastian/environment": "^1.3.4 || ^2.0",
+ "sebastian/exporter": "~2.0",
+ "sebastian/global-state": "^1.1",
+ "sebastian/object-enumerator": "~2.0",
+ "sebastian/resource-operations": "~1.0",
+ "sebastian/version": "~1.0.3|~2.0",
+ "symfony/yaml": "~2.1|~3.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.7.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2017-03-02 15:22:43"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "3.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
+ "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/exporter": "^1.2 || ^2.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2016-12-08 20:27:08"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06 14:39:51"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2016-10-10 12:19:37"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2017-03-04 06:30:41"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2 || ~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2017-01-29 09:50:25"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2015-12-08 07:14:41"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2016-11-26 07:53:53"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2016-11-19 08:54:04"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2015-10-12 03:26:01"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2017-02-18 15:18:39"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2016-11-19 07:33:16"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2015-07-28 20:34:47"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2016-10-03 07:35:21"
+ },
+ {
+ "name": "symfony/browser-kit",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "394a2475a3a89089353fde5714a7f402fbb83880"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/394a2475a3a89089353fde5714a7f402fbb83880",
+ "reference": "394a2475a3a89089353fde5714a7f402fbb83880",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/dom-crawler": "~2.8|~3.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\BrowserKit\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony BrowserKit Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-01-31 21:49:23"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
+ "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/debug": "~2.8|~3.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/filesystem": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/filesystem": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-16 14:07:22"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
+ "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony CssSelector Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-01-02 20:32:22"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
+ "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ },
+ "require-dev": {
+ "symfony/class-loader": "~2.8|~3.0",
+ "symfony/http-kernel": "~2.8|~3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Debug Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-16 16:34:18"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "b814b41373fc4e535aff8c765abe39545216f391"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b814b41373fc4e535aff8c765abe39545216f391",
+ "reference": "b814b41373fc4e535aff8c765abe39545216f391",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/css-selector": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony DomCrawler Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-01-21 17:14:11"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6",
+ "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~2.8|~3.0",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-01-02 20:32:22"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "8c71141cae8e2957946b403cc71a67213c0380d6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6",
+ "reference": "8c71141cae8e2957946b403cc71a67213c0380d6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Finder Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-01-02 20:32:22"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2016-11-14 01:06:16"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
+ "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "symfony/console": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-16 22:46:52"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
+ "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2016-11-23 20:04:58"
+ },
+ {
+ "name": "yiisoft/yii2-debug",
+ "version": "2.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-debug.git",
+ "reference": "647be6c9d48dc2f3c2e2f33b9eba0a4ca78abde9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/647be6c9d48dc2f3c2e2f33b9eba0a4ca78abde9",
+ "reference": "647be6c9d48dc2f3c2e2f33b9eba0a4ca78abde9",
+ "shasum": ""
+ },
+ "require": {
+ "yiisoft/yii2": "~2.0.11",
+ "yiisoft/yii2-bootstrap": "~2.0.0"
+ },
+ "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": "2017-02-21 10:30:50"
+ },
+ {
+ "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": []
+}
diff --git a/console/config/.gitignore b/console/config/.gitignore
new file mode 100755
index 0000000..20da318
--- /dev/null
+++ b/console/config/.gitignore
@@ -0,0 +1,2 @@
+main-local.php
+params-local.php
\ No newline at end of file
diff --git a/console/config/bootstrap.php b/console/config/bootstrap.php
new file mode 100755
index 0000000..b3d9bbc
--- /dev/null
+++ b/console/config/bootstrap.php
@@ -0,0 +1 @@
+ 'app-console',
+ 'basePath' => dirname(__DIR__),
+ 'bootstrap' => ['log'],
+ 'controllerNamespace' => 'console\controllers',
+ 'controllerMap' => [
+ 'fixture' => [
+ 'class' => 'yii\console\controllers\FixtureController',
+ 'namespace' => 'common\fixtures',
+ ],
+ ],
+ 'components' => [
+ 'log' => [
+ 'targets' => [
+ [
+ 'class' => 'yii\log\FileTarget',
+ 'levels' => ['error', 'warning'],
+ ],
+ ],
+ ],
+ ],
+ 'params' => $params,
+];
diff --git a/console/config/params.php b/console/config/params.php
new file mode 100755
index 0000000..7f754b9
--- /dev/null
+++ b/console/config/params.php
@@ -0,0 +1,4 @@
+ 'admin@example.com',
+];
diff --git a/console/controllers/.gitkeep b/console/controllers/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/console/migrations/m130524_201442_init.php b/console/migrations/m130524_201442_init.php
new file mode 100755
index 0000000..6b649f4
--- /dev/null
+++ b/console/migrations/m130524_201442_init.php
@@ -0,0 +1,33 @@
+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}}');
+ }
+}
diff --git a/console/migrations/m170225_203605_add_win_column_to_user_table.php b/console/migrations/m170225_203605_add_win_column_to_user_table.php
new file mode 100755
index 0000000..0c44f98
--- /dev/null
+++ b/console/migrations/m170225_203605_add_win_column_to_user_table.php
@@ -0,0 +1,25 @@
+addColumn('user', 'win', $this->integer(5)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('user', 'win');
+ }
+}
diff --git a/console/migrations/m170225_203634_add_lose_column_to_user_table.php b/console/migrations/m170225_203634_add_lose_column_to_user_table.php
new file mode 100755
index 0000000..1f36ec1
--- /dev/null
+++ b/console/migrations/m170225_203634_add_lose_column_to_user_table.php
@@ -0,0 +1,25 @@
+addColumn('user', 'lose', $this->integer(5)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('user', 'lose');
+ }
+}
diff --git a/console/migrations/m170225_203656_add_draw_column_to_user_table.php b/console/migrations/m170225_203656_add_draw_column_to_user_table.php
new file mode 100755
index 0000000..61dbfbf
--- /dev/null
+++ b/console/migrations/m170225_203656_add_draw_column_to_user_table.php
@@ -0,0 +1,25 @@
+addColumn('user', 'draw', $this->integer(5)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('user', 'draw');
+ }
+}
diff --git a/console/migrations/m170225_204626_add_credits_column_to_user_table.php b/console/migrations/m170225_204626_add_credits_column_to_user_table.php
new file mode 100755
index 0000000..c863b08
--- /dev/null
+++ b/console/migrations/m170225_204626_add_credits_column_to_user_table.php
@@ -0,0 +1,25 @@
+addColumn('user', 'credits', $this->integer(5)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('user', 'credits');
+ }
+}
diff --git a/console/migrations/m170317_132201_create_ship_table.php b/console/migrations/m170317_132201_create_ship_table.php
new file mode 100755
index 0000000..803aa52
--- /dev/null
+++ b/console/migrations/m170317_132201_create_ship_table.php
@@ -0,0 +1,34 @@
+createTable('ship', [
+ 'id' => $this->primaryKey(),
+ 'name' => $this->string(255)->notNull(),
+ 'lvl' => $this->integer(5)->notNull(),
+ 'stock_gun' => $this->integer(1)->notNull(),
+ 'stock_tower' => $this->integer(1)->notNull(),
+ 'mod_gun' => $this->integer(1)->notNull(),
+ 'mod_tower' => $this->integer(1)->notNull(),
+ 'strength' => $this->integer(10)->notNull(),
+ ]);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropTable('ship');
+ }
+}
diff --git a/console/migrations/m170317_132341_create_port_table.php b/console/migrations/m170317_132341_create_port_table.php
new file mode 100755
index 0000000..81f3cba
--- /dev/null
+++ b/console/migrations/m170317_132341_create_port_table.php
@@ -0,0 +1,97 @@
+createTable('port', [
+ 'id' => $this->primaryKey(),
+ 'user_id' => $this->integer(10)->notNull(),
+ 'ship_id' => $this->integer(5)->notNull(),
+ 'exp' => $this->integer(5)->notNull(),
+ 'stock_gun' => $this->integer(1)->notNull(),
+ 'stock_tower' => $this->integer(1)->notNull(),
+ 'mod_gun' => $this->integer(1)->notNull(),
+ 'mod_tower' => $this->integer(1)->notNull(),
+ 'strength' => $this->integer(10)->notNull(),
+ ]);
+
+ // creates index for column `user_id`
+ $this->createIndex(
+ 'idx-port-user_id',
+ 'port',
+ 'user_id'
+ );
+
+ // add foreign key for table `user`
+ $this->addForeignKey(
+ 'fk-port-user_id',
+ 'port',
+ 'user_id',
+ 'user',
+ 'id',
+ 'CASCADE'
+ );
+
+ // creates index for column `ship_id`
+ $this->createIndex(
+ 'idx-port-ship_id',
+ 'port',
+ 'ship_id'
+ );
+
+ // add foreign key for table `ship`
+ $this->addForeignKey(
+ 'fk-port-ship_id',
+ 'port',
+ 'ship_id',
+ 'ship',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ // drops foreign key for table `user`
+ $this->dropForeignKey(
+ 'fk-port-user_id',
+ 'port'
+ );
+
+ // drops index for column `user_id`
+ $this->dropIndex(
+ 'idx-port-user_id',
+ 'port'
+ );
+
+ // drops foreign key for table `ship`
+ $this->dropForeignKey(
+ 'fk-port-ship_id',
+ 'port'
+ );
+
+ // drops index for column `ship_id`
+ $this->dropIndex(
+ 'idx-port-ship_id',
+ 'port'
+ );
+
+ $this->dropTable('port');
+ }
+}
diff --git a/console/migrations/m170317_141028_add_type_column_to_ship_table.php b/console/migrations/m170317_141028_add_type_column_to_ship_table.php
new file mode 100755
index 0000000..1519191
--- /dev/null
+++ b/console/migrations/m170317_141028_add_type_column_to_ship_table.php
@@ -0,0 +1,25 @@
+addColumn('ship', 'type', $this->integer(2)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('ship', 'type');
+ }
+}
diff --git a/console/migrations/m170317_141121_add_type_column_to_port_table.php b/console/migrations/m170317_141121_add_type_column_to_port_table.php
new file mode 100755
index 0000000..eb739e5
--- /dev/null
+++ b/console/migrations/m170317_141121_add_type_column_to_port_table.php
@@ -0,0 +1,25 @@
+addColumn('port', 'type', $this->integer(2)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('port', 'type');
+ }
+}
diff --git a/console/migrations/m170321_105310_create_mods_table.php b/console/migrations/m170321_105310_create_mods_table.php
new file mode 100644
index 0000000..b4c76a9
--- /dev/null
+++ b/console/migrations/m170321_105310_create_mods_table.php
@@ -0,0 +1,62 @@
+createTable('mods', [
+ 'id' => $this->primaryKey(),
+ 'ship_id' => $this->integer(5)->notNull(),
+ 'mod_gun' => $this->integer(1),
+ 'mod_tower' => $this->integer(1),
+ ]);
+
+ // creates index for column `ship_id`
+ $this->createIndex(
+ 'idx-mods-ship_id',
+ 'mods',
+ 'ship_id'
+ );
+
+ // add foreign key for table `ship`
+ $this->addForeignKey(
+ 'fk-mods-ship_id',
+ 'mods',
+ 'ship_id',
+ 'ship',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ // drops foreign key for table `ship`
+ $this->dropForeignKey(
+ 'fk-mods-ship_id',
+ 'mods'
+ );
+
+ // drops index for column `ship_id`
+ $this->dropIndex(
+ 'idx-mods-ship_id',
+ 'mods'
+ );
+
+ $this->dropTable('mods');
+ }
+}
diff --git a/console/migrations/m170321_122136_add_exp_gun_column_to_port_table.php b/console/migrations/m170321_122136_add_exp_gun_column_to_port_table.php
new file mode 100644
index 0000000..c180f3e
--- /dev/null
+++ b/console/migrations/m170321_122136_add_exp_gun_column_to_port_table.php
@@ -0,0 +1,25 @@
+addColumn('port', 'exp_gun', $this->integer(1)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('port', 'exp_gun');
+ }
+}
diff --git a/console/migrations/m170321_122225_add_exp_tower_column_to_port_table.php b/console/migrations/m170321_122225_add_exp_tower_column_to_port_table.php
new file mode 100644
index 0000000..f73ffd3
--- /dev/null
+++ b/console/migrations/m170321_122225_add_exp_tower_column_to_port_table.php
@@ -0,0 +1,25 @@
+addColumn('port', 'exp_tower', $this->integer(1)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('port', 'exp_tower');
+ }
+}
diff --git a/console/migrations/m170321_135228_create_mods_table.php b/console/migrations/m170321_135228_create_mods_table.php
new file mode 100644
index 0000000..2a147f5
--- /dev/null
+++ b/console/migrations/m170321_135228_create_mods_table.php
@@ -0,0 +1,66 @@
+createTable('mods', [
+ 'id' => $this->primaryKey(),
+ 'ship_id' => $this->integer(5)->notNull(),
+ 'mod_gun' => $this->integer(1)->notNull(),
+ 'mod_tower' => $this->integer(1)->notNull(),
+ 'exp_gun' => $this->integer(5)->notNull(),
+ 'exp_tower' => $this->integer(5)->notNull(),
+ 'cost_gun' => $this->integer(5)->notNull(),
+ 'cost_tower' => $this->integer(5)->notNull(),
+ ]);
+
+ // creates index for column `ship_id`
+ $this->createIndex(
+ 'idx-mods-ship_id',
+ 'mods',
+ 'ship_id'
+ );
+
+ // add foreign key for table `ship`
+ $this->addForeignKey(
+ 'fk-mods-ship_id',
+ 'mods',
+ 'ship_id',
+ 'ship',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ // drops foreign key for table `ship`
+ $this->dropForeignKey(
+ 'fk-mods-ship_id',
+ 'mods'
+ );
+
+ // drops index for column `ship_id`
+ $this->dropIndex(
+ 'idx-mods-ship_id',
+ 'mods'
+ );
+
+ $this->dropTable('mods');
+ }
+}
diff --git a/console/migrations/m170329_081414_add_battle_id_column_to_user_table.php b/console/migrations/m170329_081414_add_battle_id_column_to_user_table.php
new file mode 100644
index 0000000..c3dbb8f
--- /dev/null
+++ b/console/migrations/m170329_081414_add_battle_id_column_to_user_table.php
@@ -0,0 +1,25 @@
+addColumn('user', 'battle_id', $this->integer(10)->notNull());
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ $this->dropColumn('user', 'battle_id');
+ }
+}
diff --git a/console/migrations/m170408_110257_create_battles_table.php b/console/migrations/m170408_110257_create_battles_table.php
new file mode 100644
index 0000000..2d3bb48
--- /dev/null
+++ b/console/migrations/m170408_110257_create_battles_table.php
@@ -0,0 +1,64 @@
+createTable('battles', [
+ 'id' => $this->primaryKey(),
+ 'logs' => $this->text(),
+ 'bid' => $this->integer(10)->notNull(),
+ 'creator_id' => $this->integer(10)->notNull(),
+ 'date' => $this->dateTime(),
+ 'status' => $this->integer(1)->notNull(),
+ ]);
+
+ // creates index for column `creator_id`
+ $this->createIndex(
+ 'idx-battles-creator_id',
+ 'battles',
+ 'creator_id'
+ );
+
+ // add foreign key for table `user`
+ $this->addForeignKey(
+ 'fk-battles-creator_id',
+ 'battles',
+ 'creator_id',
+ 'user',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function down()
+ {
+ // drops foreign key for table `user`
+ $this->dropForeignKey(
+ 'fk-battles-creator_id',
+ 'battles'
+ );
+
+ // drops index for column `creator_id`
+ $this->dropIndex(
+ 'idx-battles-creator_id',
+ 'battles'
+ );
+
+ $this->dropTable('battles');
+ }
+}
diff --git a/console/models/.gitkeep b/console/models/.gitkeep
new file mode 100755
index 0000000..72e8ffc
--- /dev/null
+++ b/console/models/.gitkeep
@@ -0,0 +1 @@
+*
diff --git a/console/runtime/.gitignore b/console/runtime/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/console/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/environments/dev/backend/config/main-local.php b/environments/dev/backend/config/main-local.php
new file mode 100755
index 0000000..d9a8ceb
--- /dev/null
+++ b/environments/dev/backend/config/main-local.php
@@ -0,0 +1,25 @@
+ [
+ '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;
diff --git a/environments/dev/backend/config/params-local.php b/environments/dev/backend/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/dev/backend/config/params-local.php
@@ -0,0 +1,3 @@
+run();
diff --git a/environments/dev/backend/web/index.php b/environments/dev/backend/web/index.php
new file mode 100755
index 0000000..1d75140
--- /dev/null
+++ b/environments/dev/backend/web/index.php
@@ -0,0 +1,17 @@
+run();
diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php
new file mode 100755
index 0000000..43db30e
--- /dev/null
+++ b/environments/dev/common/config/main-local.php
@@ -0,0 +1,20 @@
+ [
+ '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,
+ ],
+ ],
+];
diff --git a/environments/dev/common/config/params-local.php b/environments/dev/common/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/dev/common/config/params-local.php
@@ -0,0 +1,3 @@
+ [
+ 'db' => [
+ 'dsn' => 'mysql:host=localhost;dbname=yii2advanced_test',
+ ]
+ ],
+ ]
+);
diff --git a/environments/dev/console/config/main-local.php b/environments/dev/console/config/main-local.php
new file mode 100755
index 0000000..1d2118f
--- /dev/null
+++ b/environments/dev/console/config/main-local.php
@@ -0,0 +1,7 @@
+ ['gii'],
+ 'modules' => [
+ 'gii' => 'yii\gii\Module',
+ ],
+];
diff --git a/environments/dev/console/config/params-local.php b/environments/dev/console/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/dev/console/config/params-local.php
@@ -0,0 +1,3 @@
+ [
+ '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;
diff --git a/environments/dev/frontend/config/params-local.php b/environments/dev/frontend/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/dev/frontend/config/params-local.php
@@ -0,0 +1,3 @@
+run();
diff --git a/environments/dev/frontend/web/index.php b/environments/dev/frontend/web/index.php
new file mode 100755
index 0000000..1d75140
--- /dev/null
+++ b/environments/dev/frontend/web/index.php
@@ -0,0 +1,17 @@
+run();
diff --git a/environments/dev/yii b/environments/dev/yii
new file mode 100755
index 0000000..6f0c6d2
--- /dev/null
+++ b/environments/dev/yii
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/environments/dev/yii_test b/environments/dev/yii_test
new file mode 100755
index 0000000..880050e
--- /dev/null
+++ b/environments/dev/yii_test
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/environments/dev/yii_test.bat b/environments/dev/yii_test.bat
new file mode 100755
index 0000000..854e08b
--- /dev/null
+++ b/environments/dev/yii_test.bat
@@ -0,0 +1,20 @@
+@echo off
+
+rem -------------------------------------------------------------
+rem Yii command line bootstrap script for Windows.
+rem
+rem @author Qiang Xue
+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%yii_test" %*
+
+@endlocal
diff --git a/environments/index.php b/environments/index.php
new file mode 100755
index 0000000..5c3cca3
--- /dev/null
+++ b/environments/index.php
@@ -0,0 +1,65 @@
+ [
+ * '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',
+ 'yii_test',
+ ],
+ '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',
+ ],
+ ],
+];
diff --git a/environments/prod/backend/config/main-local.php b/environments/prod/backend/config/main-local.php
new file mode 100755
index 0000000..af46ba3
--- /dev/null
+++ b/environments/prod/backend/config/main-local.php
@@ -0,0 +1,9 @@
+ [
+ 'request' => [
+ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
+ 'cookieValidationKey' => '',
+ ],
+ ],
+];
diff --git a/environments/prod/backend/config/params-local.php b/environments/prod/backend/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/prod/backend/config/params-local.php
@@ -0,0 +1,3 @@
+run();
diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php
new file mode 100755
index 0000000..84c4d9f
--- /dev/null
+++ b/environments/prod/common/config/main-local.php
@@ -0,0 +1,16 @@
+ [
+ 'db' => [
+ 'class' => 'yii\db\Connection',
+ 'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
+ 'username' => 'root',
+ 'password' => '',
+ 'charset' => 'utf8',
+ ],
+ 'mailer' => [
+ 'class' => 'yii\swiftmailer\Mailer',
+ 'viewPath' => '@common/mail',
+ ],
+ ],
+];
diff --git a/environments/prod/common/config/params-local.php b/environments/prod/common/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/prod/common/config/params-local.php
@@ -0,0 +1,3 @@
+ [
+ 'request' => [
+ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
+ 'cookieValidationKey' => '',
+ ],
+ ],
+];
diff --git a/environments/prod/frontend/config/params-local.php b/environments/prod/frontend/config/params-local.php
new file mode 100755
index 0000000..d0b9c34
--- /dev/null
+++ b/environments/prod/frontend/config/params-local.php
@@ -0,0 +1,3 @@
+run();
diff --git a/environments/prod/yii b/environments/prod/yii
new file mode 100755
index 0000000..1fe0342
--- /dev/null
+++ b/environments/prod/yii
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/frontend/assets/AppAsset.php b/frontend/assets/AppAsset.php
new file mode 100755
index 0000000..3a8bb96
--- /dev/null
+++ b/frontend/assets/AppAsset.php
@@ -0,0 +1,23 @@
+ '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',
+ ],
+ 'i18n' => [
+ 'translations' => [
+ 'app*' => [
+ 'class' => 'yii\i18n\PhpMessageSource',
+ 'basePath' => '@app/messages',
+ // 'sourceLanguage' => 'en-US',
+ 'fileMap' => [
+ 'app' => 'app.php',
+ 'app/error' => 'error.php',
+ ],
+ ],
+ ],
+ ],
+
+ 'urlManager' => [
+ 'class' => 'codemix\localeurls\UrlManager',
+ 'languages' => ['ru', 'en'],
+ 'enableDefaultLanguageUrlCode' => true,
+ 'enablePrettyUrl' => true,
+ 'showScriptName' => false,
+ 'enableStrictParsing' => false,
+ 'rules' => [
+ ],
+ ],
+
+ ],
+ 'params' => $params,
+];
diff --git a/frontend/config/params.php b/frontend/config/params.php
new file mode 100755
index 0000000..7f754b9
--- /dev/null
+++ b/frontend/config/params.php
@@ -0,0 +1,4 @@
+ 'admin@example.com',
+];
diff --git a/frontend/config/test.php b/frontend/config/test.php
new file mode 100755
index 0000000..775aa98
--- /dev/null
+++ b/frontend/config/test.php
@@ -0,0 +1,9 @@
+ 'app-frontend-tests',
+ 'components' => [
+ 'assetManager' => [
+ 'basePath' => __DIR__ . '/../web/assets',
+ ],
+ ],
+];
diff --git a/frontend/controllers/CombatController.php b/frontend/controllers/CombatController.php
new file mode 100755
index 0000000..b95f7b3
--- /dev/null
+++ b/frontend/controllers/CombatController.php
@@ -0,0 +1,81 @@
+user->isGuest) {
+ /**
+ * Run sessions.
+ */
+ $session = Yii::$app->session;
+ $session->open();
+ $user = User::findOne(['id' => Yii::$app->user->id]);
+ $usership = Port::findOne(['user_id' => Yii::$app->user->id]);
+ /**
+ * Checking user ship in port.
+ */
+ if(isset($usership)) {
+
+ $user_items = UserItems::findOne(['user_id' => $user->id]);
+ $shipname = Ship::findOne(['id' => $usership->ship_id]);
+ $battle_log = Battles::findOne(['bid' => $session['battle_id']]);
+
+ if (!isset($session['usershiphp']) && !isset($session['bothp'])) {
+ $session['usershiphp'] = $usership->strength;
+ $session['bothp'] = $usership->strength;
+ }
+ if(Yii::$app->request->post('Attack')) {
+ if(Yii::$app->request->post('shot')) {
+ $shottype = Yii::$app->request->post('shot');
+ Yii::$app->Combat->combat($shottype, $usership, $user, $session['battle_id'], $battle_log);
+
+ }
+ }
+
+ //Yii::$app->Combat->fight($user->id);
+
+ return $this->render('index', [
+ 'session' => $session,
+ 'usership' => $usership,
+ 'shipname' => $shipname,
+ 'user_items' => $user_items,
+ 'user' => $user,
+ 'battle_log' => $battle_log,
+ ]);
+ } else {
+ return $this->redirect('site/index');
+ }
+ } else {
+ return $this->redirect('site/login');
+ }
+ }
+
+ /**
+ * Redirect to win page.
+ * @return string
+ */
+ public function actionWin()
+ {
+ return $this->render('win');
+ }
+
+ /**
+ * Redirect to lose page.
+ * @return string
+ */
+ public function actionLose()
+ {
+ return $this->render('lose');
+ }
+}
diff --git a/frontend/controllers/DockController.php b/frontend/controllers/DockController.php
new file mode 100644
index 0000000..080a849
--- /dev/null
+++ b/frontend/controllers/DockController.php
@@ -0,0 +1,26 @@
+ Yii::$app->user->id]);
+ $userships = Port::find()
+ ->joinWith('user', 'ship')
+ ->andWhere(['user_id' => $player->id])
+ ->all();
+
+ return $this->render('index', [
+ 'userships' => $userships,
+ 'player' => $player,
+ ]);
+ }
+
+}
diff --git a/frontend/controllers/ListController.php b/frontend/controllers/ListController.php
new file mode 100644
index 0000000..10ede41
--- /dev/null
+++ b/frontend/controllers/ListController.php
@@ -0,0 +1,45 @@
+session;
+ $session->open();
+ $session['battle_id'] = date('dmhs');
+ $user = User::findOne(['id' => Yii::$app->user->id]);
+
+ /**
+ * Checking the battle's params.
+ * Redirect to the combat page.
+ */
+ if(Yii::$app->request->post('start')) {
+ $bid = new Battles();
+ $bid->bid = $session['battle_id'];
+ $bid->creator_id = $user->id;
+ $bid->status = 0;
+ $bid->date = date('d.m.Y');
+ $bid->save();
+
+ $user->updateAll(['battle_id' => $session['battle_id']], ['id' => $user->id]);
+ $this->redirect(Yii::$app->homeUrl.'/combat');
+ }
+ return $this->render('index', [
+ 'user' => $user,
+ ]);
+ }
+
+}
diff --git a/frontend/controllers/LogsController.php b/frontend/controllers/LogsController.php
new file mode 100644
index 0000000..4d4e49e
--- /dev/null
+++ b/frontend/controllers/LogsController.php
@@ -0,0 +1,19 @@
+ 1])->all();
+
+ return $this->render('index', [
+ 'models' => $models,
+ ]);
+ }
+
+}
diff --git a/frontend/controllers/ShopController.php b/frontend/controllers/ShopController.php
new file mode 100644
index 0000000..6f2722b
--- /dev/null
+++ b/frontend/controllers/ShopController.php
@@ -0,0 +1,27 @@
+ [
+ 'pageSize' => 20,
+ ],
+ 'query' => Ship::find()
+ ->orderBy('lvl DESC')
+ ->limit(20)
+ ]);
+
+ return $this->render('index', [
+ 'shopProvider' => $shopProvider,
+ ]);
+ }
+
+}
diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php
new file mode 100755
index 0000000..1b64335
--- /dev/null
+++ b/frontend/controllers/SiteController.php
@@ -0,0 +1,300 @@
+ [
+ 'class' => AccessControl::className(),
+ 'only' => ['login', 'signup', 'error', 'logout', 'index', 'combat', 'contact', 'about' ],
+ 'rules' => [
+ [
+ 'actions' => ['login', 'signup', 'error'],
+ 'allow' => true,
+ 'roles' => ['?'],
+ ],
+ [
+ 'actions' => ['logout', 'index', 'combat', 'error', 'contact', 'about'],
+ '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()
+ {
+ if(!Yii::$app->user->isGuest) {
+ $user = User::findOne(Yii::$app->user->getId());
+
+ //
+ if(Yii::$app->request->post('shipfirst')) {
+ $newship = new Port();
+
+ $newship->user_id = Yii::$app->user->id;
+ $newship->ship_id = 2;
+ $newship->exp = 0;
+ $newship->stock_gun = 1;
+ $newship->stock_tower = 1;
+ $newship->mod_gun = 0;
+ $newship->mod_tower = 0;
+ $newship->strength = 1600;
+ $newship->type = 2;
+
+ $newship->save();
+
+ return $this->goHome();
+ } elseif(Yii::$app->request->post('shipsecond')) {
+ $newship = new Port();
+
+ $newship->user_id = Yii::$app->user->id;
+ $newship->ship_id = 4;
+ $newship->exp = 0;
+ $newship->stock_gun = 1;
+ $newship->stock_tower = 1;
+ $newship->mod_gun = 0;
+ $newship->mod_tower = 0;
+ $newship->strength = 1600;
+ $newship->type = 3;
+
+ $newship->save();
+
+ return $this->goHome();
+ }
+
+ $model = Port::findOne(['user_id' => Yii::$app->user->id]);
+ if($model) {
+ $shipname = Ship::findOne(['id' => $model->ship_id]);
+
+ $avaible_mods = Mods::findOne(['ship_id' => $model->ship_id]);
+
+
+ if(Yii::$app->request->post('expmodgun')) {
+ $model->updateCounters(['exp' => -($avaible_mods->exp_gun)]);
+ $model->updateCounters(['exp_gun' => 1]);
+
+ $this->goHome();
+ }
+ if(Yii::$app->request->post('expmodtower')) {
+ $model->updateCounters(['exp' => -($avaible_mods->exp_tower)]);
+ $model->updateCounters(['exp_tower' => 1]);
+
+ $this->goHome();
+ }
+
+ if(Yii::$app->request->post('buymodgun')) {
+ if(($user->credits) >= ($avaible_mods->cost_gun)) {
+ $user->updateCounters(['credits' => -($avaible_mods->cost_gun)]);
+ $model->updateCounters(['mod_gun' => 1]);
+ $model->updateCounters(['stock_gun' => -1]);
+
+ $this->goHome();
+ }
+ }
+ if(Yii::$app->request->post('buymodtower')) {
+ if(($user->credits) >= ($avaible_mods->cost_tower)) {
+ $user->updateCounters(['credits' => -($avaible_mods->cost_tower)]);
+ $model->updateCounters(['mod_tower' => 1]);
+ $model->updateCounters(['stock_tower' => -1]);
+ $model->updateCounters(['strength' => +500]);
+
+ $this->goHome();
+ }
+ }
+
+
+ return $this->render('main', [
+ 'model' => $model,
+ 'shipname' => $shipname,
+ 'user' => $user,
+ 'avaible_mods' => $avaible_mods,
+ ]);
+ } else {
+ return $this->render('main', [
+ 'user' => $user,
+ ]);
+ }
+ } else {
+ return $this->redirect('site/login');
+ }
+ }
+
+ /**
+ * 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 your message.');
+ }
+
+ return $this->refresh();
+ } else {
+ return $this->render('contact', [
+ 'model' => $model,
+ ]);
+ }
+ }
+
+ /**
+ * 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 the provided email address.');
+ }
+ }
+
+ 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 saved.');
+
+ return $this->goHome();
+ }
+
+ return $this->render('resetPassword', [
+ 'model' => $model,
+ ]);
+ }
+}
diff --git a/frontend/controllers/ToprankController.php b/frontend/controllers/ToprankController.php
new file mode 100644
index 0000000..20a0035
--- /dev/null
+++ b/frontend/controllers/ToprankController.php
@@ -0,0 +1,22 @@
+joinWith('user', 'ship')
+ ->orderBy('user.win')
+ ->all();
+
+ return $this->render('index', [
+ 'userships' => $userships,
+ ]);
+
+ }
+}
diff --git a/frontend/messages/ru/app.php b/frontend/messages/ru/app.php
new file mode 100755
index 0000000..b997a26
--- /dev/null
+++ b/frontend/messages/ru/app.php
@@ -0,0 +1,190 @@
+Battle Ships' => 'Морской Бой',
+ 'Home' => 'Главная',
+ 'Combat' => 'В бой',
+ 'Logout' => 'Выйти',
+ 'Login' => 'Авторизация',
+ 'Signup' => 'Регистрация',
+ 'Toprank' => 'Топ-игроки',
+ 'Hello' => 'Здравствуй',
+ 'Battle of WarShips!' => 'Битва Кораблей!',
+ 'Here is your Port of Battle Ships!' => 'Это Ваш порт!',
+ 'Strength' => 'Прочность',
+ 'Experience' => 'Опыт',
+ 'Credits' => 'Кредиты',
+ 'Statistics' => 'Статистика',
+ 'WIN' => 'Побед',
+ 'LOSE' => 'Поражений',
+ 'DRAW' => 'Ничьих',
+ 'Stock Gun' => 'Стоковое Орудие',
+ 'Modificate Gun' => 'Улучшеное Орудие',
+ 'Stock Tower' => 'Стоковый корпус корабля',
+ 'Modificate Tower' => 'Улучшеный корпус корабля',
+ 'Please, chose your first Warship' => 'Пожалуйста, выберите Ваш новый корабль',
+ 'getShip' => 'Выбрать боевой корабль',
+ 'Available Mods' => 'Доступные моды',
+ 'Improved Hit Points(HP)' => 'Улучшеный корпус корабля',
+ 'Modified Main Battery' => 'Модифицирован Главный-Калибр',
+ 'Explore' => 'Исследовать',
+ 'Installed modules' => 'Установленные модули',
+ 'Buy' => 'Купить',
+ //Combat
+ 'Battle Ship Combat Begin' => 'Великая битва кораблей началась',
+ 'Top Rank users' => 'Лучшие игроки',
+ 'Battle Shop' => 'Магазин кораблей',
+ 'Shop' => 'Магазин',
+ // Battle
+ 'Start battle' => 'Начать бой',
+ 'Reg Battle' => 'Вступить в бой',
+ 'Go Battle' => 'Вступить в бой',
+ 'You attacked the bot warship on -' => 'Вы нанесли урон вражескому кораблю на -',
+ 'Our warship were attacked by bot warship on -' => 'Ваш корабль был атакован на -',
+ 'Congratulations, You are Win' => 'Поздравляем, победа за Вами',
+ 'Go Port' => 'Перейти в порт',
+ 'Unfortunately' => 'К сожалению, Вы проиграли',
+ // Auth
+ 'Auth' => 'Авторизация',
+ 'Login' => 'Войти',
+ 'username' => 'Имя пользователя',
+ 'password' => 'Пароль',
+ 'rememberMe' => 'Запомнить меня',
+ 'reset it' => 'сбросить',
+ 'Please fill out the following fields to login' => 'Пожалуйста, заполните следующие поля',
+ 'If you forgot your password you can' => 'Если Вы забилы свой пароль, нажмите здесь',
+ // Signup
+ 'Signup' => 'Зарегистрировать',
+ 'Please fill out the following fields to signup' => 'Пожалуйста заполните следующие поля для регистрации',
+ 'Reg' => 'Регистрация',
+ // Others
+ 'Powered by {yii}' => 'Работает на {yii}',
+ 'Unknown alias: -{name}' => 'Неизвестный псевдоним: -{name}',
+ 'Yii Framework' => 'Yii Framework',
+ '(not set)' => '(не задано)',
+ ' and ' => ' и ',
+ 'An internal server error occurred.' => 'Возникла внутренняя ошибка сервера.',
+ 'Are you sure you want to delete this item?' => 'Вы уверены, что хотите удалить этот элемент?',
+ 'Delete' => 'Удалить',
+ 'Error' => 'Ошибка',
+ 'File upload failed.' => 'Загрузка файла не удалась.',
+ 'Home' => 'Главная',
+ 'Invalid data received for parameter "{param}".' => 'Неправильное значение параметра "{param}".',
+ 'Login Required' => 'Требуется вход.',
+ 'Missing required arguments: {params}' => 'Отсутствуют обязательные аргументы: {params}',
+ 'Missing required parameters: {params}' => 'Отсутствуют обязательные параметры: {params}',
+ 'No' => 'Нет',
+ 'No results found.' => 'Ничего не найдено.',
+ 'Only files with these MIME types are allowed: {mimeTypes}.' => 'Разрешена загрузка файлов только со следующими MIME-типами: {mimeTypes}.',
+ 'Only files with these extensions are allowed: {extensions}.' => 'Разрешена загрузка файлов только со следующими расширениями: {extensions}.',
+ 'Page not found.' => 'Страница не найдена.',
+ 'Please fix the following errors:' => 'Исправьте следующие ошибки:',
+ 'Please upload a file.' => 'Загрузите файл.',
+ 'Showing {begin, number}-{end, number} of {totalCount, number} {totalCount, plural, one{item} other{items}}.' => 'Показаны записи {begin, number}-{end, number} из {totalCount, number}.',
+ 'The combination {values} of {attributes} has already been taken.' => 'Комбинация {values} параметров {attributes} уже существует.',
+ 'The file "{file}" is not an image.' => 'Файл «{file}» не является изображением.',
+ 'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'Файл «{file}» слишком большой. Размер не должен превышать {formattedLimit}.',
+ 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'Файл «{file}» слишком маленький. Размер должен быть более {formattedLimit}.',
+ 'The format of {attribute} is invalid.' => 'Неверный формат значения «{attribute}».',
+ 'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Файл «{file}» слишком большой. Высота не должна превышать {limit, number} {limit, plural, one{пиксель} few{пикселя} many{пикселей} other{пикселя}}.',
+ 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Файл «{file}» слишком большой. Ширина не должна превышать {limit, number} {limit, plural, one{пиксель} few{пикселя} many{пикселей} other{пикселя}}.',
+ 'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Файл «{file}» слишком маленький. Высота должна быть более {limit, number} {limit, plural, one{пиксель} few{пикселя} many{пикселей} other{пикселя}}.',
+ 'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Файл «{file}» слишком маленький. Ширина должна быть более {limit, number} {limit, plural, one{пиксель} few{пикселя} many{пикселей} other{пикселя}}.',
+ 'The requested view "{name}" was not found.' => 'Запрашиваемый файл представления "{name}" не найден.',
+ 'The verification code is incorrect.' => 'Неправильный проверочный код.',
+ 'Total {count, number} {count, plural, one{item} other{items}}.' => 'Всего {count, number} {count, plural, one{запись} few{записи} many{записей} other{записи}}.',
+ 'Unable to verify your data submission.' => 'Не удалось проверить переданные данные.',
+ 'Unknown option: --{name}' => 'Неизвестная опция: --{name}',
+ 'Update' => 'Редактировать',
+ 'View' => 'Просмотр',
+ 'Yes' => 'Да',
+ 'You are not allowed to perform this action.' => 'Вам не разрешено производить данное действие.',
+ 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Вы не можете загружать более {limit, number} {limit, plural, one{файла} few{файлов} many{файлов} other{файла}}.',
+ 'in {delta, plural, =1{a day} other{# days}}' => 'через {delta, plural, =1{день} one{# день} few{# дня} many{# дней} other{# дня}}',
+ 'in {delta, plural, =1{a minute} other{# minutes}}' => 'через {delta, plural, =1{минуту} one{# минуту} few{# минуты} many{# минут} other{# минуты}}',
+ 'in {delta, plural, =1{a month} other{# months}}' => 'через {delta, plural, =1{месяц} one{# месяц} few{# месяца} many{# месяцев} other{# месяца}}',
+ 'in {delta, plural, =1{a second} other{# seconds}}' => 'через {delta, plural, =1{секунду} one{# секунду} few{# секунды} many{# секунд} other{# секунды}}',
+ 'in {delta, plural, =1{a year} other{# years}}' => 'через {delta, plural, =1{год} one{# год} few{# года} many{# лет} other{# года}}',
+ 'in {delta, plural, =1{an hour} other{# hours}}' => 'через {delta, plural, =1{час} one{# час} few{# часа} many{# часов} other{# часа}}',
+ 'just now' => 'прямо сейчас',
+ 'the input value' => 'введённое значение',
+ '{attribute} "{value}" has already been taken.' => 'Значение «{value}» для «{attribute}» уже занято.',
+ '{attribute} cannot be blank.' => 'Необходимо заполнить «{attribute}».',
+ '{attribute} contains wrong subnet mask.' => 'Значение «{attribute}» содержит неверную маску подсети.',
+ '{attribute} is invalid.' => 'Значение «{attribute}» неверно.',
+ '{attribute} is not a valid URL.' => 'Значение «{attribute}» не является правильным URL.',
+ '{attribute} is not a valid email address.' => 'Значение «{attribute}» не является правильным email адресом.',
+ '{attribute} is not in the allowed range.' => 'Значение «{attribute}» не входит в список разрешенных диапазонов адресов.',
+ '{attribute} must be "{requiredValue}".' => 'Значение «{attribute}» должно быть равно «{requiredValue}».',
+ '{attribute} must be a number.' => 'Значение «{attribute}» должно быть числом.',
+ '{attribute} must be a string.' => 'Значение «{attribute}» должно быть строкой.',
+ '{attribute} must be a valid IP address.' => 'Значение «{attribute}» должно быть правильным IP адресом.',
+ '{attribute} must be an IP address with specified subnet.' => 'Значение «{attribute}» должно быть IP адресом с подсетью.',
+ '{attribute} must be an integer.' => 'Значение «{attribute}» должно быть целым числом.',
+ '{attribute} must be either "{true}" or "{false}".' => 'Значение «{attribute}» должно быть равно «{true}» или «{false}».',
+ '{attribute} must be equal to "{compareValueOrAttribute}".' => 'Значение «{attribute}» должно быть равно «{compareValueOrAttribute}».',
+ '{attribute} must be greater than "{compareValueOrAttribute}".' => 'Значение «{attribute}» должно быть больше значения «{compareValueOrAttribute}».',
+ '{attribute} must be greater than or equal to "{compareValueOrAttribute}".' => 'Значение «{attribute}» должно быть больше или равно значения «{compareValueOrAttribute}».',
+ '{attribute} must be less than "{compareValueOrAttribute}".' => 'Значение «{attribute}» должно быть меньше значения «{compareValueOrAttribute}».',
+ '{attribute} must be less than or equal to "{compareValueOrAttribute}".' => 'Значение «{attribute}» должно быть меньше или равно значения «{compareValueOrAttribute}».',
+ '{attribute} must be no greater than {max}.' => 'Значение «{attribute}» не должно превышать {max}.',
+ '{attribute} must be no less than {min}.' => 'Значение «{attribute}» должно быть не меньше {min}.',
+ '{attribute} must not be a subnet.' => 'Значение «{attribute}» не должно быть подсетью.',
+ '{attribute} must not be an IPv4 address.' => 'Значение «{attribute}» не должно быть IPv4 адресом.',
+ '{attribute} must not be an IPv6 address.' => 'Значение «{attribute}» не должно быть IPv6 адресом.',
+ '{attribute} must not be equal to "{compareValueOrAttribute}".' => 'Значение «{attribute}» не должно быть равно «{compareValueOrAttribute}».',
+ '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => 'Значение «{attribute}» должно содержать минимум {min, number} {min, plural, one{символ} few{символа} many{символов} other{символа}}.',
+ '{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => 'Значение «{attribute}» должно содержать максимум {max, number} {max, plural, one{символ} few{символа} many{символов} other{символа}}.',
+ '{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => 'Значение «{attribute}» должно содержать {length, number} {length, plural, one{символ} few{символа} many{символов} other{символа}}.',
+ '{delta, plural, =1{1 day} other{# days}}' => '{delta, plural, one{# день} few{# дня} many{# дней} other{# дня}}',
+ '{delta, plural, =1{1 hour} other{# hours}}' => '{delta, plural, one{# час} few{# часа} many{# часов} other{# часа}}',
+ '{delta, plural, =1{1 minute} other{# minutes}}' => '{delta, plural, one{# минута} few{# минуты} many{# минут} other{# минуты}}',
+ '{delta, plural, =1{1 month} other{# months}}' => '{delta, plural, one{# месяц} few{# месяца} many{# месяцев} other{# месяца}}',
+ '{delta, plural, =1{1 second} other{# seconds}}' => '{delta, plural, one{# секунда} few{# секунды} many{# секунд} other{# секунды}}',
+ '{delta, plural, =1{1 year} other{# years}}' => '{delta, plural, one{# год} few{# года} many{# лет} other{# года}}',
+ '{delta, plural, =1{a day} other{# days}} ago' => '{delta, plural, =1{день} one{# день} few{# дня} many{# дней} other{# дня}} назад',
+ '{delta, plural, =1{a minute} other{# minutes}} ago' => '{delta, plural, =1{минуту} one{# минуту} few{# минуты} many{# минут} other{# минуты}} назад',
+ '{delta, plural, =1{a month} other{# months}} ago' => '{delta, plural, =1{месяц} one{# месяц} few{# месяца} many{# месяцев} other{# месяца}} назад',
+ '{delta, plural, =1{a second} other{# seconds}} ago' => '{delta, plural, =1{секунду} one{# секунду} few{# секунды} many{# секунд} other{# секунды}} назад',
+ '{delta, plural, =1{a year} other{# years}} ago' => '{delta, plural, =1{год} one{# год} few{# года} many{# лет} other{# года}} назад',
+ '{delta, plural, =1{an hour} other{# hours}} ago' => '{delta, plural, =1{час} one{# час} few{# часа} many{# часов} other{# часа}} назад',
+ '{nFormatted} B' => '{nFormatted} Б',
+ '{nFormatted} GB' => '{nFormatted} ГБ',
+ '{nFormatted} GiB' => '{nFormatted} ГиБ',
+ '{nFormatted} KB' => '{nFormatted} КБ',
+ '{nFormatted} KiB' => '{nFormatted} КиБ',
+ '{nFormatted} MB' => '{nFormatted} МБ',
+ '{nFormatted} MiB' => '{nFormatted} МиБ',
+ '{nFormatted} PB' => '{nFormatted} ПБ',
+ '{nFormatted} PiB' => '{nFormatted} ПиБ',
+ '{nFormatted} TB' => '{nFormatted} ТБ',
+ '{nFormatted} TiB' => '{nFormatted} ТиБ',
+ '{nFormatted} {n, plural, =1{byte} other{bytes}}' => '{nFormatted} {n, plural, one{байт} few{байта} many{байтов} other{байта}}',
+ '{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}' => '{nFormatted} {n, plural, one{гибибайт} few{гибибайта} many{гибибайтов} other{гибибайта}}',
+ '{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}' => '{nFormatted} {n, plural, one{гигабайт} few{гигабайта} many{гигабайтов} other{гигабайта}}',
+ '{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}' => '{nFormatted} {n, plural, one{кибибайт} few{кибибайта} many{кибибайтов} other{кибибайта}}',
+ '{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}' => '{nFormatted} {n, plural, one{килобайт} few{килобайта} many{килобайтов} other{килобайта}}',
+ '{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}' => '{nFormatted} {n, plural, one{мебибайт} few{мебибайта} many{мебибайтов} other{мебибайта}}',
+ '{nFormatted} {n, plural, =1{megabyte} other{megabytes}}' => '{nFormatted} {n, plural, one{мегабайт} few{мегабайта} many{мегабайтов} other{мегабайта}}',
+ '{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}' => '{nFormatted} {n, plural, one{пебибайт} few{пебибайта} many{пебибайтов} other{пебибайта}}',
+ '{nFormatted} {n, plural, =1{petabyte} other{petabytes}}' => '{nFormatted} {n, plural, one{петабайт} few{петабайта} many{петабайтов} other{петабайта}}',
+ '{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}' => '{nFormatted} {n, plural, one{тебибайт} few{тебибайта} many{тебибайтов} other{тебибайта}}',
+ '{nFormatted} {n, plural, =1{terabyte} other{terabytes}}' => '{nFormatted} {n, plural, one{терабайт} few{терабайта} many{терабайтов} other{терабайта}}',
+];
diff --git a/frontend/models/ContactForm.php b/frontend/models/ContactForm.php
new file mode 100755
index 0000000..d0cc9cb
--- /dev/null
+++ b/frontend/models/ContactForm.php
@@ -0,0 +1,60 @@
+ '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 bool 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();
+ }
+}
diff --git a/frontend/models/PasswordResetRequestForm.php b/frontend/models/PasswordResetRequestForm.php
new file mode 100755
index 0000000..c11aeec
--- /dev/null
+++ b/frontend/models/PasswordResetRequestForm.php
@@ -0,0 +1,68 @@
+ '\common\models\User',
+ 'filter' => ['status' => User::STATUS_ACTIVE],
+ 'message' => 'There is no user with this email address.'
+ ],
+ ];
+ }
+
+ /**
+ * Sends an email with a link, for resetting the password.
+ *
+ * @return bool 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();
+ }
+}
diff --git a/frontend/models/ResetPasswordForm.php b/frontend/models/ResetPasswordForm.php
new file mode 100755
index 0000000..fb36dd0
--- /dev/null
+++ b/frontend/models/ResetPasswordForm.php
@@ -0,0 +1,64 @@
+_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 bool if password was reset.
+ */
+ public function resetPassword()
+ {
+ $user = $this->_user;
+ $user->setPassword($this->password);
+ $user->removePasswordResetToken();
+
+ return $user->save(false);
+ }
+}
diff --git a/frontend/models/SignupForm.php b/frontend/models/SignupForm.php
new file mode 100755
index 0000000..dac4d96
--- /dev/null
+++ b/frontend/models/SignupForm.php
@@ -0,0 +1,71 @@
+ '\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],
+ ];
+ }
+
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'username' => Yii::t('app', 'username'),
+ 'password' => Yii::t('app', 'password'),
+ ];
+ }
+
+ /**
+ * 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;
+ }
+}
diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/frontend/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/frontend/tests/1bootstrap.php b/frontend/tests/1bootstrap.php
new file mode 100755
index 0000000..83a1f26
--- /dev/null
+++ b/frontend/tests/1bootstrap.php
@@ -0,0 +1,9 @@
+ 'erau',
+ 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI',
+ // password_0
+ 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne',
+ 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490',
+ 'created_at' => '1392559490',
+ 'updated_at' => '1392559490',
+ 'email' => 'sfriesen@jenkins.info',
+ ],
+];
diff --git a/frontend/tests/_data/user.php b/frontend/tests/_data/user.php
new file mode 100755
index 0000000..3670e09
--- /dev/null
+++ b/frontend/tests/_data/user.php
@@ -0,0 +1,23 @@
+ 'okirlin',
+ 'auth_key' => 'iwTNae9t34OmnK6l4vT4IeaTk-YWI2Rv',
+ 'password_hash' => '$2y$13$CXT0Rkle1EMJ/c1l5bylL.EylfmQ39O5JlHJVFpNn618OUS1HwaIi',
+ 'password_reset_token' => 't5GU9NwpuGYSfb7FEZMAxqtuz2PkEvv_' . time(),
+ 'created_at' => '1391885313',
+ 'updated_at' => '1391885313',
+ 'email' => 'brady.renner@rutherford.com',
+ ],
+ [
+ 'username' => 'troy.becker',
+ 'auth_key' => 'EdKfXrx88weFMV0vIxuTMWKgfK2tS3Lp',
+ 'password_hash' => '$2y$13$g5nv41Px7VBqhS3hVsVN2.MKfgT3jFdkXEsMC4rQJLfaMa7VaJqL2',
+ 'password_reset_token' => '4BSNyiZNAuxjs5Mty990c47sVrgllIi_' . time(),
+ 'created_at' => '1391885313',
+ 'updated_at' => '1391885313',
+ 'email' => 'nicolas.dianna@hotmail.com',
+ 'status' => '0',
+ ],
+];
diff --git a/frontend/tests/_output/.gitignore b/frontend/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/frontend/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/frontend/tests/_support/.gitignore b/frontend/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/frontend/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/frontend/tests/_support/AcceptanceTester.php b/frontend/tests/_support/AcceptanceTester.php
new file mode 100755
index 0000000..3c79b4f
--- /dev/null
+++ b/frontend/tests/_support/AcceptanceTester.php
@@ -0,0 +1,26 @@
+see($message, '.help-block');
+ }
+
+ public function dontSeeValidationError($message)
+ {
+ $this->dontSee($message, '.help-block');
+ }
+}
diff --git a/frontend/tests/_support/UnitTester.php b/frontend/tests/_support/UnitTester.php
new file mode 100755
index 0000000..8c708e7
--- /dev/null
+++ b/frontend/tests/_support/UnitTester.php
@@ -0,0 +1,25 @@
+amOnPage(Url::toRoute('/site/index'));
+ $I->see('My Company');
+
+ $I->seeLink('About');
+ $I->click('About');
+ $I->wait(2); // wait for page to be opened
+
+ $I->see('This is the About page.');
+ }
+}
diff --git a/frontend/tests/acceptance/_bootstrap.php b/frontend/tests/acceptance/_bootstrap.php
new file mode 100755
index 0000000..47716f0
--- /dev/null
+++ b/frontend/tests/acceptance/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cept
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/functional.suite.yml b/frontend/tests/functional.suite.yml
new file mode 100755
index 0000000..3f851d1
--- /dev/null
+++ b/frontend/tests/functional.suite.yml
@@ -0,0 +1,5 @@
+class_name: FunctionalTester
+modules:
+ enabled:
+ - Filesystem
+ - Yii2
diff --git a/frontend/tests/functional/AboutCest.php b/frontend/tests/functional/AboutCest.php
new file mode 100755
index 0000000..6c3cb9e
--- /dev/null
+++ b/frontend/tests/functional/AboutCest.php
@@ -0,0 +1,13 @@
+amOnRoute('site/about');
+ $I->see('About', 'h1');
+ }
+}
diff --git a/frontend/tests/functional/ContactCest.php b/frontend/tests/functional/ContactCest.php
new file mode 100755
index 0000000..bdda991
--- /dev/null
+++ b/frontend/tests/functional/ContactCest.php
@@ -0,0 +1,59 @@
+amOnPage(['site/contact']);
+ }
+
+ public function checkContact(FunctionalTester $I)
+ {
+ $I->see('Contact', 'h1');
+ }
+
+ public function checkContactSubmitNoData(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', []);
+ $I->see('Contact', 'h1');
+ $I->seeValidationError('Name cannot be blank');
+ $I->seeValidationError('Email cannot be blank');
+ $I->seeValidationError('Subject cannot be blank');
+ $I->seeValidationError('Body cannot be blank');
+ $I->seeValidationError('The verification code is incorrect');
+ }
+
+ public function checkContactSubmitNotCorrectEmail(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', [
+ 'ContactForm[name]' => 'tester',
+ 'ContactForm[email]' => 'tester.email',
+ 'ContactForm[subject]' => 'test subject',
+ 'ContactForm[body]' => 'test content',
+ 'ContactForm[verifyCode]' => 'testme',
+ ]);
+ $I->seeValidationError('Email is not a valid email address.');
+ $I->dontSeeValidationError('Name cannot be blank');
+ $I->dontSeeValidationError('Subject cannot be blank');
+ $I->dontSeeValidationError('Body cannot be blank');
+ $I->dontSeeValidationError('The verification code is incorrect');
+ }
+
+ public function checkContactSubmitCorrectData(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', [
+ 'ContactForm[name]' => 'tester',
+ 'ContactForm[email]' => 'tester@example.com',
+ 'ContactForm[subject]' => 'test subject',
+ 'ContactForm[body]' => 'test content',
+ 'ContactForm[verifyCode]' => 'testme',
+ ]);
+ $I->seeEmailIsSent();
+ $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
+ }
+}
diff --git a/frontend/tests/functional/HomeCest.php b/frontend/tests/functional/HomeCest.php
new file mode 100755
index 0000000..8f99b48
--- /dev/null
+++ b/frontend/tests/functional/HomeCest.php
@@ -0,0 +1,17 @@
+amOnPage(\Yii::$app->homeUrl);
+ $I->see('My Company');
+ $I->seeLink('About');
+ $I->click('About');
+ $I->see('This is the About page.');
+ }
+}
\ No newline at end of file
diff --git a/frontend/tests/functional/LoginCest.php b/frontend/tests/functional/LoginCest.php
new file mode 100755
index 0000000..696aeda
--- /dev/null
+++ b/frontend/tests/functional/LoginCest.php
@@ -0,0 +1,49 @@
+haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'login_data.php'
+ ]
+ ]);
+ $I->amOnRoute('site/login');
+ }
+
+ protected function formParams($login, $password)
+ {
+ return [
+ 'LoginForm[username]' => $login,
+ 'LoginForm[password]' => $password,
+ ];
+ }
+
+ public function checkEmpty(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('', ''));
+ $I->seeValidationError('Username cannot be blank.');
+ $I->seeValidationError('Password cannot be blank.');
+ }
+
+ public function checkWrongPassword(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('admin', 'wrong'));
+ $I->seeValidationError('Incorrect username or password.');
+ }
+
+ public function checkValidLogin(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('erau', 'password_0'));
+ $I->see('Logout (erau)', 'form button[type=submit]');
+ $I->dontSeeLink('Login');
+ $I->dontSeeLink('Signup');
+ }
+}
diff --git a/frontend/tests/functional/SignupCest.php b/frontend/tests/functional/SignupCest.php
new file mode 100755
index 0000000..8cfde9a
--- /dev/null
+++ b/frontend/tests/functional/SignupCest.php
@@ -0,0 +1,57 @@
+amOnRoute('site/signup');
+ }
+
+ public function signupWithEmptyFields(FunctionalTester $I)
+ {
+ $I->see('Signup', 'h1');
+ $I->see('Please fill out the following fields to signup:');
+ $I->submitForm($this->formId, []);
+ $I->seeValidationError('Username cannot be blank.');
+ $I->seeValidationError('Email cannot be blank.');
+ $I->seeValidationError('Password cannot be blank.');
+
+ }
+
+ public function signupWithWrongEmail(FunctionalTester $I)
+ {
+ $I->submitForm(
+ $this->formId, [
+ 'SignupForm[username]' => 'tester',
+ 'SignupForm[email]' => 'ttttt',
+ 'SignupForm[password]' => 'tester_password',
+ ]
+ );
+ $I->dontSee('Username cannot be blank.', '.help-block');
+ $I->dontSee('Password cannot be blank.', '.help-block');
+ $I->see('Email is not a valid email address.', '.help-block');
+ }
+
+ public function signupSuccessfully(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, [
+ 'SignupForm[username]' => 'tester',
+ 'SignupForm[email]' => 'tester.email@example.com',
+ 'SignupForm[password]' => 'tester_password',
+ ]);
+
+ $I->seeRecord('common\models\User', [
+ 'username' => 'tester',
+ 'email' => 'tester.email@example.com',
+ ]);
+
+ $I->see('Logout (tester)', 'form button[type=submit]');
+ }
+}
diff --git a/frontend/tests/functional/_bootstrap.php b/frontend/tests/functional/_bootstrap.php
new file mode 100755
index 0000000..30ed54b
--- /dev/null
+++ b/frontend/tests/functional/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/unit.suite.yml b/frontend/tests/unit.suite.yml
new file mode 100755
index 0000000..27f2907
--- /dev/null
+++ b/frontend/tests/unit.suite.yml
@@ -0,0 +1,6 @@
+class_name: UnitTester
+modules:
+ enabled:
+ - Yii2:
+ part: [orm, email, fixtures]
+ - Asserts
diff --git a/frontend/tests/unit/_bootstrap.php b/frontend/tests/unit/_bootstrap.php
new file mode 100755
index 0000000..e432ce5
--- /dev/null
+++ b/frontend/tests/unit/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Tests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
diff --git a/frontend/tests/unit/models/ContactFormTest.php b/frontend/tests/unit/models/ContactFormTest.php
new file mode 100755
index 0000000..acdf9db
--- /dev/null
+++ b/frontend/tests/unit/models/ContactFormTest.php
@@ -0,0 +1,32 @@
+attributes = [
+ 'name' => 'Tester',
+ 'email' => 'tester@example.com',
+ 'subject' => 'very important letter subject',
+ 'body' => 'body of current message',
+ ];
+
+ expect_that($model->sendEmail('admin@example.com'));
+
+ // using Yii2 module actions to check email was sent
+ $this->tester->seeEmailIsSent();
+
+ $emailMessage = $this->tester->grabLastSentEmail();
+ expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
+ expect($emailMessage->getTo())->hasKey('admin@example.com');
+ expect($emailMessage->getFrom())->hasKey('tester@example.com');
+ expect($emailMessage->getSubject())->equals('very important letter subject');
+ expect($emailMessage->toString())->contains('body of current message');
+ }
+}
diff --git a/frontend/tests/unit/models/PasswordResetRequestFormTest.php b/frontend/tests/unit/models/PasswordResetRequestFormTest.php
new file mode 100755
index 0000000..eba7203
--- /dev/null
+++ b/frontend/tests/unit/models/PasswordResetRequestFormTest.php
@@ -0,0 +1,59 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testSendMessageWithWrongEmailAddress()
+ {
+ $model = new PasswordResetRequestForm();
+ $model->email = 'not-existing-email@example.com';
+ expect_not($model->sendEmail());
+ }
+
+ public function testNotSendEmailsToInactiveUser()
+ {
+ $user = $this->tester->grabFixture('user', 1);
+ $model = new PasswordResetRequestForm();
+ $model->email = $user['email'];
+ expect_not($model->sendEmail());
+ }
+
+ public function testSendEmailSuccessfully()
+ {
+ $userFixture = $this->tester->grabFixture('user', 0);
+
+ $model = new PasswordResetRequestForm();
+ $model->email = $userFixture['email'];
+ $user = User::findOne(['password_reset_token' => $userFixture['password_reset_token']]);
+
+ expect_that($model->sendEmail());
+ expect_that($user->password_reset_token);
+
+ $emailMessage = $this->tester->grabLastSentEmail();
+ expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
+ expect($emailMessage->getTo())->hasKey($model->email);
+ expect($emailMessage->getFrom())->hasKey(Yii::$app->params['supportEmail']);
+ }
+}
diff --git a/frontend/tests/unit/models/ResetPasswordFormTest.php b/frontend/tests/unit/models/ResetPasswordFormTest.php
new file mode 100755
index 0000000..74929bf
--- /dev/null
+++ b/frontend/tests/unit/models/ResetPasswordFormTest.php
@@ -0,0 +1,44 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ],
+ ]);
+ }
+
+ public function testResetWrongToken()
+ {
+ $this->tester->expectException('yii\base\InvalidParamException', function() {
+ new ResetPasswordForm('');
+ });
+
+ $this->tester->expectException('yii\base\InvalidParamException', function() {
+ new ResetPasswordForm('notexistingtoken_1391882543');
+ });
+ }
+
+ public function testResetCorrectToken()
+ {
+ $user = $this->tester->grabFixture('user', 0);
+ $form = new ResetPasswordForm($user['password_reset_token']);
+ expect_that($form->resetPassword());
+ }
+
+}
diff --git a/frontend/tests/unit/models/SignupFormTest.php b/frontend/tests/unit/models/SignupFormTest.php
new file mode 100755
index 0000000..23a3463
--- /dev/null
+++ b/frontend/tests/unit/models/SignupFormTest.php
@@ -0,0 +1,59 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::className(),
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testCorrectSignup()
+ {
+ $model = new SignupForm([
+ 'username' => 'some_username',
+ 'email' => 'some_email@example.com',
+ 'password' => 'some_password',
+ ]);
+
+ $user = $model->signup();
+
+ expect($user)->isInstanceOf('common\models\User');
+
+ expect($user->username)->equals('some_username');
+ expect($user->email)->equals('some_email@example.com');
+ expect($user->validatePassword('some_password'))->true();
+ }
+
+ public function testNotCorrectSignup()
+ {
+ $model = new SignupForm([
+ 'username' => 'troy.becker',
+ 'email' => 'nicolas.dianna@hotmail.com',
+ 'password' => 'some_password',
+ ]);
+
+ expect_not($model->signup());
+ expect_that($model->getErrors('username'));
+ expect_that($model->getErrors('email'));
+
+ expect($model->getFirstError('username'))
+ ->equals('This username has already been taken.');
+ expect($model->getFirstError('email'))
+ ->equals('This email address has already been taken.');
+ }
+}
diff --git a/frontend/views/combat/index.php b/frontend/views/combat/index.php
new file mode 100755
index 0000000..2e5a5a1
--- /dev/null
+++ b/frontend/views/combat/index.php
@@ -0,0 +1,97 @@
+title = Yii::t('app', 'Battle of WarShips!');
+
+$curhpplayer = ceil(($session['usershiphp'] / $usership->strength)*100);
+$curhpbot = ceil(($session['bothp'] / $usership->strength)*100);
+?>
+ 'battle-form']); ?>
+
+
=Yii::t('app', 'Battle Ship Combat Begin') ?>!
+
+
+
+
+
+
+ user->identity->username; ?> [/strength ?>]
+
+
+
+ 
+
+
+ Items:
+ hp.' +HP ['.$user_items->qnt.'] ';
+ echo Html::submitButton(Yii::t('app', 'getHP'), ['class' => 'btn btn-primary', 'name' => 'gethp', 'value' => 'gethp']);
+ }
+ ?>
+
+ |
+
+
+
+ 'my-test']); ?>
+ = Html::radio('shot', false, ['value' => '1', 'id' => 'radio1']); ?>= Html::label('Выстрелить в пункт управления', 'radio1', false) ?>
+ = Html::radio('shot', false, ['value' => '2', 'id' => 'radio2']); ?>= Html::label('Выстрелить в нос', 'radio2', false) ?>
+ = Html::radio('shot', false, ['value' => '3', 'id' => 'radio3']); ?>= Html::label('Выстрелить в корму', 'radio3', false) ?>
+ = Html::radio('shot', false, ['value' => '4', 'id' => 'radio4']); ?>= Html::label('Выстрелить в борт', 'radio4', false) ?>
+
+
+
+ |
+
+
+ BotShip [/strength ?>]
+
+
+
+ 
+
+
+ |
+
+
+
+
+ = Html::submitButton(Yii::t('app', 'Attack'), ['class' => 'btn btn-primary', 'style' => 'width: 220px', 'name' => 'Attack', 'id' => 'battle-form', 'value' => 'Attack']) ?>
+
+ |
+
+
+
+logs . ' ';
+}
+?>
+ |
+
+
+
\ No newline at end of file
diff --git a/frontend/views/combat/lose.php b/frontend/views/combat/lose.php
new file mode 100755
index 0000000..9b8812f
--- /dev/null
+++ b/frontend/views/combat/lose.php
@@ -0,0 +1,14 @@
+title = 'Battle Win!';
+?>
+
+
+
= Yii::t('app', 'Unfortunately, You are Lose') ?>!
+
+
+
diff --git a/frontend/views/combat/win.php b/frontend/views/combat/win.php
new file mode 100755
index 0000000..c1bfc53
--- /dev/null
+++ b/frontend/views/combat/win.php
@@ -0,0 +1,14 @@
+title = 'Battle Win!';
+?>
+
+
+
= Yii::t('app', 'Congratulations, You are Win') ?>!
+
+
+
diff --git a/frontend/views/dock/index.php b/frontend/views/dock/index.php
new file mode 100644
index 0000000..fbc59ec
--- /dev/null
+++ b/frontend/views/dock/index.php
@@ -0,0 +1,27 @@
+
+
+User Dock
+
+ Ships
+
+
+
+
+
+ 
+
+
+ = $ships->ship->name; ?> | = $ships->user->username; ?>
+
+
+
+ |
+
\ No newline at end of file
diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php
new file mode 100755
index 0000000..af8d676
--- /dev/null
+++ b/frontend/views/layouts/main.php
@@ -0,0 +1,87 @@
+
+beginPage() ?>
+
+
+
+
+
+ = Html::csrfMetaTags() ?>
+ = Html::encode(Yii::t('app', $this->title)) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+ Yii::t('app', '
Battle Ships'),
+ 'brandUrl' => Yii::$app->homeUrl,
+ 'options' => [
+ 'class' => 'navbar-inverse navbar-fixed-top',
+ ],
+ ]);
+ $menuItems = [
+ ['label' => Yii::t('app', 'Home'), 'url' => ['/site']],
+ ['label' => Yii::t('app', 'Reg Battle'), 'url' => ['/list']],
+ ['label' => Yii::t('app', 'Toprank'), 'url' => ['/toprank']],
+ ['label' => Yii::t('app', 'Shop'), 'url' => ['/shop']],
+ ];
+ if (Yii::$app->user->isGuest) {
+ $menuItems[] = ['label' => Yii::t('app', 'Signup'), 'url' => ['/site/signup']];
+ $menuItems[] = ['label' => Yii::t('app', 'Login'), 'url' => ['/site/login']];
+ } else {
+ $menuItems[] = '
'
+ . Html::beginForm(['/site/logout'], 'post')
+ . Html::submitButton(
+ Yii::t('app', 'Logout') . '(' . Yii::$app->user->identity->username . ')',
+ ['class' => 'btn btn-link logout']
+ )
+ . Html::endForm()
+ . '';
+ }
+ echo Nav::widget([
+ 'options' => ['class' => 'navbar-nav navbar-right'],
+ 'items' => $menuItems,
+ ]);
+ NavBar::end();
+ ?>
+
+
+
+ = Breadcrumbs::widget([
+ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
+ ]) ?>
+ = Alert::widget() ?>
+ = $content ?>
+
+
+
+
+
+endBody() ?>
+
+
+endPage() ?>
diff --git a/frontend/views/layouts/main/select-language.php b/frontend/views/layouts/main/select-language.php
new file mode 100755
index 0000000..a9bb2e5
--- /dev/null
+++ b/frontend/views/layouts/main/select-language.php
@@ -0,0 +1,15 @@
+language == 'ru'):
+ echo Html::a('Go to English', array_merge(
+ \Yii::$app->request->get(),
+ [\Yii::$app->controller->route, 'language' => 'en']
+ ));
+else:
+ echo Html::a('Перейти на русский', array_merge(
+ \Yii::$app->request->get(),
+ [\Yii::$app->controller->route, 'language' => 'ru']
+ ));
+endif;
\ No newline at end of file
diff --git a/frontend/views/list/index.php b/frontend/views/list/index.php
new file mode 100644
index 0000000..b1dbc71
--- /dev/null
+++ b/frontend/views/list/index.php
@@ -0,0 +1,13 @@
+
+
+
=Yii::t('app', 'Go Battle') ?>!
+
+
+ 'battle-form']); ?>
+ = Html::submitButton(Yii::t('app', 'Start battle'), ['class' => 'btn btn-outlined btn-primary', 'name' => 'start', 'id' => 'start-battle', 'value' => 'Start']) ?>
+
+
diff --git a/frontend/views/logs/index.php b/frontend/views/logs/index.php
new file mode 100644
index 0000000..379ed21
--- /dev/null
+++ b/frontend/views/logs/index.php
@@ -0,0 +1,17 @@
+title = 'Battle logs';
+?>
+logs
+
+
+ Viewing Full Battle Log
';
+ echo '
'.$model->bid.' | '.$model->date.'
';
+ echo '
'.$model->logs .'';
+ }
+ }
+ ?>
+
diff --git a/frontend/views/shop/_list.php b/frontend/views/shop/_list.php
new file mode 100755
index 0000000..9a66c29
--- /dev/null
+++ b/frontend/views/shop/_list.php
@@ -0,0 +1,11 @@
+
+
+

+
+
name ?>
+
+
+
+
+ Уровень: lvl ?>
+
\ No newline at end of file
diff --git a/frontend/views/shop/index.php b/frontend/views/shop/index.php
new file mode 100755
index 0000000..0cbdae6
--- /dev/null
+++ b/frontend/views/shop/index.php
@@ -0,0 +1,19 @@
+title = Yii::t('app', 'Battle Shop');
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Yii::t('app', 'Battle Shop') ?>
+
+
+
+ = ListView::widget([
+ 'dataProvider' => $shopProvider,
+ 'layout' => '{items}',
+ 'options' => ['class' => 'projects-flow'],
+ 'itemOptions' => ['class' => 'item'],
+ 'itemView' => '_list'
+ ]) ?>
+
+
diff --git a/frontend/views/site/about.php b/frontend/views/site/about.php
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/frontend/views/site/about.php
@@ -0,0 +1 @@
+
diff --git a/frontend/views/site/contact.php b/frontend/views/site/contact.php
new file mode 100755
index 0000000..dc48410
--- /dev/null
+++ b/frontend/views/site/contact.php
@@ -0,0 +1,45 @@
+title = 'Contact';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
diff --git a/frontend/views/site/error.php b/frontend/views/site/error.php
new file mode 100755
index 0000000..0ba2574
--- /dev/null
+++ b/frontend/views/site/error.php
@@ -0,0 +1,27 @@
+title = $name;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = nl2br(Html::encode($message)) ?>
+
+
+
+ The above error occurred while the Web server was processing your request.
+
+
+ Please contact us if you think this is a server error. Thank you.
+
+
+
diff --git a/frontend/views/site/index.php b/frontend/views/site/index.php
new file mode 100755
index 0000000..5a6dfdd
--- /dev/null
+++ b/frontend/views/site/index.php
@@ -0,0 +1,16 @@
+title = 'BattleShips GunS!';
+?>
+
+
+
+
You are Welcome!
+
+
+
+
+
+
diff --git a/frontend/views/site/login.php b/frontend/views/site/login.php
new file mode 100755
index 0000000..d9808a5
--- /dev/null
+++ b/frontend/views/site/login.php
@@ -0,0 +1,39 @@
+title = Yii::t('app', 'Auth');
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
= Yii::t('app', 'Please fill out the following fields to login') ?>:
+
+
+
+ 'login-form']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+ = $form->field($model, 'rememberMe')->checkbox() ?>
+
+
+ =Yii::t('app', 'If you forgot your password you can') ?> = Html::a(Yii::t('app', 'reset it'), ['site/request-password-reset']) ?>.
+
+
+
+ = Html::submitButton(Yii::t('app', 'Login'), ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/main.php b/frontend/views/site/main.php
new file mode 100755
index 0000000..81852bb
--- /dev/null
+++ b/frontend/views/site/main.php
@@ -0,0 +1,139 @@
+title = Yii::t('app', 'Battle of WarShips!');
+?>
+
+
+
=Yii::t('app', 'Hello') ?>, =Yii::$app->user->identity->username; ?>!
+ =Yii::t('app', 'Here is your Port of Battle Ships!') ?>
+
+
+
+
+
+
+ [ ' . $shipname->name . ' ]';
+ echo ' ';
+ echo '  name . '.png>';
+ echo '
';
+ echo Yii::t('app', 'Strength').': ' . $model->strength . ' | '.Yii::t('app', 'Experience').': ' . $model->exp . ' | '.Yii::t('app', 'Credits').': ' . $user->credits . '. ';
+?>
+
+
+ =Yii::t('app', 'Statistics') ?>:
+
+ '.$user->win.' ';
+ echo Yii::t('app', 'LOSE').': '.$user->lose.' ';
+ echo Yii::t('app', 'DRAW').': '.$user->draw.' ';
+ ?>
+
+ |
+
+
+
+ " . Yii::t('app', 'Available Mods') . "
";
+ if (($model->exp_gun) != 1) {
+ if (($model->exp) >= ($avaible_mods->exp_gun)) {
+ $form = ActiveForm::begin(['id' => 'exp_mod_gun']);
+ echo "  - " . Yii::t('app', 'Modified Main Battery') . " " . Html::submitButton(Yii::t('app', 'Explore'), ['class' => 'btn btn-lg btn-success', 'style' => 'width: 140px; height: 25px; padding: 0px 3px 1px 3px', 'name' => 'expmodgun', 'id' => 'exp_mod_gun', 'value' => 'Explore']);
+ ActiveForm::end();
+ } else {
+ echo "  - " . Yii::t('app', 'Modified Main Battery') . "";
+ }
+ } else {
+ if (($model->mod_gun) != 1) {
+ $form = ActiveForm::begin(['id' => 'buy_mod_gun']);
+ echo "  - " . Yii::t('app', 'Modified Main Battery') . " - Already explored ".Html::submitButton(Yii::t('app', 'Buy'), ['class' => 'btn btn-primary', 'style' => 'width: 70px; height: 25px; padding: 0px 3px 1px 3px', 'name' => 'buymodgun', 'id' => 'buy_mod_gun', 'value' => 'Buy']);
+ ActiveForm::end();
+ } else {
+ echo "  - " . Yii::t('app', 'Modified Main Battery') . " - Installed ";
+ }
+ }
+ echo " ";
+ if (($model->exp_tower) != 1) {
+ if (($model->exp) >= ($avaible_mods->exp_tower)) {
+ $form = ActiveForm::begin(['id' => 'exp_mod_tower']);
+ echo "  - " . Yii::t('app', 'Improved Hit Points(HP)') . " " . Html::submitButton(Yii::t('app', 'Explore'), ['class' => 'btn btn-lg btn-success', 'style' => 'width: 140px; height: 25px; padding: 0px 3px 1px 3px', 'name' => 'expmodtower', 'id' => 'exp_mod_tower', 'value' => 'Explore']);
+ ActiveForm::end();
+ } else {
+ echo "  - " . Yii::t('app', 'Improved Hit Points(HP)') . "";
+ }
+ } else {
+ if(($model->mod_tower) != 1) {
+ $form = ActiveForm::begin(['id' => 'buy_mod_tower']);
+ echo "  - " . Yii::t('app', 'Improved Hit Points(HP)') . " - Already explored ".Html::submitButton(Yii::t('app', 'Buy'), ['class' => 'btn btn-primary', 'style' => 'width: 70px; height: 25px; padding: 0px 3px 1px 3px', 'name' => 'buymodtower', 'id' => 'buy_mod_tower', 'value' => 'Buy']);
+ ActiveForm::end();
+ } else {
+ echo "  - " . Yii::t('app', 'Improved Hit Points(HP)') . " Installed";
+ }
+ }
+ }
+ ?>
+
+
+
+ =Yii::t('app', 'Installed modules') ?>
+
+
+ stock_gun == 1 && $model->mod_gun == 0) {
+ echo ''.Yii::t('app', 'Stock Gun').' - ';
+ } elseif($model->stock_gun == 0 && $model->mod_gun == 1) {
+ echo ''.Yii::t('app', 'Modificate Gun').' - ';
+ }
+ if($model->stock_tower == 1 && $model->mod_tower == 0) {
+ echo ''.Yii::t('app', 'Stock Tower').' - ';
+ } elseif($model->stock_tower == 0 && $model->mod_tower == 1) {
+ echo ''.Yii::t('app', 'Modificate Tower').' - ';
+ }
+
+ } else {
+ echo "".Yii::t('app', 'Please, chose your first Warship')."!";
+?>
+
+
+
+ 'shipone']); ?>
+
+
+ 
+ =Yii::t('app', 'Leningrad') ?>
+
+
+
+ = Html::submitButton(Yii::t('app', 'getShip'), ['class' => 'btn btn-primary', 'style' => 'width: 320px', 'name' => 'shipfirst', 'id' => 'shipone', 'value' => '2', 'width' => 50]) ?>
+
+
+ |
+
+ 'shiptwo']); ?>
+
+
+ 
+ =Yii::t('app', 'Warspite') ?>
+
+
+
+ = Html::submitButton(Yii::t('app', 'getShip'), ['class' => 'btn btn-primary', 'style' => 'width: 320px', 'name' => 'shipsecond', 'id' => 'shiptwo', 'value' => '4', 'width' => 150]) ?>
+
+
+ |
+
+
+
+ |
+
+
+
+
diff --git a/frontend/views/site/requestPasswordResetToken.php b/frontend/views/site/requestPasswordResetToken.php
new file mode 100755
index 0000000..9f6822e
--- /dev/null
+++ b/frontend/views/site/requestPasswordResetToken.php
@@ -0,0 +1,31 @@
+title = 'Request password reset';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out your email. A link to reset password will be sent there.
+
+
+
+ 'request-password-reset-form']); ?>
+
+ = $form->field($model, 'email')->textInput(['autofocus' => true]) ?>
+
+
+ = Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/resetPassword.php b/frontend/views/site/resetPassword.php
new file mode 100755
index 0000000..36ef452
--- /dev/null
+++ b/frontend/views/site/resetPassword.php
@@ -0,0 +1,31 @@
+title = 'Reset password';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please choose your new password:
+
+
+
+ 'reset-password-form']); ?>
+
+ = $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>
+
+
+ = Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/signup.php b/frontend/views/site/signup.php
new file mode 100755
index 0000000..d57438a
--- /dev/null
+++ b/frontend/views/site/signup.php
@@ -0,0 +1,44 @@
+title = Yii::t('app', 'Reg');
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+ = Html::encode($this->title) ?>
+
+ = Yii::t('app', 'Please fill out the following fields to signup') ?>:
+
+
+
+ 'form-signup']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'email') ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+
+ = Html::submitButton(Yii::t('app', 'Signup'), ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
+
+
+
+
+
+
+
+ |
+
+
diff --git a/frontend/views/toprank/index.php b/frontend/views/toprank/index.php
new file mode 100644
index 0000000..4555612
--- /dev/null
+++ b/frontend/views/toprank/index.php
@@ -0,0 +1,42 @@
+
+=Yii::t('app', 'Top Rank users') ?>!
+
+
+
+
diff --git a/frontend/web/.gitignore b/frontend/web/.gitignore
new file mode 100755
index 0000000..25c74e6
--- /dev/null
+++ b/frontend/web/.gitignore
@@ -0,0 +1,2 @@
+/index.php
+/index-test.php
diff --git a/frontend/web/.htaccess b/frontend/web/.htaccess
new file mode 100755
index 0000000..1426180
--- /dev/null
+++ b/frontend/web/.htaccess
@@ -0,0 +1,10 @@
+Options +FollowSymLinks
+
+RewriteEngine on
+
+# if a directory or a file exists, use it directly
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+
+# otherwise forward it to index.php
+RewriteRule . index.php
diff --git a/frontend/web/assets/.gitignore b/frontend/web/assets/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/frontend/web/assets/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/frontend/web/css/site.css b/frontend/web/css/site.css
new file mode 100755
index 0000000..269da07
--- /dev/null
+++ b/frontend/web/css/site.css
@@ -0,0 +1,444 @@
+html,
+body {
+ height: 100%;
+ background: url('../img/bg.jpg');
+}
+
+l-separator{
+ width:100%;
+ padding:0;
+ z-index:-1;
+}
+
+l-separator__header{
+ position:absolute;
+ margin:0;
+ left:0;
+ bottom:-33px;
+}
+
+.b-separator{
+ background:url('../img/separator.png') no-repeat scroll 0 0;
+}
+
+.b-separator-right{
+ background:url('../img/separator_1.png') no-repeat scroll 100% 0 transparent;
+ height:81px;
+ width:349px;
+ float:right;
+ margin-right:-349px;
+ position:relative;
+}
+
+.wrap {
+ min-height: 100%;
+ height: auto;
+ margin: 0 auto -60px;
+ padding: 0 0 60px;
+}
+
+.wrap > .container {
+ padding: 70px 15px 20px;
+}
+
+.toprank {
+ font-weight: bold;
+ padding: 3px 4px;
+ text-align: left;
+}
+.toprank td {
+ padding: 4px 10px;
+}
+
+.toph {
+ border-bottom:3px solid lightblue;
+}
+
+.footer {
+ height: 60px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ padding-top: 20px;
+}
+
+.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 th {
+ white-space: nowrap;
+}
+
+.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 > button.logout {
+ padding: 15px;
+ border: none;
+}
+
+@media(max-width:767px) {
+ .nav li > form > button.logout {
+ display:block;
+ text-align: left;
+ width: 100%;
+ padding: 10px 15px;
+ }
+}
+
+.nav > li > form > button.logout:focus,
+.nav > li > form > button.logout:hover {
+ text-decoration: none;
+}
+
+.nav > li > form > button.logout:focus {
+ outline: none;
+}
+
+.CodeMirror {
+ border: 1px solid #eee;
+}
+
+.project-card {
+ padding: 2rem;
+ background: rgba(128, 128, 128, .1);
+ position: relative;
+ margin: 0 1rem 1rem 0;
+}
+
+.featured {
+ color: #ffcc4b;
+}
+
+.label.status-deleted {
+ background: rgba(200, 10, 10, .5);
+}
+
+.label.status-draft {
+ background: rgba(10, 10, 200, .8);
+}
+
+.project-card {
+ display: inline-block;
+}
+
+.project-card img {
+ border: 2px solid transparent;
+}
+
+.project-card.status-deleted img {
+ border: 2px solid rgba(200, 10, 10, .5);
+}
+
+.project-card.status-draft img {
+ border: 2px solid rgba(10, 10, 200, .5);
+}
+
+.project-card img {
+ background: rgba(128, 128, 128, .1);
+}
+
+.project-card h1 {
+ font-size: large;
+}
+
+.authors {
+ list-style: none;
+ padding: 0;
+}
+
+.authors li {
+ display: inline-block;
+}
+
+.author img {
+ border-radius: 32px;
+}
+
+.tags {
+ list-style: none;
+ padding: 0;
+}
+
+.tags li {
+ display: inline-block;
+ padding: .5rem;
+ background: #eedc43;
+ border-radius: .25em;
+}
+
+.project-view .content {
+ margin: 4rem 0 1rem 0;
+ padding-bottom: 2rem;
+ border-bottom: 1px solid #eee;
+}
+
+.project-view .images {
+ margin-top: 2rem;
+}
+
+.project-view .image a {
+ display: inline-block;
+ padding: 2rem;
+ background: rgba(128, 128, 128, .1);
+}
+
+.project-view .image {
+ position: relative;
+ display: inline-block;
+}
+
+.project-view .image .delete {
+ position: absolute;
+ top: 0;
+ right: 0;
+ font-size: 150%;
+ background: #fff;
+ border-radius: 10rem;
+ cursor: pointer;
+}
+
+.project-view .image .delete:hover {
+ color: #f00;
+}
+
+.projects-flow {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-start;
+ align-content: space-around;
+ align-items: flex-start;
+}
+
+.projects-flow .item {
+ min-width: 25em;
+ margin: 1em;
+ flex: 1 0 0;
+}
+
+.pagination {
+ width: 100%;
+}
+
+.row_b {
+ padding: 6px;
+ border:1px solid #0d3349;
+}
+
+.radio {
+ padding-left: 20px;
+}
+.radio label {
+ display: inline-block;
+ position: relative;
+ padding-left: 5px;
+}
+.radio label::before {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ width: 17px;
+ height: 17px;
+ left: 0;
+ margin-left: -20px;
+ border: 1px solid #cccccc;
+ border-radius: 50%;
+ background-color: #fff;
+ -webkit-transition: border 0.15s ease-in-out;
+ -o-transition: border 0.15s ease-in-out;
+ transition: border 0.15s ease-in-out;
+}
+.radio label::after {
+ display: inline-block;
+ position: absolute;
+ content: " ";
+ width: 11px;
+ height: 11px;
+ left: 3px;
+ top: 3px;
+ margin-left: -20px;
+ border-radius: 50%;
+ background-color: #555555;
+ -webkit-transform: scale(0, 0);
+ -ms-transform: scale(0, 0);
+ -o-transform: scale(0, 0);
+ transform: scale(0, 0);
+ -webkit-transition: -webkit-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);
+ -moz-transition: -moz-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);
+ -o-transition: -o-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);
+ transition: transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);
+}
+.radio input[type="radio"] {
+ opacity: 0;
+}
+.radio input[type="radio"]:focus + label::before {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.radio input[type="radio"]:checked + label::after {
+ -webkit-transform: scale(1, 1);
+ -ms-transform: scale(1, 1);
+ -o-transform: scale(1, 1);
+ transform: scale(1, 1);
+}
+.radio input[type="radio"]:disabled + label {
+ opacity: 0.65;
+}
+.radio input[type="radio"]:disabled + label::before {
+ cursor: not-allowed;
+}
+.radio.radio-inline {
+ margin-top: 0;
+}
+
+.radio-primary input[type="radio"] + label::after {
+ background-color: #428bca;
+}
+.radio-primary input[type="radio"]:checked + label::before {
+ border-color: #428bca;
+}
+.radio-primary input[type="radio"]:checked + label::after {
+ background-color: #428bca;
+}
+
+.radio-danger input[type="radio"] + label::after {
+ background-color: #d9534f;
+}
+.radio-danger input[type="radio"]:checked + label::before {
+ border-color: #d9534f;
+}
+.radio-danger input[type="radio"]:checked + label::after {
+ background-color: #d9534f;
+}
+
+.radio-info input[type="radio"] + label::after {
+ background-color: #5bc0de;
+}
+.radio-info input[type="radio"]:checked + label::before {
+ border-color: #5bc0de;
+}
+.radio-info input[type="radio"]:checked + label::after {
+ background-color: #5bc0de;
+}
+
+.radio-warning input[type="radio"] + label::after {
+ background-color: #f0ad4e;
+}
+.radio-warning input[type="radio"]:checked + label::before {
+ border-color: #f0ad4e;
+}
+.radio-warning input[type="radio"]:checked + label::after {
+ background-color: #f0ad4e;
+}
+
+.radio-success input[type="radio"] + label::after {
+ background-color: #5cb85c;
+}
+.radio-success input[type="radio"]:checked + label::before {
+ border-color: #5cb85c;
+}
+.radio-success input[type="radio"]:checked + label::after {
+ background-color: #5cb85c;
+}
+
+.btn-outlined {
+ border-radius: 0;
+ -webkit-transition: all 0.3s;
+ -moz-transition: all 0.3s;
+ transition: all 0.3s;
+}
+.btn-outlined.btn-primary {
+ background: none;
+ border: 1px solid #428bca;
+ color: #428bca;
+}
+.btn-outlined.btn-primary:hover,
+.btn-outlined.btn-primary:active {
+ color: #FFF;
+ background: #428bca;
+ border-color: #428bca;
+}
+
+.dock {
+ height: 100%;
+ width: 100%;
+ background: url('../img/dock_bg.jpg') no-repeat;
+}
\ No newline at end of file
diff --git a/frontend/web/favicon.ico b/frontend/web/favicon.ico
new file mode 100755
index 0000000..580ed73
Binary files /dev/null and b/frontend/web/favicon.ico differ
diff --git a/frontend/web/img/1.png b/frontend/web/img/1.png
new file mode 100755
index 0000000..319c477
Binary files /dev/null and b/frontend/web/img/1.png differ
diff --git a/frontend/web/img/2.png b/frontend/web/img/2.png
new file mode 100755
index 0000000..a7e3527
Binary files /dev/null and b/frontend/web/img/2.png differ
diff --git a/frontend/web/img/bg.jpg b/frontend/web/img/bg.jpg
new file mode 100644
index 0000000..37dd76c
Binary files /dev/null and b/frontend/web/img/bg.jpg differ
diff --git a/frontend/web/img/dock_bg.jpg b/frontend/web/img/dock_bg.jpg
new file mode 100644
index 0000000..e976e1d
Binary files /dev/null and b/frontend/web/img/dock_bg.jpg differ
diff --git a/frontend/web/img/mod_gun.png b/frontend/web/img/mod_gun.png
new file mode 100755
index 0000000..d93d354
Binary files /dev/null and b/frontend/web/img/mod_gun.png differ
diff --git a/frontend/web/img/mod_tower.png b/frontend/web/img/mod_tower.png
new file mode 100755
index 0000000..a603922
Binary files /dev/null and b/frontend/web/img/mod_tower.png differ
diff --git a/frontend/web/img/projectgame_bg.jpg b/frontend/web/img/projectgame_bg.jpg
new file mode 100755
index 0000000..ed56a22
Binary files /dev/null and b/frontend/web/img/projectgame_bg.jpg differ
diff --git a/frontend/web/img/projectgame_bg1 b/frontend/web/img/projectgame_bg1
new file mode 100755
index 0000000..2fd8d27
Binary files /dev/null and b/frontend/web/img/projectgame_bg1 differ
diff --git a/frontend/web/img/projectgame_bg1.jpg b/frontend/web/img/projectgame_bg1.jpg
new file mode 100755
index 0000000..2fd8d27
Binary files /dev/null and b/frontend/web/img/projectgame_bg1.jpg differ
diff --git a/frontend/web/img/projectgame_bg_1.jpg b/frontend/web/img/projectgame_bg_1.jpg
new file mode 100755
index 0000000..27e79bc
Binary files /dev/null and b/frontend/web/img/projectgame_bg_1.jpg differ
diff --git a/frontend/web/img/separator.png b/frontend/web/img/separator.png
new file mode 100644
index 0000000..5d32d8d
Binary files /dev/null and b/frontend/web/img/separator.png differ
diff --git a/frontend/web/img/separator_1.png b/frontend/web/img/separator_1.png
new file mode 100644
index 0000000..5d32d8d
Binary files /dev/null and b/frontend/web/img/separator_1.png differ
diff --git a/frontend/web/img/ships/Albany.png b/frontend/web/img/ships/Albany.png
new file mode 100755
index 0000000..f98f54f
Binary files /dev/null and b/frontend/web/img/ships/Albany.png differ
diff --git a/frontend/web/img/ships/Arizona.png b/frontend/web/img/ships/Arizona.png
new file mode 100755
index 0000000..703d673
Binary files /dev/null and b/frontend/web/img/ships/Arizona.png differ
diff --git a/frontend/web/img/ships/Atago.png b/frontend/web/img/ships/Atago.png
new file mode 100755
index 0000000..50222f8
Binary files /dev/null and b/frontend/web/img/ships/Atago.png differ
diff --git a/frontend/web/img/ships/Atlanta.png b/frontend/web/img/ships/Atlanta.png
new file mode 100755
index 0000000..39a7440
Binary files /dev/null and b/frontend/web/img/ships/Atlanta.png differ
diff --git a/frontend/web/img/ships/Aurora.png b/frontend/web/img/ships/Aurora.png
new file mode 100755
index 0000000..80a6003
Binary files /dev/null and b/frontend/web/img/ships/Aurora.png differ
diff --git a/frontend/web/img/ships/Bliskavutsya.png b/frontend/web/img/ships/Bliskavutsya.png
new file mode 100755
index 0000000..fb0de21
Binary files /dev/null and b/frontend/web/img/ships/Bliskavutsya.png differ
diff --git a/frontend/web/img/ships/Campbeltown.png b/frontend/web/img/ships/Campbeltown.png
new file mode 100755
index 0000000..79977f0
Binary files /dev/null and b/frontend/web/img/ships/Campbeltown.png differ
diff --git a/frontend/web/img/ships/Diana.png b/frontend/web/img/ships/Diana.png
new file mode 100755
index 0000000..225ef46
Binary files /dev/null and b/frontend/web/img/ships/Diana.png differ
diff --git a/frontend/web/img/ships/Emden.png b/frontend/web/img/ships/Emden.png
new file mode 100755
index 0000000..e0a25da
Binary files /dev/null and b/frontend/web/img/ships/Emden.png differ
diff --git a/frontend/web/img/ships/Ishiz.png b/frontend/web/img/ships/Ishiz.png
new file mode 100755
index 0000000..feed962
Binary files /dev/null and b/frontend/web/img/ships/Ishiz.png differ
diff --git a/frontend/web/img/ships/KoenigAlbert.png b/frontend/web/img/ships/KoenigAlbert.png
new file mode 100755
index 0000000..112460f
Binary files /dev/null and b/frontend/web/img/ships/KoenigAlbert.png differ
diff --git a/frontend/web/img/ships/Leningrad.png b/frontend/web/img/ships/Leningrad.png
new file mode 100644
index 0000000..66f9ee9
Binary files /dev/null and b/frontend/web/img/ships/Leningrad.png differ
diff --git a/frontend/web/img/ships/Marblehead.png b/frontend/web/img/ships/Marblehead.png
new file mode 100755
index 0000000..6238dc7
Binary files /dev/null and b/frontend/web/img/ships/Marblehead.png differ
diff --git a/frontend/web/img/ships/MixailKytyzov.png b/frontend/web/img/ships/MixailKytyzov.png
new file mode 100755
index 0000000..00a325a
Binary files /dev/null and b/frontend/web/img/ships/MixailKytyzov.png differ
diff --git a/frontend/web/img/ships/Molotov.png b/frontend/web/img/ships/Molotov.png
new file mode 100755
index 0000000..7d72ea4
Binary files /dev/null and b/frontend/web/img/ships/Molotov.png differ
diff --git a/frontend/web/img/ships/Murmansk.png b/frontend/web/img/ships/Murmansk.png
new file mode 100755
index 0000000..bbcefa8
Binary files /dev/null and b/frontend/web/img/ships/Murmansk.png differ
diff --git a/frontend/web/img/ships/RedCrimea.png b/frontend/web/img/ships/RedCrimea.png
new file mode 100755
index 0000000..462945e
Binary files /dev/null and b/frontend/web/img/ships/RedCrimea.png differ
diff --git a/frontend/web/img/ships/Simple.png b/frontend/web/img/ships/Simple.png
new file mode 100755
index 0000000..319c477
Binary files /dev/null and b/frontend/web/img/ships/Simple.png differ
diff --git a/frontend/web/img/ships/Smith.png b/frontend/web/img/ships/Smith.png
new file mode 100755
index 0000000..64b4d00
Binary files /dev/null and b/frontend/web/img/ships/Smith.png differ
diff --git a/frontend/web/img/ships/Tachibana.png b/frontend/web/img/ships/Tachibana.png
new file mode 100755
index 0000000..3342e49
Binary files /dev/null and b/frontend/web/img/ships/Tachibana.png differ
diff --git a/frontend/web/img/ships/Texas.png b/frontend/web/img/ships/Texas.png
new file mode 100755
index 0000000..7a1e939
Binary files /dev/null and b/frontend/web/img/ships/Texas.png differ
diff --git a/frontend/web/img/ships/Tirpitz.png b/frontend/web/img/ships/Tirpitz.png
new file mode 100755
index 0000000..26a08ac
Binary files /dev/null and b/frontend/web/img/ships/Tirpitz.png differ
diff --git a/frontend/web/img/ships/Warspite.png b/frontend/web/img/ships/Warspite.png
new file mode 100644
index 0000000..cae2172
Binary files /dev/null and b/frontend/web/img/ships/Warspite.png differ
diff --git a/frontend/web/img/ships/belfast.png b/frontend/web/img/ships/belfast.png
new file mode 100755
index 0000000..100efdc
Binary files /dev/null and b/frontend/web/img/ships/belfast.png differ
diff --git a/frontend/web/img/stock_gun.png b/frontend/web/img/stock_gun.png
new file mode 100755
index 0000000..7ea8921
Binary files /dev/null and b/frontend/web/img/stock_gun.png differ
diff --git a/frontend/web/img/stock_tower.png b/frontend/web/img/stock_tower.png
new file mode 100755
index 0000000..c333241
Binary files /dev/null and b/frontend/web/img/stock_tower.png differ
diff --git a/frontend/web/robots.txt b/frontend/web/robots.txt
new file mode 100755
index 0000000..6f27bb6
--- /dev/null
+++ b/frontend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:
\ No newline at end of file
diff --git a/init b/init
new file mode 100755
index 0000000..7aaf086
--- /dev/null
+++ b/init
@@ -0,0 +1,299 @@
+#!/usr/bin/env php
+
+ *
+ * @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")) {
+ if (@chmod("$root/$writable", 0777)) {
+ echo " chmod 0777 $writable\n";
+ } else {
+ printError("Operation chmod not permitted for directory $writable.");
+ }
+ } else {
+ printError("Directory $writable does not exist.");
+ }
+ }
+}
+
+function setExecutable($root, $paths)
+{
+ foreach ($paths as $executable) {
+ if (file_exists("$root/$executable")) {
+ if (@chmod("$root/$executable", 0755)) {
+ echo " chmod 0755 $executable\n";
+ } else {
+ printError("Operation chmod not permitted for $executable.");
+ }
+ } else {
+ printError("$executable does not exist.");
+ }
+ }
+}
+
+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) {
+ //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);
+ }
+ if (@symlink($root . "/" . $target, $root . "/" . $link)) {
+ echo " symlink $root/$target $root/$link\n";
+ } else {
+ printError("Cannot create symlink $root/$target $root/$link.");
+ }
+ }
+}
+
+/**
+ * Prints error message.
+ * @param string $message message
+ */
+function printError($message)
+{
+ echo "\n " . formatMessage("Error. $message", ['fg-red']) . " \n";
+}
+
+/**
+ * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream.
+ *
+ * - windows without ansicon
+ * - not tty consoles
+ *
+ * @return boolean true if the stream supports ANSI colors, otherwise false.
+ */
+function ansiColorsSupported()
+{
+ return DIRECTORY_SEPARATOR === '\\'
+ ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'
+ : function_exists('posix_isatty') && @posix_isatty(STDOUT);
+}
+
+/**
+ * Get ANSI code of style.
+ * @param string $name style name
+ * @return integer ANSI code of style.
+ */
+function getStyleCode($name)
+{
+ $styles = [
+ 'bold' => 1,
+ 'fg-black' => 30,
+ 'fg-red' => 31,
+ 'fg-green' => 32,
+ 'fg-yellow' => 33,
+ 'fg-blue' => 34,
+ 'fg-magenta' => 35,
+ 'fg-cyan' => 36,
+ 'fg-white' => 37,
+ 'bg-black' => 40,
+ 'bg-red' => 41,
+ 'bg-green' => 42,
+ 'bg-yellow' => 43,
+ 'bg-blue' => 44,
+ 'bg-magenta' => 45,
+ 'bg-cyan' => 46,
+ 'bg-white' => 47,
+ ];
+ return $styles[$name];
+}
+
+/**
+ * Formats message using styles if STDOUT supports it.
+ * @param string $message message
+ * @param string[] $styles styles
+ * @return string formatted message.
+ */
+function formatMessage($message, $styles)
+{
+ if (empty($styles) || !ansiColorsSupported()) {
+ return $message;
+ }
+
+ return sprintf("\x1b[%sm", implode(';', array_map('getStyleCode', $styles))) . $message . "\x1b[0m";
+}
diff --git a/init.bat b/init.bat
new file mode 100755
index 0000000..e50c242
--- /dev/null
+++ b/init.bat
@@ -0,0 +1,20 @@
+@echo off
+
+rem -------------------------------------------------------------
+rem Yii command line init script for Windows.
+rem
+rem @author Qiang Xue
+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
diff --git a/requirements.php b/requirements.php
new file mode 100755
index 0000000..62c731b
--- /dev/null
+++ b/requirements.php
@@ -0,0 +1,132 @@
+Error';
+ echo 'The path to yii framework seems to be incorrect.
';
+ echo 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . '.
';
+ echo 'Please refer to the README on how to install Yii.
';
+}
+
+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' => 'MemCache',
+ 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : ''
+ ),
+ array(
+ 'name' => 'APC extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('apc'),
+ 'by' => 'ApcCache',
+ ),
+ // CAPTCHA:
+ array(
+ 'name' => 'GD PHP extension with FreeType support',
+ 'mandatory' => false,
+ 'condition' => $gdOK,
+ 'by' => 'Captcha',
+ 'memo' => $gdMemo,
+ ),
+ array(
+ 'name' => 'ImageMagick PHP extension with PNG support',
+ 'mandatory' => false,
+ 'condition' => $imagickOK,
+ 'by' => 'Captcha',
+ '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();
diff --git a/vagrant/config/.gitignore b/vagrant/config/.gitignore
new file mode 100755
index 0000000..0685a56
--- /dev/null
+++ b/vagrant/config/.gitignore
@@ -0,0 +1,2 @@
+# local configuration
+vagrant-local.yml
\ No newline at end of file
diff --git a/vagrant/config/vagrant-local.example.yml b/vagrant/config/vagrant-local.example.yml
new file mode 100755
index 0000000..32dd3ab
--- /dev/null
+++ b/vagrant/config/vagrant-local.example.yml
@@ -0,0 +1,22 @@
+# Your personal GitHub token
+github_token:
+# Read more: https://github.com/blog/1509-personal-api-tokens
+# You can generate it here: https://github.com/settings/tokens
+
+# Guest OS timezone
+timezone: Europe/London
+
+# Are we need check box updates for every 'vagrant up'?
+box_check_update: false
+
+# Virtual machine name
+machine_name: y2aa
+
+# Virtual machine IP
+ip: 192.168.83.137
+
+# Virtual machine CPU cores number
+cpus: 1
+
+# Virtual machine RAM
+memory: 512
diff --git a/vagrant/nginx/app.conf b/vagrant/nginx/app.conf
new file mode 100755
index 0000000..fc8fe40
--- /dev/null
+++ b/vagrant/nginx/app.conf
@@ -0,0 +1,77 @@
+server {
+ charset utf-8;
+ client_max_body_size 128M;
+ sendfile off;
+
+ listen 80; ## listen for ipv4
+ #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
+
+ server_name y2aa-frontend.dev;
+ root /app/frontend/web/;
+ index index.php;
+
+ access_log /app/vagrant/nginx/log/frontend-access.log;
+ error_log /app/vagrant/nginx/log/frontend-error.log;
+
+ location / {
+ # Redirect everything that isn't a real file to index.php
+ try_files $uri $uri/ /index.php$is_args$args;
+ }
+
+ # uncomment to avoid processing of calls to non-existing static files by Yii
+ #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
+ # try_files $uri =404;
+ #}
+ #error_page 404 /404.html;
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ #fastcgi_pass 127.0.0.1:9000;
+ fastcgi_pass unix:/var/run/php5-fpm.sock;
+ try_files $uri =404;
+ }
+
+ location ~ /\.(ht|svn|git) {
+ deny all;
+ }
+}
+
+server {
+ charset utf-8;
+ client_max_body_size 128M;
+ sendfile off;
+
+ listen 80; ## listen for ipv4
+ #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
+
+ server_name y2aa-backend.dev;
+ root /app/backend/web/;
+ index index.php;
+
+ access_log /app/vagrant/nginx/log/backend-access.log;
+ error_log /app/vagrant/nginx/log/backend-error.log;
+
+ location / {
+ # Redirect everything that isn't a real file to index.php
+ try_files $uri $uri/ /index.php$is_args$args;
+ }
+
+ # uncomment to avoid processing of calls to non-existing static files by Yii
+ #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
+ # try_files $uri =404;
+ #}
+ #error_page 404 /404.html;
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ #fastcgi_pass 127.0.0.1:9000;
+ fastcgi_pass unix:/var/run/php5-fpm.sock;
+ try_files $uri =404;
+ }
+
+ location ~ /\.(ht|svn|git) {
+ deny all;
+ }
+}
diff --git a/vagrant/nginx/log/.gitignore b/vagrant/nginx/log/.gitignore
new file mode 100755
index 0000000..c15cedd
--- /dev/null
+++ b/vagrant/nginx/log/.gitignore
@@ -0,0 +1,5 @@
+# nginx logs
+backend-access.log
+backend-error.log
+frontend-access.log
+frontend-error.log
\ No newline at end of file
diff --git a/vagrant/provision/always-as-root.sh b/vagrant/provision/always-as-root.sh
new file mode 100755
index 0000000..f2465e7
--- /dev/null
+++ b/vagrant/provision/always-as-root.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+#== Bash helpers ==
+
+function info {
+ echo " "
+ echo "--> $1"
+ echo " "
+}
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+info "Restart web-stack"
+service php5-fpm restart
+service nginx restart
+service mysql restart
\ No newline at end of file
diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh
new file mode 100755
index 0000000..1dd108c
--- /dev/null
+++ b/vagrant/provision/once-as-root.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+
+#== Import script args ==
+
+timezone=$(echo "$1")
+
+#== Bash helpers ==
+
+function info {
+ echo " "
+ echo "--> $1"
+ echo " "
+}
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+info "Allocate swap for MySQL 5.6"
+fallocate -l 2048M /swapfile
+chmod 600 /swapfile
+mkswap /swapfile
+swapon /swapfile
+echo '/swapfile none swap defaults 0 0' >> /etc/fstab
+
+info "Configure locales"
+update-locale LC_ALL="C"
+dpkg-reconfigure locales
+
+info "Configure timezone"
+echo ${timezone} | tee /etc/timezone
+dpkg-reconfigure --frontend noninteractive tzdata
+
+info "Prepare root password for MySQL"
+debconf-set-selections <<< "mysql-server-5.6 mysql-server/root_password password \"''\""
+debconf-set-selections <<< "mysql-server-5.6 mysql-server/root_password_again password \"''\""
+echo "Done!"
+
+info "Update OS software"
+apt-get update
+apt-get upgrade -y
+
+info "Install additional software"
+apt-get install -y git php5-curl php5-cli php5-intl php5-mysqlnd php5-gd php5-fpm nginx mysql-server-5.6
+
+info "Configure MySQL"
+sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
+echo "Done!"
+
+info "Configure PHP-FPM"
+sed -i 's/user = www-data/user = vagrant/g' /etc/php5/fpm/pool.d/www.conf
+sed -i 's/group = www-data/group = vagrant/g' /etc/php5/fpm/pool.d/www.conf
+sed -i 's/owner = www-data/owner = vagrant/g' /etc/php5/fpm/pool.d/www.conf
+echo "Done!"
+
+info "Configure NGINX"
+sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf
+echo "Done!"
+
+info "Enabling site configuration"
+ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf
+echo "Done!"
+
+info "Initailize databases for MySQL"
+mysql -uroot <<< "CREATE DATABASE yii2advanced"
+mysql -uroot <<< "CREATE DATABASE yii2advanced_test"
+echo "Done!"
+
+info "Install composer"
+curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
\ No newline at end of file
diff --git a/vagrant/provision/once-as-vagrant.sh b/vagrant/provision/once-as-vagrant.sh
new file mode 100755
index 0000000..a9a5e33
--- /dev/null
+++ b/vagrant/provision/once-as-vagrant.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+#== Import script args ==
+
+github_token=$(echo "$1")
+
+#== Bash helpers ==
+
+function info {
+ echo " "
+ echo "--> $1"
+ echo " "
+}
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+info "Configure composer"
+composer config --global github-oauth.github.com ${github_token}
+echo "Done!"
+
+info "Install plugins for composer"
+composer global require "fxp/composer-asset-plugin:^1.2.0" --no-progress
+
+info "Install codeception"
+composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*" --no-progress
+echo 'export PATH=/home/vagrant/.config/composer/vendor/bin:$PATH' | tee -a /home/vagrant/.profile
+
+info "Install project dependencies"
+cd /app
+composer --no-progress --prefer-dist install
+
+info "Init project"
+./init --env=Development --overwrite=y
+
+info "Apply migrations"
+./yii migrate <<< "yes"
+
+info "Create bash-alias 'app' for vagrant user"
+echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases
+
+info "Enabling colorized prompt for guest console"
+sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc
diff --git a/yii.bat b/yii.bat
new file mode 100755
index 0000000..d516b3a
--- /dev/null
+++ b/yii.bat
@@ -0,0 +1,20 @@
+@echo off
+
+rem -------------------------------------------------------------
+rem Yii command line bootstrap script for Windows.
+rem
+rem @author Qiang Xue
+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%yii" %*
+
+@endlocal