From c381e58b109c7e1df9d720a706cb1f98f822abfd Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 04:23:51 +0300 Subject: [PATCH 01/12] add approval database field The field is integer and recognizes the following values 0=>Pending, 1=>Approved, 2=>Approved and mailed, 3=>Rejected, 4=>Rejected and mailed. This field is only visible when players_require_approval flag is set to true --- ...32_add_approval_column_to_player_table.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 backend/migrations/m240502_232532_add_approval_column_to_player_table.php diff --git a/backend/migrations/m240502_232532_add_approval_column_to_player_table.php b/backend/migrations/m240502_232532_add_approval_column_to_player_table.php new file mode 100644 index 000000000..e1f74dcde --- /dev/null +++ b/backend/migrations/m240502_232532_add_approval_column_to_player_table.php @@ -0,0 +1,25 @@ +addColumn('{{%player}}', 'approval', $this->integer()->defaultValue(0)); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('{{%player}}', 'approval'); + } +} From 34f626f3bd8918655e53e2689571f89b915c39a1 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:23:27 +0300 Subject: [PATCH 02/12] Make mail action respect approval status when players_require_approval flag is set. Also update approval status as necessary --- .../frontend/actions/player/MailAction.php | 116 ++++++++++-------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/backend/modules/frontend/actions/player/MailAction.php b/backend/modules/frontend/actions/player/MailAction.php index 5974134e6..71e8a636f 100644 --- a/backend/modules/frontend/actions/player/MailAction.php +++ b/backend/modules/frontend/actions/player/MailAction.php @@ -1,4 +1,5 @@ controller->findModel($id); - if($player->status==10) + $player = $this->controller->findModel($id); + if ($player->status == 10) { - \Yii::$app->getSession()->setFlash('warning', Yii::t('app','Player already active skipping mail.')); - return $this->controller->goBack(Yii::$app->request->referrer); + \Yii::$app->getSession()->setFlash('warning', Yii::t('app', 'Player already active skipping mail.')); } - elseif($player->status==9) + elseif ($player->status == 9) { - //$event_name=Sysconfig::findOne('event_name')->val; - try { - $activationURL=sprintf("https://%s/verify-email?token=%s",\Yii::$app->sys->offense_domain, $player->verification_token); - Yii::$app - ->mailer - ->compose( - ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'], - ['user' => $player,'verifyLink'=>$activationURL] - ) - ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName.' robot']) - ->setTo([$player->email => $player->fullname]) - ->setSubject(Yii::t('app','{event_name} Account approved',['event_name'=>trim(Yii::$app->sys->event_name)])) - ->send(); - \Yii::$app->getSession()->setFlash('success', Yii::t('app','Player activation mail send.')); - } - catch(\Exception $e) - { - \Yii::$app->getSession()->setFlash('error', Yii::t('app','Failed to mail player. {exception}',['exception'=>Html::encode($e->getMessage())])); - } + if(\Yii::$app->sys->players_require_approval === true && $player->approval>0 && $player->approval<=2) + $this->approvalMail($player); + elseif(\Yii::$app->sys->players_require_approval === true && $player->approval>2 && $player->approval<=4) + $this->rejectionMail($player); } - elseif($player->status==0) + elseif ($player->status == 0) { - try { - $activationURL=sprintf("https://%s/verify-email?token=%s",\Yii::$app->sys->offense_domain, $player->verification_token); - Yii::$app - ->mailer - ->compose( - ['html' => 'rejectVerify-html', 'text' => 'rejectVerify-text'], - ['user' => $player] - ) - ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName.' robot']) - ->setTo([$player->email => $player->fullname]) - ->setSubject(Yii::t('app','{event_name} Account Rejected',['event_name'=>trim(Yii::$app->sys->event_name)])) - ->send(); - \Yii::$app->getSession()->setFlash('success', Yii::t('app','Player rejection mail send.')); - } - catch(\Exception $e) - { - \Yii::$app->getSession()->setFlash('error', Yii::t('app','Failed to mail rejection to player. {exception}',['exception'=>Html::encode($e->getMessage())])); - } - + $this->rejectionMail($player); } - // Generate activation URL -// $activationURL=sprintf("%s%s", $baseURL, $player->activkey); -// $content=$this->controller->renderPartial('_account_activation_email', ['player' => $player, 'activationURL'=>$activationURL, 'event_name'=>$event_name]); -// $player->mail($content, 'echoCTF RED re-sending of account activation URL'); - + if($player->approval==1) + $player->updateAttributes(['approval' => 2]); + elseif($player->approval==3) + $player->updateAttributes(['approval' => 4]); return $this->controller->goBack(Yii::$app->request->referrer); } + + /** + * Send player rejection mail + */ + private function rejectionMail($player) + { + try { + Yii::$app + ->mailer + ->compose( + ['html' => 'rejectVerify-html', 'text' => 'rejectVerify-text'], + ['user' => $player] + ) + ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot']) + ->setTo([$player->email => $player->fullname]) + ->setSubject(Yii::t('app', '{event_name} Account rejected', ['event_name' => trim(Yii::$app->sys->event_name)])) + ->send(); + \Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player rejection mail send.')); + } catch (\Exception $e) { + \Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail rejection to player. {exception}', ['exception' => Html::encode($e->getMessage())])); + } + } + + /** + * Send approval email to user + */ + private function approvalMail($player) + { + try { + $activationURL = sprintf("https://%s/verify-email?token=%s", \Yii::$app->sys->offense_domain, $player->verification_token); + Yii::$app + ->mailer + ->compose( + ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'], + ['user' => $player, 'verifyLink' => $activationURL] + ) + ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot']) + ->setTo([$player->email => $player->fullname]) + ->setSubject(Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)])) + ->send(); + if (Yii::$app->sys->players_require_approval === true && $player->approval == 1) { + $player->updateAttributes(['approval' => 2]); + \Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player activation mail send and approval status updated.')); + } else { + \Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player activation mail send.')); + } + } catch (\Exception $e) { + \Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail player. {exception}', ['exception' => Html::encode($e->getMessage())])); + } + } } From f19be37283db58f24c28c85b426b35bb27194bb7 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:23:44 +0300 Subject: [PATCH 03/12] Add rejection mail template --- .../m211204_005430_load_default_email_templates.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/migrations-init/m211204_005430_load_default_email_templates.php b/backend/migrations-init/m211204_005430_load_default_email_templates.php index 3b4ff41a2..987a3ac44 100644 --- a/backend/migrations-init/m211204_005430_load_default_email_templates.php +++ b/backend/migrations-init/m211204_005430_load_default_email_templates.php @@ -10,7 +10,8 @@ class m211204_005430_load_default_email_templates extends Migration public $TPL=[ 'emailChangeVerify', 'emailVerify', - 'passwordResetToken' + 'passwordResetToken', + 'rejectVerify', ]; /** * {@inheritdoc} From ce85b6b4868daa93c2a8dd9216df77a7667f8a80 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:25:08 +0300 Subject: [PATCH 04/12] When we set the deleted flag for a player also update the approval status --- backend/modules/frontend/controllers/PlayerController.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/modules/frontend/controllers/PlayerController.php b/backend/modules/frontend/controllers/PlayerController.php index d751b803f..41a94a87d 100644 --- a/backend/modules/frontend/controllers/PlayerController.php +++ b/backend/modules/frontend/controllers/PlayerController.php @@ -245,11 +245,15 @@ public function actionDelete($id) */ public function actionSetDeleted($id) { + if(\Yii::$app->sys->players_require_approval===true) + $updateAttributes=['status' => 0, 'active' => 0,'approval'=>3]; + else + $updateAttributes=['status' => 0, 'active' => 0]; - if (($model = Player::findOne($id)) !== null && $model->updateAttributes(['status' => 0, 'active' => 0])) + if (($model = Player::findOne($id)) !== null && $model->updateAttributes($updateAttributes)) Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] status set to deleted.', ['username'=>Html::encode($model->username)])); else - Yii::$app->session->setFlash('error', Yii::t('app','Player deletion failed.')); + Yii::$app->session->setFlash('error', Yii::t('app','Player setting deletion flag failed.')); return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); } From e2533d00ed1dca0a2124ef82c98229df737ac4cc Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:25:37 +0300 Subject: [PATCH 05/12] introduce approve/reject operations for players --- .../frontend/controllers/PlayerController.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/backend/modules/frontend/controllers/PlayerController.php b/backend/modules/frontend/controllers/PlayerController.php index 41a94a87d..4c9da0f15 100644 --- a/backend/modules/frontend/controllers/PlayerController.php +++ b/backend/modules/frontend/controllers/PlayerController.php @@ -47,6 +47,8 @@ public function behaviors() 'reset-player-progress' => ['POST'], 'toggle-academic' => ['POST'], 'toggle-active' => ['POST'], + 'approve' => ['POST'], + 'reject' => ['POST'], ], ], ]); @@ -345,6 +347,51 @@ public function actionToggleActive($id) return $this->redirect(['index']); } + /** + * Approve player registration. + * @param integer $id + * @param bool $id (optional) mail user + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionApprove($id) + { + $trans = Yii::$app->db->beginTransaction(); + try { + $model = $this->findModel($id); + $model->updateAttributes(['approval' => 1]); + $trans->commit(); + Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] registration approved.', ['username'=>Html::encode($model->username)])); + } catch (\Exception $e) { + $trans->rollBack(); + Yii::$app->session->setFlash('error', Yii::t('app','Failed to approve player [{username}] registration [{exception}]', ['username'=>Html::encode($model->username),'exception'=>Html::encode($e->getMessage())])); + } + + return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); + } + + /** + * Reject player registration. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionReject($id) + { + $trans = Yii::$app->db->beginTransaction(); + try { + $model = $this->findModel($id); + $model->updateAttributes(['approval' => 3]); + $trans->commit(); + Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] registration rejected.', ['username'=>Html::encode($model->username)])); + } catch (\Exception $e) { + $trans->rollBack(); + Yii::$app->session->setFlash('error', Yii::t('app','Failed to reject player [{username}] registration.', ['username'=>Html::encode($model->username)])); + } + + return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); + } + public function actionGenerateSsl($id) { $player = $this->findModel($id); From 765334ae463b4fc969915945d050fe68d69865ff Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:26:31 +0300 Subject: [PATCH 06/12] add approval field to model and search --- backend/modules/frontend/models/PlayerAR.php | 5 ++++- backend/modules/frontend/models/PlayerSearch.php | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/modules/frontend/models/PlayerAR.php b/backend/modules/frontend/models/PlayerAR.php index 680d5befd..b5018d394 100644 --- a/backend/modules/frontend/models/PlayerAR.php +++ b/backend/modules/frontend/models/PlayerAR.php @@ -32,6 +32,7 @@ * @property int $active * @property int $academic * @property int $status + * @property int $approval * @property string $ts * * @property PlayerBadge[] $playerBadges @@ -63,6 +64,8 @@ class PlayerAR extends \yii\db\ActiveRecord const STATUS_UNVERIFIED=8; const STATUS_INACTIVE=9; const STATUS_ACTIVE=10; + const APPROVAL=[4 => 'Rejection Mailed',3 => 'Rejected', 2 => 'Approval Mailed', 1 => "Approved", 0 => "Pending",]; + /** * {@inheritdoc} */ @@ -100,7 +103,7 @@ public function rules() return [ [['username', 'type', 'status','email'], 'required'], [['type','affiliation'], 'string'], - [['active', 'status'], 'integer'], + [['active', 'status','approval'], 'integer'], [['academic'], 'integer'], [['academic'], 'default','value'=>0], [['password_hash'], 'default', 'value'=>""], diff --git a/backend/modules/frontend/models/PlayerSearch.php b/backend/modules/frontend/models/PlayerSearch.php index 3f777539b..21086467c 100644 --- a/backend/modules/frontend/models/PlayerSearch.php +++ b/backend/modules/frontend/models/PlayerSearch.php @@ -43,8 +43,8 @@ public function behaviors() public function rules() { return [ - [['id', 'academic', 'status', 'active'], 'integer'], - [['created','vpn_local_address', 'status', 'username', 'fullname', 'email', 'type', 'password', 'activkey', 'ts', 'last_seen', 'online', 'ovpn', 'on_pui', 'on_vpn'], 'safe'], + [['id', 'academic', 'status', 'active','approval'], 'integer'], + [['affiliation','created','vpn_local_address', 'status', 'username', 'fullname', 'email', 'type', 'password', 'activkey', 'ts', 'last_seen', 'online', 'ovpn', 'on_pui', 'on_vpn'], 'safe'], ]; } @@ -89,6 +89,7 @@ public function search($params) 'player.active' => $this->active, 'player.academic' => $this->academic, 'player.status' => $this->status, + 'player.approval' => $this->approval, 'player_last.on_pui' => $this->on_pui, 'player_last.on_vpn' => $this->on_vpn, 'player.ts' => $this->ts, @@ -101,6 +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', 'INET_NTOA(player_last.vpn_local_address)', $this->vpn_local_address]); // if(!empty($this->ovpn)) $query->andHaving(['like', 'ovpn', $this->ovpn]); From fc66b2b67bd1cf54d2264bb665a1d4d3320226ea Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 14:27:15 +0300 Subject: [PATCH 07/12] Add a few more conditionals to the player grid as well as improved actions --- .../modules/frontend/views/player/index.php | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/backend/modules/frontend/views/player/index.php b/backend/modules/frontend/views/player/index.php index f7069ad55..ee0a89b73 100644 --- a/backend/modules/frontend/views/player/index.php +++ b/backend/modules/frontend/views/player/index.php @@ -5,7 +5,6 @@ /* @var $this yii\web\View */ /* @var $searchModel app\modules\frontend\models\PlayerSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ - $this->title = ucfirst(Yii::$app->controller->module->id) . ' / ' . ucfirst(Yii::$app->controller->id); $this->params['breadcrumbs'][] = ['label' => 'Players', 'url' => ['index']]; yii\bootstrap5\Modal::begin([ @@ -103,25 +102,34 @@ } ], 'online:boolean', - 'active:boolean', + //'active:boolean', [ 'attribute' => 'academic', 'value' => 'academicShort', 'contentOptions' => ['class' => 'small'], 'filter' => [0 => Yii::$app->sys->academic_0short, 1 => Yii::$app->sys->academic_1short, 2 => Yii::$app->sys->academic_2short], + 'visible'=> trim(Yii::$app->sys->academic_0short)!=='' ], [ 'attribute' => 'status', 'format' => 'playerStatus', 'filter' => [10 => 'Enabled', 9 => 'Inactive', 8 => "Change", 0 => "Deleted",], 'contentOptions' => ['class' => 'small'], - + ], + [ + 'attribute'=>'approval', + 'filter'=>$searchModel::APPROVAL, + 'visible'=> Yii::$app->sys->players_require_approval===true, + 'value' => function ($model) { + return $model::APPROVAL[$model->approval]; + } ], [ 'attribute' => 'type', 'filter' => ["offense"=>"offense","defense"=>"defense"], 'contentOptions' => ['class' => 'small'], + 'visible'=>trim(Yii::$app->sys->defense_scenario)!=='' ], [ @@ -132,13 +140,17 @@ [ 'class' => 'yii\grid\ActionColumn', 'visibleButtons'=>[ - 'generate-ssl'=>function($model){ if ($model->status==10 || $model->active==1) return true; return false;}, - 'mail'=>function($model){ if ($model->status==10 || $model->active==1) return false; return true;}, 'clear-vpn'=>function($model){ if ($model->last->vpn_local_address!==null) return true; return false;}, + 'view'=>function($model){return false;}, + 'generate-ssl'=>function($model){ if ($model->status==10) return true; return false;}, + 'set-deleted'=>function($model){ if($model->status==0) return false; return true;}, + 'mail'=>function($model){ if ($model->status==10 || $model->approval==0) return false; return true;}, 'delete'=>function($model){ if (\Yii::$app->user->identity->isAdmin) return true; return false;}, 'reset-activkey'=>function($model){ if ($model->active && trim($model->activkey)!=="") return true; return false;}, + 'approve'=>function($model){ if ($model->active==0 && Yii::$app->sys->players_require_approval===true && $model->approval<1) return true; return false;}, + 'reject'=>function($model){ if ($model->active==0 && Yii::$app->sys->players_require_approval===true && $model->approval<2) return true; return false;} ], - 'template' => '{player-view-full} {clear-vpn} {view} {generate-ssl} {set-deleted} ' . '{update} {delete} {ban} {mail} {reset-activkey}', + 'template' => '{player-view-full} {clear-vpn} {view} {generate-ssl} {update} {delete} {ban} {mail} {reset-activkey} {approve} {reject} {set-deleted}', 'header' => Html::a( '', ['ban-filtered'], @@ -167,6 +179,26 @@ ] ), 'buttons' => [ + 'approve'=>function($url, $model){ + return Html::a('', ['approve', 'id' => $model->id], [ + 'class' => '', + 'title'=>'Approve Player', + 'data' => [ + 'confirm' => 'Are you absolutely sure you want to approve this player ['.Html::encode($model->username).'] ?', + 'method' => 'post', + ], + ]); + }, + 'reject'=>function($url, $model){ + return Html::a('', ['reject', 'id' => $model->id], [ + 'class' => '', + 'title'=>'Reject Player', + 'data' => [ + 'confirm' => 'Are you absolutely sure you want to reject this player ['.Html::encode($model->username).'] ?', + 'method' => 'post', + ], + ]); + }, 'reset-activkey' => function($url, $model) { return Html::a('', ['reset-activkey', 'id' => $model->id], [ 'class' => '', @@ -258,14 +290,11 @@ }, 'player-view-full' => function ($url, $model) { $url = \yii\helpers\Url::to(['/frontend/profile/view-full', 'id' => $model->profile->id]); - return Html::a( - '', - $url, - [ - 'title' => 'View full profile', - 'data-pjax' => '0', - ] - ); + return Html::a('', $url,[ + 'class'=>'', + 'title' => 'View full profile', + 'data-pjax' => '0', + ]); }, ], From 25debe063d1e76fae73c6475132647780f14aaee Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 15:34:57 +0300 Subject: [PATCH 08/12] phdoc fix --- backend/modules/frontend/controllers/PlayerController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/modules/frontend/controllers/PlayerController.php b/backend/modules/frontend/controllers/PlayerController.php index 4c9da0f15..ed31a1386 100644 --- a/backend/modules/frontend/controllers/PlayerController.php +++ b/backend/modules/frontend/controllers/PlayerController.php @@ -350,7 +350,6 @@ public function actionToggleActive($id) /** * Approve player registration. * @param integer $id - * @param bool $id (optional) mail user * @return mixed * @throws NotFoundHttpException if the model cannot be found */ From aff9202b8cca309368381006a69521ec8699769f Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 15:47:52 +0300 Subject: [PATCH 09/12] make the sending of the email operation unified --- .../frontend/actions/player/MailAction.php | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/backend/modules/frontend/actions/player/MailAction.php b/backend/modules/frontend/actions/player/MailAction.php index 71e8a636f..1148e51cf 100644 --- a/backend/modules/frontend/actions/player/MailAction.php +++ b/backend/modules/frontend/actions/player/MailAction.php @@ -29,19 +29,19 @@ public function run(int $id, $baseURL = "https://echoctf.red/activate/") } elseif ($player->status == 9) { - if(\Yii::$app->sys->players_require_approval === true && $player->approval>0 && $player->approval<=2) + if (\Yii::$app->sys->players_require_approval === true && $player->approval > 0 && $player->approval <= 2) $this->approvalMail($player); - elseif(\Yii::$app->sys->players_require_approval === true && $player->approval>2 && $player->approval<=4) + elseif (\Yii::$app->sys->players_require_approval === true && $player->approval > 2 && $player->approval <= 4) $this->rejectionMail($player); } elseif ($player->status == 0) { - $this->rejectionMail($player); + $this->rejectionMail($player); } - if($player->approval==1) + if ($player->approval == 1) $player->updateAttributes(['approval' => 2]); - elseif($player->approval==3) + elseif ($player->approval == 3) $player->updateAttributes(['approval' => 4]); return $this->controller->goBack(Yii::$app->request->referrer); @@ -53,16 +53,12 @@ public function run(int $id, $baseURL = "https://echoctf.red/activate/") private function rejectionMail($player) { try { - Yii::$app - ->mailer - ->compose( - ['html' => 'rejectVerify-html', 'text' => 'rejectVerify-text'], - ['user' => $player] - ) - ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot']) - ->setTo([$player->email => $player->fullname]) - ->setSubject(Yii::t('app', '{event_name} Account rejected', ['event_name' => trim(Yii::$app->sys->event_name)])) - ->send(); + $this->sendMail( + $player, + 'rejectVerify-html', + 'rejectVerify-text', + Yii::t('app', '{event_name} Account rejected', ['event_name' => trim(Yii::$app->sys->event_name)]) + ); \Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player rejection mail send.')); } catch (\Exception $e) { \Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail rejection to player. {exception}', ['exception' => Html::encode($e->getMessage())])); @@ -76,16 +72,12 @@ private function approvalMail($player) { try { $activationURL = sprintf("https://%s/verify-email?token=%s", \Yii::$app->sys->offense_domain, $player->verification_token); - Yii::$app - ->mailer - ->compose( - ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'], - ['user' => $player, 'verifyLink' => $activationURL] - ) - ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot']) - ->setTo([$player->email => $player->fullname]) - ->setSubject(Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)])) - ->send(); + $this->sendMail( + $player, + 'emailVerify-html', + 'emailVerify-text', + Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)]) + ); if (Yii::$app->sys->players_require_approval === true && $player->approval == 1) { $player->updateAttributes(['approval' => 2]); \Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player activation mail send and approval status updated.')); @@ -96,4 +88,18 @@ private function approvalMail($player) \Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail player. {exception}', ['exception' => Html::encode($e->getMessage())])); } } + + private function sendMail($player, $html, $text, $subject) + { + Yii::$app + ->mailer + ->compose( + ['html' => $html, 'text' => $text], + ['user' => $player] + ) + ->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot']) + ->setTo([$player->email => $player->fullname]) + ->setSubject($subject) + ->send(); + } } From e99ccff07f7fff36193290080a8207134f73956c Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Sat, 4 May 2024 17:36:19 +0300 Subject: [PATCH 10/12] make fullname visible only when not empty and include the player affiliation and team --- backend/modules/frontend/views/profile/_heading.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/modules/frontend/views/profile/_heading.php b/backend/modules/frontend/views/profile/_heading.php index 5484d6bff..6c4446a81 100644 --- a/backend/modules/frontend/views/profile/_heading.php +++ b/backend/modules/frontend/views/profile/_heading.php @@ -14,9 +14,9 @@

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

-

ranked owner->rank->ordinalPlace ?> with owner->score->points) ?> points

