Club System

This commit is contained in:
2026-06-02 20:54:08 +02:00
parent d79dbecad4
commit f4dc336c88
13 changed files with 371 additions and 40 deletions

View File

@@ -0,0 +1,25 @@
<?php
namespace RomhackPlaza\Master\Api\Controller;
use XF\Api\Controller\AbstractController;
use XF\Mvc\Reply\AbstractReply;
class EntryController extends AbstractController
{
public function actionPostUpdateEntryCount(): AbstractReply
{
$userId = $this->filter('user_id', 'uint');
$count = $this->filter('count', 'uint');
$user = $this->assertRecordExists('XF:User', $userId);
$user->rhpz_entry_count = $count;
$user->save();
$trophyRepo = $this->repository('XF:Trophy');
$trophyRepo->updateTrophiesForUser($user);
return $this->apiSuccess(['success' => true,'user_id' => $user->user_id,'count' => $count]);
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace RomhackPlaza\Master\ApprovalQueue;
use XF\ApprovalQueue\AbstractHandler;
use XF\Mvc\Entity\Entity;
class ClubRequest extends AbstractHandler
{
protected function canViewContent(Entity $content, &$error = null)
{
return $this->canActionContent($content, $error);
}
protected function canActionContent(Entity $content, &$error = null)
{
return \XF::visitor()->hasAdminPermission('node');
}
public function getEntityWith()
{
return ['User'];
}
public function actionApprove(\RomhackPlaza\Master\Entity\ClubRequest $clubRequest)
{
$clubRequest->request_state = 'visible';
$clubRequest->save();
$node = \XF::em()->create('XF:Node');
$node->node_type_id = 'Forum';
$node->title = $clubRequest->title;
$node->description = $clubRequest->description;
$node->parent_node_id = \XF::options()->rhpz_club_node_id ?? 0;
$node->display_order = 1;
$node->save();
$forum = \XF::em()->create('XF:Forum');
$forum->node_id = $node->node_id;
$forum->allow_posting = true;
$forum->save();
$user = $clubRequest->User;
if ($user) {
$modContent = \XF::em()->create('XF:ModeratorContent');
$modContent->content_type = 'node';
$modContent->content_id = $node->node_id;
$modContent->user_id = $user->user_id;
$modContent->save();
$permissionUpdater = \XF::app()->service('XF:UpdatePermissions');
$permissionUpdater->setContent('node', $node->node_id);
$permissionUpdater->setUser($user);
$permissionUpdater->updatePermissions([
'forum' => [
'editAnyPost' => 'content_allow',
'deleteAnyPost' => 'content_allow',
'deleteAnyThread' => 'content_allow',
'inlineMod' => 'content_allow',
'lockUnlockThread' => 'content_allow',
'stickUnstickThread' => 'content_allow'
]
]);
// D. Reconstruction des permissions
\XF::app()->jobManager()->enqueueUnique('permissionRebuild', 'XF:PermissionRebuild');
}
}
public function actionReject(\RomhackPlaza\Master\Entity\ClubRequest $clubRequest)
{
$clubRequest->request_state = 'rejected';
$clubRequest->save();
}
public function getTemplateName()
{
return 'public:approval_item_club_request';
}
}

75
Entity/ClubRequest.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
namespace RomhackPlaza\Master\Entity;
use XF\Mvc\Entity\Entity;
use XF\Mvc\Entity\Structure;
class ClubRequest extends Entity
{
public static function getStructure(Structure $structure): Structure
{
$structure->table = 'xf_club_request';
$structure->shortName = 'RomhackPlaza\Master:ClubRequest';
$structure->primaryKey = 'request_id';
$structure->columns = [
'request_id' => ['type' => self::UINT, 'autoIncrement' => true],
'user_id' => ['type' => self::UINT, 'required' => true],
'title' => ['type' => self::STR, 'maxLength' => 100, 'required' => true],
'description' => ['type' => self::STR, 'required' => true],
'request_state' => ['type' => self::STR, 'default' => 'moderated',
'allowedValues' => ['visible', 'moderated', 'rejected']
],
'request_date' => ['type' => self::UINT, 'default' => \XF::$time]
];
$structure->relations = [
'User' => [
'entity' => 'XF:User',
'type' => self::TO_ONE,
'conditions' => 'user_id',
'primary' => true
]
];
return $structure;
}
protected function _postSave()
{
if( $this->isInsert() && $this->request_state == 'moderated' ){
$this->inQueue();
} else if( $this->isUpdate() && $this->isChanged('request_state') ){
if( $this->request_state === 'moderated' ){
$this->inQueue();
} else {
$this->removeQueue();
}
}
}
protected function _postDelete()
{
if( $this->request_state === 'moderated' ){
$this->removeQueue();
}
}
protected function inQueue()
{
$queue = $this->em()->find('XF:ApprovalQueue', ['club_request', $this->request_id ] );
if( !$queue )
{
$newQueue = $this->em()->create('XF:ApprovalQueue');
$newQueue->content_type = 'club_request';
$newQueue->content_id = $this->request_id;
$newQueue->save();
}
}
protected function removeQueue()
{
$queue = $this->em()->find('XF:ApprovalQueue', ['club_request', $this->request_id ] );
if( $queue )
$queue->delete();
}
}

32
Pub/Controller/Club.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
namespace RomhackPlaza\Master\Pub\Controller;
use XF\Mvc\ParameterBag;
use XF\Pub\Controller\AbstractController;
class Club extends AbstractController
{
public function actionSubmit(ParameterBag $params)
{
$this->assertRegistrationRequired();
return $this->view('RomhackPlaza\Master:Club\Request', 'club_request_form');
}
public function actionSave(ParameterBag $params)
{
$this->assertRegistrationRequired();
$this->assertPostOnly();
$entity = $this->em()->create('RomhackPlaza\Master:ClubRequest');
$entity->user_id = \XF::visitor()->user_id;
$entity->title = $this->filter('title','str');
$entity->description = $this->filter('description','str');
$entity->request_state = 'moderated';
$entity->save();
return $this->redirect($this->buildLink('clubs'), "Your club creation request has been submitted and is awaiting approval by a staff member.");
}
}

View File

@@ -1,36 +0,0 @@
<?php
namespace RomhackPlaza\Master\Pub\Controller;
use XF\Mvc\Controller;
use XF\Mvc\Reply\AbstractReply;
class Webhook extends Controller
{
public function actionUpdateUserEntryCount(): AbstractReply
{
$this->assertPostOnly();
$token = $this->filter('_token', 'str');
$secret = \XF::options()->rhpz_webhook_secret ?? '';
if( !$secret || !hash_equals($secret, $token) ){
return $this->error('Unauthorized', 401);
}
$userId = $this->filter('user_id', 'uint');
$count = $this->filter('count', 'uint');
$user = \XF::em()->find('XF:User', $userId);
if( !$user ){
return $this->error('User not found', 404);
}
$user->rhpz_entry_count = $count;
$user->save();
$trophyService = \XF::service('XF:Trophy\Notify', $user);
$trophyService->checkAndAwardTrophies();
return $this->apiSuccess(['count' => $count]);
}
}

View File

@@ -6,6 +6,7 @@ use XF\AddOn\AbstractSetup;
use XF\AddOn\StepRunnerInstallTrait; use XF\AddOn\StepRunnerInstallTrait;
use XF\AddOn\StepRunnerUninstallTrait; use XF\AddOn\StepRunnerUninstallTrait;
use XF\AddOn\StepRunnerUpgradeTrait; use XF\AddOn\StepRunnerUpgradeTrait;
use XF\Db\Schema\Create;
class Setup extends AbstractSetup class Setup extends AbstractSetup
{ {
@@ -23,10 +24,32 @@ class Setup extends AbstractSetup
}); });
} }
/**
* Create club request table.
* @return void
*/
public function installStep2(): void
{
$this->schemaManager()->createTable('xf_club_request', function(Create $table){
$table->addColumn('request_id', 'int')->autoIncrement();
$table->addColumn('user_id', 'int');
$table->addColumn('title', 'varchar', 100);
$table->addColumn('description', 'text');
$table->addColumn('request_state', 'enum')->values(['visible','moderated','rejected'])->setDefault('moderated');
$table->addColumn('request_date','int');
$table->addKey('request_state');
});
}
public function uninstallStep1(): void public function uninstallStep1(): void
{ {
$this->schemaManager()->alterTable('xf_user', function($table) { $this->schemaManager()->alterTable('xf_user', function($table) {
$table->dropColumns(['rhpz_entry_count']); $table->dropColumns(['rhpz_entry_count']);
}); });
} }
public function uninstallStep2(): void
{
$this->schemaManager()->dropTable('xf_club_request');
}
} }

