misuzu/src/MisuzuSasaeExtension.php

245 lines
9 KiB
PHP

<?php
namespace Misuzu;
use DateTimeInterface;
use Misuzu\MisuzuContext;
use Misuzu\Tools;
use Misuzu\Parsers\Parser;
use Carbon\CarbonImmutable;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
final class MisuzuSasaeExtension extends AbstractExtension {
private MisuzuContext $ctx;
private ?object $assets;
public function __construct(MisuzuContext $ctx) {
$this->ctx = $ctx;
$this->assets = $ctx->getWebAssetInfo();
}
public function getFilters() {
return [
new TwigFilter('country_name', Tools::countryName(...)),
new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)),
new TwigFilter('time_format', $this->timeFormat(...)),
];
}
public function getFunctions() {
return [
new TwigFunction('asset', $this->getAssetPath(...)),
new TwigFunction('url', $this->ctx->getURLs()->format(...)),
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->getDbQueryCount(...)),
new TwigFunction('msz_header_menu', $this->getHeaderMenu(...)),
new TwigFunction('msz_user_menu', $this->getUserMenu(...)),
new TwigFunction('msz_manage_menu', $this->getManageMenu(...)),
];
}
public function getAssetPath(string $name): string {
return $this->assets?->{$name} ?? '';
}
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();
}
public function getHeaderMenu(): array {
$menu = [];
$urls = $this->ctx->getURLs();
$authInfo = $this->ctx->getAuthInfo();
$home = [
'title' => 'Home',
'url' => $urls->format('index'),
'menu' => [],
];
if($authInfo->isLoggedIn())
$home['menu'][] = [
'title' => 'Members',
'url' => $urls->format('user-list'),
];
$home['menu'][] = [
'title' => 'Changelog',
'url' => $urls->format('changelog-index'),
];
$home['menu'][] = [
'title' => 'Contact',
'url' => $urls->format('info', ['title' => 'contact']),
];
$home['menu'][] = [
'title' => 'Rules',
'url' => $urls->format('info', ['title' => 'rules']),
];
$menu[] = $home;
$menu[] = [
'title' => 'News',
'url' => $urls->format('news-index'),
];
$forum = [
'title' => 'Forum',
'url' => $urls->format('forum-index'),
'menu' => [],
];
if($authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
$forum['menu'][] = [
'title' => 'Leaderboard',
'url' => $urls->format('forum-leaderboard'),
];
$menu[] = $forum;
$chatPath = $this->ctx->getChatURL();
if(!empty($chatPath))
$menu[] = [
'title' => 'Chat',
'url' => $chatPath,
];
return $menu;
}
public function getUserMenu(bool $inBroomCloset, string $manageUrl = ''): array {
$menu = [];
$urls = $this->ctx->getURLs();
$authInfo = $this->ctx->getAuthInfo();
$usersCtx = $this->ctx->getUsersContext();
if($authInfo->isLoggedIn()) {
$userInfo = $authInfo->getUserInfo();
$globalPerms = $authInfo->getPerms('global');
$menu[] = [
'title' => 'Profile',
'url' => $urls->format('user-profile', ['user' => $userInfo->getId()]),
'icon' => 'fas fa-user fa-fw',
];
if($globalPerms->check(Perm::G_MESSAGES_VIEW))
$menu[] = [
'title' => 'Messages',
'url' => $urls->format('messages-index'),
'icon' => 'fas fa-envelope fa-fw',
'class' => 'js-header-pms-button',
];
$menu[] = [
'title' => 'Settings',
'url' => $urls->format('settings-index'),
'icon' => 'fas fa-cog fa-fw',
];
$menu[] = [
'title' => 'Search',
'url' => $urls->format('search-index'),
'icon' => 'fas fa-search fa-fw',
];
if(!$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 === '' ? $urls->format('index') : $manageUrl,
'icon' => 'fas fa-door-open fa-fw',
];
else
$menu[] = [
'title' => 'Enter Broom Closet',
'url' => $manageUrl === '' ? $urls->format('manage-index') : $manageUrl,
'icon' => 'fas fa-door-closed fa-fw',
];
}
$menu[] = [
'title' => 'Log out',
'url' => $urls->format('auth-logout', ['csrf' => CSRF::token()]),
'icon' => 'fas fa-sign-out-alt fa-fw',
];
} else {
$menu[] = [
'title' => 'Register',
'url' => $urls->format('auth-register'),
'icon' => 'fas fa-user-plus fa-fw',
];
$menu[] = [
'title' => 'Log in',
'url' => $urls->format('auth-login'),
'icon' => 'fas fa-sign-in-alt fa-fw',
];
}
return $menu;
}
public function getManageMenu(): array {
$urls = $this->ctx->getURLs();
$authInfo = $this->ctx->getAuthInfo();
$globalPerms = $authInfo->getPerms('global');
if(!$authInfo->isLoggedIn() || !$globalPerms->check(Perm::G_IS_JANITOR))
return [];
$menu = [
'General' => [
'Overview' => $urls->format('manage-general-overview'),
],
];
if($globalPerms->check(Perm::G_LOGS_VIEW))
$menu['General']['Logs'] = $urls->format('manage-general-logs');
if($globalPerms->check(Perm::G_EMOTES_MANAGE))
$menu['General']['Emoticons'] = $urls->format('manage-general-emoticons');
if($globalPerms->check(Perm::G_CONFIG_MANAGE))
$menu['General']['Settings'] = $urls->format('manage-general-settings');
$userPerms = $authInfo->getPerms('user');
if($userPerms->check(Perm::U_USERS_MANAGE))
$menu['Users & Roles']['Users'] = $urls->format('manage-users');
if($userPerms->check(Perm::U_ROLES_MANAGE))
$menu['Users & Roles']['Roles'] = $urls->format('manage-roles');
if($userPerms->check(Perm::U_NOTES_MANAGE))
$menu['Users & Roles']['Notes'] = $urls->format('manage-users-notes');
if($userPerms->check(Perm::U_WARNINGS_MANAGE))
$menu['Users & Roles']['Warnings'] = $urls->format('manage-users-warnings');
if($userPerms->check(Perm::U_BANS_MANAGE))
$menu['Users & Roles']['Bans'] = $urls->format('manage-users-bans');
if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
$menu['News']['Posts'] = $urls->format('manage-news-posts');
if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
$menu['News']['Categories'] = $urls->format('manage-news-categories');
if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
$menu['Forum']['Permission Calculator'] = $urls->format('manage-forum-categories');
if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
$menu['Forum']['Topic Redirects'] = $urls->format('manage-forum-topic-redirs');
if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
$menu['Changelog']['Changes'] = $urls->format('manage-changelog-changes');
if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
$menu['Changelog']['Tags'] = $urls->format('manage-changelog-tags');
return $menu;
}
}