+ owner->teamPlayer):?>

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

bio) ?>

diff --git a/backend/modules/frontend/views/profile/view_full.php b/backend/modules/frontend/views/profile/view_full.php index 3c9ef213c..7faf4cb59 100644 --- a/backend/modules/frontend/views/profile/view_full.php +++ b/backend/modules/frontend/views/profile/view_full.php @@ -4,8 +4,6 @@ use yii\helpers\Url; use yii\widgets\DetailView; use kartik\tabs\TabsX; -use yii\bootstrap5\Dropdown; -use yii\bootstrap5\ButtonDropdown; /* @var $this yii\web\View */ /* @var $model app\modules\frontend\models\Profile */ @@ -24,41 +22,7 @@
- + render('_quick_actions',['model'=>$model]); ?>
render('_player_details', ['model' => $model]); ?> From 0eee80ad052ce4b0bf2deff6b3c14483b9257790 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Mon, 6 May 2024 01:56:45 +0300 Subject: [PATCH 12/12] Add reject/approve/mail filtered --- .../frontend/controllers/PlayerController.php | 98 +++++++++++++++++++ .../modules/frontend/views/player/index.php | 39 ++++++++ 2 files changed, 137 insertions(+) diff --git a/backend/modules/frontend/controllers/PlayerController.php b/backend/modules/frontend/controllers/PlayerController.php index ed31a1386..99513459f 100644 --- a/backend/modules/frontend/controllers/PlayerController.php +++ b/backend/modules/frontend/controllers/PlayerController.php @@ -490,6 +490,104 @@ public function actionClearVpn($id) } /** + * Reject all filtered results + */ + public function actionRejectFiltered() + { + $searchModel = new PlayerSearch(); + $query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]); + $query->pagination = false; + if (intval($query->count) === intval(Player::find()->count())) { + Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to reject all the records.')); + return $this->redirect(['index']); + } + + $trans = Yii::$app->db->beginTransaction(); + try { + $counter = $query->count; + foreach ($query->getModels() as $q) + { + $q->approval=3; + $q->save(); + } + $trans->commit(); + Yii::$app->session->setFlash('success', Yii::t('app','[{counter}] Players rejected',['counter'=>intval($counter)])); + } catch (\Exception $e) { + $trans->rollBack(); + Yii::$app->session->setFlash('error', Yii::t('app','Failed to reject users')); + } + return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); + } + + /** + * Approve all filtered results + */ + public function actionApproveFiltered() + { + $searchModel = new PlayerSearch(); + $query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]); + $query->pagination = false; + if (intval($query->count) === intval(Player::find()->count())) { + Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to approve all the records.')); + return $this->redirect(['index']); + } + + $trans = Yii::$app->db->beginTransaction(); + try { + $counter = $query->count; + foreach ($query->getModels() as $q) + { + $q->approval=1; + $q->save(); + } + $trans->commit(); + Yii::$app->session->setFlash('success', Yii::t('app','[{counter}] Players approved',['counter'=>intval($counter)])); + } catch (\Exception $e) { + $trans->rollBack(); + Yii::$app->session->setFlash('error', Yii::t('app','Failed to approve users')); + } + return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); + } + + /** + * Mail all filtered results + */ + public function actionMailFiltered() + { + $searchModel = new PlayerSearch(); + $query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]); + $query->query->andFilterWhere([ + 'player.approval' => [1,3], + ]); + //$query->pagination = false; + $query->pagination = ['pageSize' => 5]; + if (intval($query->count) === intval(Player::find()->count())) { + Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to mail all the players.')); + return $this->redirect(['index']); + } + $approved=$rejected=0; + $trans = Yii::$app->db->beginTransaction(); + try { + $counter = $query->count; + foreach ($query->getModels() as $q) + { + if($q->approval==1) + $approved++; + elseif($q->approval==3) + $rejected++; + Yii::$app->runAction('frontend/player/mail', ['id' => $q->id]); + } + $trans->commit(); + + Yii::$app->session->setFlash('success', Yii::t('app','[{counter}] total Players mailed [{approved} approved/{rejected} rejected]',['counter'=>intval($counter),'approved'=>$approved,'rejected'=>$rejected])); + } catch (\Exception $e) { + $trans->rollBack(); + Yii::$app->session->setFlash('error', Yii::t('app','Failed to mail users')); + } + return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null)); + } + + /** * Finds the Player model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. * @param integer $id diff --git a/backend/modules/frontend/views/player/index.php b/backend/modules/frontend/views/player/index.php index ee0a89b73..fab347dac 100644 --- a/backend/modules/frontend/views/player/index.php +++ b/backend/modules/frontend/views/player/index.php @@ -177,6 +177,45 @@ 'confirm' => 'Are you sure you want to delete the currently filtered users?', ], ] + ). ' ' . Html::a( + '', + ['mail-filtered'], + [ + 'title' => 'Mass Mail Filtered players', + 'data-pjax' => '0', + 'data-method' => 'POST', + 'data' => [ + 'method' => 'post', + 'params' => $searchModel->attributes, + 'confirm' => 'Are you sure you want to mail the currently filtered users?', + ], + ] + ). ' ' . Html::a( + '', + ['approve-filtered'], + [ + 'title' => 'Mass Approve Filtered players', + 'data-pjax' => '0', + 'data-method' => 'POST', + 'data' => [ + 'method' => 'post', + 'params' => $searchModel->attributes, + 'confirm' => 'Are you sure you want to approve the currently filtered users?', + ], + ] + ). ' ' . Html::a( + '', + ['reject-filtered'], + [ + 'title' => 'Mass Reject Filtered players', + 'data-pjax' => '0', + 'data-method' => 'POST', + 'data' => [ + 'method' => 'post', + 'params' => $searchModel->attributes, + 'confirm' => 'Are you sure you want to reject the currently filtered users?', + ], + ] ), 'buttons' => [ 'approve'=>function($url, $model){