From d09b3ad72fe9f43fad23d9b888c5cb84bff9bf33 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:40:15 +0300 Subject: [PATCH 01/11] introduce player metadata table for affiliation and identificationFile --- ...06_091812_create_player_metadata_table.php | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 backend/migrations/m240506_091812_create_player_metadata_table.php diff --git a/backend/migrations/m240506_091812_create_player_metadata_table.php b/backend/migrations/m240506_091812_create_player_metadata_table.php new file mode 100644 index 000000000..c427fa511 --- /dev/null +++ b/backend/migrations/m240506_091812_create_player_metadata_table.php @@ -0,0 +1,61 @@ +createTable('{{%player_metadata}}', [ + 'player_id' => $this->primaryKey()->unsigned()->notNull(), + 'identificationFile'=>$this->string(64), + 'affiliation'=>$this->string(64), + ]); + + // creates index for column `player_id` + $this->createIndex( + '{{%idx-player_metadata-player_id}}', + '{{%player_metadata}}', + 'player_id' + ); + + // add foreign key for table `{{%player}}` + $this->addForeignKey( + '{{%fk-player_metadata-player_id}}', + '{{%player_metadata}}', + 'player_id', + '{{%player}}', + 'id', + 'CASCADE' + ); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + // drops foreign key for table `{{%player}}` + $this->dropForeignKey( + '{{%fk-player_metadata-player_id}}', + '{{%player_metadata}}' + ); + + // drops index for column `player_id` + $this->dropIndex( + '{{%idx-player_metadata-player_id}}', + '{{%player_metadata}}' + ); + + $this->dropTable('{{%player_metadata}}'); + } +} From 2542d1436de71152902178eac7508d8ca6c35058 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:42:42 +0300 Subject: [PATCH 02/11] drop affiliation from player table --- ...p_affiliation_column_from_player_table.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 backend/migrations/m240506_093953_drop_affiliation_column_from_player_table.php diff --git a/backend/migrations/m240506_093953_drop_affiliation_column_from_player_table.php b/backend/migrations/m240506_093953_drop_affiliation_column_from_player_table.php new file mode 100644 index 000000000..08bdec3dd --- /dev/null +++ b/backend/migrations/m240506_093953_drop_affiliation_column_from_player_table.php @@ -0,0 +1,25 @@ +dropColumn('{{%player}}', 'affiliation'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->addColumn('{{%player}}', 'affiliation', $this->integer()); + } +} From 9eb91b01dd13e3c9dc0ce58206a0f5dff5b38afa Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:43:36 +0300 Subject: [PATCH 03/11] introduce player metadata crud --- .../controllers/PlayerMetadataController.php | 134 ++++++++++++++++++ .../frontend/models/PlayerMetadata.php | 67 +++++++++ .../frontend/models/PlayerMetadataQuery.php | 34 +++++ .../frontend/models/PlayerMetadataSearch.php | 69 +++++++++ .../frontend/views/player-metadata/_form.php | 27 ++++ .../views/player-metadata/_search.php | 34 +++++ .../frontend/views/player-metadata/create.php | 20 +++ .../frontend/views/player-metadata/index.php | 47 ++++++ .../frontend/views/player-metadata/update.php | 23 +++ .../frontend/views/player-metadata/view.php | 38 +++++ backend/views/layouts/main.php | 1 + 11 files changed, 494 insertions(+) create mode 100644 backend/modules/frontend/controllers/PlayerMetadataController.php create mode 100644 backend/modules/frontend/models/PlayerMetadata.php create mode 100644 backend/modules/frontend/models/PlayerMetadataQuery.php create mode 100644 backend/modules/frontend/models/PlayerMetadataSearch.php create mode 100644 backend/modules/frontend/views/player-metadata/_form.php create mode 100644 backend/modules/frontend/views/player-metadata/_search.php create mode 100644 backend/modules/frontend/views/player-metadata/create.php create mode 100644 backend/modules/frontend/views/player-metadata/index.php create mode 100644 backend/modules/frontend/views/player-metadata/update.php create mode 100644 backend/modules/frontend/views/player-metadata/view.php diff --git a/backend/modules/frontend/controllers/PlayerMetadataController.php b/backend/modules/frontend/controllers/PlayerMetadataController.php new file mode 100644 index 000000000..62d1dbb8e --- /dev/null +++ b/backend/modules/frontend/controllers/PlayerMetadataController.php @@ -0,0 +1,134 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ] + ); + } + + /** + * Lists all PlayerMetadata models. + * + * @return string + */ + public function actionIndex() + { + $searchModel = new PlayerMetadataSearch(); + $dataProvider = $searchModel->search($this->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single PlayerMetadata model. + * @param int $player_id Player ID + * @return string + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($player_id) + { + return $this->render('view', [ + 'model' => $this->findModel($player_id), + ]); + } + + /** + * Creates a new PlayerMetadata model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return string|\yii\web\Response + */ + public function actionCreate() + { + $model = new PlayerMetadata(); + + if ($this->request->isPost) { + if ($model->load($this->request->post()) && $model->save()) { + return $this->redirect(['view', 'player_id' => $model->player_id]); + } + } else { + $model->loadDefaultValues(); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing PlayerMetadata model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param int $player_id Player ID + * @return string|\yii\web\Response + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($player_id) + { + $model = $this->findModel($player_id); + + if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) { + return $this->redirect(['view', 'player_id' => $model->player_id]); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing PlayerMetadata model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param int $player_id Player ID + * @return \yii\web\Response + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($player_id) + { + $this->findModel($player_id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the PlayerMetadata model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param int $player_id Player ID + * @return PlayerMetadata the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($player_id) + { + if (($model = PlayerMetadata::findOne(['player_id' => $player_id])) !== null) { + return $model; + } + + throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); + } +} diff --git a/backend/modules/frontend/models/PlayerMetadata.php b/backend/modules/frontend/models/PlayerMetadata.php new file mode 100644 index 000000000..a0bdfe4f2 --- /dev/null +++ b/backend/modules/frontend/models/PlayerMetadata.php @@ -0,0 +1,67 @@ + 64], + [['player_id'], 'exist', 'skipOnError' => true, 'targetClass' => Player::class, 'targetAttribute' => ['player_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'player_id' => Yii::t('app', 'Player ID'), + 'identificationFile' => Yii::t('app', 'Identification File'), + 'affiliation' => Yii::t('app', 'Affiliation'), + ]; + } + + /** + * Gets query for [[Player]]. + * + * @return \yii\db\ActiveQuery|yii\db\ActiveQuery + */ + public function getPlayer() + { + return $this->hasOne(Player::class, ['id' => 'player_id']); + } + + /** + * {@inheritdoc} + * @return PlayerMetadataQuery the active query used by this AR class. + */ + public static function find() + { + return new PlayerMetadataQuery(get_called_class()); + } +} diff --git a/backend/modules/frontend/models/PlayerMetadataQuery.php b/backend/modules/frontend/models/PlayerMetadataQuery.php new file mode 100644 index 000000000..ad880f20b --- /dev/null +++ b/backend/modules/frontend/models/PlayerMetadataQuery.php @@ -0,0 +1,34 @@ +andWhere('[[status]]=1'); + }*/ + + /** + * {@inheritdoc} + * @return PlayerMetadata[]|array + */ + public function all($db = null) + { + return parent::all($db); + } + + /** + * {@inheritdoc} + * @return PlayerMetadata|array|null + */ + public function one($db = null) + { + return parent::one($db); + } +} diff --git a/backend/modules/frontend/models/PlayerMetadataSearch.php b/backend/modules/frontend/models/PlayerMetadataSearch.php new file mode 100644 index 000000000..76929c855 --- /dev/null +++ b/backend/modules/frontend/models/PlayerMetadataSearch.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([ + 'player_id' => $this->player_id, + ]); + + $query->andFilterWhere(['like', 'identificationFile', $this->identificationFile]) + ->andFilterWhere(['like', 'affiliation', $this->affiliation]); + + return $dataProvider; + } +} diff --git a/backend/modules/frontend/views/player-metadata/_form.php b/backend/modules/frontend/views/player-metadata/_form.php new file mode 100644 index 000000000..fbf9edc2b --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/_form.php @@ -0,0 +1,27 @@ + + + diff --git a/backend/modules/frontend/views/player-metadata/_search.php b/backend/modules/frontend/views/player-metadata/_search.php new file mode 100644 index 000000000..440c95afa --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/_search.php @@ -0,0 +1,34 @@ + + + diff --git a/backend/modules/frontend/views/player-metadata/create.php b/backend/modules/frontend/views/player-metadata/create.php new file mode 100644 index 000000000..9886ba2d4 --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/create.php @@ -0,0 +1,20 @@ +title = Yii::t('app', 'Create Player Metadata'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Player Metadatas'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/backend/modules/frontend/views/player-metadata/index.php b/backend/modules/frontend/views/player-metadata/index.php new file mode 100644 index 000000000..22e9a8200 --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/index.php @@ -0,0 +1,47 @@ +title = Yii::t('app', 'Player Metadata'); +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/backend/modules/frontend/views/player-metadata/update.php b/backend/modules/frontend/views/player-metadata/update.php new file mode 100644 index 000000000..8e51fbcc6 --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/update.php @@ -0,0 +1,23 @@ +title = Yii::t('app', 'Update Player Metadata: {name}', [ + 'name' => $model->player_id, +]); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Player Metadatas'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->player_id, 'url' => ['view', 'player_id' => $model->player_id]]; +$this->params['breadcrumbs'][] = Yii::t('app', 'Update'); +?> + diff --git a/backend/modules/frontend/views/player-metadata/view.php b/backend/modules/frontend/views/player-metadata/view.php new file mode 100644 index 000000000..ff1b0ce66 --- /dev/null +++ b/backend/modules/frontend/views/player-metadata/view.php @@ -0,0 +1,38 @@ +title = $model->player_id; +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Player Metadatas'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> + diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php index 6bb3f8cc9..59ee5d8fa 100644 --- a/backend/views/layouts/main.php +++ b/backend/views/layouts/main.php @@ -141,6 +141,7 @@ 'items' => [ ['label' => 'Players', 'url' => ['/frontend/player/index'], 'visible' => !Yii::$app->user->isGuest,], ['label' => 'Profiles', 'url' => ['/frontend/profile/index'], 'visible' => !Yii::$app->user->isGuest,], + ['label' => 'Player Metadata', 'url' => ['/frontend/player-metadata/index'], 'visible' => !Yii::$app->user->isGuest,], ['label' => 'Player Last', 'url' => ['/frontend/player-last/index'], 'visible' => !Yii::$app->user->isGuest,], ['label' => 'Player SSL', 'url' => ['/frontend/player-ssl/index'], 'visible' => !Yii::$app->user->isGuest,], ['label' => 'Player Spins', 'url' => ['/frontend/player-spin/index'], 'visible' => !Yii::$app->user->isGuest,], From 5ef43d1d4f90ef8cad43611e3d2693767a026912 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:44:58 +0300 Subject: [PATCH 04/11] add metadata relation --- backend/modules/frontend/models/PlayerAR.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/backend/modules/frontend/models/PlayerAR.php b/backend/modules/frontend/models/PlayerAR.php index b5018d394..cc16ada2b 100644 --- a/backend/modules/frontend/models/PlayerAR.php +++ b/backend/modules/frontend/models/PlayerAR.php @@ -8,7 +8,6 @@ use app\modules\activity\models\PlayerQuestion; use app\modules\activity\models\PlayerTreasure; use app\modules\activity\models\SpinQueue; -use app\modules\activity\models\SpinHistory; use app\modules\activity\models\Report; use app\modules\activity\models\Stream; use app\modules\gameplay\models\Hint; @@ -102,7 +101,6 @@ public function rules() { return [ [['username', 'type', 'status','email'], 'required'], - [['type','affiliation'], 'string'], [['active', 'status','approval'], 'integer'], [['academic'], 'integer'], [['academic'], 'default','value'=>0], @@ -157,7 +155,7 @@ public function attributeLabels() 'created' => 'Created', 'active' => 'Active', 'academic' => 'Academic', - 'affiliation' => 'Affiliation', + 'metadata.affiliation' => 'Affiliation', 'status'=>'Status', 'ts' => 'Ts', ]; @@ -379,6 +377,14 @@ public function getTeamPlayer() return $this->hasOne(TeamPlayer::class, ['player_id' => 'id']); } + /** + * @return \yii\db\ActiveQuery + */ + public function getMetadata() + { + return $this->hasOne(PlayerMetadata::class, ['player_id' => 'id']); + } + /** * @return \yii\db\ActiveQuery */ From 972d78525350a24e785a2a6158f51af07c42faf1 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:45:23 +0300 Subject: [PATCH 05/11] allow searching by affiliation to the related table --- backend/modules/frontend/models/PlayerSearch.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/modules/frontend/models/PlayerSearch.php b/backend/modules/frontend/models/PlayerSearch.php index 21086467c..321a5fd68 100644 --- a/backend/modules/frontend/models/PlayerSearch.php +++ b/backend/modules/frontend/models/PlayerSearch.php @@ -14,7 +14,7 @@ */ class PlayerSearch extends Player { - public $on_pui, $on_vpn, $vpn_local_address; + public $on_pui, $on_vpn, $vpn_local_address,$affiliation; public function behaviors() { return [ @@ -66,7 +66,7 @@ public function scenarios() */ public function search($params) { - $query=Player::find()->joinWith(['last']); + $query=Player::find()->joinWith(['last','metadata']); // add conditions that should always apply here $dataProvider=new ActiveDataProvider([ @@ -102,7 +102,7 @@ public function search($params) ->andFilterWhere(['like', 'player.created', $this->created]) ->andFilterWhere(['like', 'player.password', $this->password]) ->andFilterWhere(['like', 'player.activkey', $this->activkey]) - ->andFilterWhere(['like', 'player.affiliation', $this->affiliation]) + ->andFilterWhere(['like', 'player_metadata.affiliation', $this->affiliation]) ->andFilterWhere(['like', 'INET_NTOA(player_last.vpn_local_address)', $this->vpn_local_address]); // if(!empty($this->ovpn)) $query->andHaving(['like', 'ovpn', $this->ovpn]); @@ -133,6 +133,10 @@ public function search($params) 'asc' => ['player_last.vpn_local_address' => SORT_ASC], 'desc' => ['player_last.vpn_local_address' => SORT_DESC], ], + 'affiliation' => [ + 'asc' => ['player_metadata.affiliation' => SORT_ASC], + 'desc' => ['player_metadata.affiliation' => SORT_DESC], + ], ] ), From 79136c2684497455dfb4067004c884950fda112e Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:48:55 +0300 Subject: [PATCH 06/11] use the related affiliation field instead --- .../controllers/TeamScoreController.php | 5 ++++- .../modules/frontend/views/player/index.php | 22 +++++++------------ .../modules/frontend/views/player/view.php | 2 +- .../frontend/views/profile/_heading.php | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/backend/modules/activity/controllers/TeamScoreController.php b/backend/modules/activity/controllers/TeamScoreController.php index d2c5b31bb..8720f6d43 100644 --- a/backend/modules/activity/controllers/TeamScoreController.php +++ b/backend/modules/activity/controllers/TeamScoreController.php @@ -153,7 +153,10 @@ public function actionTop15Inclusive() { if($tp->approved==0) continue; - fputcsv($csv, [$rank,$ts->team->name,$tp->player->fullname, $tp->player->username,$tp->player->email,Yii::$app->sys->{"academic_".$tp->player->academic.'short'},$tp->player->affiliation]); + if($tp->player->metadata) + fputcsv($csv, [$rank,$ts->team->name,$tp->player->fullname, $tp->player->username,$tp->player->email,Yii::$app->sys->{"academic_".$tp->player->academic.'short'},$tp->player->metadata->affiliation]); + else + fputcsv($csv, [$rank,$ts->team->name,$tp->player->fullname, $tp->player->username,$tp->player->email,Yii::$app->sys->{"academic_".$tp->player->academic.'short'},'']); } $rank++; } diff --git a/backend/modules/frontend/views/player/index.php b/backend/modules/frontend/views/player/index.php index 6097bc0a9..d0b2d647d 100644 --- a/backend/modules/frontend/views/player/index.php +++ b/backend/modules/frontend/views/player/index.php @@ -68,25 +68,19 @@ ['class' => 'app\components\columns\ProfileColumn', 'idkey' => 'profile.id', 'attribute' => 'username', 'field' => 'username'], [ 'attribute'=>'affiliation', + 'label'=>'Affiliation', 'visible' => Yii::$app->sys->player_require_approval, 'format'=>'html', 'value'=>function($model){ - if($model->active==1) return Html::encode($model->affiliation); - $formats=['.pdf','.png','.jpg','.jpeg','.docx']; - $format=null; - $baseDir=\Yii::getAlias('@app/web/identificationFiles/'); - foreach ($formats as $f) + if(Yii::$app->sys->player_require_identification===true && $model->metadata) { - if(file_exists($baseDir.$model->profile->id.$f)) - { - $format=$f; - break; - } + $filePath=\Yii::getAlias('@app/web/identificationFiles/'.$model->metadata->identificationFile); + if(file_exists($filePath)) + return Html::a($model->metadata->affiliation,'/identificationFiles/'.$model->metadata->identificationFile,['width' => '50px']); } - if($format!==null) - return Html::a($model->affiliation,'/identificationFiles/'.$model->profile->id.$format,['width' => '50px']); - else - return Html::encode($model->affiliation); + if($model->metadata) + return Html::encode($model->metadata->affiliation); + }, ], [ diff --git a/backend/modules/frontend/views/player/view.php b/backend/modules/frontend/views/player/view.php index dd651c0a0..b46290a1b 100644 --- a/backend/modules/frontend/views/player/view.php +++ b/backend/modules/frontend/views/player/view.php @@ -57,7 +57,7 @@ ], 'email:email', 'academicLong', - 'affiliation', + 'metadata.affiliation', 'active:boolean', 'status', 'type', diff --git a/backend/modules/frontend/views/profile/_heading.php b/backend/modules/frontend/views/profile/_heading.php index 6c4446a81..97882f36a 100644 --- a/backend/modules/frontend/views/profile/_heading.php +++ b/backend/modules/frontend/views/profile/_heading.php @@ -14,7 +14,7 @@

