Commit 2f324895bc56cd4fca30b2028c8f6e53d80c0e67

Authored by Yarik
1 parent d6077779

test

  1 +/node_modules
1 # yii console command 2 # yii console command
2 /yii 3 /yii
3 4
@@ -22,6 +23,10 @@ Thumbs.db @@ -22,6 +23,10 @@ Thumbs.db
22 composer.phar 23 composer.phar
23 24
24 # Mac DS_Store Files 25 # Mac DS_Store Files
  26 +/server.js
  27 +/frontend/controllers/ModellingController.php
  28 +/frontend/views/modelling
  29 +/frontend/models/SMOClosed.php
25 .DS_Store 30 .DS_Store
26 31
27 # phpunit itself is not needed 32 # phpunit itself is not needed
common/components/rules/DeleteRule.php
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 11
12 public function execute ($user, $item, $params) 12 public function execute ($user, $item, $params)
13 { 13 {
  14 + return true;
14 $auth = \Yii::$app->authManager; 15 $auth = \Yii::$app->authManager;
15 $access = false; 16 $access = false;
16 if($params['record']) { 17 if($params['record']) {
common/models/Portfolio.php
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 * @property string $preview 25 * @property string $preview
26 * @property PortfolioSpecialization[] $portfolioSpecializations 26 * @property PortfolioSpecialization[] $portfolioSpecializations
27 * @property Specialization[] $specializations 27 * @property Specialization[] $specializations
  28 + * @property User $user
28 */ 29 */
29 class Portfolio extends \yii\db\ActiveRecord 30 class Portfolio extends \yii\db\ActiveRecord
30 { 31 {
@@ -55,7 +56,7 @@ @@ -55,7 +56,7 @@
55 'value' => new Expression('NOW()'), 56 'value' => new Expression('NOW()'),
56 ], 57 ],
57 [ 58 [
58 - 'class' => 'common\behaviors\ShowImage', 59 + 'class' => 'common\behaviors\ShowImage',
59 ], 60 ],
60 ]; 61 ];
61 } 62 }
@@ -71,7 +72,7 @@ @@ -71,7 +72,7 @@
71 'name', 72 'name',
72 'preview', 73 'preview',
73 'city', 74 'city',
74 - 'cover' 75 + 'cover',
75 ], 76 ],
76 'required', 77 'required',
77 ], 78 ],
@@ -190,6 +191,12 @@ @@ -190,6 +191,12 @@
190 191
191 public function getPortfolioUsers() 192 public function getPortfolioUsers()
192 { 193 {
193 - return $this->hasMany(PortfolioUser::className(), ['portfolio_id' => 'portfolio_id'])->with('user'); 194 + return $this->hasMany(PortfolioUser::className(), [ 'portfolio_id' => 'portfolio_id' ])
  195 + ->with('user');
  196 + }
  197 +
  198 + public function getUser()
  199 + {
  200 + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]);
194 } 201 }
195 } 202 }
common/models/PortfolioGallery.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "portfolio_gallery".
  9 + *
  10 + * @property integer $portfolio_gallery_id
  11 + * @property integer $gallery_id
  12 + * @property integer $portfolio_id
  13 + * @property string $caption
  14 + * @property integer $visible
  15 + *
  16 + * @property Gallery $gallery
  17 + * @property Portfolio $portfolio
  18 + */
  19 +class PortfolioGallery extends \yii\db\ActiveRecord
  20 +{
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public static function tableName()
  25 + {
  26 + return 'portfolio_gallery';
  27 + }
  28 +
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public function rules()
  33 + {
  34 + return [
  35 + [['gallery_id', 'portfolio_id'], 'required'],
  36 + [['gallery_id', 'portfolio_id', 'visible'], 'integer'],
  37 + [['caption'], 'string', 'max' => 255],
  38 + [['gallery_id'], 'exist', 'skipOnError' => true, 'targetClass' => Gallery::className(), 'targetAttribute' => ['gallery_id' => 'gallery_id']],
  39 + [['portfolio_id'], 'exist', 'skipOnError' => true, 'targetClass' => Portfolio::className(), 'targetAttribute' => ['portfolio_id' => 'portfolio_id']],
  40 + ];
  41 + }
  42 +
  43 + /**
  44 + * @inheritdoc
  45 + */
  46 + public function attributeLabels()
  47 + {
  48 + return [
  49 + 'portfolio_gallery_id' => Yii::t('app', 'Portfolio Gallery ID'),
  50 + 'gallery_id' => Yii::t('app', 'Gallery ID'),
  51 + 'portfolio_id' => Yii::t('app', 'Portfolio ID'),
  52 + 'caption' => Yii::t('app', 'Описание'),
  53 + 'visible' => Yii::t('app', 'Visible'),
  54 + ];
  55 + }
  56 +
  57 + /**
  58 + * @return \yii\db\ActiveQuery
  59 + */
  60 + public function getGallery()
  61 + {
  62 + return $this->hasOne(Gallery::className(), ['gallery_id' => 'gallery_id']);
  63 + }
  64 +
  65 + /**
  66 + * @return \yii\db\ActiveQuery
  67 + */
  68 + public function getPortfolio()
  69 + {
  70 + return $this->hasOne(Portfolio::className(), ['portfolio_id' => 'portfolio_id']);
  71 + }
  72 +}
