commit 9e8e98c3794ba59961195c09aa5c8916718b13e1 Author: king199025 Date: Thu Oct 11 11:15:09 2018 +0300 first commit diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..a39b5b0 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "vendor/bower-asset" +} diff --git a/.gitignore b/.gitignore new file mode 100644 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/.htaccess b/.htaccess new file mode 100644 index 0000000..9e16a54 --- /dev/null +++ b/.htaccess @@ -0,0 +1,19 @@ +php_value date.timezone Europe/Moscow +AddDefaultCharset UTF-8 +# Mod_Autoindex + + # Запрещаем просмотр содержимого папок + Options -Indexes + + +# Mod_Rewrite + + Options +SymLinksIfOwnerMatch + # Включаем mod_rewrite + RewriteEngine On + IndexIgnore */* + # Перенаправляем administrator на входной скрипт админки + RewriteRule ^secure(.*)?$ /backend/web/$1 [L,PT] + # Перенаправляем все запросы на входной скрипт + RewriteRule ^([^/].*)?$ /frontend/web/$1 + \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 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/README.md b/README.md new file mode 100644 index 0000000..66fc082 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +

+ + + +

Yii 2 Advanced Project Template

+
+

+ +Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for +developing complex Web applications with multiple tiers. + +The template includes three tiers: front end, back end, and console, each of which +is a separate Yii application. + +The template is designed to work in a team development environment. It supports +deploying the application in different environments. + +Documentation is at [docs/guide/README.md](docs/guide/README.md). + +[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced) +[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced) +[![Build Status](https://travis-ci.org/yiisoft/yii2-app-advanced.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-advanced) + +DIRECTORY STRUCTURE +------------------- + +``` +common + config/ contains shared configurations + mail/ contains view files for e-mails + models/ contains model classes used in both backend and frontend + tests/ contains tests for common classes +console + config/ contains console configurations + controllers/ contains console controllers (commands) + migrations/ contains database migrations + models/ contains console-specific model classes + runtime/ contains files generated during runtime +backend + assets/ contains application assets such as JavaScript and CSS + config/ contains backend configurations + controllers/ contains Web controller classes + models/ contains backend-specific model classes + runtime/ contains files generated during runtime + tests/ contains tests for backend application + views/ contains view files for the Web application + web/ contains the entry script and Web resources +frontend + assets/ contains application assets such as JavaScript and CSS + config/ contains frontend configurations + controllers/ contains Web controller classes + models/ contains frontend-specific model classes + runtime/ contains files generated during runtime + tests/ contains tests for frontend application + views/ contains view files for the Web application + web/ contains the entry script and Web resources + widgets/ contains frontend widgets +vendor/ contains dependent 3rd-party packages +environments/ contains environment-based overrides +``` diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..4376f11 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,77 @@ +require 'yaml' +require 'fileutils' + +required_plugins = %w( vagrant-hostmanager vagrant-vbguest ) +required_plugins.each do |plugin| + exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin +end + +domains = { + frontend: 'y2aa-frontend.test', + backend: 'y2aa-backend.test' +} + +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 = 'bento/ubuntu-16.04' + + # 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 100644 index 0000000..940c0af --- /dev/null +++ b/backend/assets/AppAsset.php @@ -0,0 +1,23 @@ + 'app-backend', + 'basePath' => dirname(__DIR__), + 'controllerNamespace' => 'backend\controllers', + 'bootstrap' => ['log'], + + 'modules' => [ + 'status' => [ + 'class' => 'backend\modules\status\Status', + ], + 'fields' => [ + 'class' => 'backend\modules\fields\Fields', + ], + 'card' => [ + 'class' => 'backend\modules\card\Card', + ], + 'project' => [ + 'class' => 'backend\modules\project\Project', + ], + ], + 'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'baseUrl' => '/secure', + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true], + ], + 'session' => [ + // this is the name of the session cookie used for login on the backend + 'name' => 'advanced-backend', + ], + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + ], + ], + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => [ + ], + ], + + ], + 'params' => $params, +]; diff --git a/backend/config/params.php b/backend/config/params.php new file mode 100644 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 100644 index 0000000..ec2e9a1 --- /dev/null +++ b/backend/config/test.php @@ -0,0 +1,12 @@ + 'app-backend-tests', + 'components' => [ + 'assetManager' => [ + 'basePath' => __DIR__ . '/../web/assets', + ], + 'urlManager' => [ + 'showScriptName' => true, + ], + ], +]; diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php new file mode 100644 index 0000000..6d0a165 --- /dev/null +++ b/backend/controllers/SiteController.php @@ -0,0 +1,100 @@ + [ + '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 { + $model->password = ''; + + return $this->render('login', [ + 'model' => $model, + ]); + } + } + + /** + * Logout action. + * + * @return string + */ + public function actionLogout() + { + Yii::$app->user->logout(); + + return $this->goHome(); + } +} diff --git a/backend/models/.gitkeep b/backend/models/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/backend/models/.gitkeep @@ -0,0 +1 @@ +* diff --git a/backend/modules/card/Card.php b/backend/modules/card/Card.php new file mode 100644 index 0000000..88ffc41 --- /dev/null +++ b/backend/modules/card/Card.php @@ -0,0 +1,24 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all UserCard models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new UserCardSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single UserCard model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + $dataProvider = new ActiveDataProvider([ + 'query' => FieldsValue::find()->where(['card_id' => $id])->orderBy('order'), + 'pagination' => [ + 'pageSize' => 200, + ], + ]); + + return $this->render('view', [ + 'model' => $this->findModel($id), + 'modelFildValue' => $dataProvider, + ]); + } + + /** + * Creates a new UserCard model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new UserCard(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing UserCard model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing UserCard model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the UserCard model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return UserCard the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = UserCard::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/backend/modules/card/models/UserCard.php b/backend/modules/card/models/UserCard.php new file mode 100644 index 0000000..514241c --- /dev/null +++ b/backend/modules/card/models/UserCard.php @@ -0,0 +1,57 @@ +where( + [ + 'card_id' => \Yii::$app->request->get('id'), + 'project_id' => null, + ]) + ->all(); + $array = []; + if(!empty($fieldValue)){ + foreach ($fieldValue as $item){ + array_push($array, ['field_id' => $item->field_id, 'value' => $item->value, 'order' => $item->order]); + } + $this->fields = $array; + } + else{ + $this->fields = [ + [ + 'field_id' => null, + 'value' => null, + 'order' => null, + ], + ]; + } + } + + public function afterSave($insert, $changedAttributes) + { + $post = \Yii::$app->request->post('UserCard'); + + FieldsValue::deleteAll(['card_id' => $this->id]); + + foreach ( $post['fields'] as $item) { + $fildsValue = new FieldsValue(); + $fildsValue->field_id = $item['field_id']; + $fildsValue->value = $item['value']; + $fildsValue->order = $item['order']; + $fildsValue->card_id = $this->id; + + $fildsValue->save(); + } + + parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub + } +} \ No newline at end of file diff --git a/backend/modules/card/models/UserCardSearch.php b/backend/modules/card/models/UserCardSearch.php new file mode 100644 index 0000000..e0e7bd2 --- /dev/null +++ b/backend/modules/card/models/UserCardSearch.php @@ -0,0 +1,77 @@ + $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, + 'gender' => $this->gender, + 'dob' => $this->dob, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'fio', $this->fio]) + ->andFilterWhere(['like', 'passport', $this->passport]) + ->andFilterWhere(['like', 'photo', $this->photo]) + ->andFilterWhere(['like', 'email', $this->email]); + + return $dataProvider; + } +} diff --git a/backend/modules/card/views/user-card/_form.php b/backend/modules/card/views/user-card/_form.php new file mode 100644 index 0000000..dc2ffd0 --- /dev/null +++ b/backend/modules/card/views/user-card/_form.php @@ -0,0 +1,148 @@ + + +
+ + +
+
+ field($model, 'fio')->textInput(['maxlength' => true]) ?> +
+ +
+ field($model, 'passport')->textInput(['maxlength' => true]) ?> +
+
+ +
+
+
+ 'ru', + 'controller' => 'elfinder', + // вставляем название контроллера, по умолчанию равен elfinder + 'filter' => 'image', + // фильтр файлов, можно задать массив фильтров https://github.com/Studio-42/elFinder/wiki/Client-con.. + 'name' => 'UserCard[photo]', + 'id' => 'usercard-photo', + 'template' => '
{input}{button}
', + 'options' => ['class' => 'form-control itemImg', 'maxlength' => '255'], + 'buttonOptions' => ['class' => 'btn btn-primary'], + 'value' => $model->photo, + 'buttonName' => 'Выбрать изображение', + ]); + ?> +
+
+ + 'ru', + 'controller' => 'elfinder', + // вставляем название контроллера, по умолчанию равен elfinder + 'filter' => ['image','application/zip','application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document'], + // фильтр файлов, можно задать массив фильтров https://github.com/Studio-42/elFinder/wiki/Client-con.. + 'name' => 'UserCard[resume]', + 'id' => 'usercard-resume', + 'template' => '
{input}{button}
', + 'options' => ['class' => 'form-control itemImg', 'maxlength' => '255'], + 'buttonOptions' => ['class' => 'btn btn-primary'], + 'value' => $model->photo, + 'buttonName' => 'Выбрать резюме', + ]); + ?> +
+
+ +
+
+ field($model, 'email')->textInput(['maxlength' => true]) ?> +
+ +
+ field($model, 'gender')->dropDownList($model->genders, + [ + 'prompt' => 'Выберите' + ]) ?> +
+
+ +
+
+ field($model, 'dob')->input('date', + [ + 'placeholder' => 'Zadejte svůj Datum narození', + 'language' => 'en', + "data-format" => "DD MMMM YYYY", + + ]) ?> +
+
+ field($model, 'status') + ->dropDownList(\yii\helpers\ArrayHelper::map( + \common\models\Status::find() + ->joinWith('useStatuses') + ->where(['`use_status`.`use`' => \common\models\UseStatus::USE_PROFILE])->all(), 'id', 'name'), + [ + 'prompt' => 'Выберите' + ] + ) ?> +
+
+
+
+ field($model, 'fields')->widget(MultipleInput::class, [ + + 'columns' => [ + [ + 'name' => 'field_id', + 'type' => 'dropDownList', + 'title' => 'Поле', + 'defaultValue' => null, + 'items' => \yii\helpers\ArrayHelper::map(\backend\modules\fields\models\AdditionalFields::find() + ->joinWith('useFields') + ->where(['`use_field`.`use`' => \common\models\UseStatus::USE_PROFILE]) + ->all(), + 'id', 'name'), + 'options' => ['prompt' => 'Выберите'] + ], + [ + 'name' => 'value', + 'title' => 'Значение', + 'enableError' => true, + 'options' => [ + 'class' => 'input-priority' + ] + ], + [ + 'name' => 'order', + 'title' => 'Приоритет', + 'enableError' => true, + 'options' => [ + 'class' => 'input-priority' + ] + ] + ] + ])->label('Дополнительно'); + ?> +
+
+ +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/backend/modules/card/views/user-card/_search.php b/backend/modules/card/views/user-card/_search.php new file mode 100644 index 0000000..a328d09 --- /dev/null +++ b/backend/modules/card/views/user-card/_search.php @@ -0,0 +1,45 @@ + + + diff --git a/backend/modules/card/views/user-card/create.php b/backend/modules/card/views/user-card/create.php new file mode 100644 index 0000000..f3bb8da --- /dev/null +++ b/backend/modules/card/views/user-card/create.php @@ -0,0 +1,16 @@ +title = 'Новый профиль'; +$this->params['breadcrumbs'][] = ['label' => 'Профили', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/card/views/user-card/index.php b/backend/modules/card/views/user-card/index.php new file mode 100644 index 0000000..95741a2 --- /dev/null +++ b/backend/modules/card/views/user-card/index.php @@ -0,0 +1,39 @@ +title = 'Профили'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + 'fio', + 'passport', + 'photo', + 'email:email', + //'gender', + //'dob', + //'status', + //'created_at', + //'updated_at', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/backend/modules/card/views/user-card/update.php b/backend/modules/card/views/user-card/update.php new file mode 100644 index 0000000..917119b --- /dev/null +++ b/backend/modules/card/views/user-card/update.php @@ -0,0 +1,21 @@ +title = 'Update User Card: ' . $model->id; +$this->params['breadcrumbs'][] = ['label' => 'User Cards', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update'; +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/card/views/user-card/view.php b/backend/modules/card/views/user-card/view.php new file mode 100644 index 0000000..1a600ad --- /dev/null +++ b/backend/modules/card/views/user-card/view.php @@ -0,0 +1,68 @@ +title = $model->fio; +$this->params['breadcrumbs'][] = ['label' => 'User Cards', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> +

+ + $model, + 'attributes' => [ + 'fio', + 'passport', + [ + 'label' => 'Photo', + 'format' => 'raw', + 'value' => function($model){ + return Html::tag('img', null, ['src' => $model->photo, 'width' => '100px']); + } + ], + [ + 'label' => 'Resume', + 'format' => 'raw', + 'value' => function($model){ + return Html::a('Скачать', $model->resume, ['target' => '_blank']); + } + ], + [ + 'label' => 'gender', + 'value' => $model->gendersText, + ], + + 'email:email', + + 'dob', + [ + 'label' => 'status', + 'value' => $model->status0->name, + ], + 'created_at', + 'updated_at', + ], + ]) ?> + +

Дополнительные сведения

+ + $modelFildValue, + 'layout'=>"{items}", + 'columns' => [ + 'field.name:text:Поле', + 'value', + ], + ]); ?> + + +
diff --git a/backend/modules/fields/Fields.php b/backend/modules/fields/Fields.php new file mode 100644 index 0000000..9c04946 --- /dev/null +++ b/backend/modules/fields/Fields.php @@ -0,0 +1,24 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all AdditionalFields models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new AdditionalFieldsSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single AdditionalFields model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new AdditionalFields model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new AdditionalFields(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing AdditionalFields model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + $model->use = ArrayHelper::getColumn( + \common\models\UseField::find()->where(['field_id' => $model->id])->asArray()->all(), + 'use'); + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing AdditionalFields model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the AdditionalFields model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return AdditionalFields the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = AdditionalFields::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/backend/modules/fields/models/AdditionalFields.php b/backend/modules/fields/models/AdditionalFields.php new file mode 100644 index 0000000..f63bd1c --- /dev/null +++ b/backend/modules/fields/models/AdditionalFields.php @@ -0,0 +1,23 @@ + $this->id]); + + foreach ($this->use as $item) { + $useField = new UseField(); + $useField->field_id = $this->id; + $useField->use = $item; + + $useField->save(); + } + parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub + } +} \ No newline at end of file diff --git a/backend/modules/fields/models/AdditionalFieldsSearch.php b/backend/modules/fields/models/AdditionalFieldsSearch.php new file mode 100644 index 0000000..55f92d7 --- /dev/null +++ b/backend/modules/fields/models/AdditionalFieldsSearch.php @@ -0,0 +1,68 @@ + $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, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]); + + return $dataProvider; + } +} diff --git a/backend/modules/fields/views/additional-fields/_form.php b/backend/modules/fields/views/additional-fields/_form.php new file mode 100644 index 0000000..d89afe1 --- /dev/null +++ b/backend/modules/fields/views/additional-fields/_form.php @@ -0,0 +1,25 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'use')->checkboxList((new \common\models\UseField())->statuses); ?> + +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/backend/modules/fields/views/additional-fields/_search.php b/backend/modules/fields/views/additional-fields/_search.php new file mode 100644 index 0000000..68154c4 --- /dev/null +++ b/backend/modules/fields/views/additional-fields/_search.php @@ -0,0 +1,29 @@ + + + diff --git a/backend/modules/fields/views/additional-fields/create.php b/backend/modules/fields/views/additional-fields/create.php new file mode 100644 index 0000000..29fcfbf --- /dev/null +++ b/backend/modules/fields/views/additional-fields/create.php @@ -0,0 +1,19 @@ +title = 'Добавление поля'; +$this->params['breadcrumbs'][] = ['label' => 'Дополнительные поля', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/fields/views/additional-fields/index.php b/backend/modules/fields/views/additional-fields/index.php new file mode 100644 index 0000000..2443c2d --- /dev/null +++ b/backend/modules/fields/views/additional-fields/index.php @@ -0,0 +1,33 @@ +title = 'Дополнительные поля'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + 'name', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/backend/modules/fields/views/additional-fields/update.php b/backend/modules/fields/views/additional-fields/update.php new file mode 100644 index 0000000..4379236 --- /dev/null +++ b/backend/modules/fields/views/additional-fields/update.php @@ -0,0 +1,19 @@ +title = 'Редактирование: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Additional Fields', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update'; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/fields/views/additional-fields/view.php b/backend/modules/fields/views/additional-fields/view.php new file mode 100644 index 0000000..9d43ddf --- /dev/null +++ b/backend/modules/fields/views/additional-fields/view.php @@ -0,0 +1,36 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Additional Fields', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> + $model->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ]) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + ], + ]) ?> + +
diff --git a/backend/modules/project/Project.php b/backend/modules/project/Project.php new file mode 100644 index 0000000..8f1e18e --- /dev/null +++ b/backend/modules/project/Project.php @@ -0,0 +1,24 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Project models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new ProjectSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single Project model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + $dataProvider = new ActiveDataProvider([ + 'query' => FieldsValue::find()->where(['project_id' => $id])->orderBy('order'), + 'pagination' => [ + 'pageSize' => 200, + ], + ]); + + $dataProviderUser = new ActiveDataProvider([ + 'query' => ProjectUser::find()->where(['project_id' => $id]), + 'pagination' => [ + 'pageSize' => 200, + ], + ]); + + return $this->render('view', [ + 'model' => $this->findModel($id), + 'modelFildValue' => $dataProvider, + 'modelUser' => $dataProviderUser, + ]); + } + + /** + * Creates a new Project model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Project(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Project model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Project model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the Project model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Project the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Project::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/backend/modules/project/models/Project.php b/backend/modules/project/models/Project.php new file mode 100644 index 0000000..2721e74 --- /dev/null +++ b/backend/modules/project/models/Project.php @@ -0,0 +1,79 @@ +where( + [ + 'project_id' => \Yii::$app->request->get('id'), + 'card_id' => null, + ]) + ->all(); + $array = []; + if (!empty($fieldValue)) { + foreach ($fieldValue as $item) { + array_push($array, ['field_id' => $item->field_id, 'value' => $item->value, 'order' => $item->order]); + } + $this->fields = $array; + } else { + $this->fields = [ + [ + 'field_id' => null, + 'value' => null, + 'order' => null, + ], + ]; + } + + $user = ArrayHelper::getColumn(ProjectUser::find()->where(['project_id' => \Yii::$app->request->get('id')])->all(), + 'card_id'); + + if (!empty($user)) { + $this->user = $user; + + } + } + + public function afterSave($insert, $changedAttributes) + { + $post = \Yii::$app->request->post('Project'); + + FieldsValue::deleteAll(['project_id' => $this->id]); + + foreach ($post['fields'] as $item) { + $fildsValue = new FieldsValue(); + $fildsValue->field_id = $item['field_id']; + $fildsValue->value = $item['value']; + $fildsValue->order = $item['order']; + $fildsValue->project_id = $this->id; + + $fildsValue->save(); + } + + ProjectUser::deleteAll(['project_id' => $this->id]); + + foreach ($post['user'] as $item) { + $prUser = new ProjectUser(); + $prUser->project_id = $this->id; + $prUser->card_id = $item; + + $prUser->save(); + } + + parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub + } +} \ No newline at end of file diff --git a/backend/modules/project/models/ProjectSearch.php b/backend/modules/project/models/ProjectSearch.php new file mode 100644 index 0000000..9d80e61 --- /dev/null +++ b/backend/modules/project/models/ProjectSearch.php @@ -0,0 +1,72 @@ + $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, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]) + ->andFilterWhere(['like', 'description', $this->description]); + + return $dataProvider; + } +} diff --git a/backend/modules/project/views/project/_form.php b/backend/modules/project/views/project/_form.php new file mode 100644 index 0000000..a8bf3dd --- /dev/null +++ b/backend/modules/project/views/project/_form.php @@ -0,0 +1,77 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'description')->textarea(['rows' => 6]) ?> + +
+
+ field($model, 'fields')->widget(MultipleInput::class, [ + + 'columns' => [ + [ + 'name' => 'field_id', + 'type' => 'dropDownList', + 'title' => 'Поле', + 'defaultValue' => null, + 'items' => \yii\helpers\ArrayHelper::map(\backend\modules\fields\models\AdditionalFields::find() + ->joinWith('useFields') + ->where(['`use_field`.`use`' => \common\models\UseStatus::USE_PROJECT]) + ->all(), + 'id', 'name'), + 'options' => ['prompt' => 'Выберите'] + ], + [ + 'name' => 'value', + 'title' => 'Значение', + 'enableError' => true, + 'options' => [ + 'class' => 'input-priority' + ] + ], + [ + 'name' => 'order', + 'title' => 'Приоритет', + 'enableError' => true, + 'options' => [ + 'class' => 'input-priority' + ] + ] + ] + ])->label('Дополнительно'); + ?> +
+
+ + + field($model, 'user')->widget(Select2::class, + [ + 'data' => \yii\helpers\ArrayHelper::map(\common\models\UserCard::find()->all(),'id', 'fio'), + 'options' => ['placeholder' => '...','class' => 'form-control', 'multiple' => true], + 'pluginOptions' => [ + 'allowClear' => true + ], + ] + ); ?> + +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/backend/modules/project/views/project/_search.php b/backend/modules/project/views/project/_search.php new file mode 100644 index 0000000..c41830a --- /dev/null +++ b/backend/modules/project/views/project/_search.php @@ -0,0 +1,35 @@ + + + diff --git a/backend/modules/project/views/project/create.php b/backend/modules/project/views/project/create.php new file mode 100644 index 0000000..d96cece --- /dev/null +++ b/backend/modules/project/views/project/create.php @@ -0,0 +1,19 @@ +title = 'Создать'; +$this->params['breadcrumbs'][] = ['label' => 'Проекты', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/project/views/project/index.php b/backend/modules/project/views/project/index.php new file mode 100644 index 0000000..bed75ab --- /dev/null +++ b/backend/modules/project/views/project/index.php @@ -0,0 +1,36 @@ +title = 'Проекты'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + 'name', + 'description:ntext', + 'created_at', + 'updated_at', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/backend/modules/project/views/project/update.php b/backend/modules/project/views/project/update.php new file mode 100644 index 0000000..b56b0d9 --- /dev/null +++ b/backend/modules/project/views/project/update.php @@ -0,0 +1,18 @@ +title = 'Редактирование: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Проекты', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/project/views/project/view.php b/backend/modules/project/views/project/view.php new file mode 100644 index 0000000..4a59955 --- /dev/null +++ b/backend/modules/project/views/project/view.php @@ -0,0 +1,80 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Projects', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> + $model->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ]) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + 'description:ntext', + 'created_at', + 'updated_at', + ], + ]) ?> +

Дополнительные сведения

+ + $modelFildValue, + 'layout'=>"{items}", + 'columns' => [ + 'field.name:text:Поле', + 'value', + ], + ]); ?> + +

Пользователи проекта

+ + $modelUser, + 'layout'=>"{items}", + 'columns' => [ + 'card.fio:text:ФИО', + [ + 'class' => 'yii\grid\ActionColumn', + 'template' => '{view} {update}', + 'buttons' => [ + 'update' => function ($url,$model) { + return Html::a( + '', + ['/card/user-card/update', 'id' => $model->id], + ['target' => '_blank'] + ); + }, + 'view' => function ($url,$model) { + return Html::a( + '', + ['/card/user-card/view', 'id' => $model->id], + ['target' => '_blank'] + ); + }, + ], + + ], + ], + ]); ?> +
diff --git a/backend/modules/status/Status.php b/backend/modules/status/Status.php new file mode 100644 index 0000000..69976c9 --- /dev/null +++ b/backend/modules/status/Status.php @@ -0,0 +1,24 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Status models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new StatusSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single Status model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Status model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Status(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Status model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + $model->use = ArrayHelper::getColumn( + \common\models\UseStatus::find()->where(['status_id' => $model->id])->asArray()->all(), + 'use'); + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Status model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the Status model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Status the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Status::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/backend/modules/status/models/Status.php b/backend/modules/status/models/Status.php new file mode 100644 index 0000000..3e1b932 --- /dev/null +++ b/backend/modules/status/models/Status.php @@ -0,0 +1,22 @@ + $this->id]); + foreach ($this->use as $item) { + $useStatus = new UseStatus(); + $useStatus->status_id = $this->id; + $useStatus->use = $item; + + $useStatus->save(); + } + + parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub + } +} \ No newline at end of file diff --git a/backend/modules/status/models/StatusSearch.php b/backend/modules/status/models/StatusSearch.php new file mode 100644 index 0000000..cfeec40 --- /dev/null +++ b/backend/modules/status/models/StatusSearch.php @@ -0,0 +1,69 @@ + $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, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]); + + return $dataProvider; + } +} diff --git a/backend/modules/status/views/status/_form.php b/backend/modules/status/views/status/_form.php new file mode 100644 index 0000000..600f928 --- /dev/null +++ b/backend/modules/status/views/status/_form.php @@ -0,0 +1,26 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'use')->checkboxList((new \common\models\UseStatus())->statuses); ?> + +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/backend/modules/status/views/status/_search.php b/backend/modules/status/views/status/_search.php new file mode 100644 index 0000000..e5cb808 --- /dev/null +++ b/backend/modules/status/views/status/_search.php @@ -0,0 +1,29 @@ + + + diff --git a/backend/modules/status/views/status/create.php b/backend/modules/status/views/status/create.php new file mode 100644 index 0000000..411168c --- /dev/null +++ b/backend/modules/status/views/status/create.php @@ -0,0 +1,16 @@ +title = 'Добавить статус'; +$this->params['breadcrumbs'][] = ['label' => 'Статусы', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/status/views/status/index.php b/backend/modules/status/views/status/index.php new file mode 100644 index 0000000..a28ebd9 --- /dev/null +++ b/backend/modules/status/views/status/index.php @@ -0,0 +1,33 @@ +title = 'Statuses'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + 'name', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/backend/modules/status/views/status/update.php b/backend/modules/status/views/status/update.php new file mode 100644 index 0000000..95993bd --- /dev/null +++ b/backend/modules/status/views/status/update.php @@ -0,0 +1,17 @@ +title = 'Update Status: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Statuses', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update'; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/status/views/status/view.php b/backend/modules/status/views/status/view.php new file mode 100644 index 0000000..0920711 --- /dev/null +++ b/backend/modules/status/views/status/view.php @@ -0,0 +1,36 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Statuses', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> + $model->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ]) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + ], + ]) ?> + +
diff --git a/backend/runtime/.gitignore b/backend/runtime/.gitignore new file mode 100644 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 100644 index 0000000..44f5e81 --- /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 100644 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 100644 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 100644 index 0000000..80a79ed --- /dev/null +++ b/backend/tests/_support/FunctionalTester.php @@ -0,0 +1,25 @@ + [ + '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 100644 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 100644 index 0000000..f90030f --- /dev/null +++ b/backend/tests/unit.suite.yml @@ -0,0 +1,2 @@ +suite_namespace: backend\tests\unit +actor: UnitTester diff --git a/backend/tests/unit/_bootstrap.php b/backend/tests/unit/_bootstrap.php new file mode 100644 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/content.php b/backend/views/layouts/content.php new file mode 100644 index 0000000..38c9442 --- /dev/null +++ b/backend/views/layouts/content.php @@ -0,0 +1,235 @@ + +
+
+ blocks['content-header'])) { ?> +

blocks['content-header'] ?>

+ +

+ title !== null) { + echo \yii\helpers\Html::encode($this->title); + } else { + echo \yii\helpers\Inflector::camel2words( + \yii\helpers\Inflector::id2camel($this->context->module->id) + ); + echo ($this->context->module->id !== \Yii::$app->id) ? 'Module' : ''; + } ?> +

+ + + isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + ] + ) ?> +
+ +
+ + +
+
+ + + + + + +
\ No newline at end of file diff --git a/backend/views/layouts/header.php b/backend/views/layouts/header.php new file mode 100644 index 0000000..8d22b6a --- /dev/null +++ b/backend/views/layouts/header.php @@ -0,0 +1,281 @@ + + +
+ + APP' . Yii::$app->name . '', Yii::$app->homeUrl, ['class' => 'logo']) ?> + + +
diff --git a/backend/views/layouts/left.php b/backend/views/layouts/left.php new file mode 100644 index 0000000..931afec --- /dev/null +++ b/backend/views/layouts/left.php @@ -0,0 +1,48 @@ + diff --git a/backend/views/layouts/main-login.php b/backend/views/layouts/main-login.php new file mode 100644 index 0000000..c6525db --- /dev/null +++ b/backend/views/layouts/main-login.php @@ -0,0 +1,29 @@ + +beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + +beginBody() ?> + + + +endBody() ?> + + +endPage() ?> diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php new file mode 100644 index 0000000..329db7a --- /dev/null +++ b/backend/views/layouts/main.php @@ -0,0 +1,65 @@ +controller->action->id === 'login') { +/** + * Do not use this code in your template. Remove it. + * Instead, use the code $this->layout = '//main-login'; in your controller. + */ + echo $this->render( + 'main-login', + ['content' => $content] + ); +} else { + + if (class_exists('backend\assets\AppAsset')) { + backend\assets\AppAsset::register($this); + } else { + app\assets\AppAsset::register($this); + } + + dmstr\web\AdminLteAsset::register($this); + + $directoryAsset = Yii::$app->assetManager->getPublishedUrl('@vendor/almasaeed2010/adminlte/dist'); + ?> + beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + beginBody() ?> +
+ + render( + 'header.php', + ['directoryAsset' => $directoryAsset] + ) ?> + + render( + 'left.php', + ['directoryAsset' => $directoryAsset] + ) + ?> + + render( + 'content.php', + ['content' => $content, 'directoryAsset' => $directoryAsset] + ) ?> + +
+ + endBody() ?> + + + endPage() ?> + diff --git a/backend/views/site/error.php b/backend/views/site/error.php new file mode 100644 index 0000000..c1ba82e --- /dev/null +++ b/backend/views/site/error.php @@ -0,0 +1,44 @@ +title = $name; +?> +
+ +
+

+ +
+

+ +

+ +

+ +

+ 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. + Meanwhile, you may return to dashboard or try using the search + form. +

+ +
+
+ + +
+ +
+
+
+
+
+ +
diff --git a/backend/views/site/index.php b/backend/views/site/index.php new file mode 100644 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 100644 index 0000000..bbe2136 --- /dev/null +++ b/backend/views/site/login.php @@ -0,0 +1,70 @@ +title = 'Sign In'; + +$fieldOptions1 = [ + 'options' => ['class' => 'form-group has-feedback'], + 'inputTemplate' => "{input}" +]; + +$fieldOptions2 = [ + 'options' => ['class' => 'form-group has-feedback'], + 'inputTemplate' => "{input}" +]; +?> + +
+ + + + +
diff --git a/backend/web/.gitignore b/backend/web/.gitignore new file mode 100644 index 0000000..d94a089 --- /dev/null +++ b/backend/web/.gitignore @@ -0,0 +1,3 @@ +/index.php +/index-test.php +/robots.txt diff --git a/backend/web/.htaccess b/backend/web/.htaccess new file mode 100644 index 0000000..c5935ce --- /dev/null +++ b/backend/web/.htaccess @@ -0,0 +1,19 @@ +# ���� ��� ����� ��� ����, ��������� ��� +#RewriteCond %{REQUEST_FILENAME} !-f +#RewriteCond %{REQUEST_FILENAME} !-d +# � ��������� ������ �������������� �� index.php +#RewriteRule . index.php + +Options +SymLinksIfOwnerMatch +IndexIgnore / + +RewriteEngine on +#RewriteBase / + +# 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 100644 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 100644 index 0000000..e337b19 --- /dev/null +++ b/backend/web/css/site.css @@ -0,0 +1,21 @@ +.media__upload_img{ + margin-bottom: 10px; + float: left; +} +.input-group { + position: relative; + display: table; + width: 100%; + border-collapse: separate; +} + +.itemImg, .itemImgs{ + float: left!important; + display: inline-block; + width: 30%!important; +} + +.media__upload_img img{ + margin: 3px; + object-fit: cover; +} diff --git a/backend/web/favicon.ico b/backend/web/favicon.ico new file mode 100644 index 0000000..580ed73 Binary files /dev/null and b/backend/web/favicon.ico differ diff --git a/codeception.yml b/codeception.yml new file mode 100644 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/classes/Debug.php b/common/classes/Debug.php new file mode 100644 index 0000000..24e49b0 --- /dev/null +++ b/common/classes/Debug.php @@ -0,0 +1,20 @@ +'; + print_r($content); + echo ''; + } + public static function dd($content) + { + echo '
';
+        print_r($content);
+        echo '
'; + die(); + } +} \ No newline at end of file diff --git a/common/codeception.yml b/common/codeception.yml new file mode 100644 index 0000000..d21394f --- /dev/null +++ b/common/codeception.yml @@ -0,0 +1,15 @@ +namespace: common\tests +actor_suffix: Tester +paths: + tests: tests + output: tests/_output + data: tests/_data + support: tests/_support +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Yii2: + configFile: 'config/test-local.php' diff --git a/common/config/.gitignore b/common/config/.gitignore new file mode 100644 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 100644 index 0000000..93d0185 --- /dev/null +++ b/common/config/bootstrap.php @@ -0,0 +1,5 @@ + [ + '@bower' => '@vendor/bower-asset', + '@npm' => '@vendor/npm-asset', + ], + 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', + 'components' => [ + 'cache' => [ + 'class' => 'yii\caching\FileCache', + ], + ], + 'controllerMap' => [ + 'elfinder' => [ + 'class' => 'mihaildev\elfinder\Controller', + 'access' => ['@', '?'], + 'disabledCommands' => ['netmount'], + 'roots' => [ + [ + 'baseUrl' => '', + 'basePath' => '@frontend/web', + 'path' => 'media/upload', + 'name' => 'Изображения', + ], + ], + 'watermark' => [ + 'source' => __DIR__ . '/logo.png', // Path to Water mark image + 'marginRight' => 5, // Margin right pixel + 'marginBottom' => 5, // Margin bottom pixel + 'quality' => 95, // JPEG image save quality + 'transparency' => 70, // Water mark image transparency ( other than PNG ) + 'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field ) + 'targetMinPixel' => 200 // Target image minimum pixel size + ] + ] + ], +]; diff --git a/common/config/params.php b/common/config/params.php new file mode 100644 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 100644 index 0000000..cbc18c2 --- /dev/null +++ b/common/config/test.php @@ -0,0 +1,14 @@ + 'app-common-tests', + 'basePath' => dirname(__DIR__), + 'components' => [ + 'user' => [ + 'class' => 'yii\web\User', + 'identityClass' => 'common\models\User', + ], + 'request' => [ + 'cookieValidationKey' => 'test', + ], + ], +]; diff --git a/common/fixtures/UserFixture.php b/common/fixtures/UserFixture.php new file mode 100644 index 0000000..034d975 --- /dev/null +++ b/common/fixtures/UserFixture.php @@ -0,0 +1,9 @@ + +beginPage() ?> + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + beginBody() ?> + + endBody() ?> + + +endPage() ?> diff --git a/common/mail/layouts/text.php b/common/mail/layouts/text.php new file mode 100644 index 0000000..aab1d5d --- /dev/null +++ b/common/mail/layouts/text.php @@ -0,0 +1,14 @@ + + +beginPage() ?> +beginBody() ?> + +endBody() ?> +endPage() ?> diff --git a/common/mail/passwordResetToken-html.php b/common/mail/passwordResetToken-html.php new file mode 100644 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 username) ?>,

+ +

Follow the link below to reset your password:

+ +

+
diff --git a/common/mail/passwordResetToken-text.php b/common/mail/passwordResetToken-text.php new file mode 100644 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 username ?>, + +Follow the link below to reset your password: + + diff --git a/common/models/AdditionalFields.php b/common/models/AdditionalFields.php new file mode 100644 index 0000000..fc5ad30 --- /dev/null +++ b/common/models/AdditionalFields.php @@ -0,0 +1,66 @@ + 100], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'name' => 'Название', + 'use' => 'Применение', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getFieldsValues() + { + return $this->hasMany(FieldsValue::className(), ['field_id' => 'id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getUseFields() + { + return $this->hasMany(UseField::className(), ['field_id' => 'id']); + } +} diff --git a/common/models/FieldsValue.php b/common/models/FieldsValue.php new file mode 100644 index 0000000..763a098 --- /dev/null +++ b/common/models/FieldsValue.php @@ -0,0 +1,82 @@ + 255], + [['field_id'], 'exist', 'skipOnError' => true, 'targetClass' => AdditionalFields::class, 'targetAttribute' => ['field_id' => 'id']], + [['project_id'], 'exist', 'skipOnError' => true, 'targetClass' => Project::class, 'targetAttribute' => ['project_id' => 'id']], + [['card_id'], 'exist', 'skipOnError' => true, 'targetClass' => UserCard::class, 'targetAttribute' => ['card_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'card_id' => 'Card ID', + 'field_id' => 'Field ID', + 'value' => 'Value', + 'project_id' => 'Project ID', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getField() + { + return $this->hasOne(AdditionalFields::class, ['id' => 'field_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProject() + { + return $this->hasOne(Project::class, ['id' => 'project_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getCard() + { + return $this->hasOne(UserCard::class, ['id' => 'card_id']); + } +} diff --git a/common/models/LoginForm.php b/common/models/LoginForm.php new file mode 100644 index 0000000..5a4dff5 --- /dev/null +++ b/common/models/LoginForm.php @@ -0,0 +1,78 @@ +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); + } + + 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/Project.php b/common/models/Project.php new file mode 100644 index 0000000..2751f00 --- /dev/null +++ b/common/models/Project.php @@ -0,0 +1,66 @@ + TimestampBehavior::class, + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => new Expression('NOW()'), + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['name'], 'required'], + [['description'], 'string'], + [['created_at', 'updated_at'], 'safe'], + [['name'], 'string', 'max' => 255], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'name' => 'Название', + 'description' => 'Описание', + 'created_at' => 'Дата создания', + 'updated_at' => 'Дата редактирования', + ]; + } +} diff --git a/common/models/ProjectUser.php b/common/models/ProjectUser.php new file mode 100644 index 0000000..eb27642 --- /dev/null +++ b/common/models/ProjectUser.php @@ -0,0 +1,67 @@ + true, 'targetClass' => Project::className(), 'targetAttribute' => ['project_id' => 'id']], + [['card_id'], 'exist', 'skipOnError' => true, 'targetClass' => UserCard::className(), 'targetAttribute' => ['card_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'card_id' => 'Card ID', + 'project_id' => 'Project ID', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProject() + { + return $this->hasOne(Project::className(), ['id' => 'project_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getCard() + { + return $this->hasOne(UserCard::className(), ['id' => 'card_id']); + } +} diff --git a/common/models/Status.php b/common/models/Status.php new file mode 100644 index 0000000..be8e6a2 --- /dev/null +++ b/common/models/Status.php @@ -0,0 +1,66 @@ + 100], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'name' => 'Название', + 'use' => 'Применение', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getUseStatuses() + { + return $this->hasMany(UseStatus::class, ['status_id' => 'id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getUserCards() + { + return $this->hasMany(UserCard::class, ['status' => 'id']); + } +} diff --git a/common/models/UseField.php b/common/models/UseField.php new file mode 100644 index 0000000..d7b8519 --- /dev/null +++ b/common/models/UseField.php @@ -0,0 +1,80 @@ + true, 'targetClass' => AdditionalFields::className(), 'targetAttribute' => ['field_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'field_id' => 'Поле', + 'use' => 'Применение', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getField() + { + return $this->hasOne(AdditionalFields::className(), ['id' => 'field_id']); + } + + public function getStatuses() + { + return [ + self::USE_PROFILE => 'Профиль', + self::USE_PROJECT => 'Проект' + ]; + } + + /** + * @return string status text label + */ + public function getStatusesText() + { + return $this->statuses[$this->status_id]; + } +} diff --git a/common/models/UseStatus.php b/common/models/UseStatus.php new file mode 100644 index 0000000..8cfe051 --- /dev/null +++ b/common/models/UseStatus.php @@ -0,0 +1,79 @@ + true, 'targetClass' => Status::class, 'targetAttribute' => ['status_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'status_id' => 'Статус', + 'use' => 'Применение', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getStatus() + { + return $this->hasOne(Status::class, ['id' => 'status_id']); + } + + public function getStatuses() + { + return [ + self::USE_PROFILE => 'Профиль', + self::USE_PROJECT => 'Проект' + ]; + } + + /** + * @return string status text label + */ + public function getStatusesText() + { + return $this->statuses[$this->status_id]; + } +} diff --git a/common/models/User.php b/common/models/User.php new file mode 100644 index 0000000..e1f39cb --- /dev/null +++ b/common/models/User.php @@ -0,0 +1,189 @@ + 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; + } +} diff --git a/common/models/UserCard.php b/common/models/UserCard.php new file mode 100644 index 0000000..c0a3f7c --- /dev/null +++ b/common/models/UserCard.php @@ -0,0 +1,112 @@ + TimestampBehavior::class, + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => new Expression('NOW()'), + ], + ]; + } + + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'user_card'; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['fio', 'status'], 'required'], + [['status'], 'integer'], + [['gender'], 'in', 'range' => array_keys($this->genders)], + [['dob', 'created_at', 'updated_at'], 'safe'], + [['fio', 'passport', 'photo', 'email', 'resume'], 'string', 'max' => 255], + [['status'], 'exist', 'skipOnError' => true, 'targetClass' => Status::class, 'targetAttribute' => ['status' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'fio' => 'ФИО', + 'passport' => 'Паспорт', + 'photo' => 'Фото', + 'email' => 'Email', + 'gender' => 'Пол', + 'dob' => 'Дата рождения', + 'status' => 'Статус', + 'created_at' => 'Дата создания', + 'updated_at' => 'Дата редактирование', + 'resume' => 'Резюме', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getStatus0() + { + return $this->hasOne(Status::class, ['id' => 'status']); + } + + public function getGenders() + { + return [ + self::GENDER_M => 'Мужчина', + self::GENDER_W => 'Женщина' + ]; + } + + /** + * @return string status text label + */ + public function getGendersText() + { + return $this->genders[$this->gender]; + } +} diff --git a/common/tests/_bootstrap.php b/common/tests/_bootstrap.php new file mode 100644 index 0000000..3513a6f --- /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 100644 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 100644 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 100644 index 0000000..91cb34f --- /dev/null +++ b/common/tests/_support/UnitTester.php @@ -0,0 +1,25 @@ + [ + '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 100644 index 0000000..7281fa8 --- /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: the name of the session flash variable + * - value: 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. + * Array will be passed to [[\yii\bootstrap\Alert::closeButton]]. + */ + public $closeButton = []; + + + /** + * {@inheritdoc} + */ + public function run() + { + $session = Yii::$app->session; + $flashes = $session->getAllFlashes(); + $appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; + + foreach ($flashes as $type => $flash) { + if (!isset($this->alertTypes[$type])) { + continue; + } + + foreach ((array) $flash as $i => $message) { + echo \yii\bootstrap\Alert::widget([ + 'body' => $message, + 'closeButton' => $this->closeButton, + 'options' => array_merge($this->options, [ + 'id' => $this->getId() . '-' . $type . '-' . $i, + 'class' => $this->alertTypes[$type] . $appendClass, + ]), + ]); + } + + $session->removeFlash($type); + } + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..965a0fe --- /dev/null +++ b/composer.json @@ -0,0 +1,45 @@ +{ + "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 || ~2.1.0", + "dmstr/yii2-adminlte-asset": "^2.1", + "unclead/yii2-multiple-input": "~2.0", + "mihaildev/yii2-elfinder": "*", + "kartik-v/yii2-widget-select2": "@dev" + }, + "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, + "fxp-asset": { + "enabled": false + } + }, + "repositories": [ + { + "type": "composer", + "url": "https://asset-packagist.org" + } + ] +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..5c065fa --- /dev/null +++ b/composer.lock @@ -0,0 +1,3921 @@ +{ + "_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" + ], + "content-hash": "a85750ca57985e0961df5763c3927a1a", + "packages": [ + { + "name": "almasaeed2010/adminlte", + "version": "v2.4.8", + "source": { + "type": "git", + "url": "https://github.com/almasaeed2010/AdminLTE.git", + "reference": "d9e68301848a95dff2e2dbef6569e617a9b3fa30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/almasaeed2010/AdminLTE/zipball/d9e68301848a95dff2e2dbef6569e617a9b3fa30", + "reference": "d9e68301848a95dff2e2dbef6569e617a9b3fa30", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.9.0 <4.0.0", + "composer/installers": "1.*" + }, + "type": "template", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Abdullah Almsaeed", + "email": "abdullah@almsaeedstudio.com" + } + ], + "description": "AdminLTE - admin control panel and dashboard that's based on Bootstrap 3", + "homepage": "https://adminlte.io/", + "keywords": [ + "JS", + "admin", + "back-end", + "css", + "less", + "responsive", + "template", + "theme", + "web" + ], + "time": "2018-07-15T18:48:11+00:00" + }, + { + "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": null + }, + "require": { + "bower-asset/jquery": ">=1.9.1,<4.0" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/inputmask", + "version": "3.3.11", + "source": { + "type": "git", + "url": "https://github.com/RobinHerbots/Inputmask.git", + "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b", + "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b", + "shasum": null + }, + "require": { + "bower-asset/jquery": ">=1.7" + }, + "type": "bower-asset", + "license": [ + "http://opensource.org/licenses/mit-license.php" + ] + }, + { + "name": "bower-asset/jquery", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/jquery/jquery-dist.git", + "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/77d2a51d0520d2ee44173afdf4e40a9201f5964e", + "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e", + "shasum": null + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/jquery-ui", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/components/jqueryui.git", + "reference": "44ecf3794cc56b65954cc19737234a3119d036cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/components/jqueryui/zipball/44ecf3794cc56b65954cc19737234a3119d036cc", + "reference": "44ecf3794cc56b65954cc19737234a3119d036cc", + "shasum": null + }, + "require": { + "bower-asset/jquery": ">=1.6" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/punycode", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "git@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": null + }, + "type": "bower-asset" + }, + { + "name": "bower-asset/yii2-pjax", + "version": "2.0.7.1", + "source": { + "type": "git", + "url": "git@github.com:yiisoft/jquery-pjax.git", + "reference": "aef7b953107264f00234902a3880eb50dafc48be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be", + "reference": "aef7b953107264f00234902a3880eb50dafc48be", + "shasum": null + }, + "require": { + "bower-asset/jquery": ">=1.8" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "cebe/markdown", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/cebe/markdown.git", + "reference": "25b28bae8a6f185b5030673af77b32e1163d5c6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/markdown/zipball/25b28bae8a6f185b5030673af77b32e1163d5c6e", + "reference": "25b28bae8a6f185b5030673af77b32e1163d5c6e", + "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": "2017-07-16T21:13:23+00:00" + }, + { + "name": "cebe/yii2-gravatar", + "version": "1.1", + "target-dir": "cebe/gravatar", + "source": { + "type": "git", + "url": "https://github.com/cebe/yii2-gravatar.git", + "reference": "c9c01bd14c9bdee9e5ae1ef1aad23f80c182c057" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/yii2-gravatar/zipball/c9c01bd14c9bdee9e5ae1ef1aad23f80c182c057", + "reference": "c9c01bd14c9bdee9e5ae1ef1aad23f80c182c057", + "shasum": "" + }, + "require": { + "yiisoft/yii2": "*" + }, + "type": "yii2-extension", + "autoload": { + "psr-0": { + "cebe\\gravatar\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Core framework development" + } + ], + "description": "Gravatar Widget for Yii 2", + "keywords": [ + "gravatar", + "yii" + ], + "time": "2013-12-10T17:49:58+00:00" + }, + { + "name": "composer/installers", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "^4.8.36" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "time": "2018-08-27T06:10:37+00:00" + }, + { + "name": "dmstr/yii2-adminlte-asset", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/dmstr/yii2-adminlte-asset.git", + "reference": "c96336e1960ebc6c1e72487a7c6ca1a1589519fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dmstr/yii2-adminlte-asset/zipball/c96336e1960ebc6c1e72487a7c6ca1a1589519fe", + "reference": "c96336e1960ebc6c1e72487a7c6ca1a1589519fe", + "shasum": "" + }, + "require": { + "almasaeed2010/adminlte": "^2.4.0", + "cebe/yii2-gravatar": "1.*", + "rmrevin/yii2-fontawesome": "~2.9", + "yiisoft/yii2": "2.*", + "yiisoft/yii2-bootstrap": "~2.0.0" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "dmstr\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tobias Munk", + "email": "tobias@diemeisterei.de" + }, + { + "name": "Evgeniy Tkachenko", + "email": "et.coder@gmail.com" + } + ], + "description": "AdminLTE backend theme asset bundle for Yii 2.0 Framework", + "keywords": [ + "AdminLTE", + "admin", + "asset", + "backend", + "css", + "extension", + "less", + "theme", + "yii2" + ], + "time": "2018-07-24T14:47:13+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "egulias/email-validator", + "version": "2.1.6", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "0578b32b30b22de3e8664f797cf846fc9246f786" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0578b32b30b22de3e8664f797cf846fc9246f786", + "reference": "0578b32b30b22de3e8664f797cf846fc9246f786", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">= 5.5" + }, + "require-dev": { + "dominicsayers/isemail": "dev-master", + "phpunit/phpunit": "^4.8.35||^5.7||^6.0", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "EmailValidator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "time": "2018-09-25T20:47:26+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.10.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "d85d39da4576a6934b72480be6978fb10c860021" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021", + "reference": "d85d39da4576a6934b72480be6978fb10c860021", + "shasum": "" + }, + "require": { + "php": ">=5.2" + }, + "require-dev": { + "simpletest/simpletest": "^1.1" + }, + "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": "2018-02-23T01:58:20+00:00" + }, + { + "name": "fortawesome/font-awesome", + "version": "v4.7.0", + "source": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome.git", + "reference": "a8386aae19e200ddb0f6845b5feeee5eb7013687" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FortAwesome/Font-Awesome/zipball/a8386aae19e200ddb0f6845b5feeee5eb7013687", + "reference": "a8386aae19e200ddb0f6845b5feeee5eb7013687", + "shasum": "" + }, + "require-dev": { + "jekyll": "1.0.2", + "lessc": "1.4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.6.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OFL-1.1", + "MIT" + ], + "authors": [ + { + "name": "Dave Gandy", + "email": "dave@fontawesome.io", + "homepage": "http://twitter.com/davegandy", + "role": "Developer" + } + ], + "description": "The iconic font and CSS framework", + "homepage": "http://fontawesome.io/", + "keywords": [ + "FontAwesome", + "awesome", + "bootstrap", + "font", + "icon" + ], + "time": "2016-10-24T15:52:54+00:00" + }, + { + "name": "kartik-v/yii2-krajee-base", + "version": "v1.9.9", + "source": { + "type": "git", + "url": "https://github.com/kartik-v/yii2-krajee-base.git", + "reference": "1693374160c24443524ddc23508d2eb2955443f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kartik-v/yii2-krajee-base/zipball/1693374160c24443524ddc23508d2eb2955443f4", + "reference": "1693374160c24443524ddc23508d2eb2955443f4", + "shasum": "" + }, + "require": { + "yiisoft/yii2-bootstrap": "@dev" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "1.9.x-dev" + } + }, + "autoload": { + "psr-4": { + "kartik\\base\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kartik Visweswaran", + "email": "kartikv2@gmail.com", + "homepage": "http://www.krajee.com/" + } + ], + "description": "Base library and foundation components for all Yii2 Krajee extensions.", + "homepage": "https://github.com/kartik-v/yii2-krajee-base", + "keywords": [ + "base", + "extension", + "foundation", + "krajee", + "widget", + "yii2" + ], + "time": "2018-09-27T18:02:35+00:00" + }, + { + "name": "kartik-v/yii2-widget-select2", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/kartik-v/yii2-widget-select2.git", + "reference": "0df692c8772c2b53406ae705492c8401ea6501d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kartik-v/yii2-widget-select2/zipball/0df692c8772c2b53406ae705492c8401ea6501d6", + "reference": "0df692c8772c2b53406ae705492c8401ea6501d6", + "shasum": "" + }, + "require": { + "kartik-v/yii2-krajee-base": ">=1.9" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "kartik\\select2\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kartik Visweswaran", + "email": "kartikv2@gmail.com", + "homepage": "http://www.krajee.com/" + } + ], + "description": "Enhanced Yii2 wrapper for the Select2 jQuery plugin (sub repo split from yii2-widgets).", + "homepage": "https://github.com/kartik-v/yii2-widget-select2", + "keywords": [ + "dropdown", + "extension", + "form", + "jquery", + "plugin", + "select2", + "widget", + "yii2" + ], + "time": "2018-10-03T07:09:03+00:00" + }, + { + "name": "mihaildev/yii2-elfinder", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/MihailDev/yii2-elfinder.git", + "reference": "3cc3001a84e3cc3841131a0a947d7917948a60b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MihailDev/yii2-elfinder/zipball/3cc3001a84e3cc3841131a0a947d7917948a60b1", + "reference": "3cc3001a84e3cc3841131a0a947d7917948a60b1", + "shasum": "" + }, + "require": { + "studio-42/elfinder": "^2.1.10", + "yiisoft/yii2": "~2.0.13", + "yiisoft/yii2-jui": "*" + }, + "type": "yii2-extension", + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + }, + "autoload": { + "psr-4": { + "mihaildev\\elfinder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Mihail", + "email": "mihail.kucher@gmail.com", + "homepage": "https://github.com/MihailDev", + "role": "Developer" + } + ], + "description": "Yii2 ElFinder", + "homepage": "https://github.com/MihailDev/yii2-elfinder", + "keywords": [ + "elfinder", + "filemanager", + "yii" + ], + "time": "2018-10-01T17:00:54+00:00" + }, + { + "name": "rmrevin/yii2-fontawesome", + "version": "2.17.1", + "source": { + "type": "git", + "url": "https://github.com/rmrevin/yii2-fontawesome.git", + "reference": "65ce306da864f4d558348aeba040ed7876878090" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rmrevin/yii2-fontawesome/zipball/65ce306da864f4d558348aeba040ed7876878090", + "reference": "65ce306da864f4d558348aeba040ed7876878090", + "shasum": "" + }, + "require": { + "fortawesome/font-awesome": "~4.7", + "php": ">=5.4.0", + "yiisoft/yii2": "2.0.*" + }, + "type": "yii2-extension", + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + }, + "autoload": { + "psr-4": { + "rmrevin\\yii\\fontawesome\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Revin Roman", + "email": "roman@rmrevin.com", + "homepage": "https://rmrevin.com/" + } + ], + "description": "Asset Bundle for Yii2 with Font Awesome", + "keywords": [ + "asset", + "awesome", + "bundle", + "font", + "yii" + ], + "time": "2017-01-11T14:05:47+00:00" + }, + { + "name": "studio-42/elfinder", + "version": "2.1.42", + "source": { + "type": "git", + "url": "https://github.com/Studio-42/elFinder.git", + "reference": "83f4b3102bafd4393cb51ff41af4edd34f8132f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Studio-42/elFinder/zipball/83f4b3102bafd4393cb51ff41af4edd34f8132f4", + "reference": "83f4b3102bafd4393cb51ff41af4edd34f8132f4", + "shasum": "" + }, + "require": { + "php": ">=5.2" + }, + "suggest": { + "barryvdh/elfinder-flysystem-driver": "VolumeDriver for elFinder to use Flysystem as a root.", + "google/apiclient": "VolumeDriver GoogleDrive require `google/apiclient:^2.0.", + "kunalvarma05/dropbox-php-sdk": "VolumeDriver `Dropbox`2 require `kunalvarma05/dropbox-php-sdk.", + "nao-pon/flysystem-google-drive": "require in GoogleDrive network volume mounting with Flysystem." + }, + "type": "library", + "autoload": { + "classmap": [ + "php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Dmitry Levashov", + "email": "dio@std42.ru", + "homepage": "http://std42.ru" + }, + { + "name": "Troex Nevelin", + "email": "troex@fury.scancode.ru", + "homepage": "http://std42.ru" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/Studio-42/elFinder/contributors" + }, + { + "name": "Naoki Sawada", + "email": "hypweb+elfinder@gmail.com", + "homepage": "http://xoops.hypweb.net" + } + ], + "description": "File manager for web", + "homepage": "http://elfinder.org", + "time": "2018-08-29T06:44:30+00:00" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8ddcb66ac10c392d3beb54829eef8ac1438595f4", + "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4", + "shasum": "" + }, + "require": { + "egulias/email-validator": "~2.0", + "php": ">=7.0.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.1", + "symfony/phpunit-bridge": "~3.3@dev" + }, + "suggest": { + "ext-intl": "Needed to support internationalized email addresses", + "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-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": "https://swiftmailer.symfony.com", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2018-09-11T07:12:52+00:00" + }, + { + "name": "unclead/yii2-multiple-input", + "version": "2.16.0", + "source": { + "type": "git", + "url": "https://github.com/unclead/yii2-multiple-input.git", + "reference": "bc7fe00b7e63d4d01241bf4655273c3856c43b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/unclead/yii2-multiple-input/zipball/bc7fe00b7e63d4d01241bf4655273c3856c43b9f", + "reference": "bc7fe00b7e63d4d01241bf4655273c3856c43b9f", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": ">=2.0.13" + }, + "require-dev": { + "phpunit/phpunit": "5.7.*" + }, + "type": "yii2-extension", + "autoload": { + "psr-4": { + "unclead\\multipleinput\\examples\\": "examples/", + "unclead\\multipleinput\\": "src/", + "unclead\\multipleinput\\tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Eugene Tupikov", + "email": "unclead.nsk@gmail.com" + } + ], + "description": "Widget for handle multiple inputs for an attribute of Yii2 framework model", + "keywords": [ + "yii2", + "yii2 array input", + "yii2 multiple field", + "yii2 multiple input", + "yii2 tabular input" + ], + "time": "2018-09-30T14:37:22+00:00" + }, + { + "name": "yiisoft/yii2", + "version": "2.0.15.1", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-framework.git", + "reference": "ed3a9e1c4abe206e1c3ce48a6b3624119b79850d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/ed3a9e1c4abe206e1c3ce48a6b3624119b79850d", + "reference": "ed3a9e1c4abe206e1c3ce48a6b3624119b79850d", + "shasum": "" + }, + "require": { + "bower-asset/inputmask": "~3.2.2 | ~3.3.5", + "bower-asset/jquery": "3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", + "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": "2018-03-21T18:36:53+00:00" + }, + { + "name": "yiisoft/yii2-bootstrap", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-bootstrap.git", + "reference": "3f49c47924bb9fa5363c3fc7b073d954168cf438" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/3f49c47924bb9fa5363c3fc7b073d954168cf438", + "reference": "3f49c47924bb9fa5363c3fc7b073d954168cf438", + "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" + } + }, + "autoload": { + "psr-4": { + "yii\\bootstrap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + }, + { + "name": "Alexander Makarov", + "email": "sam@rmcreative.ru", + "homepage": "http://rmcreative.ru/" + }, + { + "name": "Antonio Ramirez", + "email": "amigo.cobos@gmail.com" + }, + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com", + "homepage": "http://www.yiiframework.com/" + } + ], + "description": "The Twitter Bootstrap extension for the Yii framework", + "keywords": [ + "bootstrap", + "yii2" + ], + "time": "2018-02-16T10:41:52+00:00" + }, + { + "name": "yiisoft/yii2-composer", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-composer.git", + "reference": "1439e78be1218c492e6cde251ed87d3f128b9534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/1439e78be1218c492e6cde251ed87d3f128b9534", + "reference": "1439e78be1218c492e6cde251ed87d3f128b9534", + "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" + }, + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc" + } + ], + "description": "The composer plugin for Yii extension installer", + "keywords": [ + "composer", + "extension installer", + "yii2" + ], + "time": "2018-07-05T15:44:47+00:00" + }, + { + "name": "yiisoft/yii2-jui", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-jui.git", + "reference": "ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-jui/zipball/ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed", + "reference": "ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed", + "shasum": "" + }, + "require": { + "bower-asset/jquery-ui": "~1.12.1", + "yiisoft/yii2": "~2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\jui\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The Jquery UI extension for the Yii framework", + "keywords": [ + "jQuery UI", + "yii2" + ], + "time": "2017-11-25T15:32:29+00:00" + }, + { + "name": "yiisoft/yii2-swiftmailer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-swiftmailer.git", + "reference": "09659a55959f9e64b8178d842b64a9ffae42b994" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/09659a55959f9e64b8178d842b64a9ffae42b994", + "reference": "09659a55959f9e64b8178d842b64a9ffae42b994", + "shasum": "" + }, + "require": { + "swiftmailer/swiftmailer": "~6.0", + "yiisoft/yii2": ">=2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\swiftmailer\\": "src" + } + }, + "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": "2018-09-23T22:00:47+00:00" + } + ], + "packages-dev": [ + { + "name": "behat/gherkin", + "version": "v4.5.1", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a", + "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a", + "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": "2017-08-30T11:04:43+00:00" + }, + { + "name": "bower-asset/typeahead.js", + "version": "v0.11.1", + "source": { + "type": "git", + "url": "git@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": null + }, + "require": { + "bower-asset/jquery": ">=1.7" + }, + "type": "bower-asset" + }, + { + "name": "codeception/base", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/Codeception/base.git", + "reference": "04761aa6864d8fe7f6360aa3210cbf8235ad0d76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/base/zipball/04761aa6864d8fe7f6360aa3210cbf8235ad0d76", + "reference": "04761aa6864d8fe7f6360aa3210cbf8235ad0d76", + "shasum": "" + }, + "require": { + "behat/gherkin": "^4.4.0", + "codeception/phpunit-wrapper": "^6.0.9|^7.0.6", + "codeception/stub": "^2.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/psr7": "~1.0", + "php": ">=5.6.0 <8.0", + "symfony/browser-kit": ">=2.7 <5.0", + "symfony/console": ">=2.7 <5.0", + "symfony/css-selector": ">=2.7 <5.0", + "symfony/dom-crawler": ">=2.7 <5.0", + "symfony/event-dispatcher": ">=2.7 <5.0", + "symfony/finder": ">=2.7 <5.0", + "symfony/yaml": ">=2.7 <5.0" + }, + "require-dev": { + "codeception/specify": "~0.3", + "facebook/graph-sdk": "~5.3", + "flow/jsonpath": "~0.2", + "monolog/monolog": "~1.8", + "pda/pheanstalk": "~3.0", + "php-amqplib/php-amqplib": "~2.4", + "predis/predis": "^1.0", + "squizlabs/php_codesniffer": "~2.0", + "symfony/process": ">=2.7 <5.0", + "vlucas/phpdotenv": "^2.4.0" + }, + "suggest": { + "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module", + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests", + "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", + "stecman/symfony-console-completion": "For BASH autocompletion", + "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": "2018-09-24T09:46:36+00:00" + }, + { + "name": "codeception/phpunit-wrapper", + "version": "7.3.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/phpunit-wrapper.git", + "reference": "1967be130082effb3c30510cf8f8397fbd9d8b84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/1967be130082effb3c30510cf8f8397fbd9d8b84", + "reference": "1967be130082effb3c30510cf8f8397fbd9d8b84", + "shasum": "" + }, + "require": { + "phpunit/php-code-coverage": "^6.0", + "phpunit/phpunit": "~7.1.0|~7.2.0|~7.3.0", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0" + }, + "require-dev": { + "codeception/specify": "*", + "vlucas/phpdotenv": "^2.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\PHPUnit\\": "src\\" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "PHPUnit classes used by Codeception", + "time": "2018-09-28T15:36:26+00:00" + }, + { + "name": "codeception/stub", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Stub.git", + "reference": "f50bc271f392a2836ff80690ce0c058efe1ae03e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Stub/zipball/f50bc271f392a2836ff80690ce0c058efe1ae03e", + "reference": "f50bc271f392a2836ff80690ce0c058efe1ae03e", + "shasum": "" + }, + "require": { + "phpunit/phpunit": ">=4.8 <8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", + "time": "2018-07-26T11:55:37+00:00" + }, + { + "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-09T10:58:51+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.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": "2017-07-22T11:58:36+00:00" + }, + { + "name": "fzaninotto/faker", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "f72816b43e74063c8b10357394b6bba8cb1c10de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/f72816b43e74063c8b10357394b6bba8cb1c10de", + "reference": "f72816b43e74063c8b10357394b6bba8cb1c10de", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7", + "squizlabs/php_codesniffer": "^1.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "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": "2018-07-12T10:23:15+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "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-03-20T17:10:46+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2018-06-11T23:09:50+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.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": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "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": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "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": "2017-07-14T14:27:02+00:00" + }, + { + "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-07T12:29:16+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.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": "2018-08-05T17:53:17+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-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 provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-06-01T07:51:50+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "050bedf145a257b1ff02746c31894800e5122946" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "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": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-09-13T20:33:42+00:00" + }, + { + "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-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.3.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "7b331efabbb628c518c408fdfcaf571156775de2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b331efabbb628c518c408fdfcaf571156775de2", + "reference": "7b331efabbb628c518c408fdfcaf571156775de2", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.3-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": "2018-09-08T15:14:29+00:00" + }, + { + "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-06T14:39:51+00:00" + }, + { + "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-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "366541b989927187c4ca70490a35615d3fef2dce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", + "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-06-10T07:54:39+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.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": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.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": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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": "2017-03-03T06:23:57+00:00" + }, + { + "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-28T20:34:47+00:00" + }, + { + "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-03T07:35:21+00:00" + }, + { + "name": "symfony/browser-kit", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "c55fe9257003b2d95c0211b3f6941e8dfd26dffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c55fe9257003b2d95c0211b3f6941e8dfd26dffd", + "reference": "c55fe9257003b2d95c0211b3f6941e8dfd26dffd", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/dom-crawler": "~3.4|~4.0" + }, + "require-dev": { + "symfony/css-selector": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-07-26T09:10:45+00:00" + }, + { + "name": "symfony/console", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "d3dbe91fd5b8b11ecb73508c844bc6a490de15b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/d3dbe91fd5b8b11ecb73508c844bc6a490de15b4", + "reference": "d3dbe91fd5b8b11ecb73508c844bc6a490de15b4", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-09-30T03:38:13+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "9ac515bde3c725ca46efa918d37e37c7cece6353" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/9ac515bde3c725ca46efa918d37e37c7cece6353", + "reference": "9ac515bde3c725ca46efa918d37e37c7cece6353", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-09-08T13:24:10+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "8ffa4c496c782e5591182318a6199b7507431651" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8ffa4c496c782e5591182318a6199b7507431651", + "reference": "8ffa4c496c782e5591182318a6199b7507431651", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "~3.4|~4.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-09-21T12:49:42+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-07-26T09:10:45+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "f0b042d445c155501793e7b8007457f9f5bb1c8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/f0b042d445c155501793e7b8007457f9f5bb1c8c", + "reference": "f0b042d445c155501793e7b8007457f9f5bb1c8c", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-09-21T12:49:42+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-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": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/yaml", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "ac5af7c14c4f8abf0f77419e8397eff7a370df19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac5af7c14c4f8abf0f77419e8397eff7a370df19", + "reference": "ac5af7c14c4f8abf0f77419e8397eff7a370df19", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-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": "2018-09-30T03:38:13+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "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": "2018-01-29T19:49:41+00:00" + }, + { + "name": "yiisoft/yii2-debug", + "version": "2.0.14", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-debug.git", + "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/dc5a4a8529de1a41dbb037dbabf1f3f93002f21d", + "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d", + "shasum": "" + }, + "require": { + "yiisoft/yii2": "~2.0.13", + "yiisoft/yii2-bootstrap": "~2.0.0" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\debug\\": "src" + } + }, + "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": "2018-09-23T21:41:04+00:00" + }, + { + "name": "yiisoft/yii2-faker", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-faker.git", + "reference": "3df62b1dcb272a8413f9c6e532c9d73f325ccde1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/3df62b1dcb272a8413f9c6e532c9d73f325ccde1", + "reference": "3df62b1dcb272a8413f9c6e532c9d73f325ccde1", + "shasum": "" + }, + "require": { + "fzaninotto/faker": "~1.4", + "yiisoft/yii2": "~2.0.0" + }, + "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": "2018-02-19T20:27:10+00:00" + }, + { + "name": "yiisoft/yii2-gii", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-gii.git", + "reference": "9ec1374d0844f448d2af29c707f77c9f8d1375c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/9ec1374d0844f448d2af29c707f77c9f8d1375c8", + "reference": "9ec1374d0844f448d2af29c707f77c9f8d1375c8", + "shasum": "" + }, + "require": { + "bower-asset/typeahead.js": "0.10.* | ~0.11.0", + "phpspec/php-diff": ">=1.0.2", + "yiisoft/yii2": "~2.0.14", + "yiisoft/yii2-bootstrap": "~2.0.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\\": "src" + } + }, + "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": "2018-05-02T22:05:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "kartik-v/yii2-widget-select2": 20 + }, + "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 100644 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 100644 index 0000000..b3d9bbc --- /dev/null +++ b/console/config/bootstrap.php @@ -0,0 +1 @@ + 'app-console', + 'basePath' => dirname(__DIR__), + 'bootstrap' => ['log'], + 'controllerNamespace' => 'console\controllers', + 'aliases' => [ + '@bower' => '@vendor/bower-asset', + '@npm' => '@vendor/npm-asset', + ], + '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 100644 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 100644 index 0000000..e69de29 diff --git a/console/migrations/m130524_201442_init.php b/console/migrations/m130524_201442_init.php new file mode 100644 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/m181003_070416_create_status_table.php b/console/migrations/m181003_070416_create_status_table.php new file mode 100644 index 0000000..412d86e --- /dev/null +++ b/console/migrations/m181003_070416_create_status_table.php @@ -0,0 +1,44 @@ +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('status', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(100)->notNull(), + ], $tableOptions); + + $this->insert('status', + [ + 'name' => 'Активный', + ]); + + $this->insert('status', + [ + 'name' => 'Уволен', + ]); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable('status'); + } +} diff --git a/console/migrations/m181003_070636_create_user_card_table.php b/console/migrations/m181003_070636_create_user_card_table.php new file mode 100644 index 0000000..be12454 --- /dev/null +++ b/console/migrations/m181003_070636_create_user_card_table.php @@ -0,0 +1,54 @@ +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_card', [ + 'id' => $this->primaryKey(), + 'fio' => $this->string(255)->notNull(), + 'passport' => $this->string(255), + 'photo' => $this->string(255), + 'email' => $this->string(255), + 'gender' => $this->tinyInteger(1), + 'dob' => $this->date(), + 'status' => $this->integer(11)->notNull(), + 'created_at' => $this->dateTime(), + 'updated_at' => $this->dateTime(), + ], $tableOptions); + + $this->addForeignKey( + 'user_card_ibfk_status', + 'user_card', + 'status', + 'status', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('user_card_ibfk_status', 'user_card'); + + $this->dropTable('user_card'); + } +} diff --git a/console/migrations/m181003_082730_create_additional_fields_table.php b/console/migrations/m181003_082730_create_additional_fields_table.php new file mode 100644 index 0000000..56c2ad3 --- /dev/null +++ b/console/migrations/m181003_082730_create_additional_fields_table.php @@ -0,0 +1,34 @@ +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('additional_fields', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(100)->notNull(), + ], $tableOptions); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable('additional_fields'); + } +} diff --git a/console/migrations/m181003_092319_create_fields_value_table.php b/console/migrations/m181003_092319_create_fields_value_table.php new file mode 100644 index 0000000..bd43923 --- /dev/null +++ b/console/migrations/m181003_092319_create_fields_value_table.php @@ -0,0 +1,59 @@ +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('fields_value', [ + 'id' => $this->primaryKey(), + 'card_id' => $this->integer(11)->notNull(), + 'field_id' => $this->integer(11)->notNull(), + 'value' => $this->string(255)->notNull(), + ], $tableOptions); + + $this->addForeignKey( + 'fields_value_ibfk_additional_fields', + 'fields_value', + 'field_id', + 'additional_fields', + 'id', + 'RESTRICT', + 'CASCADE' + ); + + $this->addForeignKey( + 'fields_value_ibfk_user_card', + 'fields_value', + 'card_id', + 'user_card', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('fields_value_ibfk_additional_fields','fields_value'); + $this->dropForeignKey('fields_value_ibfk_user_card','fields_value'); + + $this->dropTable('fields_value'); + } +} diff --git a/console/migrations/m181004_095927_add_column_resume_to_user_card_table.php b/console/migrations/m181004_095927_add_column_resume_to_user_card_table.php new file mode 100644 index 0000000..4261689 --- /dev/null +++ b/console/migrations/m181004_095927_add_column_resume_to_user_card_table.php @@ -0,0 +1,40 @@ +addColumn('user_card', 'resume', $this->string(255)); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('user_card', 'resume'); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m181004_095927_add_column_resume_to_user_card_table cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/console/migrations/m181004_102703_add_column_order_to_fields_value_table.php b/console/migrations/m181004_102703_add_column_order_to_fields_value_table.php new file mode 100644 index 0000000..62f036d --- /dev/null +++ b/console/migrations/m181004_102703_add_column_order_to_fields_value_table.php @@ -0,0 +1,40 @@ +addColumn('fields_value', 'order', $this->integer(11)); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('fields_value', 'order'); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m181004_102703_add_column_order_to_fields_value_table cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/console/migrations/m181005_114117_create_use_status_table.php b/console/migrations/m181005_114117_create_use_status_table.php new file mode 100644 index 0000000..cd7dda6 --- /dev/null +++ b/console/migrations/m181005_114117_create_use_status_table.php @@ -0,0 +1,47 @@ +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('use_status', [ + 'id' => $this->primaryKey(), + 'status_id' => $this->integer(11)->notNull(), + 'use' => $this->integer(11)->notNull(), + ], $tableOptions); + + $this->addForeignKey( + 'use_status_ibfk_status', + 'use_status', + 'status_id', + 'status', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('use_status_ibfk_status', 'use_status'); + + $this->dropTable('use_status'); + } +} diff --git a/console/migrations/m181008_065248_create_use_field_table.php b/console/migrations/m181008_065248_create_use_field_table.php new file mode 100644 index 0000000..0b94a36 --- /dev/null +++ b/console/migrations/m181008_065248_create_use_field_table.php @@ -0,0 +1,46 @@ +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('use_field', [ + 'id' => $this->primaryKey(), + 'field_id' => $this->integer(11)->notNull(), + 'use' => $this->integer(11)->notNull(), + ], $tableOptions); + + $this->addForeignKey( + 'use_field_ibfk_additional_fields', + 'use_field', + 'field_id', + 'additional_fields', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('use_field_ibfk_additional_fields', 'use_field'); + + $this->dropTable('use_field'); + } +} diff --git a/console/migrations/m181008_090446_create_project_table.php b/console/migrations/m181008_090446_create_project_table.php new file mode 100644 index 0000000..d82e662 --- /dev/null +++ b/console/migrations/m181008_090446_create_project_table.php @@ -0,0 +1,37 @@ +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('project', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(255)->notNull(), + 'description' => $this->text(), + 'created_at' => $this->dateTime(), + 'updated_at' => $this->dateTime(), + ], $tableOptions); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable('project'); + } +} diff --git a/console/migrations/m181008_095803_add_project_id_field_to_fields_value.php b/console/migrations/m181008_095803_add_project_id_field_to_fields_value.php new file mode 100644 index 0000000..ba07724 --- /dev/null +++ b/console/migrations/m181008_095803_add_project_id_field_to_fields_value.php @@ -0,0 +1,53 @@ +addColumn('fields_value', 'project_id', $this->integer(11)); + $this->alterColumn('fields_value', 'card_id', $this->integer(11)); + + $this->addForeignKey( + 'fields_value_ibfk_project', + 'fields_value', + 'project_id', + 'project', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('fields_value_ibfk_project', 'fields_value'); + + $this->dropColumn('fields_value', 'project_id'); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m181008_095803_add_project_id_field_to_fields_value cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/console/migrations/m181008_105959_create_project_user_table.php b/console/migrations/m181008_105959_create_project_user_table.php new file mode 100644 index 0000000..0db5c72 --- /dev/null +++ b/console/migrations/m181008_105959_create_project_user_table.php @@ -0,0 +1,58 @@ +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('project_user', [ + 'id' => $this->primaryKey(), + 'card_id' => $this->integer(11)->notNull(), + 'project_id' => $this->integer(11)->notNull(), + ], $tableOptions); + + $this->addForeignKey( + 'project_user_ibfk_project', + 'project_user', + 'project_id', + 'project', + 'id', + 'RESTRICT', + 'CASCADE' + ); + + $this->addForeignKey( + 'project_user_ibfk_user_card', + 'project_user', + 'card_id', + 'user_card', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('project_user_ibfk_project', 'project_user'); + $this->dropForeignKey('project_user_ibfk_user_card', 'project_user'); + + $this->dropTable('project_user'); + } +} diff --git a/console/models/.gitkeep b/console/models/.gitkeep new file mode 100644 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 100644 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 100644 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 100644 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 100644 index 0000000..1649b25 --- /dev/null +++ b/environments/dev/backend/web/index.php @@ -0,0 +1,17 @@ +run(); diff --git a/environments/dev/backend/web/robots.txt b/environments/dev/backend/web/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/environments/dev/backend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 0000000..1649b25 --- /dev/null +++ b/environments/dev/frontend/web/index.php @@ -0,0 +1,17 @@ +run(); diff --git a/environments/dev/frontend/web/robots.txt b/environments/dev/frontend/web/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/environments/dev/frontend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/environments/dev/yii b/environments/dev/yii new file mode 100644 index 0000000..b93b5cf --- /dev/null +++ b/environments/dev/yii @@ -0,0 +1,24 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/environments/dev/yii_test b/environments/dev/yii_test new file mode 100644 index 0000000..70ba616 --- /dev/null +++ b/environments/dev/yii_test @@ -0,0 +1,23 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/environments/dev/yii_test.bat b/environments/dev/yii_test.bat new file mode 100644 index 0000000..29fbbea --- /dev/null +++ b/environments/dev/yii_test.bat @@ -0,0 +1,15 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line bootstrap script for Windows. +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 100644 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 100644 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 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/prod/backend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/prod/backend/web/robots.txt b/environments/prod/backend/web/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/environments/prod/backend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php new file mode 100644 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 100644 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 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/prod/frontend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/prod/frontend/web/robots.txt b/environments/prod/frontend/web/robots.txt new file mode 100644 index 0000000..14267e9 --- /dev/null +++ b/environments/prod/frontend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / \ No newline at end of file diff --git a/environments/prod/yii b/environments/prod/yii new file mode 100644 index 0000000..5b0d890 --- /dev/null +++ b/environments/prod/yii @@ -0,0 +1,24 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/frontend/assets/AppAsset.php b/frontend/assets/AppAsset.php new file mode 100644 index 0000000..8b5f017 --- /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', + ], + /* + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => [ + ], + ], + */ + ], + 'params' => $params, +]; diff --git a/frontend/config/params.php b/frontend/config/params.php new file mode 100644 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 100644 index 0000000..5881579 --- /dev/null +++ b/frontend/config/test.php @@ -0,0 +1,12 @@ + 'app-frontend-tests', + 'components' => [ + 'assetManager' => [ + 'basePath' => __DIR__ . '/../web/assets', + ], + 'urlManager' => [ + 'showScriptName' => true, + ], + ], +]; diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php new file mode 100644 index 0000000..d24e107 --- /dev/null +++ b/frontend/controllers/SiteController.php @@ -0,0 +1,215 @@ + [ + 'class' => AccessControl::className(), + 'only' => ['logout', 'signup'], + 'rules' => [ + [ + 'actions' => ['signup'], + 'allow' => true, + 'roles' => ['?'], + ], + [ + 'actions' => ['logout'], + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'logout' => ['post'], + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + 'captcha' => [ + 'class' => 'yii\captcha\CaptchaAction', + 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, + ], + ]; + } + + /** + * Displays homepage. + * + * @return mixed + */ + public function actionIndex() + { + return $this->render('index'); + } + + /** + * Logs in a user. + * + * @return mixed + */ + public function actionLogin() + { + if (!Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new LoginForm(); + if ($model->load(Yii::$app->request->post()) && $model->login()) { + return $this->goBack(); + } else { + $model->password = ''; + + 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, + ]); + } + } + + /** + * Displays about page. + * + * @return mixed + */ + public function actionAbout() + { + return $this->render('about'); + } + + /** + * Signs user up. + * + * @return mixed + */ + public function actionSignup() + { + $model = new SignupForm(); + if ($model->load(Yii::$app->request->post())) { + if ($user = $model->signup()) { + if (Yii::$app->getUser()->login($user)) { + return $this->goHome(); + } + } + } + + return $this->render('signup', [ + 'model' => $model, + ]); + } + + /** + * Requests password reset. + * + * @return mixed + */ + public function actionRequestPasswordReset() + { + $model = new PasswordResetRequestForm(); + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + if ($model->sendEmail()) { + Yii::$app->session->setFlash('success', 'Check your email for further instructions.'); + + return $this->goHome(); + } else { + Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for 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/models/ContactForm.php b/frontend/models/ContactForm.php new file mode 100644 index 0000000..8c00d47 --- /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 100644 index 0000000..56c2bc8 --- /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 100644 index 0000000..f580986 --- /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 100644 index 0000000..a66a875 --- /dev/null +++ b/frontend/models/SignupForm.php @@ -0,0 +1,58 @@ + '\common\models\User', 'message' => 'This username has already been taken.'], + ['username', 'string', 'min' => 2, 'max' => 255], + + ['email', 'trim'], + ['email', 'required'], + ['email', 'email'], + ['email', 'string', 'max' => 255], + ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'], + + ['password', 'required'], + ['password', 'string', 'min' => 6], + ]; + } + + /** + * Signs user up. + * + * @return User|null the saved model or null if saving fails + */ + public function signup() + { + if (!$this->validate()) { + return null; + } + + $user = new User(); + $user->username = $this->username; + $user->email = $this->email; + $user->setPassword($this->password); + $user->generateAuthKey(); + + return $user->save() ? $user : null; + } +} diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore new file mode 100644 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/_bootstrap.php b/frontend/tests/_bootstrap.php new file mode 100644 index 0000000..44f5e81 --- /dev/null +++ b/frontend/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/frontend/tests/_data/user.php b/frontend/tests/_data/user.php new file mode 100644 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 100644 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 100644 index 0000000..36e264c --- /dev/null +++ b/frontend/tests/_support/.gitignore @@ -0,0 +1 @@ +_generated diff --git a/frontend/tests/_support/FunctionalTester.php b/frontend/tests/_support/FunctionalTester.php new file mode 100644 index 0000000..7475d8a --- /dev/null +++ b/frontend/tests/_support/FunctionalTester.php @@ -0,0 +1,33 @@ +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 100644 index 0000000..8c708e7 --- /dev/null +++ b/frontend/tests/_support/UnitTester.php @@ -0,0 +1,25 @@ +amOnPage(Url::toRoute('/site/index')); + $I->see('My Application'); + + $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 100644 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 100644 index 0000000..8f9c4cb --- /dev/null +++ b/frontend/tests/functional.suite.yml @@ -0,0 +1,6 @@ +suite_namespace: frontend\tests\functional +actor: FunctionalTester +modules: + enabled: + - Filesystem + - Yii2 diff --git a/frontend/tests/functional/AboutCest.php b/frontend/tests/functional/AboutCest.php new file mode 100644 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 100644 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 100644 index 0000000..9a5a93d --- /dev/null +++ b/frontend/tests/functional/HomeCest.php @@ -0,0 +1,17 @@ +amOnPage(\Yii::$app->homeUrl); + $I->see('My Application'); + $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 100644 index 0000000..ed358d0 --- /dev/null +++ b/frontend/tests/functional/LoginCest.php @@ -0,0 +1,60 @@ + [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'login_data.php' + ] + ]; + } + + public function _before(FunctionalTester $I) + { + $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 100644 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 100644 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 100644 index 0000000..23ea63b --- /dev/null +++ b/frontend/tests/unit.suite.yml @@ -0,0 +1,7 @@ +suite_namespace: frontend\tests\unit +actor: 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 100644 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 100644 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 100644 index 0000000..6f4a8e7 --- /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 100644 index 0000000..f506368 --- /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 100644 index 0000000..eb9b61c --- /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/layouts/main.php b/frontend/views/layouts/main.php new file mode 100644 index 0000000..f4beaf5 --- /dev/null +++ b/frontend/views/layouts/main.php @@ -0,0 +1,83 @@ + +beginPage() ?> + + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + +beginBody() ?> + +
+ Yii::$app->name, + 'brandUrl' => Yii::$app->homeUrl, + 'options' => [ + 'class' => 'navbar-inverse navbar-fixed-top', + ], + ]); + $menuItems = [ + ['label' => 'Home', 'url' => ['/site/index']], + ['label' => 'About', 'url' => ['/site/about']], + ['label' => 'Contact', 'url' => ['/site/contact']], + ]; + if (Yii::$app->user->isGuest) { + $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; + $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; + } else { + $menuItems[] = '
  • ' + . 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(); + ?> + +
    + isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + ]) ?> + + +
    +
    + +
    +
    +

    © name) ?>

    + +

    +
    +
    + +endBody() ?> + + +endPage() ?> diff --git a/frontend/views/site/about.php b/frontend/views/site/about.php new file mode 100644 index 0000000..8eb0764 --- /dev/null +++ b/frontend/views/site/about.php @@ -0,0 +1,16 @@ +title = 'About'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +

    title) ?>

    + +

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

    + + +
    diff --git a/frontend/views/site/contact.php b/frontend/views/site/contact.php new file mode 100644 index 0000000..dc48410 --- /dev/null +++ b/frontend/views/site/contact.php @@ -0,0 +1,45 @@ +title = 'Contact'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +

    title) ?>

    + +

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

    + +
    +
    + 'contact-form']); ?> + + field($model, 'name')->textInput(['autofocus' => true]) ?> + + field($model, 'email') ?> + + field($model, 'subject') ?> + + field($model, 'body')->textarea(['rows' => 6]) ?> + + field($model, 'verifyCode')->widget(Captcha::className(), [ + 'template' => '
    {image}
    {input}
    ', + ]) ?> + +
    + 'btn btn-primary', 'name' => 'contact-button']) ?> +
    + + +
    +
    + +
    diff --git a/frontend/views/site/error.php b/frontend/views/site/error.php new file mode 100644 index 0000000..0ba2574 --- /dev/null +++ b/frontend/views/site/error.php @@ -0,0 +1,27 @@ +title = $name; +?> +
    + +

    title) ?>

    + +
    + +
    + +

    + 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 100644 index 0000000..f780610 --- /dev/null +++ b/frontend/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/frontend/views/site/login.php b/frontend/views/site/login.php new file mode 100644 index 0000000..56ea98e --- /dev/null +++ b/frontend/views/site/login.php @@ -0,0 +1,39 @@ +title = 'Login'; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/frontend/views/site/requestPasswordResetToken.php b/frontend/views/site/requestPasswordResetToken.php new file mode 100644 index 0000000..9f6822e --- /dev/null +++ b/frontend/views/site/requestPasswordResetToken.php @@ -0,0 +1,31 @@ +title = 'Request password reset'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +

    title) ?>

    + +

    Please fill out your email. A link to reset password will be sent there.

    + +
    +
    + 'request-password-reset-form']); ?> + + field($model, 'email')->textInput(['autofocus' => true]) ?> + +
    + 'btn btn-primary']) ?> +
    + + +
    +
    +
    diff --git a/frontend/views/site/resetPassword.php b/frontend/views/site/resetPassword.php new file mode 100644 index 0000000..36ef452 --- /dev/null +++ b/frontend/views/site/resetPassword.php @@ -0,0 +1,31 @@ +title = 'Reset password'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +

    title) ?>

    + +

    Please choose your new password:

    + +
    +
    + 'reset-password-form']); ?> + + field($model, 'password')->passwordInput(['autofocus' => true]) ?> + +
    + 'btn btn-primary']) ?> +
    + + +
    +
    +
    diff --git a/frontend/views/site/signup.php b/frontend/views/site/signup.php new file mode 100644 index 0000000..de9dad6 --- /dev/null +++ b/frontend/views/site/signup.php @@ -0,0 +1,35 @@ +title = 'Signup'; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/frontend/web/.gitignore b/frontend/web/.gitignore new file mode 100644 index 0000000..d94a089 --- /dev/null +++ b/frontend/web/.gitignore @@ -0,0 +1,3 @@ +/index.php +/index-test.php +/robots.txt diff --git a/frontend/web/.htaccess b/frontend/web/.htaccess new file mode 100644 index 0000000..c5935ce --- /dev/null +++ b/frontend/web/.htaccess @@ -0,0 +1,19 @@ +# ���� ��� ����� ��� ����, ��������� ��� +#RewriteCond %{REQUEST_FILENAME} !-f +#RewriteCond %{REQUEST_FILENAME} !-d +# � ��������� ������ �������������� �� index.php +#RewriteRule . index.php + +Options +SymLinksIfOwnerMatch +IndexIgnore / + +RewriteEngine on +#RewriteBase / + +# 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 100644 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 100644 index 0000000..5f1e6b9 --- /dev/null +++ b/frontend/web/css/site.css @@ -0,0 +1,120 @@ +html, +body { + height: 100%; +} + +.wrap { + min-height: 100%; + height: auto; + margin: 0 auto -60px; + padding: 0 0 60px; +} + +.wrap > .container { + padding: 70px 15px 20px; +} + +.footer { + height: 60px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + padding-top: 20px; +} + +.jumbotron { + text-align: center; + background-color: transparent; +} + +.jumbotron .btn { + font-size: 21px; + padding: 14px 24px; +} + +.not-set { + color: #c55; + font-style: italic; +} + +/* add sorting icons to gridview sort links */ +a.asc:after, a.desc:after { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + padding-left: 5px; +} + +a.asc:after { + content: "\e151"; +} + +a.desc:after { + content: "\e152"; +} + +.sort-numerical a.asc:after { + content: "\e153"; +} + +.sort-numerical a.desc:after { + content: "\e154"; +} + +.sort-ordinal a.asc:after { + content: "\e155"; +} + +.sort-ordinal a.desc:after { + content: "\e156"; +} + +.grid-view td { + white-space: nowrap; +} + +.grid-view .filters input, +.grid-view .filters select { + min-width: 50px; +} + +.hint-block { + display: block; + margin-top: 5px; + color: #999; +} + +.error-summary { + color: #a94442; + background: #fdf7f7; + border-left: 3px solid #eed3d7; + padding: 10px 20px; + margin: 0 0 15px 0; +} + +/* align the logout "link" (button in form) of the navbar */ +.nav li > form > 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/frontend/web/favicon.ico b/frontend/web/favicon.ico new file mode 100644 index 0000000..580ed73 Binary files /dev/null and b/frontend/web/favicon.ico differ diff --git a/frontend/web/media/upload/.gitignore b/frontend/web/media/upload/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/frontend/web/media/upload/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/init b/init new file mode 100755 index 0000000..47be99e --- /dev/null +++ b/init @@ -0,0 +1,293 @@ +#!/usr/bin/env php + $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 100644 index 0000000..1b92c19 --- /dev/null +++ b/init.bat @@ -0,0 +1,15 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line init script for Windows. +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 100644 index 0000000..acc65d8 --- /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 100644 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 100644 index 0000000..7b36400 --- /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: 1024 diff --git a/vagrant/nginx/app.conf b/vagrant/nginx/app.conf new file mode 100644 index 0000000..711ca7c --- /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.test; + 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/php/php7.0-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.test; + 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/php/php7.0-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 100644 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 100644 index 0000000..6dcbf4f --- /dev/null +++ b/vagrant/provision/always-as-root.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +source /app/vagrant/provision/common.sh + +#== Provision script == + +info "Provision-script user: `whoami`" + +info "Restart web-stack" +service php7.0-fpm restart +service nginx restart +service mysql restart \ No newline at end of file diff --git a/vagrant/provision/common.sh b/vagrant/provision/common.sh new file mode 100644 index 0000000..ab5e1e0 --- /dev/null +++ b/vagrant/provision/common.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +#== Bash helpers == + +function info { + echo " " + echo "--> $1" + echo " " +} diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh new file mode 100644 index 0000000..a9ae46a --- /dev/null +++ b/vagrant/provision/once-as-root.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +source /app/vagrant/provision/common.sh + +#== Import script args == + +timezone=$(echo "$1") + +#== Provision script == + +info "Provision-script user: `whoami`" + +export DEBIAN_FRONTEND=noninteractive + +info "Configure timezone" +timedatectl set-timezone ${timezone} --no-ask-password + +info "Prepare root password for MySQL" +debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass password \"''\"" +debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass password \"''\"" +echo "Done!" + +info "Update OS software" +apt-get update +apt-get upgrade -y + +info "Install additional software" +apt-get install -y php7.0-curl php7.0-cli php7.0-intl php7.0-mysqlnd php7.0-gd php7.0-fpm php7.0-mbstring php7.0-xml unzip nginx mysql-server-5.7 php.xdebug + +info "Configure MySQL" +sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf +mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''" +mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'" +mysql -uroot <<< "DROP USER 'root'@'localhost'" +mysql -uroot <<< "FLUSH PRIVILEGES" +echo "Done!" + +info "Configure PHP-FPM" +sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +cat << EOF > /etc/php/7.0/mods-available/xdebug.ini +zend_extension=xdebug.so +xdebug.remote_enable=1 +xdebug.remote_connect_back=1 +xdebug.remote_port=9000 +xdebug.remote_autostart=1 +EOF +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 100644 index 0000000..ffaa898 --- /dev/null +++ b/vagrant/provision/once-as-vagrant.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +source /app/vagrant/provision/common.sh + +#== Import script args == + +github_token=$(echo "$1") + +#== Provision script == + +info "Provision-script user: `whoami`" + +info "Configure composer" +composer config --global github-oauth.github.com ${github_token} +echo "Done!" + +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 --interactive=0 +./yii_test migrate --interactive=0 + +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 100644 index 0000000..3a68942 --- /dev/null +++ b/yii.bat @@ -0,0 +1,15 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line bootstrap script for Windows. +rem ------------------------------------------------------------- + +@setlocal + +set YII_PATH=%~dp0 + +if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe + +"%PHP_COMMAND%" "%YII_PATH%yii" %* + +@endlocal