owner->username) ?> - owner->fullname)!=="") echo " - ",Html::encode($model->owner->fullname) ?>owner->affiliation)!=="") echo " - ",Html::encode($model->owner->affiliation) ?> + owner->fullname)!=="") echo " - ",Html::encode($model->owner->fullname) ?>owner->metadata && trim($model->owner->metadata->affiliation)!=="") echo " - ",Html::encode($model->owner->metadata->affiliation) ?>

owner->teamPlayer):?>

Team: owner->teamPlayer->team->name ?>

bio) ?>

From ac851be734d387ba137708cf2054d7ac66acb543 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:49:10 +0300 Subject: [PATCH 07/11] remove affiliation from form --- backend/modules/frontend/views/player/_form.php | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/modules/frontend/views/player/_form.php b/backend/modules/frontend/views/player/_form.php index 7161ec1ea..dfac2763b 100644 --- a/backend/modules/frontend/views/player/_form.php +++ b/backend/modules/frontend/views/player/_form.php @@ -17,7 +17,6 @@ field($model, 'fullname')->textInput(['maxlength' => true])->hint('The fullname of the player') ?> field($model, 'academic')->dropDownList([0=>'0: '.Yii::$app->sys->academic_0short,1=>'1: '.Yii::$app->sys->academic_1short, 2=>'2: '.Yii::$app->sys->academic_2short])->hint('Whether the player is gov, edu or pro') ?> - field($model, 'affiliation')->textInput(['maxlength' => true])->hint('The player affiliation') ?> field($model, 'email')->textInput(['maxlength' => true])->hint('The email address of the player') ?> From b70747125d5f9f1748ac632ed172d0e1618463ee Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:49:25 +0300 Subject: [PATCH 08/11] make avatar a tiny bit smaller --- backend/modules/frontend/views/player/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/modules/frontend/views/player/index.php b/backend/modules/frontend/views/player/index.php index d0b2d647d..4d40e8b6b 100644 --- a/backend/modules/frontend/views/player/index.php +++ b/backend/modules/frontend/views/player/index.php @@ -59,8 +59,8 @@ [ 'attribute' => 'avatar', 'label'=>false, - 'headerOptions' => ['style' => 'width:3.5em'], - 'format' => ['image', ['width' => '40px', 'class' => 'img-thumbnail']], + 'headerOptions' => ['style' => 'width:3em'], + 'format' => ['image', ['width' => '30px', 'class' => 'img-thumbnail']], 'value' => function ($data) { return '//' . Yii::$app->sys->offense_domain . '/images/avatars/' . $data->profile->avatar; } From 5dbdfa6075325d41c3f5849d6a55e4108fbb7501 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 13:50:14 +0300 Subject: [PATCH 09/11] make identification and affiliation configurable also add some missing configuration keys --- .../modules/settings/models/ConfigureForm.php | 69 ++++++++++++++++++- .../settings/views/sysconfig/configure.php | 40 +++++++++-- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/backend/modules/settings/models/ConfigureForm.php b/backend/modules/settings/models/ConfigureForm.php index 2d318364b..444e69bd7 100644 --- a/backend/modules/settings/models/ConfigureForm.php +++ b/backend/modules/settings/models/ConfigureForm.php @@ -65,6 +65,22 @@ class ConfigureForm extends Model public $monthly_leaderboards; public $subscriptions_menu_show; public $subscriptions_emergency_suspend; + public $player_require_approval; + public $player_require_identification; + public $all_players_vip; + public $team_visible_instances; + public $target_hide_inactive; + public $target_guest_view_deny; + public $network_view_guest; + public $hide_timezone; + public $profile_discord; + public $profile_echoctf; + public $profile_twitter; + public $profile_github; + public $profile_htb; + public $profile_twitch; + public $profile_youtube; + public $guest_visible_leaderboards; public $dn_countryName; public $dn_stateOrProvinceName; @@ -132,7 +148,23 @@ class ConfigureForm extends Model 'stripe_webhookSecret', 'monthly_leaderboards', 'subscriptions_menu_show', - 'subscriptions_emergency_suspend' + 'subscriptions_emergency_suspend', + 'player_require_approval', + 'player_require_identification', + 'all_players_vip', + 'team_visible_instances', + 'target_hide_inactive', + 'target_guest_view_deny', + 'network_view_guest', + 'hide_timezone', + 'profile_discord', + 'profile_echoctf', + 'profile_twitter', + 'profile_github', + 'profile_htb', + 'profile_twitch', + 'profile_youtube', + 'guest_visible_leaderboards' ]; /** @@ -249,7 +281,24 @@ public function rules() 'leaderboard_show_zero', 'monthly_leaderboards', 'subscriptions_menu_show', - 'subscriptions_emergency_suspend' + 'subscriptions_emergency_suspend', + 'player_require_approval', + 'player_require_identification', + 'all_players_vip', + 'team_visible_instances', + 'target_hide_inactive', + 'target_guest_view_deny', + 'network_view_guest', + 'hide_timezone', + 'profile_discord', + 'profile_echoctf', + 'profile_twitter', + 'profile_github', + 'profile_htb', + 'profile_twitch', + 'profile_youtube', + 'guest_visible_leaderboards' + ], 'boolean'], ]; @@ -315,6 +364,22 @@ public function attributeLabels() 'monthly_leaderboards'=>'Monthly points leaderboards', 'subscriptions_menu_show'=>'Show subscriptions menu', 'subscriptions_emergency_suspend'=>'Emergency suspend subscriptions', + 'player_require_approval'=> 'Players require approval', + 'player_require_identification'=>'Players require identification', + 'all_players_vip'=>'Give all players VIP status', + 'team_visible_instances'=>'Team instances', + 'target_hide_inactive'=>'Hide inactive targets', + 'target_guest_view_deny'=>'Target deny guest view', + 'network_view_guest'=>'Allow guests network view', + 'hide_timezone'=>'Hide timezone', + 'profile_discord'=>'Discord', + 'profile_echoctf'=>'echoCTF', + 'profile_twitter'=>'Twitter/X', + 'profile_github'=>'Github', + 'profile_htb'=>'HackTheBox', + 'profile_twitch'=>'Twitch', + 'profile_youtube'=>'Youtube', + 'guest_visible_leaderboards'=>'Guest visible leaderboards', ]; } diff --git a/backend/modules/settings/views/sysconfig/configure.php b/backend/modules/settings/views/sysconfig/configure.php index 6c80f1b70..002ebf680 100644 --- a/backend/modules/settings/views/sysconfig/configure.php +++ b/backend/modules/settings/views/sysconfig/configure.php @@ -20,10 +20,11 @@

Event/CTF Settings

+
field($model, 'event_active')->checkbox()->hint('Is the site active?') ?>
+
field($model, 'hide_timezone')->checkbox()->hint('Hide timezone from frontend?') ?>
field($model, 'event_name')->textInput(['maxlength' => true])->input('text', ['placeholder' => "My Awesome CTF"])->hint('Enter your event or site name') ?>
-
field($model, 'site_description')->textInput(['maxlength' => true])->input('text', ['placeholder' => "My Awesome site description"])->hint('Enter your a description for your site') ?>
+
field($model, 'site_description')->textInput(['maxlength' => true])->input('text', ['placeholder' => "My Awesome site description"])->hint('Enter your a description for your site') ?>
field($model, 'time_zone')->dropDownList(ArrayHelper::map(DateTimeZone::listIdentifiers(), function($model){ return $model;},function($model){ return $model;}))->hint('Choose your timezone') ?>
-
field($model, 'event_active')->checkbox()->hint('Is the site active?') ?>
field($model, 'event_start')->textInput(['maxlength' => true])->input('text', ['placeholder' => "Y-m-d H:i:s"])->hint('Enter the event start date and time in UTC') ?>
@@ -32,24 +33,32 @@
field($model, 'registrations_end')->textInput(['maxlength' => true])->input('text', ['placeholder' => "Y-m-d H:i:s"])->hint('Enter the registration end date and time in UTC') ?>

+

Leaderboard Settings

+
field($model, 'guest_visible_leaderboards')->checkbox()->hint('Allow guests to view the leaderboards?') ?>
field($model, 'leaderboard_visible_before_event_start')->checkbox()->hint('Is the leaderboard going to be visible before the event starts?') ?>
field($model, 'leaderboard_visible_after_event_end') ->checkbox()->hint('Is the leaderboard going to be visible after the event ends?') ?>
-
field($model, 'leaderboard_show_zero') ->checkbox()->hint('Leaderboard show zero points?') ?>
-
field($model, 'monthly_leaderboards') ->checkbox()->hint('Show monthly leaderboards by points?') ?>
+
field($model, 'leaderboard_show_zero') ->checkbox()->hint('Leaderboard show zero points?') ?>
+
field($model, 'monthly_leaderboards') ->checkbox()->hint('Show monthly leaderboards by points?') ?>

Team properties

field($model, 'teams')->checkbox()->hint('Are teams supported?') ?>
field($model, 'team_required')->checkbox()->hint('Are teams required?') ?>
+
field($model, 'team_visible_instances')->checkbox()->hint('Make private instances accessible by team members?') ?>
field($model, 'team_manage_members')->checkbox()->hint('Allow team members management operations?') ?>
field($model, 'members_per_team')->textInput(['maxlength'=>true])->hint('How many members are allowed per team (including the team owner)?') ?>

Targets and Challenges properties

+ +
field($model, 'target_hide_inactive')->checkbox()->hint('Hide inactive targets from listings?') ?>
+
field($model, 'target_guest_view_deny')->checkbox()->hint('Hide targets from guests?') ?>
+
field($model, 'network_view_guest')->checkbox()->hint('Allow guests to view networks?') ?>
+
field($model, 'target_days_new')->textInput()->hint('How many days are targets considered new?') ?>
field($model, 'target_days_updated')->textInput()->hint('How many days are targets considered updated?') ?>
field($model, 'challenge_home')->textInput()->hint('Web accessible path for downloading challenge files?') ?>
@@ -58,15 +67,18 @@

-

Registration and Player properties

+

Player Registration properties

+
field($model, 'player_require_approval')->checkbox()->hint('Do players need to be approved?') ?>
+
field($model, 'player_require_identification')->checkbox()->hint('Do players need to provide identification proof?') ?>
+
field($model, 'all_players_vip')->checkbox()->hint('Treat all players as VIP?') ?>
field($model, 'require_activation')->checkbox()->hint('Do players need to activate their account?') ?>
field($model, 'disable_registration')->checkbox()->hint('Are online registrations allowed on the pUI?') ?>
-
field($model, 'player_profile')->checkbox()->hint('Are player profiles active?') ?>
field($model, 'approved_avatar')->checkbox()->hint('Are player profile avatars approved?') ?>
+
- +

Profile social details

field($model, 'profile_visibility')->textInput()->hint('Choose default profile visibility (ingame, public, private)') ?>
field($model, 'default_homepage')->textInput()->hint('Default homepage for logged in users (eg. /dashboard)') ?>
@@ -75,6 +87,19 @@

+

Player social details

+
+
field($model, 'player_profile')->checkbox()->hint('Are player profiles active?') ?>
+
field($model, 'profile_discord')->checkbox()->hint('Player Discord details?') ?>
+
field($model, 'profile_echoctf')->checkbox()->hint('Player echoCTF profile') ?>
+
field($model, 'profile_twitter')->checkbox()->hint('Player Twitter/X profile') ?>
+
field($model, 'profile_github')->checkbox()->hint('Player Github profile') ?>
+
field($model, 'profile_htb')->checkbox()->hint('Player HTB profile') ?>
+
field($model, 'profile_twitch')->checkbox()->hint('Player Twitch profile') ?>
+
field($model, 'profile_youtube')->checkbox()->hint('Player Youtube profile') ?>
+
+
+

Domains and Hosts

field($model, 'moderator_domain')->textInput(['maxlength' => true])->hint('Moderator domain')->input('text', ['placeholder' => "admin.example.ctf"]) ?>
@@ -82,6 +107,7 @@
field($model, 'defense_domain')->textInput(['maxlength' => true])->hint('Defense domain')->input('text', ['placeholder' => "blue.example.ctf"]) ?>
field($model, 'vpngw')->textInput(['maxlength' => true])->hint('VPN Gateway FQDN or IP (eg. vpn.echoctf.red)')->input('text', ['placeholder' => "vpngw.example.ctf"]) ?>
+

Mail Settings

From 360f1f1a616c036eb02e0bffcf8c46835a1e61ed Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 14:00:47 +0300 Subject: [PATCH 10/11] add displaying and searching by username --- .../frontend/models/PlayerMetadataSearch.php | 18 ++++++++++++++++-- .../frontend/views/player-metadata/_form.php | 7 ++++++- .../frontend/views/player-metadata/index.php | 3 ++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/backend/modules/frontend/models/PlayerMetadataSearch.php b/backend/modules/frontend/models/PlayerMetadataSearch.php index 76929c855..0a7d0a299 100644 --- a/backend/modules/frontend/models/PlayerMetadataSearch.php +++ b/backend/modules/frontend/models/PlayerMetadataSearch.php @@ -11,6 +11,7 @@ */ class PlayerMetadataSearch extends PlayerMetadata { + public $username; /** * {@inheritdoc} */ @@ -18,7 +19,7 @@ public function rules() { return [ [['player_id'], 'integer'], - [['identificationFile', 'affiliation'], 'safe'], + [['identificationFile', 'affiliation','username'], 'safe'], ]; } @@ -40,7 +41,7 @@ public function scenarios() */ public function search($params) { - $query = PlayerMetadata::find(); + $query = PlayerMetadata::find()->joinWith(['player']); // add conditions that should always apply here @@ -62,8 +63,21 @@ public function search($params) ]); $query->andFilterWhere(['like', 'identificationFile', $this->identificationFile]) + ->andFilterWhere(['like', 'player.username', $this->username]) ->andFilterWhere(['like', 'affiliation', $this->affiliation]); + $dataProvider->setSort([ + 'attributes' => array_merge( + $dataProvider->getSort()->attributes, + [ + 'username' => [ + 'asc' => ['player.username' => SORT_ASC], + 'desc' => ['player.username' => SORT_DESC], + ], + ] + ), + ]); + return $dataProvider; } } diff --git a/backend/modules/frontend/views/player-metadata/_form.php b/backend/modules/frontend/views/player-metadata/_form.php index fbf9edc2b..2c2fdd363 100644 --- a/backend/modules/frontend/views/player-metadata/_form.php +++ b/backend/modules/frontend/views/player-metadata/_form.php @@ -2,6 +2,7 @@ use yii\helpers\Html; use yii\widgets\ActiveForm; +use app\widgets\sleifer\autocompleteAjax\AutocompleteAjax; /** @var yii\web\View $this */ /** @var app\modules\frontend\models\PlayerMetadata $model */ @@ -11,8 +12,12 @@