45
Api/Controller/EntryController.php
Normal file
45
Api/Controller/EntryController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace RomhackPlaza\Master\Api\Controller;
|
||||
|
||||
use RomhackPlaza\Master\Entity\EntryFeaturedRequest;
|
||||
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]);
|
||||
}
|
||||
|
||||
public function actionPostFeatured(): AbstractReply
|
||||
{
|
||||
|
||||
$entryId = $this->filter('entry_id', 'uint');
|
||||
$userId = $this->filter('user_id', 'uint');
|
||||
$entryTitle = $this->filter('entry_title', 'string');
|
||||
|
||||
/** @var EntryFeaturedRequest $entryFeaturedRequest */
|
||||
$entryFeaturedRequest = $this->em()->create('RomhackPlaza\Master:EntryFeaturedRequest');
|
||||
$entryFeaturedRequest->entry_id = $entryId;
|
||||
$entryFeaturedRequest->user_id = $userId;
|
||||
$entryFeaturedRequest->entry_title = $entryTitle;
|
||||
$entryFeaturedRequest->featured_request_state = 'moderated';
|
||||
$entryFeaturedRequest->save();
|
||||
|
||||
return $this->apiSuccess(['success' => true]);
|
||||
|
||||
}
|
||||
}
|
||||
79
Api/Controller/MigrateController.php
Normal file
79
Api/Controller/MigrateController.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Api\Controller;
|
||||
|
||||
use RomhackPlaza\Master\Helper\Migration;
|
||||
use XF\Api\Controller\AbstractController;
|
||||
use XF\Api\ControllerPlugin\UserPlugin;
|
||||
use XF\Entity\User;
|
||||
use XF\Entity\UserAuth;
|
||||
use XF\Mvc\ParameterBag;
|
||||
use XF\Mvc\Reply\AbstractReply;
|
||||
use XF\Repository\UserRepository;
|
||||
|
||||
class MigrateController extends AbstractController
|
||||
{
|
||||
protected function preDispatchController($action, ParameterBag $params)
|
||||
{
|
||||
$rhpz_enable_migration = \XF::options()->rhpz_enable_migration;
|
||||
if( !$rhpz_enable_migration ){
|
||||
$this->error("Migration not enabled");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function actionPostUser(): AbstractReply
|
||||
{
|
||||
$input = $this->filter([
|
||||
'username' => 'str',
|
||||
'email' => 'str',
|
||||
'profile[about]' => 'str',
|
||||
'profile[website]' => 'str',
|
||||
'register_date' => 'uint',
|
||||
'user_group_id' => 'uint',
|
||||
'xf_user_id' => 'uint',
|
||||
'avatar_path' => 'str',
|
||||
'banner_path' => 'str',
|
||||
'source_real_password' => 'str',
|
||||
'wp_password' => 'str',
|
||||
'xf_scheme_class' => 'str',
|
||||
'xf_password_data' => 'str',
|
||||
]);
|
||||
|
||||
$this->assertAdminPermission('user');
|
||||
$this->assertRequiredApiInput(['username','email','user_group_id']);
|
||||
|
||||
/** @var UserRepository $userRepository */
|
||||
$userRepository = \XF::repository(UserRepository::class);
|
||||
$user = $userRepository->setupBaseUser(null);
|
||||
|
||||
$userPlugin = $this->plugin(UserPlugin::class);
|
||||
$userPlugin->userSaveProcessAdmin($user)->run();
|
||||
|
||||
/** @var UserAuth $authUser */
|
||||
$authUser = $user->getExistingRelation('Auth');
|
||||
if( $input['source_real_password'] === 'wp' ){
|
||||
$authUser->scheme_class = 'RomhackPlaza\Master:WordPress';
|
||||
$authUser->data = ['hash' => $input['wp_password']];
|
||||
$authUser->save();
|
||||
} elseif( $input['source_real_password'] === 'xf' ){
|
||||
$authUser->scheme_class = $input['xf_scheme_class'];
|
||||
$authUser->data = @unserialize($input['xf_password_data']);
|
||||
$authUser->save();
|
||||
}
|
||||
|
||||
if( $input['avatar_path'] !== "" ){
|
||||
Migration::setAvatarFromPath($input['avatar_path'], $user);
|
||||
}
|
||||
if( $input['banner_path'] !== "" ){
|
||||
Migration::setBannerFromPath($input['banner_path'], $user);
|
||||
}
|
||||
if( $input['register_date'] != 0 ){
|
||||
$user->register_date = $input['register_date'];
|
||||
$user->save();
|
||||
}
|
||||
|
||||
return $this->apiSuccess(['success' => true, 'user_id' => $user->user_id, 'password_set' => true ]);
|
||||
|
||||
}
|
||||
}
|
||||
33
Api/Controller/ThreadController.php
Normal file
33
Api/Controller/ThreadController.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Api\Controller;
|
||||
|
||||
use XF\Api\Controller\AbstractController;
|
||||
use XF\ControllerPlugin\UndeletePlugin;
|
||||
use XF\Entity\Thread;
|
||||
use XF\Mvc\ParameterBag;
|
||||
|
||||
class ThreadController extends AbstractController
|
||||
{
|
||||
public function actionPost(ParameterBag $params)
|
||||
{
|
||||
$this->assertApiScope('thread:write');
|
||||
|
||||
/** @var Thread $thread */
|
||||
$thread = $this->assertRecordExists('XF:Thread', $params->thread_id, ['FirstPost'] );
|
||||
if( $thread->discussion_state !== 'deleted' )
|
||||
return $this->error("This thread is not deleted.", 'not_deleted' );
|
||||
|
||||
if(!$thread->canUndelete($error)){
|
||||
return $this->noPermission($error);
|
||||
}
|
||||
|
||||
$thread->discussion_state = 'visible';
|
||||
$thread->save();
|
||||
|
||||
return $this->apiSuccess([
|
||||
'thread' => $thread->toApiResult()
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
76
ApprovalQueue/Club.php
Normal file
76
ApprovalQueue/Club.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\ApprovalQueue;
|
||||
|
||||
use XF\ApprovalQueue\AbstractHandler;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
|
||||
class Club 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\Club $club)
|
||||
{
|
||||
$club->club_state = 'visible';
|
||||
$club->save();
|
||||
|
||||
$node = \XF::em()->create('XF:Node');
|
||||
$node->node_type_id = 'Forum';
|
||||
$node->title = $club->title;
|
||||
$node->description = $club->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();
|
||||
|
||||
$club->node_id = $node->node_id;
|
||||
$club->save();
|
||||
|
||||
$user = $club->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(\RomhackPlaza\Master\Entity\Club::MOD_PERMISSIONS);
|
||||
|
||||
\XF::app()->jobManager()->enqueueUnique('permissionRebuild', 'XF:PermissionRebuild');
|
||||
}
|
||||
}
|
||||
|
||||
public function actionDelete(\RomhackPlaza\Master\Entity\Club $club)
|
||||
{
|
||||
$club->club_state = 'rejected';
|
||||
$club->save();
|
||||
}
|
||||
|
||||
public function getTemplateName()
|
||||
{
|
||||
return 'public:approval_item_club_request';
|
||||
}
|
||||
}
|
||||
61
ApprovalQueue/EntryFeaturedRequest.php
Normal file
61
ApprovalQueue/EntryFeaturedRequest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\ApprovalQueue;
|
||||
|
||||
use RomhackPlaza\Master\Helper\Laravel;
|
||||
use XF\ApprovalQueue\AbstractHandler;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
|
||||
class EntryFeaturedRequest extends AbstractHandler
|
||||
{
|
||||
protected function canViewContent(Entity $content, &$error = null)
|
||||
{
|
||||
return $this->canActionContent($content, $error );
|
||||
}
|
||||
|
||||
protected function canActionContent(Entity $content, &$error = null)
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'canModerateEntries');
|
||||
}
|
||||
|
||||
public function getEntityWith()
|
||||
{
|
||||
return ['User'];
|
||||
}
|
||||
|
||||
public function actionApprove(\RomhackPlaza\Master\Entity\EntryFeaturedRequest $entryFeaturedRequest)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
$db = Laravel::db();
|
||||
|
||||
$db->update('entries', [
|
||||
'featured' => 1,
|
||||
'featured_at' => date('Y-m-d H:i:s', \XF::$time),
|
||||
], 'id = ?',
|
||||
[$entryFeaturedRequest->entry_id]
|
||||
);
|
||||
|
||||
$entryFeaturedRequest->featured_request_state = 'visible';
|
||||
$entryFeaturedRequest->save();
|
||||
|
||||
|
||||
} catch ( \Exception $e ) {
|
||||
\XF::logException($e, messagePrefix: "EntryFeaturedRequest error: " );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function actionDelete(\RomhackPlaza\Master\Entity\EntryFeaturedRequest $entryFeaturedRequest)
|
||||
{
|
||||
$entryFeaturedRequest->featured_request_state = 'rejected';
|
||||
$entryFeaturedRequest->save();
|
||||
}
|
||||
|
||||
public function getTemplateName()
|
||||
{
|
||||
return 'public:approval_item_entry_featured_request';
|
||||
}
|
||||
|
||||
}
|
||||
91
Authentication/WordPress.php
Normal file
91
Authentication/WordPress.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Authentication;
|
||||
|
||||
use XF\Authentication\AbstractAuth;
|
||||
|
||||
class WordPress extends AbstractAuth
|
||||
{
|
||||
|
||||
private const ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
public function generate($password)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function authenticate($userId, $password)
|
||||
{
|
||||
if (!is_string($password) || $password === '' || empty($this->data) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->verifyPassword($password, $this->data['hash']);
|
||||
|
||||
}
|
||||
|
||||
private function verifyPassword($password, $storedHash): bool
|
||||
{
|
||||
if( str_starts_with($storedHash, '$wp') ){
|
||||
$passwordToVerify = base64_encode( hash_hmac( 'sha384', $password, 'wp-sha384', true ) );
|
||||
return password_verify( $passwordToVerify, substr($storedHash, 3) );
|
||||
}
|
||||
|
||||
if (str_starts_with($storedHash, '$2y$') || str_starts_with($storedHash, '$2a$') || str_starts_with($storedHash, '$2b$')) {
|
||||
return password_verify($password, $storedHash);
|
||||
}
|
||||
|
||||
if (strlen($storedHash) === 34 && (str_starts_with($storedHash, '$P$') || str_starts_with($storedHash, '$H$'))) {
|
||||
return $this->verifyPhpass($password, $storedHash);
|
||||
}
|
||||
|
||||
if (strlen($storedHash) <= 32) {
|
||||
return hash_equals($storedHash, md5($password));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function verifyPhpass(string $password, string $storedHash): bool
|
||||
{
|
||||
$itoa64 = self::ITOA64;
|
||||
$countLog2 = strpos($itoa64, $storedHash[3]);
|
||||
if ($countLog2 < 7 || $countLog2 > 30) return false;
|
||||
|
||||
$count = 1 << $countLog2;
|
||||
$salt = substr($storedHash, 4, 8);
|
||||
if (strlen($salt) !== 8) return false;
|
||||
|
||||
$hash = md5($salt . $password, true);
|
||||
do {
|
||||
$hash = md5($hash . $password, true);
|
||||
} while (--$count);
|
||||
|
||||
$output = substr($storedHash, 0, 12) . self::encode64($hash, $itoa64);
|
||||
return hash_equals($storedHash, $output);
|
||||
}
|
||||
|
||||
private function encode64(string $input, string $itoa64): string
|
||||
{
|
||||
$output = '';
|
||||
$i = 0;
|
||||
$count = strlen($input);
|
||||
do {
|
||||
$value = ord($input[$i++]);
|
||||
$output .= $itoa64[$value & 0x3f];
|
||||
if ($i < $count) $value |= ord($input[$i]) << 8;
|
||||
$output .= $itoa64[($value >> 6) & 0x3f];
|
||||
if ($i++ >= $count) break;
|
||||
if ($i < $count) $value |= ord($input[$i]) << 16;
|
||||
$output .= $itoa64[($value >> 12) & 0x3f];
|
||||
if ($i++ >= $count) break;
|
||||
$output .= $itoa64[($value >> 18) & 0x3f];
|
||||
} while ($i < $count);
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getAuthenticationName()
|
||||
{
|
||||
return 'RomhackPlaza\Master:WordPress';
|
||||
}
|
||||
}
|
||||
120
Entity/Club.php
Normal file
120
Entity/Club.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Entity;
|
||||
|
||||
use XF\Entity\ApprovalQueue;
|
||||
use XF\Entity\Forum;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Mvc\Entity\Structure;
|
||||
|
||||
/**
|
||||
* @property-read int club_id
|
||||
* @property int node_id
|
||||
* @property int user_id
|
||||
* @property string title
|
||||
* @property string description
|
||||
* @property string club_state
|
||||
* @property int club_date
|
||||
* @property int banner_date
|
||||
* @property ?Forum Forum
|
||||
*/
|
||||
class Club extends Entity
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public const array MOD_PERMISSIONS = [
|
||||
'forum' => [
|
||||
'editAnyPost' => 'content_allow',
|
||||
'deleteAnyPost' => 'content_allow',
|
||||
'deleteAnyThread' => 'content_allow',
|
||||
'inlineMod' => 'content_allow',
|
||||
'lockUnlockThread' => 'content_allow',
|
||||
'stickUnstickThread' => 'content_allow'
|
||||
]
|
||||
];
|
||||
|
||||
public static function getStructure(Structure $structure): Structure
|
||||
{
|
||||
$structure->table = 'xf_club';
|
||||
$structure->shortName = 'RomhackPlaza\Master:Club';
|
||||
$structure->primaryKey = 'club_id';
|
||||
$structure->columns = [
|
||||
'club_id' => ['type' => self::UINT, 'autoIncrement' => true],
|
||||
'node_id' => ['type' => self::UINT, 'default' => 0],
|
||||
'user_id' => ['type' => self::UINT, 'required' => true],
|
||||
'title' => ['type' => self::STR, 'maxLength' => 100, 'required' => true],
|
||||
'description' => ['type' => self::STR, 'required' => true],
|
||||
'club_state' => ['type' => self::STR, 'default' => 'moderated',
|
||||
'allowedValues' => ['visible', 'moderated', 'rejected']
|
||||
],
|
||||
'club_creation_date' => ['type' => self::UINT, 'default' => \XF::$time],
|
||||
'banner_date' => ['type' => self::UINT, 'default' => 0],
|
||||
];
|
||||
$structure->relations = [
|
||||
'User' => [
|
||||
'entity' => 'XF:User',
|
||||
'type' => self::TO_ONE,
|
||||
'conditions' => 'user_id',
|
||||
'primary' => true
|
||||
],
|
||||
'Forum' => [
|
||||
'entity' => 'XF:Forum',
|
||||
'type' => self::TO_ONE,
|
||||
'conditions' => 'node_id',
|
||||
'primary' => true
|
||||
]
|
||||
];
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
public function getBannerUrl(): ?string
|
||||
{
|
||||
if( !$this->banner_date )
|
||||
return null;
|
||||
|
||||
return \XF::app()->applyExternalDataUrl("club_banners/{$this->club_id}.jpg?{$this->banner_date}");
|
||||
}
|
||||
|
||||
protected function _postSave()
|
||||
{
|
||||
if( $this->isInsert() && $this->club_state == 'moderated' ){
|
||||
$this->inQueue();
|
||||
} else if( $this->isUpdate() && $this->isChanged('club_state') ){
|
||||
if( $this->club_state === 'moderated' ){
|
||||
$this->inQueue();
|
||||
} else {
|
||||
$this->removeQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _postDelete()
|
||||
{
|
||||
if( $this->club_state === 'moderated' ){
|
||||
$this->removeQueue();
|
||||
}
|
||||
}
|
||||
|
||||
protected function inQueue()
|
||||
{
|
||||
$queue = $this->em()->find('XF:ApprovalQueue', ['club', $this->club_id ] );
|
||||
if( !$queue )
|
||||
{
|
||||
/** @var ApprovalQueue $newQueue */
|
||||
$newQueue = $this->em()->create('XF:ApprovalQueue');
|
||||
$newQueue->content_type = 'club';
|
||||
$newQueue->content_id = $this->club_id;
|
||||
$newQueue->save();
|
||||
}
|
||||
}
|
||||
|
||||
protected function removeQueue()
|
||||
{
|
||||
$queue = $this->em()->find('XF:ApprovalQueue', ['club', $this->club_id ] );
|
||||
if( $queue )
|
||||
$queue->delete();
|
||||
}
|
||||
}
|
||||
28
Entity/Entry.php
Normal file
28
Entity/Entry.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Entity;
|
||||
|
||||
use Override;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Mvc\Entity\Structure;
|
||||
|
||||
class Entry extends Entity
|
||||
{
|
||||
#[Override]
|
||||
public static function getStructure(Structure $structure)
|
||||
{
|
||||
$structure->shortName = 'RomhackPlaza\Master:Entry';
|
||||
$structure->table = 'xf_romhackplaza_entry'; // Unused.
|
||||
$structure->primaryKey = 'id';
|
||||
|
||||
$structure->columns = [
|
||||
'id' => ['type' => self::UINT],
|
||||
'user_id' => ['type' => self::UINT, 'required' => true],
|
||||
'title' => ['type' => self::STR, 'required' => true],
|
||||
'slug' => ['type' => self::STR, 'required' => true],
|
||||
'type' => ['type' => self::STR, 'required' => true],
|
||||
];
|
||||
|
||||
return $structure;
|
||||
}
|
||||
}
|
||||
91
Entity/EntryFeaturedRequest.php
Normal file
91
Entity/EntryFeaturedRequest.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Entity;
|
||||
|
||||
use XF\Entity\ApprovalQueue;
|
||||
use XF\Entity\User;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Mvc\Entity\Structure;
|
||||
|
||||
/**
|
||||
* @property-read int featured_request_id
|
||||
* @property int $entry_id
|
||||
* @property int $user_id
|
||||
* @property string $entry_title
|
||||
* @property string featured_request_state
|
||||
* @property int featured_request_date
|
||||
* @property-read ?User User
|
||||
*/
|
||||
class EntryFeaturedRequest extends Entity
|
||||
{
|
||||
#[\Override]
|
||||
public static function getStructure(Structure $structure)
|
||||
{
|
||||
$structure->shortName = 'RomhackPlaza\Master:EntryFeaturedRequest';
|
||||
$structure->table = 'xf_romhackplaza_entry_featured_request';
|
||||
$structure->primaryKey = 'featured_request_id';
|
||||
|
||||
$structure->columns = [
|
||||
'featured_request_id' => ['type' => self::UINT, 'autoIncrement' => true],
|
||||
'entry_id' => ['type' => self::UINT, 'required' => true],
|
||||
'user_id' => ['type' => self::UINT],
|
||||
'entry_title' => ['type' => self::STR, 'maxLength' => 255],
|
||||
'featured_request_state' => ['type' => self::STR, 'default' => 'moderated',
|
||||
'allowedValues' => ['visible', 'moderated', 'rejected']
|
||||
],
|
||||
'featured_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->featured_request_state === 'moderated' ) {
|
||||
$this->inQueue();
|
||||
} else if( $this->isUpdate() && $this->isChanged('featured_request_state') ) {
|
||||
if( $this->featured_request_state === 'moderated' ) {
|
||||
$this->inQueue();
|
||||
} else {
|
||||
$this->removeQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _postDelete()
|
||||
{
|
||||
if( $this->featured_request_state === 'moderated' ) {
|
||||
$this->removeQueue();
|
||||
}
|
||||
}
|
||||
|
||||
protected function inQueue()
|
||||
{
|
||||
$queue = $this->em()->find('XF:ApprovalQueue', ['rhpz_entry_featurerequest', $this->featured_request_id ] );
|
||||
if( !$queue )
|
||||
{
|
||||
/** @var ApprovalQueue $newQueue */
|
||||
$newQueue = $this->em()->create('XF:ApprovalQueue');
|
||||
$newQueue->content_type = 'rhpz_entry_featurerequest';
|
||||
$newQueue->content_id = $this->featured_request_id;
|
||||
$newQueue->save();
|
||||
}
|
||||
}
|
||||
|
||||
protected function removeQueue()
|
||||
{
|
||||
$queue = $this->em()->find('XF:ApprovalQueue', ['rhpz_entry_featurerequest', $this->featured_request_id ] );
|
||||
if( $queue )
|
||||
$queue->delete();
|
||||
}
|
||||
}
|
||||
26
Entity/News.php
Normal file
26
Entity/News.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Entity;
|
||||
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Mvc\Entity\Structure;
|
||||
|
||||
class News extends Entity
|
||||
{
|
||||
#[Override]
|
||||
public static function getStructure(Structure $structure)
|
||||
{
|
||||
$structure->shortName = 'RomhackPlaza\Master:News';
|
||||
$structure->table = 'xf_romhackplaza_news'; // Unused.
|
||||
$structure->primaryKey = 'id';
|
||||
|
||||
$structure->columns = [
|
||||
'id' => ['type' => self::UINT],
|
||||
'user_id' => ['type' => self::UINT, 'required' => true],
|
||||
'title' => ['type' => self::STR, 'required' => true],
|
||||
'slug' => ['type' => self::STR, 'required' => true],
|
||||
];
|
||||
|
||||
return $structure;
|
||||
}
|
||||
}
|
||||
25
Helper/Helpers.php
Normal file
25
Helper/Helpers.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Helper;
|
||||
|
||||
use XF\Mvc\Entity\Entity;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
public static function getContentTitle( Entity $content, string $contentType )
|
||||
{
|
||||
return match ($contentType) {
|
||||
'thread' => $content->title ?? '',
|
||||
'post' => $content->Thread?->title ?? '',
|
||||
'user' => $content->username ?? '',
|
||||
'profile_post' => \XF\Util\Str::substr($content->content ?? '', 0, 50),
|
||||
'profile_post_comment' => \XF\Util\Str::substr($content->content ?? '', 0, 50),
|
||||
|
||||
// Custom
|
||||
'club' => $content->title ?? '',
|
||||
'rhpz_entry_featurerequest' => $content->entry_title ?? '',
|
||||
|
||||
default => $content->title ?? $content->username ?? $content->content ?? "#{$content->getEntityId()}",
|
||||
};
|
||||
}
|
||||
}
|
||||
24
Helper/Laravel.php
Normal file
24
Helper/Laravel.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Helper;
|
||||
|
||||
use XF\Container;
|
||||
|
||||
class Laravel
|
||||
{
|
||||
public static function db(): ?\XF\Db\Mysqli\Adapter {
|
||||
|
||||
$container = \XF::app()->container();
|
||||
if( !isset( $container['laravelDb'] ) ){
|
||||
$container['laravelDb'] = function(Container $c){
|
||||
$config = \XF::config('sitedb');
|
||||
if( !$config )
|
||||
return null;
|
||||
|
||||
return new \XF\Db\Mysqli\Adapter($config, true);
|
||||
};
|
||||
}
|
||||
|
||||
return $container['laravelDb'];
|
||||
}
|
||||
}
|
||||
86
Helper/Migration.php
Normal file
86
Helper/Migration.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Helper;
|
||||
|
||||
use XF\Container;
|
||||
use XF\Entity\User;
|
||||
use XF\Entity\UserAuth;
|
||||
use XF\Service\User\AvatarService;
|
||||
use XF\Service\User\ProfileBannerService;
|
||||
|
||||
class Migration
|
||||
{
|
||||
public static function oldXfDb(): ?\XF\Db\Mysqli\Adapter {
|
||||
|
||||
$container = \XF::app()->container();
|
||||
if( !isset( $container['oldXfDb'] ) ){
|
||||
$container['oldXfDb'] = function(Container $c){
|
||||
$config = \XF::config('oldxfdb');
|
||||
if( !$config )
|
||||
return null;
|
||||
|
||||
return new \XF\Db\Mysqli\Adapter($config, true);
|
||||
};
|
||||
}
|
||||
|
||||
return $container['oldXfDb'];
|
||||
}
|
||||
|
||||
public static function uniqueUsername(string $username): string
|
||||
{
|
||||
$u = $username;
|
||||
$i = 1;
|
||||
while(\XF::em()->findOne('XF:User', ['username' => $u])){
|
||||
$u = $username . '_' . $i++;
|
||||
}
|
||||
|
||||
return $u;
|
||||
}
|
||||
|
||||
public static function copyUserPassword(int $xf_user_id, User $user): bool
|
||||
{
|
||||
$oldDb = self::oldXfDb();
|
||||
if( !$oldDb ){
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = $oldDb->fetchRow(
|
||||
'SELECT scheme_class, data FROM xf_user_authenticate WHERE user_id = ?',
|
||||
[$xf_user_id]
|
||||
);
|
||||
if( !$row ){
|
||||
return false;
|
||||
}
|
||||
|
||||
$user->Auth->scheme_class = $row['scheme_class'];
|
||||
$user->Auth->data = $row['data'];
|
||||
return $user->Auth->save();
|
||||
}
|
||||
|
||||
public static function setAvatarFromPath(string $avatar_path, User $user): bool
|
||||
{
|
||||
if(!is_readable($avatar_path))
|
||||
return false;
|
||||
|
||||
$avatarService = \XF::service(AvatarService::class, $user);
|
||||
|
||||
if (!$avatarService->setImage($avatar_path))
|
||||
return false;
|
||||
|
||||
return $avatarService->updateAvatar();
|
||||
}
|
||||
|
||||
public static function setBannerFromPath(mixed $banner_path, User $user)
|
||||
{
|
||||
if( !is_readable($banner_path) )
|
||||
return false;
|
||||
|
||||
$bannerService = \XF::service(ProfileBannerService::class, $user);
|
||||
if( !$bannerService->setImage($banner_path) )
|
||||
return false;
|
||||
|
||||
return $bannerService->updateBanner();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
97
Import/Importer/RHPZForums.php
Normal file
97
Import/Importer/RHPZForums.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Import\Importer;
|
||||
|
||||
use RomhackPlaza\Master\Helper\Laravel;
|
||||
use XF\Import\StepState;
|
||||
use XFI\Import\Importer\XenForo23;
|
||||
|
||||
class RHPZForums extends XenForo23
|
||||
{
|
||||
public static function getListInfo(): array
|
||||
{
|
||||
return [
|
||||
'target' => 'XenForo',
|
||||
'source' => 'RHPZ Forums (XF)'
|
||||
];
|
||||
}
|
||||
|
||||
public function stepUserGroups(StepState $state)
|
||||
{
|
||||
$map = $this->getMigrationSetting('old_xf_group_to_xf_group');
|
||||
foreach( $map as $oldId => $newId ){
|
||||
$this->log('user_group', $oldId, $newId);
|
||||
$state->imported++;
|
||||
}
|
||||
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepUserFields(StepState $state)
|
||||
{
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepUsers(StepState $state, array $stepConfig, $maxTime)
|
||||
{
|
||||
$rows = $this->sourceDb->fetchAll("SELECT user_id FROM xf_user ORDER BY user_id" );
|
||||
|
||||
foreach ( $rows as $row ) {
|
||||
$oldId = $row['user_id'];
|
||||
$newId = $this->getNewUserId($oldId);
|
||||
|
||||
if( $newId ){
|
||||
$this->log('user', $oldId, $newId);
|
||||
$state->imported++;
|
||||
}
|
||||
}
|
||||
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepAvatars(StepState $state, array $stepConfig, $maxTime)
|
||||
{
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepNodes(StepState $state)
|
||||
{
|
||||
$map = $this->getMigrationSetting('old_xf_node_to_new_xf_node');
|
||||
foreach( $map as $oldId => $newId ){
|
||||
$this->log('node', $oldId, $newId);
|
||||
$state->imported++;
|
||||
}
|
||||
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepNodePermissions(StepState $state)
|
||||
{
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
public function stepModerators(StepState $state)
|
||||
{
|
||||
return $state->complete();
|
||||
}
|
||||
|
||||
private function getMigrationSetting(string $key): mixed
|
||||
{
|
||||
$db = Laravel::db();
|
||||
if( !$db )
|
||||
return null;
|
||||
|
||||
$row = $db->fetchOne("SELECT value FROM migration_settings WHERE `key` = ? ", [$key]);
|
||||
return $row ? json_decode( $row, true ) : [];
|
||||
}
|
||||
|
||||
private function getNewUserId(int $oldId): ?int
|
||||
{
|
||||
$db = Laravel::db();
|
||||
if( !$db )
|
||||
return null;
|
||||
|
||||
$row = $db->fetchOne("SELECT user_id FROM migration_user_plan WHERE xf_user_id = ?", [$oldId]);
|
||||
return $row ? (int) $row : null;
|
||||
}
|
||||
}
|
||||
50
Listener.php
50
Listener.php
@@ -2,8 +2,24 @@
|
||||
|
||||
namespace RomhackPlaza\Master;
|
||||
|
||||
use XF\Container;
|
||||
use XF\Import\Manager;
|
||||
use XF\Mvc\Renderer\AbstractRenderer;
|
||||
use XF\Mvc\Reply\AbstractReply;
|
||||
use XF\SubContainer\Import;
|
||||
|
||||
class Listener
|
||||
{
|
||||
|
||||
public static function importImporterClasses(Import $container, Container $parentContainer, array &$importers)
|
||||
{
|
||||
if( \XF::isAddOnActive('XFI') )
|
||||
$importers = array_merge(
|
||||
$importers,
|
||||
Manager::getImporterShortNamesForType('RomhackPlaza/Master')
|
||||
);
|
||||
}
|
||||
|
||||
public static function criteriaUser(string $rule, array $data, \XF\Entity\User $user, bool &$returnValue ){
|
||||
switch( $rule ){
|
||||
case 'rhpz_entry_count':
|
||||
@@ -20,4 +36,38 @@ class Listener
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Credits to Kirby for the guest part.
|
||||
* @link https://xenforo.com/community/resources/style-variation-default.9504/
|
||||
*
|
||||
* @param \XF\App $app
|
||||
* @param array $params
|
||||
* @param AbstractReply $reply
|
||||
* @param AbstractRenderer $renderer
|
||||
*
|
||||
* @return void
|
||||
* @throws \XF\PrintableException
|
||||
*/
|
||||
public static function checkStyleVariation( \XF\App $app, array &$params, AbstractReply $reply, AbstractRenderer $renderer )
|
||||
{
|
||||
$user = \XF::visitor();
|
||||
if( $user->user_id !== 0 ){ // Logged in.
|
||||
if( $user->style_variation !== 'default' && $user->style_variation !== 'alternate' ){
|
||||
$user->style_variation = 'default';
|
||||
$user->save();
|
||||
}
|
||||
} else {
|
||||
$cookie = $app->request()->getCookie('style_variation');
|
||||
if( $cookie !== 'default' && $cookie !== 'alternate' ){
|
||||
$app->response()->setCookie('style_variation', 'default', 86400 * 365);
|
||||
}
|
||||
if( $user->style_variation === '' ){
|
||||
$style = $app->templater()->getStyle();
|
||||
if( $style->isVariationsEnabled() ){
|
||||
$user->setAsSaved('style_variation', 'default');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
182
Pub/Controller/Club.php
Normal file
182
Pub/Controller/Club.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Pub\Controller;
|
||||
|
||||
use PhpParser\Node\Param;
|
||||
use RomhackPlaza\Master\Service\Club\CreatorService;
|
||||
use RomhackPlaza\Master\Service\Club\DeleterService;
|
||||
use RomhackPlaza\Master\Service\Club\EditorService;
|
||||
use RomhackPlaza\Master\Service\Club\ModeratorService;
|
||||
use XF\Mvc\ParameterBag;
|
||||
use XF\Pub\Controller\AbstractController;
|
||||
use XF\Util\File;
|
||||
|
||||
class Club extends AbstractController
|
||||
{
|
||||
|
||||
public function actionIndex(){
|
||||
$clubsForum = \XF::options()->rhpz_club_node_id;
|
||||
return $this->redirect('categories/.' . $clubsForum );
|
||||
}
|
||||
|
||||
public function actionSubmit(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
|
||||
return $this->view('RomhackPlaza\Master:Club\Request', 'club_request_form');
|
||||
}
|
||||
|
||||
public function actionEdit(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
|
||||
if( !$params->club_id )
|
||||
$this->notFound("Club not found");
|
||||
|
||||
/** @var \RomhackPlaza\Master\Entity\Club $club */
|
||||
$club = $this->assertRecordExists( 'RomhackPlaza\Master:Club', $params->club_id );
|
||||
if( $club->user_id !== \XF::visitor()->user_id && !\XF::visitor()->hasAdminPermission('node') ){
|
||||
$this->noPermission();
|
||||
}
|
||||
|
||||
$mods = [];
|
||||
$modsCount = 0;
|
||||
|
||||
if( $club->node_id ){
|
||||
$mods = $this->finder('XF:ModeratorContent')
|
||||
->where('content_type', 'node')
|
||||
->where('content_id', $club->node_id)
|
||||
->with('User')
|
||||
->fetch();
|
||||
foreach( $mods as $m ){
|
||||
if( $m->user_id !== $club->user_id ){
|
||||
$modsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->view('RomhackPlaza\Master:Club\Edit', 'club_edit_form', [ 'club' => $club, 'moderators' => $mods, 'subModCount' => $modsCount ] );
|
||||
}
|
||||
|
||||
public function actionSave(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
$this->assertPostOnly();
|
||||
|
||||
$isEdit = (bool) $params->club_id;
|
||||
if( $isEdit ){
|
||||
$club = $this->assertRecordExists('RomhackPlaza\Master:Club', $params->club_id );
|
||||
if( $club->user_id !== \XF::visitor()->user_id && !\XF::visitor()->hasAdminPermission('node') ){
|
||||
$this->noPermission();
|
||||
}
|
||||
|
||||
/** @var EditorService $editor */
|
||||
$editor = $this->service('RomhackPlaza\Master:Club\Editor', $club);
|
||||
$editor->setContent($this->filter('title','str'), $this->filter('description','str'));
|
||||
$editor->setBannerUpload($this->request->getFile('upload_banner', false, false) );
|
||||
|
||||
if( !$editor->validate($errors) ){
|
||||
return $this->error($errors);
|
||||
}
|
||||
|
||||
$editor->save();
|
||||
|
||||
return $this->redirect( $this->buildLink('clubs'), "Changes saved successfully" );
|
||||
|
||||
} else {
|
||||
|
||||
/** @var CreatorService $creator */
|
||||
$creator = $this->service('RomhackPlaza\Master:Club\Creator', \XF::visitor());
|
||||
$creator->setContent($this->filter('title','str'), $this->filter('description','str'));
|
||||
$creator->setBannerUpload($this->request->getFile('upload_banner', false, false));
|
||||
|
||||
if( !$creator->validate($errors) ){
|
||||
return $this->error($errors);
|
||||
}
|
||||
$creator->save();
|
||||
return $this->redirect( $this->buildLink('clubs'), "Your club creation request has been submitted and is awaiting approval by a staff member." );
|
||||
}
|
||||
}
|
||||
|
||||
public function actionDelete(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
|
||||
/** @var \RomhackPlaza\Master\Entity\Club $club */
|
||||
$club = $this->assertRecordExists('RomhackPlaza\Master:Club', $params->club_id);
|
||||
if( $club->user_id !== \XF::visitor()->user_id && !\XF::visitor()->hasAdminPermission('node') ){
|
||||
$this->noPermission();
|
||||
}
|
||||
|
||||
if( $this->isPost() ){
|
||||
/** @var DeleterService $deleter */
|
||||
$deleter = $this->service('RomhackPlaza\Master:Club\Deleter', $club);
|
||||
$deleter->delete();
|
||||
|
||||
return $this->redirect( $this->buildLink('clubs'), "Club deleted successfully." );
|
||||
}
|
||||
|
||||
return $this->view('RomhackPlaza\Master:Club\Delete', 'club_delete_confirm', [ 'club' => $club ] );
|
||||
}
|
||||
|
||||
public function actionAddModerator(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
$this->assertPostOnly();
|
||||
|
||||
/** @var \RomhackPlaza\Master\Entity\Club $club */
|
||||
$club = $this->assertRecordExists('RomhackPlaza\Master:Club', $params->club_id);
|
||||
if( $club->user_id !== \XF::visitor()->user_id && !\XF::visitor()->hasAdminPermission('node') ){
|
||||
return $this->noPermission();
|
||||
}
|
||||
|
||||
$username = $this->filter('username','str');
|
||||
$user = $this->em()->findOne('XF:User', ['username' => $username]);
|
||||
|
||||
if( !$user ){
|
||||
return $this->error("This user doesn't exist");
|
||||
}
|
||||
|
||||
/** @var ModeratorService $modManage */
|
||||
$modManage = \XF::app()->service('RomhackPlaza\Master:Club\Moderator', $club, $user );
|
||||
$error = "";
|
||||
$modManage->addModerator( $error );
|
||||
|
||||
if( $error && $error !== "" ){
|
||||
return $this->error($error);
|
||||
}
|
||||
|
||||
return $this->redirect( $this->buildLink('clubs/edit', $club), "Moderator added successfully." );
|
||||
}
|
||||
|
||||
public function actionRemoveModerator(ParameterBag $params)
|
||||
{
|
||||
$this->assertRegistrationRequired();
|
||||
$this->assertPostOnly();
|
||||
|
||||
/** @var \RomhackPlaza\Master\Entity\Club $club */
|
||||
$club = $this->assertRecordExists('RomhackPlaza\Master:Club', $params->club_id);
|
||||
if( $club->user_id !== \XF::visitor()->user_id && !\XF::visitor()->hasAdminPermission('node') ){
|
||||
$this->noPermission();
|
||||
}
|
||||
|
||||
$userId = $this->filter('user_id','uint');
|
||||
$user = $this->em()->findOne('XF:User', ['user_id' => $userId]);
|
||||
|
||||
if( !$user ){
|
||||
$this->error("This user doesn't exist");
|
||||
}
|
||||
|
||||
/** @var ModeratorService $modManage */
|
||||
$modManage = \XF::app()->service('RomhackPlaza\Master:Club\Moderator', $club, $user );
|
||||
$error = "";
|
||||
$modManage->deleteModerator( $error );
|
||||
|
||||
if( $error && $error !== "" ){
|
||||
return $this->error($error);
|
||||
}
|
||||
|
||||
return $this->redirect( $this->buildLink('clubs/edit', $club), "Moderator deleted successfully." );
|
||||
}
|
||||
|
||||
}
|
||||
50
Pub/Controller/Entry.php
Normal file
50
Pub/Controller/Entry.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Pub\Controller;
|
||||
|
||||
use XF\Mvc\ParameterBag;
|
||||
use XF\Mvc\Reply\AbstractReply;
|
||||
use XF\Pub\Controller\AbstractController;
|
||||
|
||||
class Entry extends AbstractController {
|
||||
|
||||
public function actionIndex(ParameterBag $params): AbstractReply
|
||||
{
|
||||
$entryId = $params->id;
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
if( !$laravelDb )
|
||||
return $this->notFound();
|
||||
|
||||
$entry = $laravelDb->fetchRow("SELECT id, slug, type FROM entries WHERE id = ?", $entryId);
|
||||
if( !$entry )
|
||||
return $this->notFound();
|
||||
|
||||
return $this->redirect(\XF::options()->homePageUrl . '/' . $entry['type'] . '/' . $entry['slug']);
|
||||
}
|
||||
|
||||
public function actionReport(ParameterBag $params): AbstractReply
|
||||
{
|
||||
|
||||
$this->assertRegistrationRequired();
|
||||
|
||||
$entryId = $params->id;
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
if( !$laravelDb )
|
||||
return $this->notFound();
|
||||
|
||||
$entry = $laravelDb->fetchRow("SELECT id, complete_title as title, slug, type, user_id, description FROM entries WHERE id = ?", $entryId);
|
||||
if( !$entry )
|
||||
return $this->notFound();
|
||||
|
||||
$entity = $this->em()->instantiateEntity('RomhackPlaza\Master:Entry', $entry);
|
||||
$entity->setReadOnly(true);
|
||||
|
||||
$reportPlugin = $this->plugin('XF:Report');
|
||||
return $reportPlugin->actionReport(
|
||||
'romhackplaza_entry', $entity,
|
||||
$this->buildLink('romhackplaza_entry/report', $entity),
|
||||
\XF::options()->homePageUrl . '/entry/report_redirect?id=' . $entity->id
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
50
Pub/Controller/News.php
Normal file
50
Pub/Controller/News.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Pub\Controller;
|
||||
|
||||
use XF\Mvc\ParameterBag;
|
||||
use XF\Mvc\Reply\AbstractReply;
|
||||
use XF\Pub\Controller\AbstractController;
|
||||
|
||||
class News extends AbstractController {
|
||||
|
||||
public function actionIndex(ParameterBag $params): AbstractReply
|
||||
{
|
||||
$entryId = $params->id;
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
if( !$laravelDb )
|
||||
return $this->notFound();
|
||||
|
||||
$entry = $laravelDb->fetchRow("SELECT id, slugFROM news WHERE id = ?", $entryId);
|
||||
if( !$entry )
|
||||
return $this->notFound();
|
||||
|
||||
return $this->redirect(\XF::options()->homePageUrl . '/news/' . $entry['slug']);
|
||||
}
|
||||
|
||||
public function actionReport(ParameterBag $params): AbstractReply
|
||||
{
|
||||
|
||||
$this->assertRegistrationRequired();
|
||||
|
||||
$entryId = $params->id;
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
if( !$laravelDb )
|
||||
return $this->notFound();
|
||||
|
||||
$entry = $laravelDb->fetchRow("SELECT id, title, slug, user_id, description FROM news WHERE id = ?", $entryId);
|
||||
if( !$entry )
|
||||
return $this->notFound();
|
||||
|
||||
$entity = $this->em()->instantiateEntity('RomhackPlaza\Master:News', $entry);
|
||||
$entity->setReadOnly(true);
|
||||
|
||||
$reportPlugin = $this->plugin('XF:Report');
|
||||
return $reportPlugin->actionReport(
|
||||
'romhackplaza_news', $entity,
|
||||
$this->buildLink('romhackplaza_news/report', $entity),
|
||||
\XF::options()->homePageUrl . '/news/report_redirect?id=' . $entity->id
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
76
Report/Entry.php
Normal file
76
Report/Entry.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Report;
|
||||
|
||||
use XF\Entity\Report;
|
||||
use Override;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Report\AbstractHandler;
|
||||
|
||||
class Entry extends AbstractHandler
|
||||
{
|
||||
|
||||
#[Override]
|
||||
protected function canViewContent(Report $report)
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'view');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected function canActionContent(Report $report)
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'canEditOthersEntries');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setupReportEntityContent(Report $report, Entity $content)
|
||||
{
|
||||
$report->content_user_id = $content['user_id'];
|
||||
$report->content_info = [
|
||||
'id' => $content['id'],
|
||||
'title' => $content['title'],
|
||||
'slug' => $content['slug'],
|
||||
'type' => $content['type'],
|
||||
'user_id' => $content['user_id'],
|
||||
'description' => $content['description'] ?? "",
|
||||
];
|
||||
}
|
||||
|
||||
public function getContent($id)
|
||||
{
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
|
||||
if( $laravelDb ){
|
||||
$entry = $laravelDb->fetchRow("SELECT id, complete_title as title, slug, type, user_id, description FROM entries WHERE id = ?", $id);
|
||||
$entity = \XF::em()->instantiateEntity('RomhackPlaza\Master:Entry', $entry);
|
||||
$entity->setReadOnly(true);
|
||||
return $entity;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentTitle(Report $report)
|
||||
{
|
||||
return $report->content_info['title'] ?? 'Unknown';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentLink(Report $report)
|
||||
{
|
||||
return \XF::options()->homePageUrl . '/' . $report->content_info['type'] . '/' . $report->content_info['slug'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentMessage(Report $report)
|
||||
{
|
||||
return $report->content_info['description'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getTemplateName()
|
||||
{
|
||||
return "public:report_content_romhackplaza_entry";
|
||||
}
|
||||
}
|
||||
75
Report/News.php
Normal file
75
Report/News.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Report;
|
||||
|
||||
use XF\Entity\Report;
|
||||
use Override;
|
||||
use XF\Mvc\Entity\Entity;
|
||||
use XF\Report\AbstractHandler;
|
||||
|
||||
class News extends AbstractHandler
|
||||
{
|
||||
|
||||
#[Override]
|
||||
protected function canViewContent(Report $report)
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'view');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected function canActionContent(Report $report)
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'canEditOthersEntries');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setupReportEntityContent(Report $report, Entity $content)
|
||||
{
|
||||
$report->content_user_id = $content['user_id'];
|
||||
$report->content_info = [
|
||||
'id' => $content['id'],
|
||||
'title' => $content['title'],
|
||||
'slug' => $content['slug'],
|
||||
'user_id' => $content['user_id'],
|
||||
'description' => $content['description'] ?? "",
|
||||
];
|
||||
}
|
||||
|
||||
public function getContent($id)
|
||||
{
|
||||
$laravelDb = \RomhackPlaza\Master\Helper\Laravel::db();
|
||||
|
||||
if( $laravelDb ){
|
||||
$entry = $laravelDb->fetchRow("SELECT id, title, slug, user_id, description FROM news WHERE id = ?", $id);
|
||||
$entity = \XF::em()->instantiateEntity('RomhackPlaza\Master:News', $entry);
|
||||
$entity->setReadOnly(true);
|
||||
return $entity;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentTitle(Report $report)
|
||||
{
|
||||
return $report->content_info['title'] ?? 'Unknown';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentLink(Report $report)
|
||||
{
|
||||
return \XF::options()->homePageUrl . '/news/' . $report->content_info['slug'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getContentMessage(Report $report)
|
||||
{
|
||||
return $report->content_info['description'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getTemplateName()
|
||||
{
|
||||
return "public:report_content_romhackplaza_news";
|
||||
}
|
||||
}
|
||||
64
Service/Club/ApproverService.php
Normal file
64
Service/Club/ApproverService.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Club;
|
||||
|
||||
use RomhackPlaza\Master\Entity\Club;
|
||||
use XF\App;
|
||||
use XF\Entity\Forum;
|
||||
use XF\Entity\Node;
|
||||
use XF\Service\AbstractService;
|
||||
use XF\Util\File;
|
||||
|
||||
class ApproverService extends AbstractService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Club
|
||||
*/
|
||||
protected $club;
|
||||
|
||||
public function __construct(App $app, Club $club)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
$this->club = $club;
|
||||
}
|
||||
|
||||
public function approve(): bool
|
||||
{
|
||||
if( $this->club->club_state !== 'moderated' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->club->club_state = 'visible';
|
||||
$this->club->save();
|
||||
|
||||
/** @var Node $node */
|
||||
$node = $this->em()->create('XF:Node');
|
||||
|
||||
$node->node_type_id = 'Forum';
|
||||
$node->title = $this->club->title;
|
||||
$node->description = $this->club->description;
|
||||
$node->parent_node_id = \XF::options()->rhpz_club_node_id ?? 0;
|
||||
$node->display_order = 1;
|
||||
$node->save();
|
||||
|
||||
/** @var Forum $forum */
|
||||
$forum = $this->em()->create('XF:Forum');
|
||||
$forum->node_id = $node->node_id;
|
||||
$forum->allow_posting = true;
|
||||
$forum->save();
|
||||
|
||||
$this->club->node_id = $node->node_id;
|
||||
$this->club->save();
|
||||
|
||||
$user = $this->club->User;
|
||||
if( $user ){
|
||||
/** @var ModeratorService $modManage */
|
||||
$modManage = \XF::app()->service('RomhackPlaza\Master:Club\Moderator', $this->club, $user );
|
||||
$modManage->addModerator( $error );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
99
Service/Club/CreatorService.php
Normal file
99
Service/Club/CreatorService.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Club;
|
||||
|
||||
use RomhackPlaza\Master\Entity\Club;
|
||||
use RomhackPlaza\Master\XF\Entity\Forum;
|
||||
use XF\App;
|
||||
use XF\Entity\Node;
|
||||
use XF\Entity\User;
|
||||
use XF\Http\Upload;
|
||||
use XF\Service\AbstractService;
|
||||
use XF\Service\ValidateAndSavableTrait;
|
||||
use XF\Util\File;
|
||||
|
||||
class CreatorService extends AbstractService
|
||||
{
|
||||
use ValidateAndSavableTrait;
|
||||
|
||||
/**
|
||||
* @var Club
|
||||
*/
|
||||
protected $club;
|
||||
|
||||
/**
|
||||
* @var Upload
|
||||
*/
|
||||
protected $bannerUpload;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
public function __construct(App $app, User $creator)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->club = $this->em()->create('RomhackPlaza\Master:Club');
|
||||
$this->setUser($creator);
|
||||
$this->setupDefaults();
|
||||
}
|
||||
|
||||
protected function setupDefaults()
|
||||
{
|
||||
$this->club->club_state = 'moderated';
|
||||
}
|
||||
|
||||
public function getClub()
|
||||
{
|
||||
return $this->club;
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->club->user_id = $this->user->user_id;
|
||||
}
|
||||
|
||||
public function setContent(string $title, string $description )
|
||||
{
|
||||
$this->club->title = $title;
|
||||
$this->club->description = $description;
|
||||
}
|
||||
|
||||
public function setBannerUpload(?Upload $upload = null)
|
||||
{
|
||||
if ($upload) {
|
||||
$upload->requireImage();
|
||||
if($upload->isValid()){
|
||||
$this->bannerUpload = $upload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _validate()
|
||||
{
|
||||
$this->club->preSave();
|
||||
return $this->club->getErrors();
|
||||
}
|
||||
|
||||
protected function _save()
|
||||
{
|
||||
$this->club->save();
|
||||
|
||||
if( $this->bannerUpload ){
|
||||
$path = 'data://club_banners/' . $this->club->club_id . '.jpg';
|
||||
if( File::copyFileToAbstractedPath($this->bannerUpload->getFileWrapper()->getFilePath(), $path) ){
|
||||
$this->club->banner_date = \XF::$time;
|
||||
$this->club->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->club;
|
||||
}
|
||||
}
|
||||
40
Service/Club/DeleterService.php
Normal file
40
Service/Club/DeleterService.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Club;
|
||||
|
||||
use RomhackPlaza\Master\Entity\Club;
|
||||
use XF\App;
|
||||
use XF\Entity\Forum;
|
||||
use XF\Entity\Node;
|
||||
use XF\Http\Upload;
|
||||
use XF\Service\AbstractService;
|
||||
use XF\Service\ValidateAndSavableTrait;
|
||||
use XF\Util\File;
|
||||
|
||||
class DeleterService extends AbstractService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Club
|
||||
*/
|
||||
protected $club;
|
||||
|
||||
public function __construct(App $app, Club $club)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
$this->club = $club;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if( $this->club->Forum && $this->club->Forum->Node ){
|
||||
$this->club->Forum->Node->delete();
|
||||
}
|
||||
|
||||
$path = 'data://club_banners/' . $this->club->club_id . '.jpg';
|
||||
File::deleteFromAbstractedPath($path);
|
||||
|
||||
$this->club->delete();
|
||||
}
|
||||
}
|
||||
73
Service/Club/EditorService.php
Normal file
73
Service/Club/EditorService.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Club;
|
||||
|
||||
use RomhackPlaza\Master\Entity\Club;
|
||||
use XF\App;
|
||||
use XF\Entity\Forum;
|
||||
use XF\Entity\Node;
|
||||
use XF\Http\Upload;
|
||||
use XF\Service\AbstractService;
|
||||
use XF\Service\ValidateAndSavableTrait;
|
||||
use XF\Util\File;
|
||||
|
||||
class EditorService extends AbstractService
|
||||
{
|
||||
use ValidateAndSavableTrait;
|
||||
|
||||
/**
|
||||
* @var Club
|
||||
*/
|
||||
protected $club;
|
||||
|
||||
public function __construct(App $app, Club $club)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
$this->club = $club;
|
||||
}
|
||||
|
||||
public function setContent(string $title, string $description)
|
||||
{
|
||||
$this->club->title = $title;
|
||||
$this->club->description = $description;
|
||||
}
|
||||
|
||||
public function setBannerUpload(?Upload $upload = null)
|
||||
{
|
||||
if( $upload ){
|
||||
$upload->requireImage();
|
||||
if( $upload->isValid() ){
|
||||
$path = 'data://club_banners/' . $this->club->club_id . '.jpg';
|
||||
if(File::copyFileToAbstractedPath($upload->getFileWrapper()->getFilePath(), $path)){
|
||||
$this->club->banner_date = \XF::$time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function syncForumNode()
|
||||
{
|
||||
if( $this->club->Forum && $this->club->Forum->Node )
|
||||
{
|
||||
$node = $this->club->Forum->Node;
|
||||
$node->title = $this->club->title;
|
||||
$node->description = $this->club->description;
|
||||
$node->save();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _validate()
|
||||
{
|
||||
$this->club->preSave();
|
||||
return $this->club->getErrors();
|
||||
}
|
||||
|
||||
protected function _save()
|
||||
{
|
||||
$this->club->save();
|
||||
$this->syncForumNode();
|
||||
|
||||
return $this->club;
|
||||
}
|
||||
}
|
||||
106
Service/Club/ModeratorService.php
Normal file
106
Service/Club/ModeratorService.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Club;
|
||||
|
||||
use RomhackPlaza\Master\Entity\Club;
|
||||
use XF\App;
|
||||
use XF\Entity\User;
|
||||
use XF\Service\AbstractService;
|
||||
|
||||
class ModeratorService extends AbstractService
|
||||
{
|
||||
|
||||
public const int MAX_MODS = 5;
|
||||
|
||||
/**
|
||||
* @var Club
|
||||
*/
|
||||
protected $club;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
public function __construct(App $app, Club $club, User $moderator)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->club = $club;
|
||||
$this->user = $moderator;
|
||||
}
|
||||
|
||||
protected function countMods( int $nodeId, int $excludeUserId = 0 )
|
||||
{
|
||||
return $this->finder('XF:ModeratorContent')
|
||||
->where('content_type', 'node')
|
||||
->where('content_id', $nodeId)
|
||||
->where('user_id', '!=', $excludeUserId)
|
||||
->total();
|
||||
}
|
||||
|
||||
public function addModerator( string &$error ): bool
|
||||
{
|
||||
if( !$this->club->Forum || !$this->club->Forum->Node ) {
|
||||
$error = "No node linked to this club.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if( $this->countMods( $this->club->node_id, $this->club->user_id ) > self::MAX_MODS ) {
|
||||
$error = "The limit of 5 moderators has been reached.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$existingMod = $this->em()->findOne('XF:ModeratorContent', [
|
||||
'content_type' => 'node',
|
||||
'content_id' => $this->club->node_id,
|
||||
'user_id' => $this->user->user_id
|
||||
]);
|
||||
if( $existingMod ){
|
||||
$error = "This user is already a moderator.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$modContent = $this->em()->create('XF:ModeratorContent');
|
||||
$modContent->content_type = 'node';
|
||||
$modContent->content_id = $this->club->node_id;
|
||||
$modContent->user_id = $this->user->user_id;
|
||||
$modContent->save();
|
||||
|
||||
$permissionUpdater = \XF::app()->service('XF:UpdatePermissions');
|
||||
$permissionUpdater->setContent('node', $this->club->node_id);
|
||||
$permissionUpdater->setUser($this->user);
|
||||
$permissionUpdater->updatePermissions(Club::MOD_PERMISSIONS);
|
||||
|
||||
\XF::app()->jobManager()->enqueueUnique('permissionRebuild', 'XF:PermissionRebuild');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteModerator( string &$error ): bool
|
||||
{
|
||||
if( !$this->club->Forum || !$this->club->Forum->Node ) {
|
||||
$error = "No node linked to this club.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if( $this->user->user_id === $this->club->user_id ){
|
||||
$error = "You cannot delete yourself.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$mod = $this->em()->findOne('XF:ModeratorContent', [
|
||||
'content_type' => 'node',
|
||||
'content_id' => $this->club->node_id,
|
||||
'user_id' => $this->user->user_id
|
||||
]);
|
||||
|
||||
if( $mod ){
|
||||
$mod->delete();
|
||||
|
||||
\XF::db()->delete('xf_permission_entry_content', 'content_type = ? AND content_id = ? AND user_id = ?', ['node', $this->club->node_id, $this->user->user_id]);
|
||||
|
||||
\XF::app()->jobManager()->enqueueUnique('permissionRebuild', 'XF:PermissionRebuild');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
30
Service/DeleteAccount/CodeService.php
Normal file
30
Service/DeleteAccount/CodeService.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\DeleteAccount;
|
||||
|
||||
use XF\Entity\User;
|
||||
use XF\Service\AbstractService;
|
||||
|
||||
class CodeService extends AbstractService
|
||||
{
|
||||
|
||||
private string $masterKey;
|
||||
|
||||
protected function setup()
|
||||
{
|
||||
$this->masterKey = \XF::options()->rhpz_delete_account_master_key;
|
||||
}
|
||||
|
||||
public function generateDeleteAllDataKey( User $user )
|
||||
{
|
||||
$dataString = "delete_data_{$user->user_id}";
|
||||
return hash_hmac('md5', $dataString, $this->masterKey );
|
||||
}
|
||||
|
||||
public function generateDeleteAccountKey( User $user )
|
||||
{
|
||||
$dataString = "delete_account_{$user->user_id}";
|
||||
return hash_hmac('md5', $dataString, $this->masterKey );
|
||||
}
|
||||
|
||||
}
|
||||
44
Service/Discord/BotService.php
Normal file
44
Service/Discord/BotService.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\Service\Discord;
|
||||
|
||||
use XF\Service\AbstractService;
|
||||
|
||||
class BotService extends AbstractService
|
||||
{
|
||||
protected string $dbPath;
|
||||
protected ?\PDO $pdo = null;
|
||||
|
||||
protected function setup()
|
||||
{
|
||||
$this->dbPath = \XF::config('discord_db_path');
|
||||
}
|
||||
|
||||
protected function getDb(): \PDO
|
||||
{
|
||||
if (!$this->pdo) {
|
||||
$this->pdo = new \PDO("sqlite:" . $this->dbPath);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$this->pdo->exec('PRAGMA journal_mode=WAL;');
|
||||
$this->pdo->exec('PRAGMA busy_timeout=5000;');
|
||||
}
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
public function createAction( string $action, array $data ): bool
|
||||
{
|
||||
try {
|
||||
$db = $this->getDb();
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO actions (action, data) VALUES (:action, :data)");
|
||||
return $stmt->execute([
|
||||
':action' => $action,
|
||||
':data' => json_encode($data)
|
||||
]);
|
||||
|
||||
} catch (\PDOException $e) {
|
||||
\XF::logException($e, messagePrefix: "BotService error: ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Setup.php
53
Setup.php
@@ -6,6 +6,7 @@ use XF\AddOn\AbstractSetup;
|
||||
use XF\AddOn\StepRunnerInstallTrait;
|
||||
use XF\AddOn\StepRunnerUninstallTrait;
|
||||
use XF\AddOn\StepRunnerUpgradeTrait;
|
||||
use XF\Db\Schema\Create;
|
||||
|
||||
class Setup extends AbstractSetup
|
||||
{
|
||||
@@ -20,13 +21,63 @@ class Setup extends AbstractSetup
|
||||
{
|
||||
$this->schemaManager()->alterTable('xf_user', function (\XF\Db\Schema\Alter $table) {
|
||||
$table->addColumn('rhpz_entry_count', 'int')->setDefault(0);
|
||||
$table->addColumn('nsfw_content', 'int')->setDefault(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create club table.
|
||||
* @return void
|
||||
*/
|
||||
public function installStep2(): void
|
||||
{
|
||||
$this->schemaManager()->createTable('xf_club', function(Create $table){
|
||||
$table->addColumn('club_id', 'int')->autoIncrement();
|
||||
$table->addColumn( 'node_id', 'int' );
|
||||
$table->addColumn('user_id', 'int');
|
||||
$table->addColumn('title', 'varchar', 100);
|
||||
$table->addColumn('description', 'text');
|
||||
$table->addColumn('club_state', 'enum')->values(['visible','moderated','rejected'])->setDefault('moderated');
|
||||
$table->addColumn('club_creation_date','int');
|
||||
$table->addColumn('banner_date', 'int')->setDefault(0);
|
||||
$table->addPrimaryKey('club_id');
|
||||
$table->addKey('club_state');
|
||||
});
|
||||
}
|
||||
|
||||
public function installStep3(): void
|
||||
{
|
||||
$this->schemaManager()->createTable('xf_romhackplaza_entry_featured_request', function(Create $table){
|
||||
$table->addColumn('featured_request_id', 'int')->autoIncrement();
|
||||
$table->addColumn('entry_id', 'int');
|
||||
$table->addColumn('user_id', 'int');
|
||||
$table->addColumn('entry_title', 'varchar', 255);
|
||||
$table->addColumn('featured_request_state', 'enum')->values(['visible','moderated','rejected'])->setDefault('moderated');
|
||||
$table->addColumn('featured_request_date', 'int');
|
||||
});
|
||||
}
|
||||
|
||||
public function upgrade1010070Step1(): void
|
||||
{
|
||||
$this->schemaManager()->alterTable('xf_user', function (\XF\Db\Schema\Alter $table) {
|
||||
$table->addColumn('nsfw_content', 'int')->setDefault(0);
|
||||
});
|
||||
}
|
||||
|
||||
public function uninstallStep1(): void
|
||||
{
|
||||
$this->schemaManager()->alterTable('xf_user', function($table) {
|
||||
$table->dropColumns(['rhpz_entry_count']);
|
||||
$table->dropColumns(['rhpz_entry_count', 'nsfw_content']);
|
||||
});
|
||||
}
|
||||
|
||||
public function uninstallStep2(): void
|
||||
{
|
||||
$this->schemaManager()->dropTable('xf_club');
|
||||
}
|
||||
|
||||
public function uninstallStep3(): void
|
||||
{
|
||||
$this->schemaManager()->dropTable('xf_romhackplaza_entry_featured_request');
|
||||
}
|
||||
}
|
||||
25
XF/Admin/Controller/UserController.php
Normal file
25
XF/Admin/Controller/UserController.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Admin\Controller;
|
||||
|
||||
use RomhackPlaza\Master\Service\DeleteAccount\CodeService;
|
||||
use XF\Mvc\ParameterBag;
|
||||
|
||||
class UserController extends XFCP_UserController
|
||||
{
|
||||
public function actionDeleteAccountCodes(ParameterBag $params)
|
||||
{
|
||||
$user = $this->assertUserExists($params->user_id);
|
||||
|
||||
/** @var CodeService $service */
|
||||
$service = \XF::service('RomhackPlaza\Master:DeleteAccount\CodeService');
|
||||
|
||||
$viewParams = [
|
||||
'user' => $user,
|
||||
'deleteAllDataCode' => $service->generateDeleteAllDataKey( $user ),
|
||||
'deleteAccountCode' => $service->generateDeleteAccountKey( $user ),
|
||||
];
|
||||
|
||||
return $this->view('XF:User\DeleteAccountCodes', 'user_delete_account_codes', $viewParams);
|
||||
}
|
||||
}
|
||||
41
XF/Entity/ApprovalQueue.php
Normal file
41
XF/Entity/ApprovalQueue.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Entity;
|
||||
|
||||
use RomhackPlaza\Master\Helper\Helpers;
|
||||
|
||||
class ApprovalQueue extends XFCP_ApprovalQueue
|
||||
{
|
||||
protected function _postSave()
|
||||
{
|
||||
parent::_postSave();
|
||||
|
||||
if( $this->isInsert() ){
|
||||
|
||||
$contentId = $this->content_id;
|
||||
$contentType = $this->content_type;
|
||||
|
||||
\XF::runLater(function () use ($contentId, $contentType) {
|
||||
|
||||
$entity = \XF::app()->getContentTypeFieldValue($contentType, 'entity');
|
||||
if( !$entity ){
|
||||
return;
|
||||
}
|
||||
|
||||
$content = \XF::em()->find($entity, $contentId);
|
||||
|
||||
$user = $contentType === 'user' ? $content : $content->User;
|
||||
|
||||
$service = \XF::service('RomhackPlaza\Master:Discord\BotService');
|
||||
$service->createAction( 'approval_queue', [
|
||||
'content_title' => Helpers::getContentTitle( $content, $contentType ),
|
||||
'approval_item_url' => \XF::app()->router('public')->buildLink('canonical:approval-queue' ),
|
||||
'approval_username' => $user?->username ?? '',
|
||||
'approval_user_url' => $user?->user_id ? \XF::app()->router('public')->buildLink('canonical:members', $user ) : '',
|
||||
'content_type' => $contentType,
|
||||
]);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
22
XF/Entity/Forum.php
Normal file
22
XF/Entity/Forum.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Entity;
|
||||
|
||||
use XF\Mvc\Entity\Structure;
|
||||
|
||||
class Forum extends XFCP_Forum
|
||||
{
|
||||
public static function getStructure(Structure $structure)
|
||||
{
|
||||
$structure = parent::getStructure($structure);
|
||||
|
||||
$structure->relations['Club'] = [
|
||||
'entity' => 'RomhackPlaza\Master:Club',
|
||||
'type' => self::TO_ONE,
|
||||
'conditions' => 'node_id',
|
||||
'primary' => false
|
||||
];
|
||||
|
||||
return $structure;
|
||||
}
|
||||
}
|
||||
24
XF/Entity/User.php
Normal file
24
XF/Entity/User.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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 ];
|
||||
$structure->columns['nsfw_content'] = [ 'type' => self::BOOL, 'default' => 0 ];
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
public function canCreateEntry()
|
||||
{
|
||||
return \XF::visitor()->hasPermission('romhackplaza', 'canSubmitEntry');
|
||||
}
|
||||
}
|
||||
40
XF/Pub/Controller/AccountController.php
Normal file
40
XF/Pub/Controller/AccountController.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Pub\Controller;
|
||||
|
||||
use RomhackPlaza\Master\Service\DeleteAccount\CodeService;
|
||||
use XF\Entity\User;
|
||||
|
||||
class AccountController extends XFCP_AccountController
|
||||
{
|
||||
public function actionDeleteAccount()
|
||||
{
|
||||
$visitor = \XF::visitor();
|
||||
|
||||
/** @var CodeService $service */
|
||||
$service = \XF::service('RomhackPlaza\Master:DeleteAccount\CodeService');
|
||||
|
||||
$viewParams = [
|
||||
'deleteAllDataCode' => $service->generateDeleteAllDataKey( $visitor ),
|
||||
'deleteAccountCode' => $service->generateDeleteAccountKey( $visitor ),
|
||||
];
|
||||
|
||||
$view = $this->view('XF:Account\DeleteAccount', 'delete_account', $viewParams);
|
||||
return $this->addAccountWrapperParams($view, 'delete_account');
|
||||
}
|
||||
|
||||
protected function preferencesSaveProcess(User $visitor)
|
||||
{
|
||||
$form = parent::preferencesSaveProcess($visitor);
|
||||
|
||||
$input = $this->filter([
|
||||
'user' => [
|
||||
'nsfw_content' => 'bool',
|
||||
]
|
||||
]);
|
||||
|
||||
$form->basicEntitySave($visitor, $input['user'] );
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
13
XF/Pub/Controller/MiscController.php
Normal file
13
XF/Pub/Controller/MiscController.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Pub\Controller;
|
||||
|
||||
use XF\Mvc\ParameterBag;
|
||||
|
||||
class MiscController extends XFCP_MiscController
|
||||
{
|
||||
public function actionPreferencesPopup()
|
||||
{
|
||||
return $this->view('RomhackPlaza\Master:Misc\PreferencesPopup', 'misc_preferences_popup');
|
||||
}
|
||||
}
|
||||
38
XF/Service/Report/CreatorService.php
Normal file
38
XF/Service/Report/CreatorService.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Service\Report;
|
||||
|
||||
use XF\Entity\Report;
|
||||
use XF\Repository\ReportRepository;
|
||||
|
||||
class CreatorService extends XFCP_CreatorService
|
||||
{
|
||||
protected function _save()
|
||||
{
|
||||
/** @var Report $report */
|
||||
$report = parent::_save();
|
||||
|
||||
if( $report ){
|
||||
|
||||
\XF::runLater(function () use ($report){
|
||||
$reportRepo = $this->repository(ReportRepository::class);
|
||||
$handler = $reportRepo->getReportHandler($report->content_type, true);
|
||||
$service = \XF::service('RomhackPlaza\Master:Discord\BotService');
|
||||
|
||||
$service->createAction('report_message', [
|
||||
'content_title' => $handler->getContentTitle( $report ),
|
||||
'report_message' => $report->Comments->last()->message,
|
||||
'report_manage_url' => \XF::app()->router('public')->buildLink('canonical:reports', $report ),
|
||||
'report_username' => $report->User?->username ?? "Unknown user",
|
||||
'report_user_url' => \XF::app()->router('public')->buildLink('canonical:members', $report->User ),
|
||||
'content_type' => $report->content_type,
|
||||
'content_link' => $handler->getContentLink( $report )
|
||||
]);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return $report;
|
||||
}
|
||||
|
||||
}
|
||||
2
_data/activity_summary_definitions.xml
Normal file
2
_data/activity_summary_definitions.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<activity_summary_definitions/>
|
||||
2
_data/admin_navigation.xml
Normal file
2
_data/admin_navigation.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<admin_navigation/>
|
||||
2
_data/admin_permission.xml
Normal file
2
_data/admin_permission.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<admin_permission/>
|
||||
2
_data/advertising_positions.xml
Normal file
2
_data/advertising_positions.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<advertising_positions/>
|
||||
2
_data/api_scopes.xml
Normal file
2
_data/api_scopes.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<api_scopes/>
|
||||
2
_data/bb_code_media_sites.xml
Normal file
2
_data/bb_code_media_sites.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bb_code_media_sites/>
|
||||
2
_data/bb_codes.xml
Normal file
2
_data/bb_codes.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bb_codes/>
|
||||
10
_data/class_extensions.xml
Normal file
10
_data/class_extensions.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<class_extensions>
|
||||
<extension from_class="XF\Admin\Controller\UserController" to_class="RomhackPlaza\Master\XF\Admin\Controller\UserController" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Entity\ApprovalQueue" to_class="RomhackPlaza\Master\XF\Entity\ApprovalQueue" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Entity\Forum" to_class="RomhackPlaza\Master\XF\Entity\Forum" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Entity\User" to_class="RomhackPlaza\Master\XF\Entity\User" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Pub\Controller\AccountController" to_class="RomhackPlaza\Master\XF\Pub\Controller\AccountController" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Pub\Controller\MiscController" to_class="RomhackPlaza\Master\XF\Pub\Controller\MiscController" execute_order="10" active="1"/>
|
||||
<extension from_class="XF\Service\Report\CreatorService" to_class="RomhackPlaza\Master\XF\Service\Report\CreatorService" execute_order="10" active="1"/>
|
||||
</class_extensions>
|
||||
6
_data/code_event_listeners.xml
Normal file
6
_data/code_event_listeners.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<code_event_listeners>
|
||||
<listener event_id="app_pub_render_page" execute_order="10" callback_class="RomhackPlaza\Master\Listener" callback_method="checkStyleVariation" active="1"/>
|
||||
<listener event_id="criteria_user" execute_order="10" callback_class="RomhackPlaza\Master\Listener" callback_method="criteriaUser" active="1"/>
|
||||
<listener event_id="import_importer_classes" execute_order="15" callback_class="RomhackPlaza\Master\Listener" callback_method="importImporterClasses" active="1"/>
|
||||
</code_event_listeners>
|
||||
2
_data/code_events.xml
Normal file
2
_data/code_events.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<code_events/>
|
||||
11
_data/content_type_fields.xml
Normal file
11
_data/content_type_fields.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<content_type_fields>
|
||||
<field content_type="club" field_name="approval_queue_handler_class">RomhackPlaza\Master\ApprovalQueue\Club</field>
|
||||
<field content_type="club" field_name="entity">RomhackPlaza\Master\Entity\Club</field>
|
||||
<field content_type="rhpz_entry_featurerequest" field_name="approval_queue_handler_class">RomhackPlaza\Master\ApprovalQueue\EntryFeaturedRequest</field>
|
||||
<field content_type="rhpz_entry_featurerequest" field_name="entity">RomhackPlaza\Master\Entity\EntryFeaturedRequest</field>
|
||||
<field content_type="romhackplaza_entry" field_name="entity">RomhackPlaza\Master\Entity\Entry</field>
|
||||
<field content_type="romhackplaza_entry" field_name="report_handler_class">RomhackPlaza\Master\Report\Entry</field>
|
||||
<field content_type="romhackplaza_news" field_name="entity">RomhackPlaza\Master\Entity\News</field>
|
||||
<field content_type="romhackplaza_news" field_name="report_handler_class">RomhackPlaza\Master\Report\News</field>
|
||||
</content_type_fields>
|
||||
2
_data/cron.xml
Normal file
2
_data/cron.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<cron/>
|
||||
2
_data/help_pages.xml
Normal file
2
_data/help_pages.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<help_pages/>
|
||||
2
_data/member_stats.xml
Normal file
2
_data/member_stats.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<member_stats/>
|
||||
22
_data/navigation.xml
Normal file
22
_data/navigation.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation>
|
||||
<navigation_entry navigation_id="about" parent_navigation_id="pages" display_order="200" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/pages\/about","display_condition":"","extra_attributes":{"icon":"info"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="clubs" parent_navigation_id="community" display_order="200" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{{ link('clubs') }}","display_condition":"","extra_attributes":{"icon":"balloon"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="community" display_order="300" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"","display_condition":"","extra_attributes":[]}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="contact_us" parent_navigation_id="pages" display_order="300" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{{ link('misc\/contact') }}","display_condition":"","extra_attributes":{"icon":"at-sign"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="database" parent_navigation_id="website" display_order="200" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/database","display_condition":"","extra_attributes":{"icon":"database"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="discord" parent_navigation_id="community" display_order="300" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/discord","display_condition":"","extra_attributes":{"icon":"messages-square"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="drafts" parent_navigation_id="website" display_order="400" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/my-drafts","display_condition":"{$xf.visitor.user_id}","extra_attributes":{"icon":"scissors"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="forum" parent_navigation_id="community" display_order="100" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.boardUrl}","display_condition":"","extra_attributes":{"icon":"message-circle"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="home" parent_navigation_id="website" display_order="100" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}","display_condition":"","extra_attributes":{"icon":"home"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="learn_romhacking" parent_navigation_id="pages" display_order="100" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/pages\/learn","display_condition":"","extra_attributes":{"icon":"graduation-cap"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="legal_pages" parent_navigation_id="pages" display_order="400" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/pages\/legal-pages","display_condition":"","extra_attributes":{"icon":"scale"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="members" parent_navigation_id="community" display_order="400" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{{ link('members') }}","display_condition":"","extra_attributes":{"icon":"users"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="news" parent_navigation_id="website" display_order="250" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/news","display_condition":"","extra_attributes":{"icon":"newspaper"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="pages" display_order="500" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"","display_condition":"","extra_attributes":[]}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="rom_hasher" parent_navigation_id="tools" display_order="200" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/hash","display_condition":"","extra_attributes":{"icon":"hash"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="rom_patcher" parent_navigation_id="tools" display_order="100" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/patch","display_condition":"","extra_attributes":{"icon":"stamp"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="submissions_queue" parent_navigation_id="website" display_order="300" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"{$xf.options.homePageUrl}\/queue","display_condition":"","extra_attributes":{"icon":"gavel"}}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="tools" display_order="400" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"","display_condition":"","extra_attributes":[]}]]></navigation_entry>
|
||||
<navigation_entry navigation_id="website" display_order="200" navigation_type_id="basic" enabled="1"><![CDATA[{"link":"","display_condition":"","extra_attributes":[]}]]></navigation_entry>
|
||||
</navigation>
|
||||
4
_data/option_groups.xml
Normal file
4
_data/option_groups.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<option_groups>
|
||||
<group group_id="romhackplaza" icon="fa-umbrella-beach" display_order="500" debug_only="0"/>
|
||||
</option_groups>
|
||||
15
_data/options.xml
Normal file
15
_data/options.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<options>
|
||||
<option option_id="rhpz_club_node_id" edit_format="spinbox" data_type="unsigned_integer" advanced="0">
|
||||
<default_value>0</default_value>
|
||||
<relation group_id="romhackplaza" display_order="1"/>
|
||||
</option>
|
||||
<option option_id="rhpz_delete_account_master_key" edit_format="textbox" data_type="string" advanced="0">
|
||||
<default_value></default_value>
|
||||
<relation group_id="romhackplaza" display_order="1"/>
|
||||
</option>
|
||||
<option option_id="rhpz_enable_migration" edit_format="onoff" data_type="boolean" advanced="1">
|
||||
<default_value>0</default_value>
|
||||
<relation group_id="romhackplaza" display_order="500"/>
|
||||
</option>
|
||||
</options>
|
||||
4
_data/permission_interface_groups.xml
Normal file
4
_data/permission_interface_groups.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<permission_interface_groups>
|
||||
<interface_group interface_group_id="romhackplaza" display_order="500" is_moderator="0"/>
|
||||
</permission_interface_groups>
|
||||
14
_data/permissions.xml
Normal file
14
_data/permissions.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<permissions>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canEditMyEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="4"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canEditOthersEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="5"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canModerateEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="6"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSeeHiddenEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="9"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSeeLockedEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="10"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSeeOthersDrafts" permission_type="flag" interface_group_id="romhackplaza" display_order="7"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSeeRejectedEntries" permission_type="flag" interface_group_id="romhackplaza" display_order="8"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSubmitEntry" permission_type="flag" interface_group_id="romhackplaza" display_order="2"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSubmitEntryInPublished" permission_type="flag" interface_group_id="romhackplaza" display_order="11"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="canSubmitTempFile" permission_type="flag" interface_group_id="romhackplaza" display_order="3"/>
|
||||
<permission permission_group_id="romhackplaza" permission_id="view" permission_type="flag" interface_group_id="romhackplaza" display_order="1"/>
|
||||
</permissions>
|
||||
49
_data/phrases.xml
Normal file
49
_data/phrases.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phrases>
|
||||
<phrase title="delete_account" version_id="1000000" version_string="1.0.0"><![CDATA[Delete account]]></phrase>
|
||||
<phrase title="delete_account_code" version_id="1000000" version_string="1.0.0"><![CDATA[Delete account code]]></phrase>
|
||||
<phrase title="delete_account_codes" version_id="1000000" version_string="1.0.0"><![CDATA[Delete account codes]]></phrase>
|
||||
<phrase title="delete_all_data_code" version_id="1000000" version_string="1.0.0"><![CDATA[Delete all data code]]></phrase>
|
||||
<phrase title="enable_nsfw_entries" version_id="1010070" version_string="1.1.0"><![CDATA[Enable NSFW Entries]]></phrase>
|
||||
<phrase title="entries" version_id="1000000" version_string="1.0.0"><![CDATA[Entries]]></phrase>
|
||||
<phrase title="entries_options" version_id="1010070" version_string="1.1.0"><![CDATA[Entries options]]></phrase>
|
||||
<phrase title="nav.about" version_id="1000000" version_string="1.0.0"><![CDATA[About]]></phrase>
|
||||
<phrase title="nav.clubs" version_id="1000000" version_string="1.0.0"><![CDATA[Clubs]]></phrase>
|
||||
<phrase title="nav.community" version_id="1000000" version_string="1.0.0"><![CDATA[Community]]></phrase>
|
||||
<phrase title="nav.contact_us" version_id="1000000" version_string="1.0.0"><![CDATA[Contact Us]]></phrase>
|
||||
<phrase title="nav.database" version_id="1000000" version_string="1.0.0"><![CDATA[Database]]></phrase>
|
||||
<phrase title="nav.discord" version_id="1000000" version_string="1.0.0"><![CDATA[Discord]]></phrase>
|
||||
<phrase title="nav.drafts" version_id="1000000" version_string="1.0.0"><![CDATA[My drafts]]></phrase>
|
||||
<phrase title="nav.forum" version_id="1000000" version_string="1.0.0"><![CDATA[Forum]]></phrase>
|
||||
<phrase title="nav.home" version_id="1000000" version_string="1.0.0"><![CDATA[Home]]></phrase>
|
||||
<phrase title="nav.learn_romhacking" version_id="1000000" version_string="1.0.0"><![CDATA[Learn Romhacking]]></phrase>
|
||||
<phrase title="nav.legal_pages" version_id="1000000" version_string="1.0.0"><![CDATA[Legal Pages]]></phrase>
|
||||
<phrase title="nav.members" version_id="1000000" version_string="1.0.0"><![CDATA[Members]]></phrase>
|
||||
<phrase title="nav.news" version_id="1000000" version_string="1.0.0"><![CDATA[News]]></phrase>
|
||||
<phrase title="nav.pages" version_id="1000000" version_string="1.0.0"><![CDATA[Pages]]></phrase>
|
||||
<phrase title="nav.rom_hasher" version_id="1000000" version_string="1.0.0"><![CDATA[ROM Hasher]]></phrase>
|
||||
<phrase title="nav.rom_patcher" version_id="1000000" version_string="1.0.0"><![CDATA[ROM Patcher]]></phrase>
|
||||
<phrase title="nav.submissions_queue" version_id="1000000" version_string="1.0.0"><![CDATA[Submissions queue]]></phrase>
|
||||
<phrase title="nav.tools" version_id="1000000" version_string="1.0.0"><![CDATA[Tools]]></phrase>
|
||||
<phrase title="nav.website" version_id="1000000" version_string="1.0.0"><![CDATA[Website]]></phrase>
|
||||
<phrase title="option.rhpz_club_node_id" version_id="1000000" version_string="1.0.0"><![CDATA[Club Parent Node ID]]></phrase>
|
||||
<phrase title="option.rhpz_delete_account_master_key" version_id="1000000" version_string="1.0.0"><![CDATA[Delete account Master key]]></phrase>
|
||||
<phrase title="option.rhpz_enable_migration" version_id="1000000" version_string="1.0.0"><![CDATA[Enable Migration functions]]></phrase>
|
||||
<phrase title="option_explain.rhpz_club_node_id" version_id="1000000" version_string="1.0.0"><![CDATA[]]></phrase>
|
||||
<phrase title="option_explain.rhpz_delete_account_master_key" version_id="1000000" version_string="1.0.0"><![CDATA[]]></phrase>
|
||||
<phrase title="option_explain.rhpz_enable_migration" version_id="1000000" version_string="1.0.0"><![CDATA[Enable migration endpoints and other things.]]></phrase>
|
||||
<phrase title="option_group.romhackplaza" version_id="1000000" version_string="1.0.0"><![CDATA[RomhackPlaza Options]]></phrase>
|
||||
<phrase title="option_group_description.romhackplaza" version_id="1000000" version_string="1.0.0"><![CDATA[These options are specific to Romhack Plaza]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canEditMyEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can Edit My Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canEditOthersEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can Edit Others Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canModerateEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can Moderate Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSeeHiddenEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can See Hidden Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSeeLockedEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can See Locked Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSeeOthersDrafts" version_id="1000000" version_string="1.0.0"><![CDATA[Can See Others Drafts]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSeeRejectedEntries" version_id="1000000" version_string="1.0.0"><![CDATA[Can See Rejected Entries]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSubmitEntry" version_id="1000000" version_string="1.0.0"><![CDATA[Can Submit Entry]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSubmitEntryInPublished" version_id="1000000" version_string="1.0.0"><![CDATA[Can Submit Entry in Published]]></phrase>
|
||||
<phrase title="permission.romhackplaza_canSubmitTempFile" version_id="1000000" version_string="1.0.0"><![CDATA[Can Submit Temporary File]]></phrase>
|
||||
<phrase title="permission.romhackplaza_view" version_id="1000000" version_string="1.0.0"><![CDATA[View entries]]></phrase>
|
||||
<phrase title="permission_interface.romhackplaza" version_id="1000000" version_string="1.0.0"><![CDATA[Romhack Plaza permissions]]></phrase>
|
||||
</phrases>
|
||||
9
_data/routes.xml
Normal file
9
_data/routes.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<routes>
|
||||
<route route_type="api" route_prefix="migrate" controller="RomhackPlaza\Master:Migrate"/>
|
||||
<route route_type="api" route_prefix="romhackplaza_entry" controller="RomhackPlaza\Master:Entry"/>
|
||||
<route route_type="api" route_prefix="threads" sub_name="undelete" format=":int<thread_id>/undelete" controller="RomhackPlaza\Master:Thread"/>
|
||||
<route route_type="public" route_prefix="clubs" format=":int<club_id>/" controller="RomhackPlaza\Master:Club"/>
|
||||
<route route_type="public" route_prefix="romhackplaza_entry" format=":int<id>" controller="RomhackPlaza\Master:Entry"/>
|
||||
<route route_type="public" route_prefix="romhackplaza_news" format=":int<id>" controller="RomhackPlaza\Master:News"/>
|
||||
</routes>
|
||||
2
_data/style_properties.xml
Normal file
2
_data/style_properties.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<style_properties/>
|
||||
2
_data/style_property_groups.xml
Normal file
2
_data/style_property_groups.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<style_property_groups/>
|
||||
111
_data/template_modifications.xml
Normal file
111
_data/template_modifications.xml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<template_modifications>
|
||||
<modification type="public" template="account_preferences" modification_key="rhpz_account_preferences_nsfw_content" description="Add NSFW Content field to the settings" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<xf:macro id="helper_account::email_options_row" arg-showConversationOption="{{ true }}" />]]></find>
|
||||
<replace><![CDATA[<xf:checkboxrow label="{{ phrase('entries_options') }}">
|
||||
<xf:option value="true" name="user[nsfw_content]" checked="{{ $xf.visitor.nsfw_content == 1 ? true : false }}"
|
||||
label="{{ phrase('enable_nsfw_entries') }}">
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="account_wrapper" modification_key="rhpz_account_wrapper_delete_account" description="Add Delete account page URL to account details" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:settings_links:bottom]-->]]></find>
|
||||
<replace><![CDATA[<a class="blockLink {{ $pageSelected == 'delete_account' ? 'is-selected' : '' }}" href="{{ link('account/delete-account') }}">
|
||||
{{ phrase('delete_account') }}
|
||||
</a>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="category_view" modification_key="rhpz_category_view_clubs_submit_button" description="Add Club Submit button" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[ <xf:button href="{{ link('categories/mark-read', $category, {'date': $xf.time}) }}"
|
||||
class="button--link" overlay="true">]]></find>
|
||||
<replace><![CDATA[<xf:if is="$xf.options.rhpz_club_node_id == $category.node_id">
|
||||
<xf:button href="{{ link('clubs/submit') }}"
|
||||
class="button--link">
|
||||
Request a club
|
||||
</xf:button>
|
||||
</xf:if>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="forum_overview_wrapper" modification_key="rhpz_forum_overview_wrapper_search_button" description="Add Search button" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[ <xf:button href="{{ $xf.options.forumsDefaultPage == 'new_posts' ? link('forums/new-posts') : link('whats-new/posts') }}" icon="bolt">
|
||||
{{ phrase('new_posts') }}
|
||||
</xf:button>]]></find>
|
||||
<replace><![CDATA[ $0
|
||||
<xf:button href="{{ link('search') }}" icon="magnifying-glass">
|
||||
{{ phrase('search') }}
|
||||
</xf:button>]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="forum_view" modification_key="rhpz_above_thread_list_clubs" description="Add the club banner above the threads list." execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<xf:extension id="above_thread_list"></xf:extension>]]></find>
|
||||
<replace><![CDATA[$0
|
||||
<xf:if is="$forum.Node.parent_node_id == $xf.options.rhpz_club_node_id">
|
||||
<div class="club-banner-container">
|
||||
<xf:if is="$forum.Club.banner_date">
|
||||
<img src="{$forum.Club.getBannerUrl()}" alt="Banner {$forum.title}" class="club-banner" />
|
||||
</xf:if>
|
||||
</div>
|
||||
</xf:if>]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="forum_view" modification_key="rhpz_above_thread_list_clubs_buttons" description="Add Owner edit/delete buttons." execution_order="5" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<xf:extension id="above_thread_list"></xf:extension>]]></find>
|
||||
<replace><![CDATA[$0
|
||||
<xf:if is="$forum.Club && $forum.Club.user_id == $xf.visitor.user_id">
|
||||
<div class="block-outer-opposite u-marginBottom">
|
||||
<div class="buttonGroup">
|
||||
<a href="{{ link('clubs/edit', $forum.Club) }}" class="button button--link" icon="edit">Edit</a>
|
||||
<a href="{{ link('clubs/delete', $forum.Club) }}" class="button button--link" icon="delete" overlay="true">Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</xf:if>]]></replace>
|
||||
</modification>
|
||||
<modification type="admin" template="helper_criteria" modification_key="rhpz_helper_criteria_entry_count" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:user:content_bottom]-->]]></find>
|
||||
<replace><![CDATA[<xf:option name="user_criteria[rhpz_entry_count][rule]" value="rhpz_entry_count" selected="{$criteria.rhpz_entry_count}" label="Number of entries:">
|
||||
<xf:numberbox name="user_criteria[rhpz_entry_count][data][entries]" value="{$criteria.rhpz_entry_count.entries}" size="5" min="0" step="1" />
|
||||
</xf:option>]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="member_macros" modification_key="rhpz_member_macros_member_stat_pairs_entry_count" description="Add RHPZ Entry count on member profile page" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:stat_pairs:above_reactions]-->]]></find>
|
||||
<replace><![CDATA[<dl class="pairs pairs--rows pairs--rows--centered">
|
||||
<dt>{{ phrase('entries') }}</dt>
|
||||
<dd>
|
||||
{$user.rhpz_entry_count|number}
|
||||
</dd>
|
||||
</dl>]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="member_view" modification_key="rhpz_member_view_add_entry_tab" description="Add entry tab on members page" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:tabs:after_recent_content]-->]]></find>
|
||||
<replace><![CDATA[<a href="{{ $xf.options.homePageUrl }}/database?userId={$user.user_id}"
|
||||
class="tabs-tab"
|
||||
id="entries">{{ phrase('entries') }}</a>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="public" template="member_view" modification_key="rhpz_member_view_add_entry_tabpanel" description="Add Entry tab panel" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:tab_panes:after_recent_content]-->]]></find>
|
||||
<replace><![CDATA[<li role="tabpanel" aria-labelledby="entries">
|
||||
<a href="{{$xf.options.homePageUrl}}/database?userId={$user.user_id}" class="button">Go to this page</a>
|
||||
</li>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="admin" template="user_edit" modification_key="rhpz_user_edit_delete_account_codes_tab" description="Add Tab for listing delete account codes in User edit" execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:tabs:end]-->]]></find>
|
||||
<replace><![CDATA[<xf:if is="$user.user_id">
|
||||
<a class="tabs-tab" role="tab" tabindex="0"
|
||||
id="user-delete-account-codes"
|
||||
aria-controls="user-delete-account-codes"
|
||||
href="{{ link('users/edit', $user) }}#delete-account-codes">{{ phrase('delete_account_codes') }}</a>
|
||||
</xf:if>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
<modification type="admin" template="user_edit" modification_key="rhpz_user_edit_delete_account_codes_tab_panes" description="Add Tab panes in User edit page for account deletion codes." execution_order="10" enabled="1" action="str_replace">
|
||||
<find><![CDATA[<!--[XF:tab_panes:end]-->]]></find>
|
||||
<replace><![CDATA[
|
||||
<xf:if is="$user.user_id">
|
||||
<li data-href="{{ link('users/delete-account-codes', $user, {'tabbed':1}) }}" role="tabpanel" aria-labelledby="user-delete-account-codes">
|
||||
<div class="block-body block-row">{{ phrase('loading...') }}</div>
|
||||
</li>
|
||||
</xf:if>
|
||||
$0]]></replace>
|
||||
</modification>
|
||||
</template_modifications>
|
||||
666
_data/templates.xml
Normal file
666
_data/templates.xml
Normal file
@@ -0,0 +1,666 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates>
|
||||
<template type="admin" title="helper_criteria" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:macro id="user_tabs" arg-container="" arg-userTabTitle="" arg-active="">
|
||||
<xf:set var="$tabs">
|
||||
<a class="tabs-tab{{ $active == 'user' ? ' is-active' : '' }}"
|
||||
role="tab" tabindex="0" aria-controls="{{ unique_id('criteriaUser') }}">
|
||||
{{ $userTabTitle ? $userTabTitle : phrase('user_criteria') }}</a>
|
||||
<a class="tabs-tab{{ $active == 'user_field' ? ' is-active' : '' }}"
|
||||
role="tab" tabindex="0" aria-controls="{{ unique_id('criteriaUserField') }}">
|
||||
{{ phrase('custom_userfield_criteria') }}</a>
|
||||
</xf:set>
|
||||
<xf:if is="$container">
|
||||
<div class="tabs" role="tablist">
|
||||
{$tabs|raw}
|
||||
</div>
|
||||
<xf:else />
|
||||
{$tabs|raw}
|
||||
</xf:if>
|
||||
</xf:macro>
|
||||
|
||||
<xf:macro id="page_tabs" arg-container="" arg-active="">
|
||||
<xf:set var="$tabs">
|
||||
<a class="tabs-tab{{ $active == 'page' ? ' is-active' : '' }}"
|
||||
role="tab" tabindex="0" aria-controls="{{ unique_id('criteriaPage') }}">{{ phrase('page_criteria') }}</a>
|
||||
</xf:set>
|
||||
<xf:if is="$container">
|
||||
<div class="tabs" role="tablist">
|
||||
{$tabs|raw}
|
||||
</div>
|
||||
<xf:else />
|
||||
{$tabs|raw}
|
||||
</xf:if>
|
||||
</xf:macro>
|
||||
|
||||
<xf:macro id="user_panes" arg-container="" arg-active="" arg-criteria="!" arg-data="!">
|
||||
|
||||
<xf:set var="$app" value="{$xf.app}" />
|
||||
<xf:set var="$visitor" value="{$xf.visitor}" />
|
||||
<xf:set var="$em" value="{$app.em}" />
|
||||
|
||||
<xf:set var="$panes">
|
||||
<li class="{{ $active == 'user' ? ' is-active' : '' }}" role="tabpanel" id="{{ unique_id('criteriaUser') }}">
|
||||
<!--[XF:user:top]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('privileges_and_status') }}">
|
||||
<!--[XF:user:status_top]-->
|
||||
|
||||
<xf:option name="user_criteria[is_guest][rule]" value="is_guest" selected="{$criteria.is_guest}"
|
||||
label="{{ phrase('user_is_guest') }}" />
|
||||
<xf:option name="user_criteria[is_logged_in][rule]" value="is_logged_in" selected="{$criteria.is_logged_in}"
|
||||
label="{{ phrase('user_is_logged_in') }}" />
|
||||
<xf:option name="user_criteria[is_moderator][rule]" value="is_moderator" selected="{$criteria.is_moderator}"
|
||||
label="{{ phrase('user_is_moderator') }}" />
|
||||
<xf:option name="user_criteria[is_admin][rule]" value="is_admin" selected="{$criteria.is_admin}"
|
||||
label="{{ phrase('user_is_administrator') }}" />
|
||||
<xf:option name="user_criteria[is_banned][rule]" value="is_banned" selected="{$criteria.is_banned}"
|
||||
label="{{ phrase('user_is_banned') }}"/>
|
||||
<xf:option name="user_criteria[birthday][rule]" value="birthday" selected="{$criteria.birthday}"
|
||||
label="{{ phrase('user_birthday_is_today') }}"/>
|
||||
<xf:option name="user_criteria[user_state][rule]" value="user_state" selected="{$criteria.user_state}"
|
||||
label="{{ phrase('user_state_is:') }}">
|
||||
|
||||
<xf:dependent>
|
||||
<xf:select name="user_criteria[user_state][data][state]" value="{$criteria.user_state.state}">
|
||||
<xf:option value="valid">{{ phrase('valid') }}</xf:option>
|
||||
<xf:option value="email_confirm">{{ phrase('awaiting_email_confirmation') }}</xf:option>
|
||||
<xf:option value="email_confirm_edit">{{ phrase('awaiting_email_confirmation_from_edit') }}</xf:option>
|
||||
<xf:option value="email_bounce">{{ phrase('email_invalid_bounced') }}</xf:option>
|
||||
<xf:option value="moderated">{{ phrase('awaiting_approval') }}</xf:option>
|
||||
<xf:option value="rejected">{{ phrase('rejected') }}</xf:option>
|
||||
<xf:option value="disabled">{{ phrase('disabled') }}</xf:option>
|
||||
</xf:select>
|
||||
</xf:dependent>
|
||||
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:status_bottom]-->
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_status]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('connected_accounts') }}">
|
||||
<xf:option name="user_criteria[connected_accounts][rule]" value="connected_accounts" selected="{$criteria.connected_accounts}"
|
||||
label="{{ phrase('user_is_associated_with_any_of_selected_connected_account_providers:') }}">
|
||||
|
||||
<xf:select name="user_criteria[connected_accounts][data][provider_ids]" size="4" multiple="true" value="{$criteria.connected_accounts.provider_ids}">
|
||||
<xf:options source="$data.connectedAccProviders" />
|
||||
</xf:select>
|
||||
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_connected]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('user_groups') }}">
|
||||
<xf:option name="user_criteria[user_groups][rule]" value="user_groups" selected="{$criteria.user_groups}"
|
||||
label="{{ phrase('user_is_member_of_any_of_selected_user_groups:') }}">
|
||||
|
||||
<xf:select name="user_criteria[user_groups][data][user_group_ids]" size="4" multiple="true" value="{$criteria.user_groups.user_group_ids}">
|
||||
<xf:foreach loop="$data.userGroups" key="$userGroupId" value="$userGroupTitle">
|
||||
<xf:option value="{$userGroupId}">{$userGroupTitle}</xf:option>
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[not_user_groups][rule]" value="not_user_groups" selected="{$criteria.not_user_groups}"
|
||||
label="{{ phrase('user_is_not_member_of_any_of_selected_user_groups:') }}">
|
||||
|
||||
<xf:select name="user_criteria[not_user_groups][data][user_group_ids]" size="4" multiple="true" value="{$criteria.not_user_groups.user_group_ids}">
|
||||
<xf:foreach loop="$data.userGroups" key="$userGroupId" value="$userGroupTitle">
|
||||
<xf:option value="{$userGroupId}">{$userGroupTitle}</xf:option>
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_groups]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('content_and_achievements') }}">
|
||||
<!--[XF:user:content_top]-->
|
||||
|
||||
<xf:option name="user_criteria[messages_posted][rule]" value="messages_posted" selected="{$criteria.messages_posted}"
|
||||
label="{{ phrase('user_has_posted_at_least_x_messages:') }}">
|
||||
<xf:numberbox name="user_criteria[messages_posted][data][messages]" value="{$criteria.messages_posted.messages}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[messages_maximum][rule]" value="messages_maximum" selected="{$criteria.messages_maximum}"
|
||||
label="{{ phrase('user_has_posted_no_more_than_x_messages:') }}">
|
||||
<xf:numberbox name="user_criteria[messages_maximum][data][messages]" value="{$criteria.messages_maximum.messages}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:content_after_messages]-->
|
||||
|
||||
<xf:option name="user_criteria[questions_solved_min][rule]" value="questions_solved_min" selected="{$criteria.questions_solved_min}"
|
||||
label="{{ phrase('user_has_solved_at_least_x_questions:') }}">
|
||||
<xf:numberbox name="user_criteria[questions_solved_min][data][solved]" value="{$criteria.questions_solved_min.solved}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[questions_solved_max][rule]" value="questions_solved_max" selected="{$criteria.questions_solved_max}"
|
||||
label="{{ phrase('user_has_solved_no_more_than_x_questions:') }}">
|
||||
<xf:numberbox name="user_criteria[questions_solved_max][data][solved]" value="{$criteria.questions_solved_max.solved}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:content_after_questions]-->
|
||||
|
||||
<xf:option name="user_criteria[reaction_score][rule]" value="reaction_score" selected="{$criteria.reaction_score}"
|
||||
label="{{ phrase('user_has_received_a_reaction_sore_of_at_least_x:') }}">
|
||||
<xf:numberbox name="user_criteria[reaction_score][data][reactions]" value="{$criteria.reaction_score.reactions}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[reaction_ratio][rule]" value="reaction_ratio" selected="{$criteria.reaction_ratio}"
|
||||
label="{{ phrase('user_reaction_message_ratio_is_at_least:') }}">
|
||||
<xf:numberbox name="user_criteria[reaction_ratio][data][ratio]" value="{$criteria.reaction_ratio.ratio}"
|
||||
size="5" min="0" step="0.25" />
|
||||
<xf:afterhint>{{ phrase('reaction_message_ratio_explanation') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:content_after_reactions]-->
|
||||
|
||||
<xf:option name="user_criteria[trophy_points][rule]" value="trophy_points" selected="{$criteria.trophy_points}"
|
||||
label="{{ phrase('user_has_at_least_x_trophy_points:') }}">
|
||||
<xf:numberbox name="user_criteria[trophy_points][data][points]" value="{$criteria.trophy_points.points}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:content_after_trophies]-->
|
||||
|
||||
<xf:option name="user_criteria[registered_days][rule]" value="registered_days" selected="{$criteria.registered_days}"
|
||||
label="{{ phrase('user_has_been_registered_for_at_least_x_days:') }}">
|
||||
<xf:numberbox name="user_criteria[registered_days][data][days]" value="{$criteria.registered_days.days}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[inactive_days][rule]" value="inactive_days" selected="{$criteria.inactive_days}"
|
||||
label="{{ phrase('user_has_not_visited_for_at_least_x_days:') }}">
|
||||
<xf:numberbox name="user_criteria[inactive_days][data][days]" value="{$criteria.inactive_days.days}"
|
||||
size="5" min="0" step="1" />
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:content_bottom]-->
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_content]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('user_profile_and_options') }}">
|
||||
<!--[XF:user:profile_top]-->
|
||||
|
||||
<xf:option name="user_criteria[language][rule]" value="language" selected="{$criteria.language}"
|
||||
label="{{ phrase('user_is_browsing_with_following_language:') }}">
|
||||
|
||||
<xf:select name="user_criteria[language][data][language_id]" value="{$criteria.language.language_id}">
|
||||
<xf:foreach loop="$data.languageTree.getFlattened(0)" value="$treeEntry">
|
||||
<xf:option value="{$treeEntry.record.language_id}">{{ repeat('--', $treeEntry.depth) }} {$treeEntry.record.title}</xf:option>
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
|
||||
</xf:option>
|
||||
|
||||
<xf:optgroup label="{{ phrase('avatar:') }}">
|
||||
<xf:option name="user_criteria[has_avatar][rule]" value="has_avatar" selected="{$criteria.has_avatar}"
|
||||
label="{{ phrase('user_has_avatar') }}" />
|
||||
|
||||
<xf:option name="user_criteria[no_avatar][rule]" value="no_avatar" selected="{$criteria.no_avatar}"
|
||||
label="{{ phrase('user_has_no_avatar') }}" />
|
||||
</xf:optgroup>
|
||||
|
||||
<xf:optgroup label="{{ phrase('high_resolution_avatar:') }}">
|
||||
<xf:option name="user_criteria[has_highdpi_avatar][rule]" value="has_highdpi_avatar" selected="{$criteria.has_highdpi_avatar}"
|
||||
label="{{ phrase('user_has_highdpi_avatar') }}" />
|
||||
|
||||
<xf:option name="user_criteria[no_highdpi_avatar][rule]" value="no_highdpi_avatar" selected="{$criteria.no_highdpi_avatar}"
|
||||
label="{{ phrase('user_has_no_highdpi_avatar') }}" />
|
||||
</xf:optgroup>
|
||||
|
||||
<xf:optgroup label="{{ phrase('two_step_verification:') }}">
|
||||
<xf:option name="user_criteria[with_tfa][rule]" value="with_tfa" selected="{$criteria.with_tfa}"
|
||||
label="{{ phrase('user_has_enabled_two_step_verification') }}" />
|
||||
|
||||
<xf:option name="user_criteria[without_tfa][rule]" value="without_tfa" selected="{$criteria.without_tfa}"
|
||||
label="{{ phrase('user_has_not_enabled_two_step_verification') }}"/>
|
||||
</xf:optgroup>
|
||||
|
||||
<xf:optgroup label="{{ phrase('activity_summary_email:') }}">
|
||||
<xf:option name="user_criteria[activity_summary_enabled][rule]" value="activity_summary_enabled" selected="{$criteria.activity_summary_enabled}"
|
||||
label="{{ phrase('user_has_activity_summary_emails_enabled') }}" />
|
||||
|
||||
<xf:option name="user_criteria[activity_summary_disabled][rule]" value="activity_summary_disabled" selected="{$criteria.activity_summary_disabled}"
|
||||
label="{{ phrase('user_has_activity_summary_emails_disabled') }}"/>
|
||||
</xf:optgroup>
|
||||
|
||||
<!--[XF:user:profile_bottom]-->
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_profile]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('user_segmentation') }}">
|
||||
<!--[XF:user:segmentation_top]-->
|
||||
|
||||
<xf:option name="user_criteria[user_id][rule]" value="user_id" selected="{$criteria.user_id}"
|
||||
label="{{ phrase('user_id_matches_expression:') }}">
|
||||
<xf:textbox
|
||||
name="user_criteria[user_id][data][expression]"
|
||||
value="{$criteria.user_id.expression}"
|
||||
placeholder="2n+1"
|
||||
/>
|
||||
<xf:afterhint>{{ phrase('user_id_match_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:segmentation_bottom]-->
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:user:after_segmentation]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('specific_users') }}">
|
||||
<!--[XF:user:specific_top]-->
|
||||
|
||||
<xf:option name="user_criteria[username][rule]" value="username" selected="{$criteria.username}"
|
||||
label="{{ phrase('username_is:') }}">
|
||||
<xf:textbox name="user_criteria[username][data][names]" value="{$criteria.username.names}" ac="true" />
|
||||
<xf:afterhint>{{ phrase('username_criteria_explain') }}</xf:afterhint>
|
||||
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[username_search][rule]" value="username_search" selected="{$criteria.username_search}"
|
||||
label="{{ phrase('username_contains:') }}">
|
||||
<xf:textbox name="user_criteria[username_search][data][needles]" value="{$criteria.username_search.needles}" />
|
||||
<xf:afterhint>{{ phrase('username_search_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="user_criteria[email_search][rule]" value="email_search" selected="{$criteria.email_search}"
|
||||
label="{{ phrase('email_address_contains:') }}">
|
||||
<xf:textbox name="user_criteria[email_search][data][needles]" value="{$criteria.email_search.needles}" />
|
||||
<xf:afterhint>{{ phrase('email_search_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<!--[XF:user:specific_bottom]-->
|
||||
</xf:checkboxrow>
|
||||
|
||||
<!--[XF:user:bottom]-->
|
||||
</li>
|
||||
|
||||
<li class="{{ $active == 'user_field' ? 'is-active' : '' }}" role="tabpanel" id="{{ unique_id('criteriaUserField') }}">
|
||||
<xf:if contentcheck="true">
|
||||
<xf:contentcheck>
|
||||
<xf:foreach loop="$xf.app.em.getRepository('XF:UserField').getDisplayGroups()" key="$fieldGroup" value="$groupPhrase">
|
||||
|
||||
<xf:set var="$customFields" value="{$app.getCustomFields('users', $fieldGroup)}" />
|
||||
<xf:if contentcheck="true">
|
||||
<h2 class="block-formSectionHeader"><span class="block-formSectionHeader-aligner">{$groupPhrase}</span></h2>
|
||||
<xf:contentcheck>
|
||||
<xf:foreach loop="$customFields" key="$fieldId" value="$fieldDefinition">
|
||||
<xf:set var="$fieldName" value="user_field_{$fieldId}" />
|
||||
<xf:set var="$choices" value="{$fieldDefinition.field_choices}" />
|
||||
<xf:checkboxrow label="{$fieldDefinition.title}">
|
||||
<xf:option name="user_criteria[{$fieldName}][rule]" value="{$fieldName}" selected="{$criteria.{$fieldName}}"
|
||||
label="{{ $choices ? phrase('criteria_userfield_choice_among') : phrase('criteria_userfield_contains_text:') }}">
|
||||
<xf:dependent>
|
||||
<xf:if is="!{$choices}">
|
||||
<xf:textbox name="user_criteria[{$fieldName}][data][text]" value="{$criteria.{$fieldName}.text}" />
|
||||
<xf:elseif is="{{ count($choices) }} > 6" />
|
||||
<xf:select name="user_criteria[{$fieldName}][data][choices]" value="{$criteria.{$fieldName}.choices}" multiple="multiple" size="5">
|
||||
<xf:options source="{$choices}" />
|
||||
</xf:select>
|
||||
<xf:else />
|
||||
<xf:checkbox name="user_criteria[{$fieldName}][data][choices]" value="{$criteria.{$fieldName}.choices}" listclass="listColumns">
|
||||
<xf:options source="{$choices}" />
|
||||
</xf:checkbox>
|
||||
</xf:if>
|
||||
</xf:dependent>
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
</xf:foreach>
|
||||
</xf:contentcheck>
|
||||
</xf:if>
|
||||
|
||||
</xf:foreach>
|
||||
</xf:contentcheck>
|
||||
<xf:else />
|
||||
{{ phrase('no_custom_fields_have_been_created_yet') }}
|
||||
</xf:if>
|
||||
</li>
|
||||
</xf:set>
|
||||
|
||||
<xf:if is="$container">
|
||||
<ul class="tabPanes">
|
||||
{$panes|raw}
|
||||
</ul>
|
||||
<xf:else />
|
||||
{$panes|raw}
|
||||
</xf:if>
|
||||
</xf:macro>
|
||||
|
||||
<xf:macro id="page_panes" arg-container="" arg-active="" arg-criteria="!" arg-data="!">
|
||||
|
||||
<xf:set var="$em" value="{$xf.app.em}" />
|
||||
<xf:set var="$visitor" value="{$xf.visitor}" />
|
||||
|
||||
<xf:set var="$panes">
|
||||
<li class="{{ $active == 'page' ? ' is-active' : '' }}" role="tabpanel" id="{{ unique_id('criteriaPage') }}">
|
||||
<!--[XF:page:after_from_search]-->
|
||||
|
||||
<xf:checkboxrow>
|
||||
<xf:option name="page_criteria[after][rule]" value="after" selected="{$criteria.after}"
|
||||
label="{{ phrase('criteria_date_time_is_after:') }}">
|
||||
|
||||
<xf:dependent>
|
||||
<div class="inputGroup">
|
||||
<xf:dateinput name="page_criteria[after][data][ymd]" value="{$criteria.after.ymd}" />
|
||||
<span class="inputGroup-text">
|
||||
{{ phrase('criteria_time:') }}
|
||||
</span>
|
||||
<span class="inputGroup" dir="ltr">
|
||||
<xf:select name="page_criteria[after][data][hh]" value="{$criteria.after.hh}" class="input--inline input--autoSize">
|
||||
<xf:foreach loop="$data.hours" value="$hour">
|
||||
<xf:option value="{$hour}" label="{$hour}" />
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
<span class="inputGroup-text">:</span>
|
||||
<xf:select name="page_criteria[after][data][mm]" value="{$criteria.after.mm}" class="input--inline input--autoSize">
|
||||
<xf:foreach loop="$data.minutes" value="$minute">
|
||||
<xf:option value="{$minute}" label="{$minute}" />
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
</span>
|
||||
</div>
|
||||
<dfn class="inputChoices-explain inputChoices-explain--after">{{ phrase('criteria_leave_date_empty') }}</dfn>
|
||||
</xf:dependent>
|
||||
|
||||
<xf:radio name="page_criteria[after][data][user_tz]" value="{{ $criteria.after.user_tz ? $criteria.after.user_tz : 0 }}">
|
||||
<xf:option value="1" label="{{ phrase('criteria_in_visitor_timezone') }}" />
|
||||
<xf:option value="0" label="{{ phrase('criteria_in_selected_timezone:') }}">
|
||||
<xf:select name="page_criteria[after][data][timezone]" value="{{ $criteria.after.timezone ? $criteria.after.timezone : $visitor.timezone }}">
|
||||
<xf:options source="{$data.timeZones}" />
|
||||
</xf:select>
|
||||
</xf:option>
|
||||
</xf:radio>
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:page:after_time_after]-->
|
||||
|
||||
<xf:checkboxrow>
|
||||
<xf:option name="page_criteria[before][rule]" value="before" selected="{$criteria.before}"
|
||||
label="{{ phrase('criteria_date_time_is_before:') }}">
|
||||
|
||||
<xf:dependent>
|
||||
<div class="inputGroup">
|
||||
<xf:dateinput name="page_criteria[before][data][ymd]" value="{$criteria.before.ymd}" />
|
||||
<span class="inputGroup-text">
|
||||
{{ phrase('criteria_time:') }}
|
||||
</span>
|
||||
<span class="inputGroup" dir="ltr">
|
||||
<xf:select name="page_criteria[before][data][hh]" value="{$criteria.before.hh}" class="input--inline input--autoSize">
|
||||
<xf:foreach loop="$data.hours" value="$hour">
|
||||
<xf:option value="{$hour}" label="{$hour}" />
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
<span class="inputGroup-text">:</span>
|
||||
<xf:select name="page_criteria[before][data][mm]" value="{$criteria.before.mm}" class="input--inline input--autoSize">
|
||||
<xf:foreach loop="$data.minutes" value="$minute">
|
||||
<xf:option value="{$minute}" label="{$minute}" />
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
</span>
|
||||
</div>
|
||||
<dfn class="inputChoices-explain inputChoices-explain--before">{{ phrase('criteria_leave_date_empty') }}</dfn>
|
||||
</xf:dependent>
|
||||
|
||||
<xf:radio name="page_criteria[before][data][user_tz]" value="{{ $criteria.before.user_tz ? $criteria.before.user_tz : 0 }}">
|
||||
<xf:option value="1" label="{{ phrase('criteria_in_visitor_timezone') }}" />
|
||||
<xf:option value="0" label="{{ phrase('criteria_in_selected_timezone:') }}">
|
||||
<xf:select name="page_criteria[before][data][timezone]" value="{{ $criteria.before.timezone ? $criteria.before.timezone : $visitor.timezone }}">
|
||||
<xf:options source="{$data.timeZones}" />
|
||||
</xf:select>
|
||||
</xf:option>
|
||||
</xf:radio>
|
||||
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:page:after_time_before]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('nodes') }}">
|
||||
<xf:option name="page_criteria[nodes][rule]" value="nodes" selected="{$criteria.nodes}"
|
||||
label="{{ phrase('page_is_within_nodes:') }}">
|
||||
|
||||
<xf:select name="page_criteria[nodes][data][node_ids]" multiple="true" value="{$criteria.nodes.node_ids}">
|
||||
<xf:foreach loop="$data.nodes" value="$option">
|
||||
<xf:option value="{$option.value}" label="{$option.label}" />
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
<xf:checkbox>
|
||||
<xf:option name="page_criteria[nodes][data][node_only]" value="1" selected="{$criteria.nodes.node_only}"
|
||||
label="{{ phrase('only_display_within_selected_nodes_no_children') }}" />
|
||||
</xf:checkbox>
|
||||
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<hr class="formRowSep" />
|
||||
|
||||
<!--[XF:page:after_nodes]-->
|
||||
|
||||
<xf:checkboxrow label="{{ phrase('page_information') }}">
|
||||
<xf:option name="page_criteria[style][rule]" value="style" selected="{$criteria.style}"
|
||||
label="{{ phrase('user_is_browsing_with_following_style:') }}">
|
||||
|
||||
<xf:select name="page_criteria[style][data][style_id]" value="{$criteria.style.style_id}">
|
||||
<xf:foreach loop="$data.styleTree.getFlattened(0)" value="$treeEntry">
|
||||
<xf:option value="{$treeEntry.record.style_id}">{{ repeat('--', $treeEntry.depth) }} {$treeEntry.record.title}</xf:option>
|
||||
</xf:foreach>
|
||||
</xf:select>
|
||||
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="page_criteria[tab][rule]" value="tab" selected="{$criteria.tab}"
|
||||
label="{{ phrase('selected_navigation_tab_id_is:') }}">
|
||||
|
||||
<xf:textbox name="page_criteria[tab][data][id]" value="{$criteria.tab.id}"dir="ltr" />
|
||||
<xf:afterhint>{{ phrase('selected_tab_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="page_criteria[controller][rule]" value="controller" selected="{$criteria.controller}"
|
||||
label="{{ phrase('controller_and_action_is:') }}">
|
||||
|
||||
<xf:macro id="helper_callback_fields::callback_fields"
|
||||
arg-className="page_criteria[controller][data][name]"
|
||||
arg-methodName="page_criteria[controller][data][action]"
|
||||
arg-classValue="{$criteria.controller.name}"
|
||||
arg-methodValue="{$criteria.controller.action}" />
|
||||
<xf:afterhint>{{ phrase('controller_and_action_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="page_criteria[view][rule]" value="view" selected="{$criteria.view}"
|
||||
label="{{ phrase('view_class_is:') }}">
|
||||
|
||||
<xf:textbox name="page_criteria[view][data][name]" value="{$criteria.view.name}" dir="ltr" />
|
||||
<xf:afterhint>{{ phrase('view_class_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
|
||||
<xf:option name="page_criteria[template][rule]" value="template" selected="{$criteria.template}"
|
||||
label="{{ phrase('content_template_is:') }}">
|
||||
|
||||
<xf:textbox name="page_criteria[template][data][name]" value="{$criteria.template.name}" dir="ltr" />
|
||||
<xf:afterhint>{{ phrase('content_template_criteria_explain') }}</xf:afterhint>
|
||||
</xf:option>
|
||||
</xf:checkboxrow>
|
||||
|
||||
<!--[XF:page:after_page_info]-->
|
||||
</li>
|
||||
</xf:set>
|
||||
|
||||
<xf:if is="$container">
|
||||
<ul class="tabPanes">
|
||||
{$panes|raw}
|
||||
</ul>
|
||||
<xf:else />
|
||||
{$panes|raw}
|
||||
</xf:if>
|
||||
</xf:macro>]]></template>
|
||||
<template type="admin" title="user_delete_account_codes" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:title>{$user.username}</xf:title>
|
||||
|
||||
<div class="block">
|
||||
<div class="block-container">
|
||||
<h3 class="block-minorHeader">{{ phrase('delete_account_code') }}</h3>
|
||||
<div class="block-body">
|
||||
<div class="block-row">{$deleteAccountCode}</div>
|
||||
</div>
|
||||
|
||||
<h3 class="block-minorHeader">{{ phrase('delete_all_data_code') }}</h3>
|
||||
<div class="block-body">
|
||||
<div class="block-row">{$deleteAllDataCode}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>]]></template>
|
||||
<template type="public" title="approval_item_club_request" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:macro id="approval_queue_macros::item_message_type"
|
||||
arg-content="{$content}"
|
||||
arg-user="{$content.User}"
|
||||
arg-messageHtml="{$content.description}"
|
||||
arg-contentDate="{$content.club_creation_date}"
|
||||
arg-typePhraseHtml="Club Request"
|
||||
arg-headerPhrase="{$content.title}"
|
||||
arg-spamDetails="{$spamDetails}"
|
||||
arg-unapprovedItem="{$unapprovedItem}"
|
||||
arg-handler="{$handler}"
|
||||
/>]]></template>
|
||||
<template type="public" title="approval_item_entry_featured_request" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:macro id="approval_queue_macros::item_message_type"
|
||||
arg-content="{$content}"
|
||||
arg-user="{$content.User}"
|
||||
arg-messageHtml="{$content.entry_title}"
|
||||
arg-contentDate="{$content.featured_request_date}"
|
||||
arg-typePhraseHtml="Featured Request"
|
||||
arg-headerPhrase="{$content.entry_title}"
|
||||
arg-spamDetails="{$spamDetails}"
|
||||
arg-unapprovedItem="{$unapprovedItem}"
|
||||
arg-handler="{$handler}"
|
||||
/>]]></template>
|
||||
<template type="public" title="club_delete_confirm" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:title>Delete club : {$club.title}</xf:title>
|
||||
|
||||
<xf:form action="{{ link('clubs/delete', $club) }}" class="block">
|
||||
<div class="block-container">
|
||||
<div class="block-body">
|
||||
<xf:inforow rowtype="confirm">
|
||||
Are you sure you want to delete this club ? <strong>{$club.title}</strong> ?<br />
|
||||
<span class="u-muted">Deleting this will also delete all threads and posts.</span>
|
||||
</xf:inforow>
|
||||
</div>
|
||||
<xf:submitrow rowtype="simple" icon="delete" submit="Delete" />
|
||||
</div>
|
||||
</xf:form>]]></template>
|
||||
<template type="public" title="club_edit_form" version_id="1000000" version_string="1.0.0"><![CDATA[<div class="block">
|
||||
<xf:form action="{{ link('clubs/save', $club ) }}" upload="true" ajax="true" class="block-container">
|
||||
<div class="block-body">
|
||||
<xf:textboxrow name="title" value="{$club.title}" label="Title" required="true" maxlength="100" />
|
||||
<xf:textarearow name="description" value="{$club.description}" label="Description" required="true" rows="4" />
|
||||
|
||||
<xf:if is="$club.banner_date">
|
||||
<xf:formrow label="Current Banner">
|
||||
<img src="{$club.getBannerUrl()}" style="max-width: 300px; border-radius: 4px;" />
|
||||
</xf:formrow>
|
||||
</xf:if>
|
||||
|
||||
<xf:uploadrow name="upload_banner" accept=".jpg,.jpeg,.png" label="Banner" />
|
||||
</div>
|
||||
<xf:submitrow icon="save" submit="Submit Changes" />
|
||||
</xf:form>
|
||||
</div>
|
||||
|
||||
<xf:if is="$club.club_id && $club.node_id">
|
||||
|
||||
<div class="block u-marginTop">
|
||||
<div class="block-container">
|
||||
<h2 class="block-header">Club Moderators ({$subModCount}/5)</h2>
|
||||
<div class="block-body">
|
||||
<xf:if is="$moderators is not empty">
|
||||
<div class="dataList">
|
||||
<xf:foreach loop="$moderators" value="$mod">
|
||||
<div class="dataList-row">
|
||||
<div class="dataList-cell dataList-cell--main">
|
||||
<strong>{$mod.User.username}</strong>
|
||||
<xf:if is="$mod.user_id == $club.user_id">
|
||||
<span class="label label--accent u-marginLeft">Owner</span>
|
||||
</xf:if>
|
||||
</div>
|
||||
<div class="dataList-cell dataList-cell--action">
|
||||
<xf:if is="$mod.user_id != $club.user_id">
|
||||
<xf:form action="{{ link('clubs/remove-moderator', $club) }}" ajax="true" class="u-inline">
|
||||
<input type="hidden" name="user_id" value="{$mod.user_id}" />
|
||||
<xf:button type="submit" class="button--small button--warn" icon="delete">Remove</xf:button>
|
||||
</xf:form>
|
||||
<xf:else />
|
||||
<span class="u-muted">-</span>
|
||||
</xf:if>
|
||||
</div>
|
||||
</div>
|
||||
</xf:foreach>
|
||||
</div>
|
||||
<xf:else />
|
||||
<div class="block-row">No moderators for this club.</div>
|
||||
</xf:if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block u-marginTop">
|
||||
<xf:if is="$subModCount < 5">
|
||||
<xf:form action="{{ link('clubs/add-moderator', $club) }}" ajax="true" class="block-container">
|
||||
<h2 class="block-header">Add a moderator</h2>
|
||||
<div class="block-body">
|
||||
<xf:textboxrow name="username" label="Username" class="namePredictor" required="true" />
|
||||
</div>
|
||||
<xf:submitrow icon="add" submit="Promote Moderator" />
|
||||
</xf:form>
|
||||
<xf:else />
|
||||
<div class="block-container">
|
||||
<div class="block-row block-row--warning">
|
||||
<strong>Limit reached:</strong> You have reached the maximum number of 5 moderators for your club. You must remove one before you can add a new one.
|
||||
</div>
|
||||
</div>
|
||||
</xf:if>
|
||||
</div>
|
||||
</xf:if>]]></template>
|
||||
<template type="public" title="club_request_form" version_id="1000000" version_string="1.0.0"><![CDATA[<xf:title>Submit Club Request</xf:title>
|
||||
|
||||
<xf:form action="{{ link('clubs/save') }}" ajax="true" class="block">
|
||||
<div class="block-container">
|
||||
<div class="block-body">
|
||||
<xf:textboxrow name="title" label="Title" required="required" />
|
||||
<xf:textarearow name="description" label="Description" rows="4" required="required" />
|
||||
<xf:uploadrow name="upload_banner" accept=".jpg,.jpeg,.jpe,.png" label="Banner" />
|
||||
</div>
|
||||
<xf:submitrow submit="Submit" icon="save" />
|
||||
</div>
|
||||
</xf:form>]]></template>
|
||||
<template type="public" title="report_content_romhackplaza_entry" version_id="1000000" version_string="1.0.0"><![CDATA[<div class="block-row block-row--separated">
|
||||
{{ phrase('content:') }}
|
||||
{$report.content_info.description}
|
||||
</div>]]></template>
|
||||
<template type="public" title="report_content_romhackplaza_news" version_id="1000000" version_string="1.0.0"><![CDATA[<div class="block-row block-row--separated">
|
||||
{{ phrase('content:') }}
|
||||
{$report.content_info.description}
|
||||
</div>]]></template>
|
||||
</templates>
|
||||
2
_data/widget_definitions.xml
Normal file
2
_data/widget_definitions.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<widget_definitions/>
|
||||
2
_data/widget_positions.xml
Normal file
2
_data/widget_positions.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<widget_positions/>
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Admin\\Controller\\UserController",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Admin\\Controller\\UserController",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Entity\\ApprovalQueue",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Entity\\ApprovalQueue",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Entity\\Forum",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Entity\\Forum",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Entity\\User",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Entity\\User",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Pub\\Controller\\AccountController",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Pub\\Controller\\AccountController",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Pub\\Controller\\MiscController",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Pub\\Controller\\MiscController",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"from_class": "XF\\Service\\Report\\CreatorService",
|
||||
"to_class": "RomhackPlaza\\Master\\XF\\Service\\Report\\CreatorService",
|
||||
"execute_order": 10,
|
||||
"active": true
|
||||
}
|
||||
23
_output/class_extensions/_metadata.json
Normal file
23
_output/class_extensions/_metadata.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"XF-Admin-Controller-UserController_RomhackPlaza-Master-XF-Admin-Controller-UserController.json": {
|
||||
"hash": "542c5dd275e5e26446a9e4a19b3c47b6"
|
||||
},
|
||||
"XF-Entity-ApprovalQueue_RomhackPlaza-Master-XF-Entity-ApprovalQueue.json": {
|
||||
"hash": "f4364e1ec74dfa80ff24368486e66ffb"
|
||||
},
|
||||
"XF-Entity-Forum_RomhackPlaza-Master-XF-Entity-Forum.json": {
|
||||
"hash": "c7747b6ea6bd924d2d02e82917ff0df3"
|
||||
},
|
||||
"XF-Entity-User_RomhackPlaza-Master-XF-Entity-User.json": {
|
||||
"hash": "811593d6f012a53b9fa2ced871de96a9"
|
||||
},
|
||||
"XF-Pub-Controller-AccountController_RomhackPlaza-Master-XF-Pub-Controller-AccountController.json": {
|
||||
"hash": "b34f519ca78e8977c98e0307125537bc"
|
||||
},
|
||||
"XF-Pub-Controller-MiscController_RomhackPlaza-Master-XF-Pub-Controller-MiscController.json": {
|
||||
"hash": "1071fd498b2958031153de55eb4ca66a"
|
||||
},
|
||||
"XF-Service-Report-CreatorService_RomhackPlaza-Master-XF-Service-Report-CreatorService.json": {
|
||||
"hash": "2def6639766241a5f2ff3c10fc168731"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
{
|
||||
"app_pub_render_page_c6149e27cfdc21a20c8047e0e5cd5503.json": {
|
||||
"hash": "95a8be583623f99ff47eef23a658e459"
|
||||
},
|
||||
"criteria_user_0cfa5d0143e6477a6bc20b11e255e850.json": {
|
||||
"hash": "f29b40ef7a5b420b212848744fd9b7db"
|
||||
},
|
||||
"import_importer_classes_64d8f27f58ba02af52958c1d4f94f812.json": {
|
||||
"hash": "2ff08f9036890eb77d7bc1c7fc02fc4c"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"event_id": "app_pub_render_page",
|
||||
"execute_order": 10,
|
||||
"callback_class": "RomhackPlaza\\Master\\Listener",
|
||||
"callback_method": "checkStyleVariation",
|
||||
"active": true,
|
||||
"hint": "",
|
||||
"description": ""
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"event_id": "import_importer_classes",
|
||||
"execute_order": 15,
|
||||
"callback_class": "RomhackPlaza\\Master\\Listener",
|
||||
"callback_method": "importImporterClasses",
|
||||
"active": true,
|
||||
"hint": "",
|
||||
"description": ""
|
||||
}
|
||||
26
_output/content_type_fields/_metadata.json
Normal file
26
_output/content_type_fields/_metadata.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"club-approval_queue_handler_class.json": {
|
||||
"hash": "468464999ab50b9de400a6eae27625ac"
|
||||
},
|
||||
"club-entity.json": {
|
||||
"hash": "ed572323131987e295051165e4ec3c5e"
|
||||
},
|
||||
"rhpz_entry_featurerequest-approval_queue_handler_class.json": {
|
||||
"hash": "0452fab1abce77fa92858ee46c615d8a"
|
||||
},
|
||||
"rhpz_entry_featurerequest-entity.json": {
|
||||
"hash": "62ab52f94cdc49ced9c18dd31eaf7f8c"
|
||||
},
|
||||
"romhackplaza_entry-entity.json": {
|
||||
"hash": "8686ffd261eb8c1698a3ec6e31118f02"
|
||||
},
|
||||
"romhackplaza_entry-report_handler_class.json": {
|
||||
"hash": "3e3d009b1b4671a506accc2e920307b2"
|
||||
},
|
||||
"romhackplaza_news-entity.json": {
|
||||
"hash": "97f9641ceb338c2fdd489e2eed7fb7d1"
|
||||
},
|
||||
"romhackplaza_news-report_handler_class.json": {
|
||||
"hash": "8af48d739b42b8794fd802eaf72e2025"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "club",
|
||||
"field_name": "approval_queue_handler_class",
|
||||
"field_value": "RomhackPlaza\\Master\\ApprovalQueue\\Club"
|
||||
}
|
||||
5
_output/content_type_fields/club-entity.json
Normal file
5
_output/content_type_fields/club-entity.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "club",
|
||||
"field_name": "entity",
|
||||
"field_value": "RomhackPlaza\\Master\\Entity\\Club"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "rhpz_entry_featurerequest",
|
||||
"field_name": "approval_queue_handler_class",
|
||||
"field_value": "RomhackPlaza\\Master\\ApprovalQueue\\EntryFeaturedRequest"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "rhpz_entry_featurerequest",
|
||||
"field_name": "entity",
|
||||
"field_value": "RomhackPlaza\\Master\\Entity\\EntryFeaturedRequest"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "romhackplaza_entry",
|
||||
"field_name": "entity",
|
||||
"field_value": "RomhackPlaza\\Master\\Entity\\Entry"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "romhackplaza_entry",
|
||||
"field_name": "report_handler_class",
|
||||
"field_value": "RomhackPlaza\\Master\\Report\\Entry"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "romhackplaza_news",
|
||||
"field_name": "entity",
|
||||
"field_value": "RomhackPlaza\\Master\\Entity\\News"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"content_type": "romhackplaza_news",
|
||||
"field_name": "report_handler_class",
|
||||
"field_value": "RomhackPlaza\\Master\\Report\\News"
|
||||
}
|
||||
32
_output/extension_hint.php
Normal file
32
_output/extension_hint.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
// ################## THIS IS A GENERATED FILE ##################
|
||||
// DO NOT EDIT DIRECTLY. EDIT THE CLASS EXTENSIONS IN THE CONTROL PANEL.
|
||||
|
||||
/**
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
* @noinspection PhpMultipleClassesDeclarationsInOneFile
|
||||
*/
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Admin\Controller
|
||||
{
|
||||
class XFCP_UserController extends \XF\Admin\Controller\UserController {}
|
||||
}
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Entity
|
||||
{
|
||||
class XFCP_ApprovalQueue extends \XF\Entity\ApprovalQueue {}
|
||||
class XFCP_Forum extends \XF\Entity\Forum {}
|
||||
class XFCP_User extends \XF\Entity\User {}
|
||||
}
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Pub\Controller
|
||||
{
|
||||
class XFCP_AccountController extends \XF\Pub\Controller\AccountController {}
|
||||
class XFCP_MiscController extends \XF\Pub\Controller\MiscController {}
|
||||
}
|
||||
|
||||
namespace RomhackPlaza\Master\XF\Service\Report
|
||||
{
|
||||
class XFCP_CreatorService extends \XF\Service\Report\CreatorService {}
|
||||
}
|
||||
17
_output/help_pages/_metadata.json
Normal file
17
_output/help_pages/_metadata.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"about.json": {
|
||||
"hash": "d2d00802b4114e28d0a69fba02973a3d"
|
||||
},
|
||||
"delete_my_data.json": {
|
||||
"hash": "f1eb8202bf076a34bc774c055cb9e7eb"
|
||||
},
|
||||
"dmca.json": {
|
||||
"hash": "e6dcff244e3981ecbc31e042315d191a"
|
||||
},
|
||||
"how_to_become_verified.json": {
|
||||
"hash": "4fa48e94d5179225b49d4d0e19daa8e9"
|
||||
},
|
||||
"takedown.json": {
|
||||
"hash": "13a1dc2ff2041b03aac5a66cc21de7c4"
|
||||
}
|
||||
}
|
||||
8
_output/help_pages/about.json
Normal file
8
_output/help_pages/about.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"page_name": "about",
|
||||
"display_order": 10,
|
||||
"callback_class": "",
|
||||
"callback_method": "",
|
||||
"advanced_mode": false,
|
||||
"active": true
|
||||
}
|
||||
8
_output/help_pages/delete_my_data.json
Normal file
8
_output/help_pages/delete_my_data.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"page_name": "delete-my-data",
|
||||
"display_order": 10,
|
||||
"callback_class": "",
|
||||
"callback_method": "",
|
||||
"advanced_mode": false,
|
||||
"active": true
|
||||
}
|
||||
8
_output/help_pages/dmca.json
Normal file
8
_output/help_pages/dmca.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"page_name": "dmca",
|
||||
"display_order": 50,
|
||||
"callback_class": "",
|
||||
"callback_method": "",
|
||||
"advanced_mode": false,
|
||||
"active": true
|
||||
}
|
||||
8
_output/help_pages/how_to_become_verified.json
Normal file
8
_output/help_pages/how_to_become_verified.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"page_name": "how-to-become-verified",
|
||||
"display_order": 20,
|
||||
"callback_class": "",
|
||||
"callback_method": "",
|
||||
"advanced_mode": false,
|
||||
"active": true
|
||||
}
|
||||
8
_output/help_pages/takedown.json
Normal file
8
_output/help_pages/takedown.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"page_name": "takedown",
|
||||
"display_order": 40,
|
||||
"callback_class": "",
|
||||
"callback_method": "",
|
||||
"advanced_mode": false,
|
||||
"active": true
|
||||
}
|
||||
@@ -1,53 +1,62 @@
|
||||
{
|
||||
"about.json": {
|
||||
"hash": "96e3aa134dd14f5d43ca9ca1d5c55113"
|
||||
"hash": "6af7d9983ab28cb4b2975a1cd0059f9f"
|
||||
},
|
||||
"clubs.json": {
|
||||
"hash": "e7ddced6269072f7db774f09424d671c"
|
||||
},
|
||||
"community.json": {
|
||||
"hash": "bddec05ee1acb9cb82ed72155bdd7817"
|
||||
"hash": "b3b5bb7146a8eb66e2830c48c4714456"
|
||||
},
|
||||
"contact_us.json": {
|
||||
"hash": "2a0528c2bc4338d4541074f90790c127"
|
||||
"hash": "59453e1b06c296c777987d0fae0eb3a5"
|
||||
},
|
||||
"database.json": {
|
||||
"hash": "7b42b608fad8ab23417a8cc3fcd331c2"
|
||||
"hash": "604cabbdf4fb4fd941dc6123eb119165"
|
||||
},
|
||||
"discord.json": {
|
||||
"hash": "d20860e95b3f4a96622733ef9ef4cfa0"
|
||||
"hash": "225fd5b2a01edb9d28b142293207943a"
|
||||
},
|
||||
"drafts.json": {
|
||||
"hash": "bea14e944290aeb07659374fa487d61c"
|
||||
},
|
||||
"forum.json": {
|
||||
"hash": "4a2e65ba6b553ed68dd5b6f7fd6d71d8"
|
||||
"hash": "ca20fad278aeab93ccbc3c3a20a743d2"
|
||||
},
|
||||
"home.json": {
|
||||
"hash": "6bf83f1a17528a3c075addfbc8fca830"
|
||||
"hash": "4f55ee2e4a49e82c18e9beab428ab0ee"
|
||||
},
|
||||
"learn_romhacking.json": {
|
||||
"hash": "dc98809d9e310f450123400bf106d2e5"
|
||||
"hash": "2a2086e4b84a08f921d1795aca7f3913"
|
||||
},
|
||||
"legal_pages.json": {
|
||||
"hash": "d379ad33a85a4387888d90fd75380b8a"
|
||||
"hash": "cd77592a612aa262580b1ad4eb0490dd"
|
||||
},
|
||||
"members.json": {
|
||||
"hash": "d625548b0c17df789d595691931732a3"
|
||||
"hash": "cad1568d161bea1a7dd1f286b8788e2d"
|
||||
},
|
||||
"news.json": {
|
||||
"hash": "c42353e9a510b365d09f2b64af401e55"
|
||||
},
|
||||
"pages.json": {
|
||||
"hash": "fe3fa7929ab20e981dd2f03d6d81f5d2"
|
||||
},
|
||||
"rom_checker.json": {
|
||||
"hash": "d23131981318ff9afa142b6512225cc3"
|
||||
"hash": "8d75bf99b2fb6528f84433f4519d4da3"
|
||||
},
|
||||
"rom_hasher.json": {
|
||||
"hash": "5f7ab5a76ff0060ac7854ca2c53ea245"
|
||||
"hash": "f322c39dd3ea03343ab626a1da796c55"
|
||||
},
|
||||
"rom_patcher.json": {
|
||||
"hash": "73fab3932646c350da9a40102f650d9d"
|
||||
"hash": "dff75392eea1fdffdaec193913d5d8a0"
|
||||
},
|
||||
"submissions_queue.json": {
|
||||
"hash": "f603ca2b1de0c4aaf60fadcec9ea85a7"
|
||||
"hash": "071c745afd8f28cf9505702496f72a18"
|
||||
},
|
||||
"support_us.json": {
|
||||
"hash": "bc0c8ad00084960abc5325c31849c543"
|
||||
},
|
||||
"tools.json": {
|
||||
"hash": "0221bb27d36511c5dd1feaf697626778"
|
||||
"hash": "3d56ca10d6cf3ff772e9ce92d200f2f8"
|
||||
},
|
||||
"website.json": {
|
||||
"hash": "e2f7d3d0102894eb09ecb359712d0fed"
|
||||
"hash": "9ca169f049cffa2cf82f395617e2b897"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"parent_navigation_id": "pages",
|
||||
"display_order": 2,
|
||||
"display_order": 200,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/pages/about",
|
||||
"link": "{{ link('help/about') }}",
|
||||
"display_condition": "",
|
||||
"extra_attributes": {
|
||||
"icon": "info"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"parent_navigation_id": "tools",
|
||||
"display_order": 3,
|
||||
"parent_navigation_id": "community",
|
||||
"display_order": 200,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/tools/rom-checker",
|
||||
"link": "{{ link('clubs') }}",
|
||||
"display_condition": "",
|
||||
"extra_attributes": {
|
||||
"icon": "check"
|
||||
"icon": "balloon"
|
||||
}
|
||||
},
|
||||
"enabled": true
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent_navigation_id": "",
|
||||
"display_order": 50,
|
||||
"display_order": 300,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"parent_navigation_id": "pages",
|
||||
"display_order": 3,
|
||||
"display_order": 300,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/pages/contact-us",
|
||||
"link": "{{ link('misc/contact') }}",
|
||||
"display_condition": "",
|
||||
"extra_attributes": {
|
||||
"icon": "at-sign"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent_navigation_id": "website",
|
||||
"display_order": 2,
|
||||
"display_order": 200,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/database",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"parent_navigation_id": "community",
|
||||
"display_order": 2,
|
||||
"display_order": 300,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/discord",
|
||||
"link": "https://discord.gg/5CKzeWmZZU",
|
||||
"display_condition": "",
|
||||
"extra_attributes": {
|
||||
"icon": "messages-square"
|
||||
|
||||
13
_output/navigation/drafts.json
Normal file
13
_output/navigation/drafts.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"parent_navigation_id": "website",
|
||||
"display_order": 400,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}/my-drafts",
|
||||
"display_condition": "{$xf.visitor.user_id}",
|
||||
"extra_attributes": {
|
||||
"icon": "scissors"
|
||||
}
|
||||
},
|
||||
"enabled": true
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent_navigation_id": "community",
|
||||
"display_order": 1,
|
||||
"display_order": 100,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.boardUrl}",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent_navigation_id": "website",
|
||||
"display_order": 1,
|
||||
"display_order": 100,
|
||||
"navigation_type_id": "basic",
|
||||
"type_config": {
|
||||
"link": "{$xf.options.homePageUrl}",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user