common/models/PortfolioUser.php
1 <?php 1 <?php
2 2
3 -namespace common\models; 3 + namespace common\models;
4 4
5 -use Yii; 5 + use Yii;
6 6
7 -/**  
8 - * This is the model class for table "portfolio_user".  
9 - *  
10 - * @property integer $portfolio_user_id  
11 - * @property integer $portfolio_id  
12 - * @property integer $user_id  
13 - * @property string $position  
14 - * @property integer $time  
15 - * @property integer $status  
16 - *  
17 - * @property Portfolio $portfolio  
18 - * @property User $user  
19 - */  
20 -class PortfolioUser extends \yii\db\ActiveRecord  
21 -{  
22 /** 7 /**
23 - * @inheritdoc 8 + * This is the model class for table "portfolio_user".
  9 + * @property integer $portfolio_user_id
  10 + * @property integer $portfolio_id
  11 + * @property integer $user_id
  12 + * @property string $position
  13 + * @property integer $time
  14 + * @property integer $status
  15 + * @property Portfolio $portfolio
  16 + * @property User $user
24 */ 17 */
25 - public static function tableName() 18 + class PortfolioUser extends \yii\db\ActiveRecord
26 { 19 {
27 - return 'portfolio_user';  
28 - }  
29 20
30 - /**  
31 - * @inheritdoc  
32 - */  
33 - public function rules()  
34 - {  
35 - return [  
36 - [['portfolio_id', 'user_id'], 'required'],  
37 - [['portfolio_id', 'user_id', 'time'], 'integer'],  
38 - [['position'], 'string', 'max' => 255],  
39 - [['portfolio_id', 'user_id'], 'unique', 'targetAttribute' => ['portfolio_id', 'user_id'], 'message' => 'The combination of Portfolio ID and User ID has already been taken.'],  
40 - [['portfolio_id'], 'exist', 'skipOnError' => true, 'targetClass' => Portfolio::className(), 'targetAttribute' => ['portfolio_id' => 'portfolio_id']],  
41 - [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],  
42 - ];  
43 - } 21 + public $project;
44 22
45 - /**  
46 - * @inheritdoc  
47 - */  
48 - public function attributeLabels()  
49 - {  
50 - return [  
51 - 'portfolio_user_id' => Yii::t('app', 'Portfolio User ID'),  
52 - 'portfolio_id' => Yii::t('app', 'Portfolio ID'),  
53 - 'user_id' => Yii::t('app', 'User ID'),  
54 - 'position' => Yii::t('app', 'Position'),  
55 - 'time' => Yii::t('app', 'Time'),  
56 - 'status' => Yii::t('app', 'Status'),  
57 - ];  
58 - } 23 + public $time_from;
59 24
60 - /**  
61 - * @return \yii\db\ActiveQuery  
62 - */  
63 - public function getPortfolio()  
64 - {  
65 - return $this->hasOne(Portfolio::className(), ['portfolio_id' => 'portfolio_id']);  
66 - } 25 + public $time_to;
  26 +
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public static function tableName()
  31 + {
  32 + return 'portfolio_user';
  33 + }
  34 +
  35 + /**
  36 + * @inheritdoc
  37 + */
  38 + public function rules()
  39 + {
  40 + return [
  41 + [
  42 + [
  43 + 'portfolio_id',
  44 + 'user_id',
  45 + ],
  46 + 'required',
  47 + ],
  48 + [
  49 + [
  50 + 'portfolio_id',
  51 + 'user_id',
  52 + 'time',
  53 + 'status',
  54 + ],
  55 + 'integer',
  56 + ],
  57 + [
  58 + [ 'position' ],
  59 + 'string',
  60 + 'max' => 255,
  61 + ],
  62 + [
  63 + [
  64 + 'portfolio_id',
  65 + 'user_id',
  66 + ],
  67 + 'unique',
  68 + 'targetAttribute' => [
  69 + 'portfolio_id',
  70 + 'user_id',
  71 + ],
  72 + 'message' => 'The combination of Portfolio ID and User ID has already been taken.',
  73 + ],
  74 + [
  75 + [ 'portfolio_id' ],
  76 + 'exist',
  77 + 'skipOnError' => true,
  78 + 'targetClass' => Portfolio::className(),
  79 + 'targetAttribute' => [ 'portfolio_id' => 'portfolio_id' ],
  80 + ],
  81 + [
  82 + [ 'user_id' ],
  83 + 'exist',
  84 + 'skipOnError' => true,
  85 + 'targetClass' => User::className(),
  86 + 'targetAttribute' => [ 'user_id' => 'id' ],
  87 + ],
  88 + ];
  89 + }
  90 +
  91 + /**
  92 + * @inheritdoc
  93 + */
  94 + public function attributeLabels()
  95 + {
  96 + return [
  97 + 'portfolio_user_id' => Yii::t('app', 'Portfolio User ID'),
  98 + 'portfolio_id' => Yii::t('app', 'Portfolio ID'),
  99 + 'user_id' => Yii::t('app', 'User ID'),
  100 + 'position' => Yii::t('app', 'Должность'),
  101 + 'time' => Yii::t('app', 'Рабочих часов'),
  102 + 'status' => Yii::t('app', 'Статус'),
  103 + 'project' => Yii::t('app', 'Проект'),
  104 + 'time_from' => Yii::t('app', 'часы от'),
  105 + 'time_to' => Yii::t('app', 'часы до'),
  106 + ];
  107 + }
  108 +
  109 + /**
  110 + * @return \yii\db\ActiveQuery
  111 + */
  112 + public function getPortfolio()
  113 + {
  114 + return $this->hasOne(Portfolio::className(), [ 'portfolio_id' => 'portfolio_id' ])
  115 + ->inverseOf('portfolioUsers');
  116 + }
  117 +
  118 + /**
  119 + * @return \yii\db\ActiveQuery
  120 + */
  121 + public function getUser()
  122 + {
  123 + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]);
  124 + }
  125 +
  126 + public function afterSave($insert, $changedAttributes)
  127 + {
  128 + if(!$insert && array_key_exists('status', $changedAttributes)) {
  129 + $portfolioGallery = PortfolioGallery::find()
  130 + ->where([
  131 + 'portfolio_id' => $this->portfolio_id,
  132 + 'user_id' => $this->user_id,
  133 + ])
  134 + ->one();
  135 + if(empty( $portfolioGallery )) {
  136 + $gallery = new Gallery([
  137 + 'user_id' => $this->user_id,
  138 + 'name' => $this->portfolio->name,
  139 + ]);
  140 + if($gallery->save()) {
  141 + $portfolioGallery = new PortfolioGallery([
  142 + 'gallery_id' => $gallery->gallery_id,
  143 + 'portfolio_id' => $this->portfolio_id,
  144 + 'user_id' => $this->user_id,
  145 + ]);
  146 + $portfolioGallery->save();
  147 + } else {
  148 + throw new \Exception('Невозможно создать галерею пользователя ' . $this->user_id . ' для проекта ' . $this->portfolio_id);
  149 + }
  150 + }
  151 + }
  152 + parent::afterSave($insert, $changedAttributes);
  153 + }
  154 +
  155 + public function getPortfolioGallery()
  156 + {
  157 + return $this->hasOne(PortfolioGallery::className(), [
  158 + 'portfolio_id' => 'portfolio_id',
  159 + 'user_id' => 'user_id',
  160 + ]);
  161 + }
  162 +
  163 + public function getGallery()
  164 + {
  165 + return $this->hasOne(Gallery::className(), [
  166 + 'gallery_id' => 'gallery_id',
  167 + 'user_id' => 'user_id',
  168 + ])
  169 + ->via('portfolioGallery');
  170 + }
67 171
68 - /**  
69 - * @return \yii\db\ActiveQuery  
70 - */  
71 - public function getUser()  
72 - {  
73 - return $this->hasOne(User::className(), ['id' => 'user_id']);  
74 } 172 }
75 -}  
common/models/PortfolioUserSearch.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use Yii;
  6 + use yii\data\ActiveDataProvider;
  7 +
  8 + class PortfolioUserSearch extends PortfolioUser
  9 + {
  10 +
  11 + /**
  12 + * @inheritdoc
  13 + */
  14 + public function rules()
  15 + {
  16 + return [
  17 + [
  18 + [
  19 + 'project',
  20 + 'position',
  21 + ],
  22 + 'safe',
  23 + ],
  24 + [
  25 + [
  26 + 'time_from',
  27 + 'time_to',
  28 + ],
  29 + 'integer',
  30 + 'min' => 0,
  31 + ],
  32 + [
  33 + [
  34 + 'time_to',
  35 + ],
  36 + 'compare',
  37 + 'compareAttribute' => 'time_from',
  38 + 'operator' => '>=',
  39 + ],
  40 + [
  41 + [
  42 + 'status',
  43 + ],
  44 + 'integer',
  45 + 'min' => 1,
  46 + 'max' => 2,
  47 + ],
  48 + ];
  49 + }
  50 +
  51 + public function search($params)
  52 + {
  53 + $query = PortfolioUser::find()
  54 + ->where([ 'portfolio_user.user_id' => \Yii::$app->user->id ]);
  55 +
  56 + $dataProvider = new ActiveDataProvider([
  57 + 'query' => $query,
  58 + ]);
  59 +
  60 + $this->load($params);
  61 +
  62 + if(!$this->validate()) {
  63 + // uncomment the following line if you do not want to return any records when validation fails
  64 + // $query->where('0=1');
  65 + return $dataProvider;
  66 + }
  67 +
  68 + if(!empty( $this->time_from ) && !empty( $this->time_to )) {
  69 + $query->andWhere([
  70 + 'between',
  71 + 'time',
  72 + $this->time_from,
  73 + $this->time_to,
  74 + ]);
  75 + } elseif(!empty( $this->time_from )) {
  76 + $query->andWhere([
  77 + '>=',
  78 + 'time',
  79 + $this->time_from,
  80 + ]);
  81 + } elseif(!empty( $this->time_to )) {
  82 + $query->andWhere([
  83 + '<=',
  84 + 'time',
  85 + $this->time_to,
  86 + ]);
  87 + }
  88 +
  89 + $query->andFilterWhere(['status' => $this->status]);
  90 +
  91 + $query->andFilterWhere([
  92 + 'like',
  93 + 'LOWER(position)',
  94 + mb_strtolower($this->position),
  95 + ]);
  96 +
  97 + $query->andFilterWhere([
  98 + 'like',
  99 + 'LOWER(portfolio.name)',
  100 + mb_strtolower($this->project),
  101 + ]);
  102 +
  103 + return $dataProvider;
  104 + }
  105 + }