18
XF/Entity/User.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace RomhackPlaza\Master\XF\Entity;
use XF\Mvc\Entity\Structure;
use XF\Mvc\Entity\Entity;
class User extends XFCP_User
{
public static function getStructure(Structure $structure): Structure
{
$structure = parent::getStructure($structure);
$structure->columns['rhpz_entry_count'] = [ 'type' => self::UINT, 'default' => 0 ];
return $structure;
}
}

View File

@@ -6,7 +6,7 @@
"hash": "bddec05ee1acb9cb82ed72155bdd7817" "hash": "bddec05ee1acb9cb82ed72155bdd7817"
}, },
"contact_us.json": { "contact_us.json": {
"hash": "2a0528c2bc4338d4541074f90790c127" "hash": "05d205aee6ac1db9d9ad0f68bdd4f7c2"
}, },
"database.json": { "database.json": {
"hash": "7b42b608fad8ab23417a8cc3fcd331c2" "hash": "7b42b608fad8ab23417a8cc3fcd331c2"
@@ -42,7 +42,7 @@
"hash": "73fab3932646c350da9a40102f650d9d" "hash": "73fab3932646c350da9a40102f650d9d"
}, },
"submissions_queue.json": { "submissions_queue.json": {
"hash": "f603ca2b1de0c4aaf60fadcec9ea85a7" "hash": "84060a775af4419d44c8dc2c083ef447"
}, },
"tools.json": { "tools.json": {
"hash": "0221bb27d36511c5dd1feaf697626778" "hash": "0221bb27d36511c5dd1feaf697626778"

View File

@@ -3,7 +3,7 @@
"display_order": 3, "display_order": 3,
"navigation_type_id": "basic", "navigation_type_id": "basic",
"type_config": { "type_config": {
"link": "{$xf.options.homePageUrl}/pages/contact-us", "link": "{{ link('misc/contact') }}",
"display_condition": "", "display_condition": "",
"extra_attributes": { "extra_attributes": {
"icon": "at-sign" "icon": "at-sign"

View File

@@ -3,7 +3,7 @@
"display_order": 3, "display_order": 3,
"navigation_type_id": "basic", "navigation_type_id": "basic",
"type_config": { "type_config": {
"link": "{$xf.options.homePageUrl}/submissions-queue", "link": "{$xf.options.homePageUrl}/queue",
"display_condition": "", "display_condition": "",
"extra_attributes": { "extra_attributes": {
"icon": "gavel" "icon": "gavel"

View File

@@ -1,7 +1,31 @@
{ {
"romhackplaza-canEditMyEntries.json": {
"hash": "4fa023f096147e72d0ca94e5ce231228"
},
"romhackplaza-canEditOthersEntries.json": {
"hash": "c2e1c6213b7266fa56ead62676784a26"
},
"romhackplaza-canModerateEntries.json": {
"hash": "dfee0d9b78d1833c648d9c5047c29a33"
},
"romhackplaza-canSeeHiddenEntries.json": {
"hash": "3a71377fae8f064eafaef3ac0f8bed68"
},
"romhackplaza-canSeeLockedEntries.json": {
"hash": "f0907b5c0da0c465195a19babd671343"
},
"romhackplaza-canSeeOthersDrafts.json": {
"hash": "fbd94dac811e001e8923ed28da460367"
},
"romhackplaza-canSeeRejectedEntries.json": {
"hash": "5c015bf4b7012720a4f7bcfdb8eb9521"
},
"romhackplaza-canSubmitEntry.json": { "romhackplaza-canSubmitEntry.json": {
"hash": "6eeb397b6596b6774af70dbbf5454106" "hash": "6eeb397b6596b6774af70dbbf5454106"
}, },
"romhackplaza-canSubmitEntryInPublished.json": {
"hash": "39acd4f2cc864663e5978b18cb390a5c"
},
"romhackplaza-canSubmitTempFile.json": { "romhackplaza-canSubmitTempFile.json": {
"hash": "d514bba0211dc91897efce276c499131" "hash": "d514bba0211dc91897efce276c499131"
}, },

View File

@@ -101,12 +101,84 @@
"version_string": "1.0.0", "version_string": "1.0.0",
"hash": "15bbb9d0bbf25e8d2978de1168c749dc" "hash": "15bbb9d0bbf25e8d2978de1168c749dc"
}, },
"option.rhpz_club_node_id.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "e73496f262c162a1a35bd9e990b36825"
},
"option_explain.rhpz_club_node_id.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"option_group.romhackplaza.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "4b206b2374c877bad80e7cd2303936be"
},
"option_group_description.romhackplaza.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"permission.romhackplaza_canEditMyEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "1a932031ffdf7a07800d30b2d898fc34"
},
"permission.romhackplaza_canEditOthersEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "83d885098bc54e2afa37b3045c8048f3"
},
"permission.romhackplaza_canModerateEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "7ab831a3557b53a4a63ac279cd33fc36"
},
"permission.romhackplaza_canSeeHiddenEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "20fbb37e0be574bb4060c16c1caf6d50"
},
"permission.romhackplaza_canSeeLockedEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "4738ddb90744d6caf4e46335eeac511a"
},
"permission.romhackplaza_canSeeOthersDrafts.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "4c2c7800c562085f51a3b486dfb8e5bb"
},
"permission.romhackplaza_canSeeRejectedEntries.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "827c586329fad5466cccf547f5011bea"
},
"permission.romhackplaza_canSubmitEntry.txt": { "permission.romhackplaza_canSubmitEntry.txt": {
"global_cache": false, "global_cache": false,
"version_id": 1000000, "version_id": 1000000,
"version_string": "1.0.0", "version_string": "1.0.0",
"hash": "d62432dfaf4d83315ed838ce10794fa1" "hash": "d62432dfaf4d83315ed838ce10794fa1"
}, },
"permission.romhackplaza_canSubmitEntryInPublished.txt": {
"global_cache": false,
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "40e2c757fc3f0056a40aa98dec7d2d25"
},
"permission.romhackplaza_canSubmitTempFile.txt": { "permission.romhackplaza_canSubmitTempFile.txt": {
"global_cache": false, "global_cache": false,
"version_id": 1000000, "version_id": 1000000,

View File

@@ -3,5 +3,20 @@
"version_id": 1000000, "version_id": 1000000,
"version_string": "1.0.0", "version_string": "1.0.0",
"hash": "19cd05c4ab254dbad0abfd0c6b8c3456" "hash": "19cd05c4ab254dbad0abfd0c6b8c3456"
},
"public/approval_item_club_request.html": {
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "39492e4fb48e7aa1622a6bb4371a36f4"
},
"public/club_request_form.html": {
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "5e1c397d93134aaa7164301d5a3553ce"
},
"public/report_content_romhackplaza_entry.html": {
"version_id": 1000000,
"version_string": "1.0.0",
"hash": "d6c5c25a9af81a7da2bd8e2b9f74229e"
} }
} }