260 lines
9.9 KiB
PHP
260 lines
9.9 KiB
PHP
<?php
|
|
namespace Misuzu;
|
|
|
|
use DateTimeInterface;
|
|
use Carbon\CarbonImmutable;
|
|
use Misuzu\Parsers\{Parsers,TextFormat};
|
|
use Twig\{TwigFilter,TwigFunction};
|
|
use Twig\Extension\AbstractExtension;
|
|
|
|
final class TemplatingExtension extends AbstractExtension {
|
|
public function __construct(
|
|
private MisuzuContext $ctx,
|
|
private AssetInfo $assetInfo
|
|
) {}
|
|
|
|
public function getFilters() {
|
|
return [
|
|
new TwigFilter('country_name', Tools::countryName(...)),
|
|
new TwigFilter('parse_text', fn(string $text, TextFormat|string $parser): string => Parsers::instance($parser)->parseText($text)),
|
|
new TwigFilter('parse_md', fn(string $text): string => Parsers::instance(TextFormat::Markdown)->parseText($text)),
|
|
new TwigFilter('time_format', $this->timeFormat(...)),
|
|
];
|
|
}
|
|
|
|
public function getFunctions() {
|
|
return [
|
|
new TwigFunction('asset', $this->assetInfo->getAssetUrl(...)),
|
|
new TwigFunction('url', $this->ctx->urls->format(...)),
|
|
new TwigFunction('csrf_available', CSRF::available(...)),
|
|
new TwigFunction('csrf_token', CSRF::token(...)),
|
|
new TwigFunction('git_commit_hash', GitInfo::hash(...)),
|
|
new TwigFunction('git_tag', GitInfo::tag(...)),
|
|
new TwigFunction('git_branch', GitInfo::branch(...)),
|
|
new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time),
|
|
new TwigFunction('sql_query_count', $this->ctx->dbCtx->getQueryCount(...)),
|
|
new TwigFunction('msz_header_menu', $this->getHeaderMenu(...)),
|
|
new TwigFunction('msz_user_menu', $this->getUserMenu(...)),
|
|
new TwigFunction('msz_manage_menu', $this->getManageMenu(...)),
|
|
new TwigFunction('parser_options', function() {
|
|
return [
|
|
TextFormat::Plain->value => 'Plain text',
|
|
TextFormat::BBCode->value => 'BB Code',
|
|
TextFormat::Markdown->value => 'Markdown',
|
|
];
|
|
}),
|
|
];
|
|
}
|
|
|
|
public function timeFormat(DateTimeInterface|string|int|null $dateTime): string {
|
|
if($dateTime === null)
|
|
return 'never';
|
|
|
|
if(is_string($dateTime))
|
|
$dateTime = new CarbonImmutable($dateTime);
|
|
elseif(is_int($dateTime))
|
|
$dateTime = CarbonImmutable::createFromTimestampUTC($dateTime);
|
|
elseif(!($dateTime instanceof CarbonImmutable))
|
|
$dateTime = new CarbonImmutable($dateTime);
|
|
|
|
return $dateTime->diffForHumans();
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* title: string,
|
|
* url: string,
|
|
* menu?: array{
|
|
* title: string,
|
|
* url: string
|
|
* }[]
|
|
* }[]
|
|
*/
|
|
public function getHeaderMenu(): array {
|
|
$menu = [];
|
|
|
|
$home = [
|
|
'title' => 'Home',
|
|
'url' => $this->ctx->urls->format('index'),
|
|
'menu' => [],
|
|
];
|
|
|
|
if($this->ctx->authInfo->loggedIn)
|
|
$home['menu'][] = [
|
|
'title' => 'Members',
|
|
'url' => $this->ctx->urls->format('user-list'),
|
|
];
|
|
|
|
$home['menu'][] = [
|
|
'title' => 'Changelog',
|
|
'url' => $this->ctx->urls->format('changelog-index'),
|
|
];
|
|
$home['menu'][] = [
|
|
'title' => 'Contact',
|
|
'url' => $this->ctx->urls->format('info', ['title' => 'contact']),
|
|
];
|
|
$home['menu'][] = [
|
|
'title' => 'Rules',
|
|
'url' => $this->ctx->urls->format('info', ['title' => 'rules']),
|
|
];
|
|
if(!empty($this->ctx->siteInfo->bsky))
|
|
$home['menu'][] = [
|
|
'title' => 'Bluesky',
|
|
'url' => $this->ctx->siteInfo->bsky,
|
|
];
|
|
|
|
$menu[] = $home;
|
|
|
|
$menu[] = [
|
|
'title' => 'News',
|
|
'url' => $this->ctx->urls->format('news-index'),
|
|
];
|
|
|
|
$forum = [
|
|
'title' => 'Forum',
|
|
'url' => $this->ctx->urls->format('forum-index'),
|
|
'menu' => [],
|
|
];
|
|
|
|
if($this->ctx->authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
|
|
$forum['menu'][] = [
|
|
'title' => 'Leaderboard',
|
|
'url' => $this->ctx->urls->format('forum-leaderboard'),
|
|
];
|
|
|
|
$menu[] = $forum;
|
|
|
|
$chatPath = $this->ctx->getChatURL();
|
|
if(!empty($chatPath))
|
|
$menu[] = [
|
|
'title' => 'Chat',
|
|
'url' => $chatPath,
|
|
];
|
|
|
|
return $menu;
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* title: string,
|
|
* url: string,
|
|
* icon: string
|
|
* }[]
|
|
*/
|
|
public function getUserMenu(bool $inBroomCloset, string $manageUrl = ''): array {
|
|
$menu = [];
|
|
|
|
if($this->ctx->authInfo->loggedIn) {
|
|
$userInfo = $this->ctx->authInfo->userInfo;
|
|
$globalPerms = $this->ctx->authInfo->getPerms('global');
|
|
|
|
$menu[] = [
|
|
'title' => 'Profile',
|
|
'url' => $this->ctx->urls->format('user-profile', ['user' => $userInfo->id]),
|
|
'icon' => 'fas fa-user fa-fw',
|
|
];
|
|
if($globalPerms->check(Perm::G_MESSAGES_VIEW))
|
|
$menu[] = [
|
|
'title' => 'Messages',
|
|
'url' => $this->ctx->urls->format('messages-index'),
|
|
'icon' => 'fas fa-envelope fa-fw',
|
|
'class' => 'js-header-pms-button',
|
|
];
|
|
$menu[] = [
|
|
'title' => 'Settings',
|
|
'url' => $this->ctx->urls->format('settings-index'),
|
|
'icon' => 'fas fa-cog fa-fw',
|
|
];
|
|
$menu[] = [
|
|
'title' => 'Search',
|
|
'url' => $this->ctx->urls->format('search-index'),
|
|
'icon' => 'fas fa-search fa-fw',
|
|
];
|
|
|
|
if(!$this->ctx->usersCtx->hasActiveBan($userInfo) && $globalPerms->check(Perm::G_IS_JANITOR)) {
|
|
// restore behaviour where clicking this button switches between
|
|
// site version and broom version
|
|
if($inBroomCloset)
|
|
$menu[] = [
|
|
'title' => 'Exit Broom Closet',
|
|
'url' => $manageUrl === '' ? $this->ctx->urls->format('index') : $manageUrl,
|
|
'icon' => 'fas fa-door-open fa-fw',
|
|
];
|
|
else
|
|
$menu[] = [
|
|
'title' => 'Enter Broom Closet',
|
|
'url' => $manageUrl === '' ? $this->ctx->urls->format('manage-index') : $manageUrl,
|
|
'icon' => 'fas fa-door-closed fa-fw',
|
|
];
|
|
}
|
|
|
|
$menu[] = [
|
|
'title' => 'Log out',
|
|
'url' => $this->ctx->urls->format('auth-logout', ['csrf' => CSRF::token()]),
|
|
'icon' => 'fas fa-sign-out-alt fa-fw',
|
|
];
|
|
} else {
|
|
$menu[] = [
|
|
'title' => 'Register',
|
|
'url' => $this->ctx->urls->format('auth-register'),
|
|
'icon' => 'fas fa-user-plus fa-fw',
|
|
];
|
|
$menu[] = [
|
|
'title' => 'Log in',
|
|
'url' => $this->ctx->urls->format('auth-login'),
|
|
'icon' => 'fas fa-sign-in-alt fa-fw',
|
|
];
|
|
}
|
|
|
|
return $menu;
|
|
}
|
|
|
|
/** @return array<string, array<string, string>> */
|
|
public function getManageMenu(): array {
|
|
$globalPerms = $this->ctx->authInfo->getPerms('global');
|
|
if(!$this->ctx->authInfo->loggedIn || !$globalPerms->check(Perm::G_IS_JANITOR))
|
|
return [];
|
|
|
|
$menu = [
|
|
'General' => [
|
|
'Overview' => $this->ctx->urls->format('manage-general-overview'),
|
|
],
|
|
];
|
|
|
|
if($globalPerms->check(Perm::G_LOGS_VIEW))
|
|
$menu['General']['Logs'] = $this->ctx->urls->format('manage-general-logs');
|
|
if($globalPerms->check(Perm::G_EMOTES_MANAGE))
|
|
$menu['General']['Emoticons'] = $this->ctx->urls->format('manage-general-emoticons');
|
|
if($globalPerms->check(Perm::G_CONFIG_MANAGE))
|
|
$menu['General']['Settings'] = $this->ctx->urls->format('manage-general-settings');
|
|
|
|
$userPerms = $this->ctx->authInfo->getPerms('user');
|
|
if($userPerms->check(Perm::U_USERS_MANAGE))
|
|
$menu['Users & Roles']['Users'] = $this->ctx->urls->format('manage-users');
|
|
if($userPerms->check(Perm::U_ROLES_MANAGE))
|
|
$menu['Users & Roles']['Roles'] = $this->ctx->urls->format('manage-roles');
|
|
if($userPerms->check(Perm::U_NOTES_MANAGE))
|
|
$menu['Users & Roles']['Notes'] = $this->ctx->urls->format('manage-users-notes');
|
|
if($userPerms->check(Perm::U_WARNINGS_MANAGE))
|
|
$menu['Users & Roles']['Warnings'] = $this->ctx->urls->format('manage-users-warnings');
|
|
if($userPerms->check(Perm::U_BANS_MANAGE))
|
|
$menu['Users & Roles']['Bans'] = $this->ctx->urls->format('manage-users-bans');
|
|
|
|
if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
|
|
$menu['News']['Posts'] = $this->ctx->urls->format('manage-news-posts');
|
|
if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
|
|
$menu['News']['Categories'] = $this->ctx->urls->format('manage-news-categories');
|
|
|
|
if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
|
|
$menu['Forum']['Permission Calculator'] = $this->ctx->urls->format('manage-forum-categories');
|
|
if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
|
|
$menu['Forum']['Topic Redirects'] = $this->ctx->urls->format('manage-forum-topic-redirs');
|
|
|
|
if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
|
|
$menu['Changelog']['Changes'] = $this->ctx->urls->format('manage-changelog-changes');
|
|
if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
|
|
$menu['Changelog']['Tags'] = $this->ctx->urls->format('manage-changelog-tags');
|
|
|
|
return $menu;
|
|
}
|
|
}
|