common/models/TenderSearch.php
@@ -117,8 +117,7 @@ @@ -117,8 +117,7 @@
117 { 117 {
118 $query = Project::find() 118 $query = Project::find()
119 ->joinWith('projectSpecializations') 119 ->joinWith('projectSpecializations')
120 - ->joinWith('projectPayments')  
121 - ->andWhere([ 'hidden' => 0 ]); 120 + ->joinWith('projectPayments');
122 121
123 $dataProvider = new ActiveDataProvider([ 122 $dataProvider = new ActiveDataProvider([
124 'query' => $query, 123 'query' => $query,
common/models/UserSearch.php
@@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
65 $dataProvider = new ActiveDataProvider([ 65 $dataProvider = new ActiveDataProvider([
66 'query' => $query, 66 'query' => $query,
67 'pagination' => new Pagination([ 67 'pagination' => new Pagination([
68 - 'pageSize' => 10, 68 + 'pageSize' => 5,
69 ]), 69 ]),
70 'sort' => new Sort([ 70 'sort' => new Sort([
71 'defaultOrder' => [ 71 'defaultOrder' => [
common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 public function execute($user, $item, $params) 12 public function execute($user, $item, $params)
13 { 13 {
14 - return true; 14 + return false;
15 } 15 }
16 16
17 } 17 }
18 \ No newline at end of file 18 \ No newline at end of file
console/migrations/m160411_143038_create_portfolio_gallery.php 0 → 100644
  1 +<?php
  2 +
  3 + use yii\db\Migration;
  4 +
  5 + /**
  6 + * Handles the creation for table `portfolio_gallery`.
  7 + */
  8 + class m160411_143038_create_portfolio_gallery extends Migration
  9 + {
  10 +
  11 + /**
  12 + * @inheritdoc
  13 + */
  14 + public function up()
  15 + {
  16 + $this->createTable('portfolio_gallery', [
  17 + 'portfolio_gallery_id' => $this->primaryKey(),
  18 + 'gallery_id' => $this->integer()
  19 + ->notNull(),
  20 + 'portfolio_id' => $this->integer()
  21 + ->notNull(),
  22 + 'user_id' => $this->integer()
  23 + ->notNull(),
  24 + 'caption' => $this->string(),
  25 + 'visible' => $this->smallInteger()
  26 + ->defaultValue(1),
  27 + ]);
  28 + $this->addForeignKey('portfolio_gallery_gallery', '{{%portfolio_gallery}}', 'gallery_id', '{{%gallery}}', 'gallery_id', 'CASCADE', 'CASCADE');
  29 + $this->addForeignKey('portfolio_gallery_portfolio', '{{%portfolio_gallery}}', 'portfolio_id', '{{%portfolio}}', 'portfolio_id', 'CASCADE', 'CASCADE');
  30 + $this->addForeignKey('portfolio_gallery_user', '{{%portfolio_gallery}}', 'user_id', '{{%user}}', 'id', 'CASCADE', 'CASCADE');
  31 + }
  32 +
  33 + /**
  34 + * @inheritdoc
  35 + */
  36 + public function down()
  37 + {
  38 + $this->dropForeignKey('portfolio_gallery_user', '{{%portfolio_gallery}}');
  39 + $this->dropForeignKey('portfolio_gallery_gallery', '{{%portfolio_gallery}}');
  40 + $this->dropForeignKey('portfolio_gallery_portfolio', '{{%portfolio_gallery}}');
  41 + $this->dropTable('portfolio_gallery');
  42 + }
  43 + }
frontend/controllers/AccountsController.php
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 use common\models\PortfolioSearch; 19 use common\models\PortfolioSearch;
20 use common\models\PortfolioSpecialization; 20 use common\models\PortfolioSpecialization;
21 use common\models\PortfolioUser; 21 use common\models\PortfolioUser;
  22 + use common\models\PortfolioUserSearch;
22 use common\models\Project; 23 use common\models\Project;
23 use common\models\ProjectSearch; 24 use common\models\ProjectSearch;
24 use common\models\Specialization; 25 use common\models\Specialization;
@@ -33,6 +34,7 @@ @@ -33,6 +34,7 @@
33 use common\models\UserInfo; 34 use common\models\UserInfo;
34 35
35 use yii\base\ErrorException; 36 use yii\base\ErrorException;
  37 + use yii\data\Sort;
36 use yii\db\ActiveRecord; 38 use yii\db\ActiveRecord;
37 use yii\filters\AccessControl; 39 use yii\filters\AccessControl;
38 use yii\filters\VerbFilter; 40 use yii\filters\VerbFilter;
@@ -77,6 +79,18 @@ @@ -77,6 +79,18 @@
77 ]; 79 ];
78 } 80 }
79 81
  82 + public function beforeAction($action)
  83 + {
  84 + $portfolio_user_count = PortfolioUser::find()
  85 + ->where([
  86 + 'user_id' => \Yii::$app->user->id,
  87 + 'status' => 2,
  88 + ])
  89 + ->count();
  90 + $this->view->params[ 'portfolio_user_count' ] = $portfolio_user_count;
  91 + return parent::beforeAction($action); // TODO: Change the autogenerated stub
  92 + }
  93 +
80 /** 94 /**
81 * Page of additional skills, consist: 95 * Page of additional skills, consist:
82 * * working with programs; 96 * * working with programs;
@@ -456,6 +470,107 @@ @@ -456,6 +470,107 @@
456 return $this->renderAjax('_job_form', [ 'index' => $lastindex + 1 ]); 470 return $this->renderAjax('_job_form', [ 'index' => $lastindex + 1 ]);
457 } 471 }
458 472
  473 + public function actionParticipant()
  474 + {
  475 + $searchModel = new PortfolioUserSearch();
  476 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  477 + $dataProvider->query->joinWith('portfolio');
  478 + $dataProvider->sort = new Sort([
  479 + 'defaultOrder' => [
  480 + 'portfolio_user_id' => SORT_ASC,
  481 + ],
  482 + 'attributes' => [
  483 + 'project' => [
  484 + 'asc' => [
  485 + 'portfolio.name' => SORT_ASC,
  486 + ],
  487 + 'desc' => [
  488 + 'portfolio.name' => SORT_DESC,
  489 + ],
  490 + ],
  491 + 'portfolio_user_id',
  492 + 'position',
  493 + 'time',
  494 + 'status',
  495 + ],
  496 + ]);
  497 + $dataProvider->pagination->pageSize = 5;
  498 + return $this->render('participant', [
  499 + 'searchModel' => $searchModel,
  500 + 'dataProvider' => $dataProvider,
  501 + ]);
  502 + }
  503 +
  504 + public function actionParticipantConfirm($id)
  505 + {
  506 + $portfolioUser = PortfolioUser::find()
  507 + ->where([
  508 + 'portfolio_user_id' => $id,
  509 + 'user_id' => \Yii::$app->user->id,
  510 + 'status' => 2,
  511 + ])
  512 + ->one();
  513 + if(empty( $portfolioUser )) {
  514 + throw new NotFoundHttpException('Приглашение не найдено');
  515 + }
  516 + $portfolioUser->status = 1;
  517 + if($portfolioUser->save(false)) {
  518 + return $this->redirect([ 'accounts/participant' ]);
  519 + } else {
  520 + throw new \Exception('Неизвестная ошибка');
  521 + }
  522 + }
  523 +
  524 + public function actionParticipantDelete($id)
  525 + {
  526 + $portfolioUser = PortfolioUser::find()
  527 + ->where([
  528 + 'portfolio_user_id' => $id,
  529 + 'user_id' => \Yii::$app->user->id,
  530 + ])
  531 + ->one();
  532 + if(empty( $portfolioUser )) {
  533 + throw new NotFoundHttpException('Приглашение не найдено');
  534 + }
  535 + if($portfolioUser->delete()) {
  536 + return $this->redirect([ 'accounts/participant' ]);
  537 + } else {
  538 + throw new \Exception('Неизвестная ошибка');
  539 + }
  540 + }
  541 +
  542 + public function actionParticipantEdit($id)
  543 + {
  544 + $portfolioUser = PortfolioUser::find()
  545 + ->where([
  546 + 'portfolio_user_id' => $id,
  547 + 'user_id' => \Yii::$app->user->id,
  548 + ])
  549 + ->with('gallery')
  550 + ->one();
  551 + if(empty( $portfolioUser )) {
  552 + throw new NotFoundHttpException('Приглашение не найдено');
  553 + }
  554 + $post = \Yii::$app->request->post();
  555 + if(!empty( $post )) {
  556 + if($portfolioUser->load($post)) {
  557 + $portfolioUser->status = 1;
  558 + if($portfolioUser->save()) {
  559 + if(!empty($portfolioUser->gallery)) {
  560 + $portfolioUser->gallery->load($post);
  561 + $portfolioUser->portfolioGallery->load($post);
  562 + if($portfolioUser->gallery->save() && $portfolioUser->portfolioGallery->save()) {
  563 + return $this->redirect(['accounts/participant']);
  564 + }
  565 + } else {
  566 + return $this->redirect(['accounts/participant-edit', 'id' => $portfolioUser->portfolio_user_id]);
  567 + }
  568 + }
  569 + }
  570 + }
  571 + return $this->render('participant-edit', [ 'model' => $portfolioUser ]);
  572 + }
  573 +
459 /** 574 /**
460 * Page of User's portfolio 575 * Page of User's portfolio
461 * @return string 576 * @return string
@@ -510,7 +625,7 @@ @@ -510,7 +625,7 @@
510 foreach($post[ 'PortfolioUser' ] as $index => $item) { 625 foreach($post[ 'PortfolioUser' ] as $index => $item) {
511 $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); 626 $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]);
512 } 627 }
513 - $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers)); 628 + $success = ( PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers) );
514 if($success) { 629 if($success) {
515 foreach($portfolioUsers as $index => $portfolioUser) { 630 foreach($portfolioUsers as $index => $portfolioUser) {
516 $portfolioUser->save(false); 631 $portfolioUser->save(false);
@@ -562,7 +677,13 @@ @@ -562,7 +677,13 @@
562 ->all(); 677 ->all();
563 678
564 $post = \Yii::$app->request->post(); 679 $post = \Yii::$app->request->post();
565 - $portfolioUsers = $portfolio->portfolioUsers; 680 + $portfolioUsers = $portfolio->getPortfolioUsers()
  681 + ->where([ 'status' => 2 ])
  682 + ->all();
  683 + $portfolioUsersConfirmed = $portfolio->getPortfolioUsers()
  684 + ->where([ 'status' => 1 ])
  685 + ->indexBy('user_id')
  686 + ->all();
566 687
567 if(!empty( $post )) { 688 if(!empty( $post )) {
568 $portfolio->load($post); 689 $portfolio->load($post);
@@ -573,18 +694,33 @@ @@ -573,18 +694,33 @@
573 foreach($portfolio->specializationInput as $one_specialization) { 694 foreach($portfolio->specializationInput as $one_specialization) {
574 $portfolio->link('specializations', Specialization::findOne($one_specialization)); 695 $portfolio->link('specializations', Specialization::findOne($one_specialization));
575 } 696 }
576 - $portfolio->unlinkAll('portfolioUsers', true); 697 + PortfolioUser::deleteAll([
  698 + 'portfolio_id' => $portfolio->portfolio_id,
  699 + 'status' => 2,
  700 + ]);
577 $success = true; 701 $success = true;
578 if(!empty( $post[ 'PortfolioUser' ] )) { 702 if(!empty( $post[ 'PortfolioUser' ] )) {
579 $portfolioUsers = [ ]; 703 $portfolioUsers = [ ];
580 foreach($post[ 'PortfolioUser' ] as $index => $item) { 704 foreach($post[ 'PortfolioUser' ] as $index => $item) {
581 $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); 705 $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]);
582 } 706 }
583 - $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers)); 707 + $success = PortfolioUser::loadMultiple($portfolioUsers, $post);
  708 + foreach($portfolioUsers as $index => $portfolioUser) {
  709 + if($portfolioUser->status == 1) {
  710 + $portfolioUsersConfirmed[ $portfolioUser->user_id ]->position = $portfolioUser->position;
  711 + $portfolioUsersConfirmed[ $portfolioUser->user_id ]->time = $portfolioUser->time;
  712 + unset( $portfolioUsers[ $index ] );
  713 + }
  714 + }
  715 + $success = ( $success && PortfolioUser::validateMultiple($portfolioUsers) && PortfolioUser::validateMultiple($portfolioUsersConfirmed) );
584 if($success) { 716 if($success) {
585 foreach($portfolioUsers as $index => $portfolioUser) { 717 foreach($portfolioUsers as $index => $portfolioUser) {
  718 + $portfolioUser->status = 2;
586 $portfolioUser->save(false); 719 $portfolioUser->save(false);
587 } 720 }
  721 + foreach($portfolioUsersConfirmed as $index => $portfolioUserConfirmed) {
  722 + $portfolioUserConfirmed->save(false);
  723 + }
588 } 724 }
589 } 725 }
590 if($success) { 726 if($success) {
@@ -594,10 +730,11 @@ @@ -594,10 +730,11 @@
594 } 730 }
595 731
596 return $this->render('_portfolio_form', [ 732 return $this->render('_portfolio_form', [
597 - 'portfolio' => $portfolio,  
598 - 'specializations' => $specializations,  
599 - 'galleries' => $galleries,  
600 - 'portfolioUsers' => $portfolioUsers, 733 + 'portfolio' => $portfolio,
  734 + 'specializations' => $specializations,
  735 + 'galleries' => $galleries,
  736 + 'portfolioUsers' => $portfolioUsers,
  737 + 'portfolioUsersConfirmed' => $portfolioUsersConfirmed,
601 ]); 738 ]);
602 } 739 }
603 740
frontend/controllers/AjaxController.php
1 <?php 1 <?php
2 namespace frontend\controllers; 2 namespace frontend\controllers;
3 3
  4 + use common\models\Portfolio;
  5 + use common\models\PortfolioUser;
4 use common\models\User; 6 use common\models\User;
5 use common\models\UserSearch; 7 use common\models\UserSearch;
6 use yii\db\ActiveRecord; 8 use yii\db\ActiveRecord;
@@ -26,7 +28,11 @@ @@ -26,7 +28,11 @@
26 $ids = json_decode(\Yii::$app->request->get('ids')); 28 $ids = json_decode(\Yii::$app->request->get('ids'));
27 $model = new UserSearch(); 29 $model = new UserSearch();
28 $dataProvider = $model->search(\Yii::$app->request->queryParams); 30 $dataProvider = $model->search(\Yii::$app->request->queryParams);
29 - $dataProvider->query->andFilterWhere(['not in', 'id', $ids]); 31 + $dataProvider->query->andFilterWhere([
  32 + 'not in',
  33 + 'id',
  34 + $ids,
  35 + ]);
30 $dataProvider->query->andWhere([ 36 $dataProvider->query->andWhere([
31 'user_info.is_freelancer' => 1, 37 'user_info.is_freelancer' => 1,
32 'type' => 1, 38 'type' => 1,
@@ -90,4 +96,53 @@ @@ -90,4 +96,53 @@
90 ]; 96 ];
91 } 97 }
92 98
  99 + public function actionPortfolioUserRemove()
  100 + {
  101 + $request = \Yii::$app->request;
  102 + $response = \Yii::$app->response;
  103 + $response->format = $response::FORMAT_JSON;
  104 + $post = $request->post();
  105 + if(empty( $post[ 'user_id' ] ) || empty( $post[ 'portfolio_id' ] )) {
  106 + return [ 'error' => 'user_id и portfolio_id должны быть заполнены.' ];
  107 + }
  108 + $user_id = $post[ 'user_id' ];
  109 + $portfolio_id = $post[ 'portfolio_id' ];
  110 + $portfolio = Portfolio::find()
  111 + ->where([
  112 + 'portfolio_id' => $portfolio_id,
  113 + 'user_id' => \Yii::$app->user->id,
  114 + ])
  115 + ->one();
  116 + if(empty( $portfolio )) {
  117 + return [ 'error' => 'Запись не найдена' ];
  118 + }
  119 + $user = User::find()
  120 + ->where([ 'id' => $user_id ])
  121 + ->one();
  122 + if(empty( $user )) {
  123 + return [ 'error' => 'Пользователь не найден' ];
  124 + }
  125 + $portfolio_user = PortfolioUser::find()
  126 + ->where([
  127 + 'portfolio_id' => $portfolio->portfolio_id,
  128 + 'user_id' => $user->id,
  129 + 'status' => 1,
  130 + ])
  131 + ->one();
  132 + if(empty( $portfolio_user )) {
  133 + return [ 'error' => 'Пользователь не относится к данной записи' ];
  134 + }
  135 + if($portfolio_user->delete()) {
  136 + return [
  137 + 'result' => [
  138 + 'message' => 'Пользователь удален',
  139 + 'user_id' => $user->id,
  140 + 'portfolio_id' => $portfolio->portfolio_id,
  141 + ],
  142 + ];
  143 + } else {
  144 + return [ 'error' => 'Ошибка удаления' ];
  145 + }
  146 + }
  147 +
93 } 148 }
frontend/controllers/SearchController.php
@@ -63,6 +63,7 @@ use common\models\Social; @@ -63,6 +63,7 @@ use common\models\Social;
63 { 63 {
64 $model = new TenderSearch(); 64 $model = new TenderSearch();
65 $dataProvider = $model->search(Yii::$app->request->queryParams); 65 $dataProvider = $model->search(Yii::$app->request->queryParams);
  66 + $dataProvider->query->andWhere(['hidden' => 0]);
66 $dataProvider->setPagination([ 67 $dataProvider->setPagination([
67 'pageSize' => 10, 68 'pageSize' => 10,
68 ]); 69 ]);
frontend/models/SMOClosed.php 0 → 100644
  1 +<?php
  2 + namespace frontend\models;
  3 +
  4 + use yii\base\Exception;
  5 + use yii\base\InvalidParamException;
  6 + use yii\base\Model;
  7 +
  8 + class SMOClosed extends Model
  9 + {
  10 +
  11 + public $n;
  12 +
  13 + public $N;
  14 +
  15 + public $p;
  16 +
  17 + public $K;
  18 +
  19 + public $r;
  20 +
  21 + public $mu;
  22 +
  23 + public $e;
  24 +
  25 + public $b;
  26 +
  27 + public $k;
  28 +
  29 + public $probs;
  30 +
  31 + public $SMO;
  32 +
  33 + public $C;
  34 +
  35 + public $L;
  36 +
  37 + public $R;
  38 +
  39 + public $M;
  40 +
  41 + public $La;
  42 +
  43 + public $T;
  44 +
  45 + public $Q;
  46 +
  47 + function __construct(array $config)
  48 + {
  49 + parent::__construct($config);
  50 + if(!intval($this->n)) {
  51 + throw new InvalidParamException('Кількість СМО має бути цілим невід\'ємним числом');
  52 + } else {
  53 + $this->k[ 0 ] = 0;
  54 + for($i = 1; $i <= $this->n; $i++) {
  55 + for($j = 1; $j <= $this->n; $j++) {
  56 + $this->p[ $i ][ $j ] = 0;
  57 + $this->r[ $i ] = 1;
  58 + $this->mu[ $i ] = 0;
  59 + }
  60 + }
  61 + }
  62 + }
  63 +
  64 + public function attributeLabels()
  65 + {
  66 + return [
  67 + 'n' => 'Кількість систем масового обслуговування (n)',
  68 + 'N' => 'Кількість вимог в мережі масового обслуговування (N)',
  69 + 'p' => 'Матриця ймовірностей (p<sub>i,j</sub>)',
  70 + 'K' => 'Показники системи масового обслуговування (K)',
  71 + 'r' => 'Кількість каналів обслуговування (r)',
  72 + 'mu' => 'Інтенсивність обслуговування каналом (1/&mu;)',
  73 + 'e' => 'Коефіцієнт передачі (e)',
  74 + 'b' => 'Початкова СМО (e = 1)',
  75 + 'k' => 'Масив вимог',
  76 + 'probs' => 'Допоміжні функції p<sub>i</sub>(k)',
  77 + 'SMO' => 'Ймовірність перебування j вимоги в i-тій СМО P<sub>СМО<sub>i</sub></sub>(j)',
  78 + 'C' => 'Нормуючий множник (C(N))',
  79 + 'L' => 'Середня кількість вимог у черзі СМО<sub>i</sub> (L<sub>i</sub>)',
  80 + 'R' => 'Середня кількість зайнятих пристроїв у СМО<sub>i</sub> (R<sub>i</sub>)',
  81 + 'M' => 'Середня кількість вимог у СМО<sub>i</sub> (M<sub>i</sub>)',
  82 + 'La' => 'Інтенсивність вихідного потоку вимог у СМО<sub>i</sub> (&lambda;<sub>i</sub>)',
  83 + 'T' => 'Середній час перебування вимоги у СМО<sub>i</sub> (T<sub>i</sub>)',
  84 + 'Q' => 'Середній час очікування у черзі СМО<sub>i</sub> (Q<sub>i</sub>)',
  85 + ];
  86 + }
  87 +
  88 + public function rules()
  89 + {
  90 + return [
  91 + [
  92 + [ 'b' ],
  93 + 'required',
  94 + ],
  95 + [
  96 + [
  97 + 'N',
  98 + ],
  99 + 'integer',
  100 + 'min' => 1,
  101 + ],
  102 + [
  103 + [ 'n' ],
  104 + 'integer',
  105 + 'min' => 2,
  106 + 'max' => 3,
  107 + 'message' => 'На даний момент допустимі значення кількості СМО лише 2 або 3',
  108 + ],
  109 + [
  110 + [
  111 + 'p',
  112 + 'mu',
  113 + ],
  114 + 'safe',
  115 + ],
  116 + [
  117 + [ 'r' ],
  118 + 'each',
  119 + 'rule' => [
  120 + 'integer',
  121 + 'min' => 1,
  122 + ],
  123 + ],
  124 + [
  125 + [ 'mu' ],
  126 + 'each',
  127 + 'rule' => [
  128 + 'number',
  129 + 'min' => 0,
  130 + ],
  131 + ],
  132 + [
  133 + [ 'b' ],
  134 + 'integer',
  135 + 'min' => 1,
  136 + ],
  137 + [
  138 + [ 'b' ],
  139 + 'compare',
  140 + 'compareAttribute' => 'n',
  141 + 'operator' => '<=',
  142 + ],
  143 + [
  144 + [ 'b' ],
  145 + 'default',
  146 + 'value' => 1,
  147 + ],
  148 + ];
  149 + }
  150 +
  151 + public function buildk()
  152 + {
  153 + if(!empty($this->N)) {
  154 + for($i = 1; $i <= $this->N; $i++) {
  155 + $this->k[$i] = $i;
  156 + }
  157 + }
  158 + }
  159 +
  160 + public function buildE($antiloop = true)
  161 + {
  162 + $this->e[ $this->b ] = 1;
  163 + for($k = 1; $k <= $this->n; $k++) {
  164 + if($k == $this->b) {
  165 + continue;
  166 + } else {
  167 + $this->e[ $k ] = '';
  168 + }
  169 + }
  170 + foreach($this->p as $i => $vals) {
  171 + foreach($vals as $j => $val) {
  172 + if($j == $this->b) {
  173 + continue;
  174 + }
  175 + if($val != 0) {
  176 + $this->e[ $j ] .= '{' . $i . '};';
  177 + }
  178 + }
  179 + }
  180 + do {
  181 + $iteration = 0;
  182 + $found = 0;
  183 + foreach($this->e as $i => $val) {
  184 + if(!preg_match('/\{\d\}/', $val)) {
  185 + foreach($this->e as $j => $value) {
  186 + if(preg_match('/\{' . $i . '\}/', $this->e[ $j ])) {
  187 + $this->e[ $j ] = preg_replace('/\{' . $i . '\}/', ( $this->p[ $i ][ $j ] * $val ), $this->e[ $j ]);
  188 + $found = 1;
  189 + }
  190 + }
  191 + }
  192 + }
  193 + if($antiloop) {
  194 + $iteration++;
  195 + }
  196 + } while($found && $iteration < 100);
  197 + foreach($this->e as $i => $val) {
  198 + if(strpos($val, ';') !== false) {
  199 + $this->e[ $i ] = array_sum(explode(';', $val));
  200 + }
  201 + }
  202 + }
  203 +
  204 + public function buildProbs()
  205 + {
  206 + for($q = 1; $q <= $this->n; $q++) {
  207 + foreach($this->k as $k) {
  208 + $prob = pow($this->e[ $q ] * $this->mu[ $q ], $k);
  209 + if($k <= $this->r[ $q ]) {
  210 + $prob = $prob * 1 / $this->factorial($k);
  211 + } else {
  212 + $prob = $prob * 1 / $this->factorial($this->r[ $q ]) * pow($this->r[ $q ], ( $k - $this->r[ $q ] ));
  213 + }
  214 + $this->probs[ $q ][ $k ] = $prob;
  215 + unset( $prob );
  216 + }
  217 + }
  218 + }
  219 +
  220 + public function factorial($x)
  221 + {
  222 + $x = intval($x);
  223 + if(!is_int($x) || $x < 0) {
  224 + throw new Exception('Factorial must be greater than 0');
  225 + }
  226 + $res = 1;
  227 + for($i = 1; $i <= $x; $i++) {
  228 + $res *= $i;
  229 + }
  230 + return $res;
  231 + }
  232 +
  233 + public function buildC()
  234 + {
  235 + $result = 0;
  236 + if($this->n == 2) {
  237 + for($a = 0; $a <= $this->N; $a++) {
  238 + $result += $this->probs[1][$a] * $this->probs[2][$this->N - $a];
  239 + }
  240 + } elseif($this->n == 3) {
  241 + for($a = 0; $a <= $this->N; $a++) {
  242 + $sum = 0;
  243 + for($b = 0; $b <= ( $this->N - $a ); $b++) {
  244 + $sum += $this->findSum($b, $a);
  245 + }
  246 + $result += $sum * $this->probs[ 1 ][ $a ];
  247 + unset( $sum );
  248 + }
  249 + }
  250 + $this->C = pow($result, ( -1 ));
  251 + }
  252 +
  253 + public function findSum($b, $a)
  254 + {
  255 + return $this->probs[ 2 ][ $b ] * $this->probs[ 3 ][ $this->N - $a - $b ];
  256 + }
  257 +
  258 + public function buildSMO()
  259 + {
  260 + for($q = 1; $q <= $this->n; $q++) {
  261 + foreach($this->k as $k) {
  262 + $sum = 0;
  263 + if($this->n == 2) {
  264 + if($q == 1) {
  265 + $sum += $this->probs[1][$k]*$this->probs[2][$this->N - $k];
  266 + } elseif($q == 2) {
  267 + $sum += $this->probs[1][$this->N - $k]*$this->probs[2][$k];
  268 + }
  269 + } elseif($this->n == 3) {
  270 + for($a = 0; $a <= ($this->N - $k); $a++) {
  271 + if($q == 1) {
  272 + $sum += $this->probs[1][$k]*$this->probs[2][$a]*$this->probs[3][($this->N - $k - $a)];
  273 + } elseif($q == 2) {
  274 + $sum += $this->probs[1][$a]*$this->probs[2][$k]*$this->probs[3][($this->N - $k - $a)];
  275 + } elseif($q ===3) {
  276 + $sum += $this->probs[1][$a]*$this->probs[2][($this->N - $k - $a)]*$this->probs[3][$k];
  277 + }
  278 + }
  279 + }
  280 + $this->SMO[$q][$k] = $sum*$this->C;
  281 + unset($sum);
  282 + }
  283 + }
  284 + }
  285 +
  286 + public function testSMO()
  287 + {
  288 + $message = '';
  289 + foreach($this->SMO as $K => $vals) {
  290 + $message .= 'SUM of SMO'.$K.': ';
  291 + $sum = 0;
  292 + foreach($vals as $val) {
  293 + $sum += $val;
  294 + }
  295 + $message .= $sum.'; <br>';
  296 + unset($sum);
  297 + }
  298 + return $message;
  299 + }
  300 +
  301 + public function buildL()
  302 + {
  303 + for($i = 1; $i <= $this->n; $i++) {
  304 + $sum = 0;
  305 + for($j = ($this->r[$i] + 1); $j <= $this->N; $j++) { // Maybe error
  306 + $sum += ($j - $this->r[$i]) * $this->SMO[$i][$j];
  307 + }
  308 + $this->L[$i] = $sum;
  309 + unset($sum);
  310 + }
  311 + }
  312 +
  313 + public function buildR()
  314 + {
  315 + for($i = 1; $i <= $this->n; $i++) {
  316 + $sum = 0;
  317 + for($j = 0; $j <= ($this->r[$i] - 1); $j++) {
  318 + $sum += ($this->r[$i] - $j) * $this->SMO[$i][$j];
  319 + }
  320 + $sum = $this->r[$i] - $sum;
  321 + $this->R[$i] = $sum;
  322 + unset($sum);
  323 + }
  324 + }
  325 +
  326 + public function buildM()
  327 + {
  328 + for($i = 1; $i <= $this->n; $i++) {
  329 + $this->M[$i] = $this->L[$i] + $this->R[$i];
  330 + }
  331 + }
  332 +
  333 + public function buildLa()
  334 + {
  335 + for($i = 1; $i <= $this->n; $i++) {
  336 + $this->La[$i] = $this->R[$i] * pow($this->mu[$i], (-1));
  337 + }
  338 + }
  339 +
  340 + public function buildT()
  341 + {
  342 + for($i = 1; $i <= $this->n; $i++) {
  343 + $this->T[$i] = $this->M[$i] / $this->La[$i];
  344 + }
  345 + }
  346 +
  347 + public function buildQ()
  348 + {
  349 + for($i = 1; $i <= $this->n; $i++) {
  350 + $this->Q[$i] = $this->L[$i] / $this->La[$i];
  351 + }
  352 + }
  353 + }
0 \ No newline at end of file 354 \ No newline at end of file
frontend/views/accounts/_portfolio_form.php
1 <?php 1 <?php
2 /** 2 /**
3 - * @var View $this  
4 - * @var Portfolio $portfolio  
5 - * @var integer[] $specializations  
6 - * @var string[] $galleries 3 + * @var View $this
  4 + * @var Portfolio $portfolio
  5 + * @var integer[] $specializations
  6 + * @var string[] $galleries
  7 + * @var PortfolioUser[] $portfolioUsers
  8 + * @var PortfolioUser[] $portfolioUsersConfirmed
7 */ 9 */
8 use common\components\Request; 10 use common\components\Request;
9 use common\models\Option; 11 use common\models\Option;
10 use common\models\Portfolio; 12 use common\models\Portfolio;
  13 + use common\models\PortfolioUser;
11 use common\models\Specialization; 14 use common\models\Specialization;
12 use common\modules\file\widgets\ImageUploader; 15 use common\modules\file\widgets\ImageUploader;
13 use common\modules\file\widgets\ImageUploaderInput; 16 use common\modules\file\widgets\ImageUploaderInput;
@@ -185,21 +188,42 @@ @@ -185,21 +188,42 @@
185 <div class="clearfix"></div> 188 <div class="clearfix"></div>
186 189
187 <?php 190 <?php
188 - /* == Project add user block == */ 191 + /* == Project add user block == */
189 ?> 192 ?>
190 <div class="add_project_user_wrapper" id="<?= $form->id ?>_project_user"> 193 <div class="add_project_user_wrapper" id="<?= $form->id ?>_project_user">
191 <p>Добавить пользователя</p> 194 <p>Добавить пользователя</p>
192 <p><?= Html::a('Добавить', false, [ 'class' => 'add_project_user_link' ]) ?></p> 195 <p><?= Html::a('Добавить', false, [ 'class' => 'add_project_user_link' ]) ?></p>
  196 + <p>Отправлено предложение:</p>
193 <div class="add_project_user_list"> 197 <div class="add_project_user_list">
194 <?php 198 <?php
195 foreach($portfolioUsers as $portfolioUser) { 199 foreach($portfolioUsers as $portfolioUser) {
196 - echo $this->render('@frontend/views/ajax/project_user', ['model' => $portfolioUser, 'user' => $portfolioUser->user]);  
197 - } 200 + echo $this->render('@frontend/views/ajax/project_user', [
  201 + 'model' => $portfolioUser,
  202 + 'user' => $portfolioUser->user,
  203 + ]);
  204 + }
198 ?> 205 ?>
199 </div> 206 </div>
  207 + <?php
  208 + if(!empty( $portfolioUsersConfirmed )) {
  209 + ?>
  210 + <p class="added_project_user_header">Подтвержденные:</p>
  211 + <div class="added_project_user_list">
  212 + <?php
  213 + foreach($portfolioUsersConfirmed as $portfolioUserConfirmed) {
  214 + echo $this->render('@frontend/views/ajax/project_user', [
  215 + 'model' => $portfolioUserConfirmed,
  216 + 'user' => $portfolioUserConfirmed->user,
  217 + ]);
  218 + }
  219 + ?>
  220 + </div>
  221 + <?php
  222 + }
  223 + ?>
200 </div> 224 </div>
201 <?php 225 <?php
202 - /* == End of project add user block == */ 226 + /* == End of project add user block == */
203 ?> 227 ?>
204 228
205 </div> 229 </div>
frontend/views/accounts/participant-edit.php 0 → 100644
  1 +<?php
  2 + use common\models\PortfolioUser;
  3 + use common\modules\file\widgets\ImageUploader;
  4 + use yii\helpers\Html;
  5 + use yii\web\View;
  6 + use yii\widgets\ActiveForm;
  7 +
  8 + /**
  9 + * @var View $this
  10 + * @var PortfolioUser $model
  11 + */
  12 + $this->title = 'Редактирование участия в проекте';
  13 + $this->params[ 'breadcrumbs' ][] = $this->title;
  14 +?>
  15 +<div class="login-left-column-title"><?= $this->title ?></div>
  16 +<div>
  17 + <p>Редактировать информацию о себе:</p>
  18 + <?php
  19 + if($model->status != 1) {
  20 + ?>
  21 + <div class="alert alert-info" role="alert">
  22 + <strong>Внимание:</strong> данным действием Вы подтверждаете свое участие в проекте.
  23 + </div>
  24 + <?php
  25 + }
  26 + ?>
  27 + <div>
  28 + <?php
  29 + $form = ActiveForm::begin();
  30 + echo $form->field($model, 'position')
  31 + ->textInput();
  32 + echo $form->field($model, 'time')
  33 + ->input('number');
  34 + ?>
  35 + </div>
  36 + <p>Добавить фотографию в личный альбом данного проекта:</p>
  37 + <?php
  38 + if($model->status == 1 && !empty($model->gallery)) {
  39 + echo $form->field($model->portfolioGallery, 'caption')->textInput();
  40 + echo Html::tag('div', ImageUploader::widget([
  41 + 'model' => $model->gallery,
  42 + 'field' => 'photo',
  43 + 'size' => [
  44 + [
  45 + 'width' => 152,
  46 + 'height' => 108,
  47 + ],
  48 + ],
  49 + 'multi' => true,
  50 + 'gallery' => $model->gallery->photo,
  51 + 'name' => 'Загрузить фото галереи',
  52 + ]), [ 'class' => 'admin-gallery-photos-load-wr style' ]);
  53 + } else {
  54 + echo Html::tag('p', 'Для добавления фотографий Вы должны подтвердить свое участие');
  55 + }
  56 + ?>
  57 + <p class="text-right">
  58 + <?php
  59 + echo Html::a('Вернуться', [ 'accounts/participant' ]);
  60 + echo Html::submitButton('Обновить');
  61 + $form->end();
  62 + ?>
  63 + </p>
  64 +</div>
0 \ No newline at end of file 65 \ No newline at end of file
frontend/views/accounts/participant.php 0 → 100644
  1 +<?php
  2 + /**
  3 + * @var View $this
  4 + * @var PortfolioUserSearch $searchModel
  5 + * @var ActiveDataProvider $dataProvider
  6 + */
  7 + use common\models\PortfolioUser;
  8 + use common\models\PortfolioUserSearch;
  9 + use yii\data\ActiveDataProvider;
  10 + use yii\grid\ActionColumn;
  11 + use yii\grid\DataColumn;
  12 + use yii\grid\GridView;
  13 + use yii\helpers\Html;
  14 + use yii\web\View;
  15 +
  16 + $this->title = 'Портфолио участник';
  17 + $this->params[ 'breadcrumbs' ][] = $this->title;
  18 +?>
  19 +<div class="login-left-column-title"><?= $this->title ?></div>
  20 +<div class="admin-table-portfolio">
  21 + <?= GridView::widget([
  22 + 'options' => [ 'class' => 'style admin-all-pages-wr' ],
  23 + 'dataProvider' => $dataProvider,
  24 + 'filterModel' => $searchModel,
  25 + 'columns' => [
  26 + [
  27 + 'attribute' => 'project',
  28 + 'content' => function($model, $key, $index, $column) {
  29 + /**
  30 + * @var PortfolioUser $model
  31 + */
  32 + $type = $model->portfolio->user->type;
  33 + $type_string = ( $type == 2 ) ? 'company' : 'performer';
  34 + return Html::a($model->portfolio->name, [
  35 + $type_string . '/portfolio-view',
  36 + $type_string . '_id' => $model->portfolio->user_id,
  37 + 'portfolio_id' => $model->portfolio->portfolio_id,
  38 + ], [
  39 + 'target' => '_blank',
  40 + ]);
  41 + },
  42 + ],
  43 + [
  44 + 'attribute' => 'position',
  45 + 'value' => function($model, $key, $index, $column) {
  46 + /**
  47 + * @var PortfolioUser $model
  48 + * @var DataColumn $column
  49 + * @var int $key
  50 + * @var int $index
  51 + */
  52 + if(empty( $model[ $column->attribute ] )) {
  53 + return NULL;
  54 + } else {
  55 + return $model[ $column->attribute ];
  56 + }
  57 + },
  58 + ],
  59 + [
  60 + 'attribute' => 'time',
  61 + 'filter' => Html::tag('div', Html::activeInput('text', $searchModel, 'time_from', [ 'class' => 'form-control' ]), [ 'style' => 'width:70px;display:inline-block' ]) . Html::tag('div', Html::tag('i', '', [
  62 + 'class' => 'glyphicon glyphicon-resize-horizontal',
  63 + 'style' => 'left:3px',
  64 + ]), [ 'style' => 'width:20px;display:inline-block;' ]) . Html::tag('div', Html::activeInput('text', $searchModel, 'time_to', [ 'class' => 'form-control' ]), [ 'style' => 'width:70px;display:inline-block' ]) . ( ( $searchModel->hasErrors('time_from') ) ? Html::error($searchModel, 'time_from', [ 'class' => 'help-block' ]) : '' ) . ( ( $searchModel->hasErrors('time_to') ) ? Html::error($searchModel, 'time_to', [ 'class' => 'help-block' ]) : '' ),
  65 + 'filterOptions' => [
  66 + 'class' => ( $searchModel->hasErrors('time_from') || $searchModel->hasErrors('time_to') ) ? 'has-error' : '',
  67 + 'style' => 'width: 200px',
  68 + ],
  69 + ],
  70 + [
  71 + 'attribute' => 'status',
  72 + 'filter' => [
  73 + 1 => 'Подтверждено',
  74 + 2 => 'Ожидание',
  75 + ],
  76 + 'value' => function($model) {
  77 + if($model->status == 1) {
  78 + return 'Подтвержден';
  79 + } elseif($model->status == 2) {
  80 + return 'В ожидании';
  81 + } else {
  82 + return 'Неизвестный';
  83 + }
  84 + },
  85 + ],
  86 + [
  87 + 'class' => ActionColumn::className(),
  88 + 'buttons' => [
  89 + 'confirm' => function($url, $model, $key) {
  90 + return ( $model->status == 2 ) ? Html::a(Html::img('/images/tick.png', [
  91 + 'width' => '15px',
  92 + 'height' => '15px',
  93 + ]), [
  94 + 'accounts/participant-confirm',
  95 + 'id' => $model->portfolio_user_id,
  96 + ], [
  97 + 'title' => 'Подтвердить',
  98 + 'aria-label' => 'Подтвердить',
  99 + 'data-confirm' => 'Вы уверены, что хотите подтвердить участие в данном проекте?',
  100 + 'data-method' => 'post',
  101 + 'data-pjax' => 0,
  102 + ]) : '';
  103 + },
  104 + 'edit' => function($url, $model, $key) {
  105 + return Html::a(Html::img('/images/ico_pencil.png'), [
  106 + 'accounts/participant-edit',
  107 + 'id' => $model->portfolio_user_id,
  108 + ], [
  109 + 'title' => 'Редактировать',
  110 + 'aria-label' => 'Редактировать',
  111 + 'data-pjax' => 0,
  112 + ]);
  113 + },
  114 + 'deny' => function($url, $model, $key) {
  115 + return Html::a(Html::img('/images/delete-ico.png'), [
  116 + 'accounts/participant-delete',
  117 + 'id' => $model->portfolio_user_id,
  118 + ], [
  119 + 'title' => 'Удалить',
  120 + 'aria-label' => 'Удалить',
  121 + 'data-confirm' => 'Вы уверены, что хотите отказаться от участия в данном проекте?',
  122 + 'data-method' => 'post',
  123 + 'data-pjax' => 0,
  124 + ]);
  125 + },
  126 + ],
  127 + 'template' => '{confirm}{edit}{deny}',
  128 + ],
  129 + ],
  130 + ]); ?>
  131 +</div>
frontend/views/ajax/project_user.php
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 use yii\web\View; 10 use yii\web\View;
11 11
12 ?> 12 ?>
13 -<div class="form-inline project_user_wrapper" data-id="<?=$user->id?>"> 13 +<div class="form-inline project_user_wrapper" data-id="<?=$user->id?>" <?php if($model->status == 1) { echo 'data-portfolio="'.$model->portfolio_id.'"'; } ?>>
14 <div class="error-summary"> 14 <div class="error-summary">
15 <?=Html::errorSummary($model)?> 15 <?=Html::errorSummary($model)?>
16 </div> 16 </div>
@@ -18,6 +18,12 @@ @@ -18,6 +18,12 @@
18 <label class="sr-only">User name</label> 18 <label class="sr-only">User name</label>
19 <p class="form-control-static"><?=Html::a($user->name, ['performer/common', 'performer_id' => $user->id], ['target' => '_blank'])?></p> 19 <p class="form-control-static"><?=Html::a($user->name, ['performer/common', 'performer_id' => $user->id], ['target' => '_blank'])?></p>
20 <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?> 20 <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?>
  21 + <?php
  22 + if($model->status == 1) {
  23 + echo Html::activeHiddenInput($model, "[{$user->id}]status", ['value' => $model->status]);
  24 + }
  25 + ?>
  26 + <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?>
21 </div> 27 </div>
22 <div class="form-group" style="display: inline-block"> 28 <div class="form-group" style="display: inline-block">
23 <?=Html::activeLabel($model, 'position', ['label' => Yii::t('app', 'Должность: ')])?> 29 <?=Html::activeLabel($model, 'position', ['label' => Yii::t('app', 'Должность: ')])?>
frontend/views/layouts/admin.php
@@ -17,7 +17,6 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;); @@ -17,7 +17,6 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
17 <div class="login-right-column"> 17 <div class="login-right-column">
18 <div class="admin-my-page">Моя страница</div> 18 <div class="admin-my-page">Моя страница</div>
19 <?php 19 <?php
20 -  
21 $item = [ 20 $item = [
22 [ 21 [
23 'label' => 'Учетные данные', 22 'label' => 'Учетные данные',
@@ -55,7 +54,12 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;); @@ -55,7 +54,12 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
55 'url' => ['accounts/portfolio'], 54 'url' => ['accounts/portfolio'],
56 'active' => preg_match('/^portfolio.*$/', $this->context->action->id)?true:false, 55 'active' => preg_match('/^portfolio.*$/', $this->context->action->id)?true:false,
57 ], 56 ],
58 - 57 + [
  58 + 'label' => "Портфолио участник <span class='badge'>{$this->params['portfolio_user_count']}</span>",
  59 + 'encode' => false,
  60 + 'url' => ['accounts/participant'],
  61 + 'active' => preg_match('/^participant.*$/', $this->context->action->id)?true:false,
  62 + ],
59 [ 63 [
60 'label' => 'Блог', 64 'label' => 'Блог',
61 'url' => ['accounts/blog'], 65 'url' => ['accounts/blog'],
frontend/web/js/script.js
@@ -1159,10 +1159,7 @@ $(document).ready( @@ -1159,10 +1159,7 @@ $(document).ready(
1159 ); 1159 );
1160 $.fancybox.open( 1160 $.fancybox.open(
1161 {href : '/ajax/project-user'}, { 1161 {href : '/ajax/project-user'}, {
1162 - type : 'ajax',  
1163 - margin: [70, 20, 30, 20],  
1164 - maxWidth : 800,  
1165 - ajax : {dataType : 'html', data : {ids : JSON.stringify(ids)}}, 1162 + type : 'ajax', margin : [70, 20, 30, 20], maxWidth : 800, ajax : {dataType : 'html', data : {ids : JSON.stringify(ids)}},
1166 tpl : {wrap : '<div class="fancybox-wrap" tabIndex="-1" data-model="common\\models\\PortfolioUser" data-component="' + component + '"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'} 1163 tpl : {wrap : '<div class="fancybox-wrap" tabIndex="-1" data-model="common\\models\\PortfolioUser" data-component="' + component + '"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'}
1167 } 1164 }
1168 ); 1165 );
@@ -1197,11 +1194,41 @@ $(document).ready( @@ -1197,11 +1194,41 @@ $(document).ready(
1197 } 1194 }
1198 ); 1195 );
1199 $(document).on( 1196 $(document).on(
1200 - 'click', '.project_user_remove', function() 1197 + 'click', '.add_project_user_list .project_user_remove', function()
1201 { 1198 {
1202 $(this).parents('.project_user_wrapper').remove(); 1199 $(this).parents('.project_user_wrapper').remove();
1203 } 1200 }
1204 ); 1201 );
  1202 + $(document).on(
  1203 + 'click', '.added_project_user_list .project_user_remove', function()
  1204 + {
  1205 + var wrapper = $(this).parents('.project_user_wrapper');
  1206 + var user_id = $(wrapper).data('id');
  1207 + var portfolio_id = $(wrapper).data('portfolio');
  1208 + $.post(
  1209 + '/ajax/portfolio-user-remove', {user_id : user_id, portfolio_id : portfolio_id}, function(data)
  1210 + {
  1211 + if(data.error) {
  1212 + alert(data.error);
  1213 + } else {
  1214 + var element = $('.added_project_user_list .project_user_wrapper[data-id='+data.result.user_id+'][data-portfolio='+data.result.portfolio_id+']');
  1215 + var widget_wrapper = $(element).parents('.add_project_user_wrapper');
  1216 + $(element).remove();
  1217 + var widget_id = $(widget_wrapper).attr('id');
  1218 + checkAddedHeader(widget_id);
  1219 + }
  1220 + }
  1221 + );
  1222 + }
  1223 + );
1205 1224
  1225 + function checkAddedHeader(id) {
  1226 + var count = $('#'+id).find('.added_project_user_list').find('.project_user_wrapper').length;
  1227 + if(count <= 0) {
  1228 + $('#'+id).find('.added_project_user_header').hide();
  1229 + } else {
  1230 + $('#'+id).find('.added_project_user_header').show();
  1231 + }
  1232 + }
1206 } 1233 }
1207 ); 1234 );
1208 \ No newline at end of file 1235 \ No newline at end of file
tests/acceptance/FirstTestCept.php
@@ -18,5 +18,5 @@ $I-&gt;click(&#39;Добавить&#39;); @@ -18,5 +18,5 @@ $I-&gt;click(&#39;Добавить&#39;);
18 $I->wait(1); 18 $I->wait(1);
19 $I->attachFile('input[type="file"]', 'ViewIllustrator_2001.jpg'); 19 $I->attachFile('input[type="file"]', 'ViewIllustrator_2001.jpg');
20 $I->fillField('#portfolio-name',''); 20 $I->fillField('#portfolio-name','');
21 -$I->click('Добавить');  
22 -$I->see('Необходимо заполнить «Название».','div'); 21 +$I->click('Добавить', '.input-blocks-wrapper');
  22 +$I->see('Необходимо заполнить «name».','div');