Switch to Sasae.
This commit is contained in:
parent
9682fa595a
commit
1da6470928
15 changed files with 503 additions and 410 deletions
|
@ -3,7 +3,7 @@
|
|||
"prefer-stable": true,
|
||||
"require": {
|
||||
"flashwave/index": "dev-master",
|
||||
"twig/twig": "^3.0",
|
||||
"flashwave/sasae": "dev-master",
|
||||
"erusev/parsedown": "~1.6",
|
||||
"chillerlan/php-qrcode": "^4.3",
|
||||
"symfony/mailer": "^6.0",
|
||||
|
|
202
composer.lock
generated
202
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c76eb19b0eb02b6a9fccb4b63f50d165",
|
||||
"content-hash": "313710f128265bd0f0f9e7687058324b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
|
@ -348,7 +348,7 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.flash.moe/flash/index.git",
|
||||
"reference": "6a38f803f4b3e49296f7472743e7c683c496ec19"
|
||||
"reference": "1172115e699acf44580ffcdcf86c9e3987d2f969"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
|
@ -386,7 +386,48 @@
|
|||
],
|
||||
"description": "Composer package for the common library for my projects.",
|
||||
"homepage": "https://railgun.sh/index",
|
||||
"time": "2023-08-22T00:04:20+00:00"
|
||||
"time": "2023-08-28T13:58:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "flashwave/sasae",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.flash.moe/flash/sasae.git",
|
||||
"reference": "739669fc8ce7ea862ed2129cb24976ceebd0f4c7"
|
||||
},
|
||||
"require": {
|
||||
"flashwave/index": "dev-master",
|
||||
"php": ">=8.2",
|
||||
"twig/html-extra": "^3.7",
|
||||
"twig/twig": "^3.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^10.2"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sasae\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"bsd-3-clause-clear"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "flashwave",
|
||||
"email": "packagist@flash.moe",
|
||||
"homepage": "https://flash.moe",
|
||||
"role": "mom"
|
||||
}
|
||||
],
|
||||
"description": "A wrapper for Twig with added common functionality.",
|
||||
"homepage": "https://railgun.sh/sasae",
|
||||
"time": "2023-08-24T23:24:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matomo/device-detector",
|
||||
|
@ -1049,16 +1090,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
|
||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1073,7 +1114,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
|
@ -1111,7 +1152,7 @@
|
|||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1127,20 +1168,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "639084e360537a19f9ee352433b84ce831f3d2da"
|
||||
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da",
|
||||
"reference": "639084e360537a19f9ee352433b84ce831f3d2da",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
|
||||
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1154,7 +1195,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
|
@ -1198,7 +1239,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1214,20 +1255,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2023-01-26T09:30:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
|
||||
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
|
||||
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
|
||||
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1239,7 +1280,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
|
@ -1282,7 +1323,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1298,20 +1339,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1326,7 +1367,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
|
@ -1365,7 +1406,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1381,20 +1422,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2023-07-28T09:04:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
|
||||
"reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
|
||||
"reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1403,7 +1444,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
|
@ -1441,7 +1482,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1457,7 +1498,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
|
@ -1542,17 +1583,81 @@
|
|||
"time": "2023-05-23T14:45:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.7.0",
|
||||
"name": "twig/html-extra",
|
||||
"version": "v3.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b"
|
||||
"url": "https://github.com/twigphp/html-extra.git",
|
||||
"reference": "95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/5cf942bbab3df42afa918caeba947f1b690af64b",
|
||||
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b",
|
||||
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386",
|
||||
"reference": "95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"symfony/mime": "^5.4|^6.0",
|
||||
"twig/twig": "^2.7|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^5.4|^6.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Twig\\Extra\\Html\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "A Twig extension for HTML",
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"keywords": [
|
||||
"html",
|
||||
"twig"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/twigphp/html-extra/tree/v3.7.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-29T15:34:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1562,7 +1667,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -1598,7 +1703,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.7.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.7.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1610,7 +1715,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-26T07:16:09+00:00"
|
||||
"time": "2023-08-28T11:09:02+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -1680,7 +1785,8 @@
|
|||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {
|
||||
"flashwave/index": 20
|
||||
"flashwave/index": 20,
|
||||
"flashwave/sasae": 20
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
|
|
127
public/index.php
127
public/index.php
|
@ -5,6 +5,7 @@ use RuntimeException;
|
|||
use Misuzu\Auth\AuthTokenBuilder;
|
||||
use Misuzu\Auth\AuthTokenCookie;
|
||||
use Misuzu\Auth\AuthTokenInfo;
|
||||
use Sasae\SasaeEnvironment;
|
||||
|
||||
require_once __DIR__ . '/../misuzu.php';
|
||||
|
||||
|
@ -38,44 +39,6 @@ if(file_exists(MSZ_ROOT . '/.migrating')) {
|
|||
exit;
|
||||
}
|
||||
|
||||
if(!MSZ_DEBUG) {
|
||||
$twigCacheDirSfx = GitInfo::hash(true);
|
||||
if(empty($twigCacheDirSfx))
|
||||
$twigCacheDirSfx = md5(MSZ_ROOT);
|
||||
|
||||
$twigCache = sys_get_temp_dir() . '/msz-tpl-' . $twigCacheDirSfx;
|
||||
if(!is_dir($twigCache))
|
||||
mkdir($twigCache, 0775, true);
|
||||
}
|
||||
|
||||
$globals = $cfg->getValues([
|
||||
['site.name:s', 'Misuzu'],
|
||||
'site.desc:s',
|
||||
'site.url:s',
|
||||
'eeprom.path:s',
|
||||
'eeprom.app:s',
|
||||
['csrf.secret:s', 'soup'],
|
||||
]);
|
||||
|
||||
Template::init($msz, $twigCache ?? null, MSZ_DEBUG);
|
||||
|
||||
Template::set('globals', [
|
||||
'site_name' => $globals['site.name'],
|
||||
'site_description' => $globals['site.desc'],
|
||||
'site_url' => $globals['site.url'],
|
||||
'eeprom' => [
|
||||
'path' => $globals['eeprom.path'],
|
||||
'app' => $globals['eeprom.app'],
|
||||
],
|
||||
]);
|
||||
|
||||
$mszAssetsInfo = json_decode(file_get_contents(MSZ_ASSETS . '/current.json'));
|
||||
if(!empty($mszAssetsInfo))
|
||||
Template::set('assets', $mszAssetsInfo);
|
||||
unset($mszAssetsInfo);
|
||||
|
||||
Template::addPath(MSZ_TEMPLATES);
|
||||
|
||||
$tokenPacker = $msz->createAuthTokenPacker();
|
||||
|
||||
if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
|
||||
|
@ -156,95 +119,21 @@ if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
|
|||
|
||||
$msz->getAuthInfo()->setInfo($tokenInfo, $userInfo, $sessionInfo, $userInfoReal);
|
||||
|
||||
if(!empty($userInfo))
|
||||
$userInfo = $users->getUser((string)$userInfo->getId(), 'id');
|
||||
if(!empty($userInfoReal))
|
||||
$userInfoReal = $users->getUser((string)$userInfoReal->getId(), 'id');
|
||||
|
||||
CSRF::init(
|
||||
$globals['csrf.secret'],
|
||||
$cfg->getString('csrf.secret', 'soup'),
|
||||
($msz->isLoggedIn() ? $sessionInfo->getToken() : $_SERVER['REMOTE_ADDR'])
|
||||
);
|
||||
|
||||
if(!empty($userInfo)) {
|
||||
Template::set('current_user', $userInfo);
|
||||
Template::set('current_user_ban_info', $msz->tryGetActiveBan());
|
||||
}
|
||||
|
||||
if(!empty($userInfoReal)) {
|
||||
Template::set('current_user_real', $userInfoReal);
|
||||
Template::set('current_user_real_colour', $users->getUserColour($userInfoReal));
|
||||
}
|
||||
|
||||
$inManageMode = str_starts_with($_SERVER['REQUEST_URI'], '/manage');
|
||||
|
||||
Template::set('header_menu', $msz->getHeaderMenu($userInfo ?? null));
|
||||
Template::set('user_menu', $msz->getUserMenu($userInfo ?? null, $inManageMode));
|
||||
Template::set('display_timings_info', MSZ_DEBUG || $msz->getAuthInfo()->getPerms('global')->check(Perm::G_TIMINGS_VIEW));
|
||||
|
||||
if($inManageMode) {
|
||||
$hasManageAccess = false;
|
||||
|
||||
if($msz->isLoggedIn() && !$msz->hasActiveBan()) {
|
||||
$manageUser = $msz->getActiveUser();
|
||||
$manageUserId = $manageUser->getId();
|
||||
$manageGlobalPerms = $msz->getAuthInfo()->getPerms('global');
|
||||
|
||||
if($manageGlobalPerms->check(Perm::G_IS_JANITOR)) {
|
||||
$hasManageAccess = true;
|
||||
$manageMenu = [
|
||||
'General' => [
|
||||
'Overview' => url('manage-general-overview'),
|
||||
],
|
||||
];
|
||||
|
||||
if($manageGlobalPerms->check(Perm::G_LOGS_VIEW))
|
||||
$manageMenu['General']['Logs'] = url('manage-general-logs');
|
||||
if($manageGlobalPerms->check(Perm::G_EMOTES_MANAGE))
|
||||
$manageMenu['General']['Emoticons'] = url('manage-general-emoticons');
|
||||
if($manageGlobalPerms->check(Perm::G_CONFIG_MANAGE))
|
||||
$manageMenu['General']['Settings'] = url('manage-general-settings');
|
||||
|
||||
$manageUserPerms = $msz->getAuthInfo()->getPerms('user');
|
||||
if($manageUserPerms->check(Perm::U_USERS_MANAGE))
|
||||
$manageMenu['Users & Roles']['Users'] = url('manage-users');
|
||||
if($manageUserPerms->check(Perm::U_ROLES_MANAGE))
|
||||
$manageMenu['Users & Roles']['Roles'] = url('manage-roles');
|
||||
if($manageUserPerms->check(Perm::U_NOTES_MANAGE))
|
||||
$manageMenu['Users & Roles']['Notes'] = url('manage-users-notes');
|
||||
if($manageUserPerms->check(Perm::U_WARNINGS_MANAGE))
|
||||
$manageMenu['Users & Roles']['Warnings'] = url('manage-users-warnings');
|
||||
if($manageUserPerms->check(Perm::U_BANS_MANAGE))
|
||||
$manageMenu['Users & Roles']['Bans'] = url('manage-users-bans');
|
||||
|
||||
if($manageGlobalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
|
||||
$manageMenu['News']['Posts'] = url('manage-news-posts');
|
||||
if($manageGlobalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
|
||||
$manageMenu['News']['Categories'] = url('manage-news-categories');
|
||||
|
||||
if($manageGlobalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
|
||||
$manageMenu['Forum']['Permission Calculator'] = url('manage-forum-categories');
|
||||
if($manageGlobalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
|
||||
$manageMenu['Forum']['Topic Redirects'] = url('manage-forum-topic-redirs');
|
||||
|
||||
if($manageGlobalPerms->check(Perm::G_CL_CHANGES_MANAGE))
|
||||
$manageMenu['Changelog']['Changes'] = url('manage-changelog-changes');
|
||||
if($manageGlobalPerms->check(Perm::G_CL_TAGS_MANAGE))
|
||||
$manageMenu['Changelog']['Tags'] = url('manage-changelog-tags');
|
||||
|
||||
Template::set('manage_menu', $manageMenu);
|
||||
}
|
||||
}
|
||||
|
||||
if(!$hasManageAccess)
|
||||
Template::throwError(403);
|
||||
}
|
||||
$msz->startTemplating();
|
||||
|
||||
$mszRequestPath = $request->getPath();
|
||||
$mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/';
|
||||
$mszLegacyPath = realpath($mszLegacyPathPrefix . $mszRequestPath);
|
||||
|
||||
if(!empty($mszLegacyPath) && str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) {
|
||||
if(str_starts_with($mszRequestPath, '/manage') && !$msz->hasManageAccess())
|
||||
Template::throwError(403);
|
||||
|
||||
if(is_dir($mszLegacyPath))
|
||||
$mszLegacyPath .= '/index.php';
|
||||
|
||||
|
@ -254,5 +143,5 @@ if(!empty($mszLegacyPath) && str_starts_with($mszLegacyPath, $mszLegacyPathPrefi
|
|||
}
|
||||
}
|
||||
|
||||
$msz->setUpHttp();
|
||||
$msz->dispatchHttp($request);
|
||||
$msz->startRouter();
|
||||
$msz->dispatchRouter($request);
|
||||
|
|
|
@ -172,9 +172,11 @@ class DbConfig implements IConfig {
|
|||
if(is_string($spec)) {
|
||||
$name = $spec;
|
||||
$default = null;
|
||||
$alias = null;
|
||||
} elseif(is_array($spec) && !empty($spec)) {
|
||||
$name = $spec[0];
|
||||
$default = $spec[1] ?? null;
|
||||
$alias = $spec[2] ?? null;
|
||||
} else
|
||||
throw new InvalidArgumentException('$specs array contains an invalid entry.');
|
||||
|
||||
|
@ -188,6 +190,7 @@ class DbConfig implements IConfig {
|
|||
'name' => $name,
|
||||
'type' => $type,
|
||||
'default' => $default,
|
||||
'alias' => $alias,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -201,6 +204,8 @@ class DbConfig implements IConfig {
|
|||
break;
|
||||
}
|
||||
|
||||
$resultName = $spec['alias'] ?? $spec['name'];
|
||||
|
||||
if(!isset($info)) {
|
||||
$defaultValue = $spec['default'] ?? null;
|
||||
if($spec['type'] !== '')
|
||||
|
@ -214,11 +219,11 @@ class DbConfig implements IConfig {
|
|||
default => throw new RuntimeException('Invalid type letter encountered.'),
|
||||
});
|
||||
|
||||
$results[$spec['name']] = $defaultValue;
|
||||
$results[$resultName] = $defaultValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
$results[$spec['name']] = match($spec['type']) {
|
||||
$results[$resultName] = match($spec['type']) {
|
||||
's' => $info->getString(),
|
||||
'a' => $info->getArray(),
|
||||
'i' => $info->getInteger(),
|
||||
|
|
|
@ -8,6 +8,7 @@ use Index\Data\Migration\FsDbMigrationRepo;
|
|||
use Index\Http\HttpFx;
|
||||
use Index\Http\HttpRequest;
|
||||
use Index\Routing\Router;
|
||||
use Sasae\SasaeEnvironment;
|
||||
use Misuzu\Template;
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Auth\AuthTokenPacker;
|
||||
|
@ -69,6 +70,7 @@ class MisuzuContext {
|
|||
private Forum $forum;
|
||||
private Permissions $perms;
|
||||
private AuthInfo $authInfo;
|
||||
private SasaeEnvironment $templating;
|
||||
|
||||
public function __construct(IDbConnection $dbConn, IConfig $config) {
|
||||
$this->dbConn = $dbConn;
|
||||
|
@ -218,10 +220,10 @@ class MisuzuContext {
|
|||
}
|
||||
|
||||
$userId = (string)$userInfo->getId();
|
||||
if(array_key_exists($userId, $this->activeBansCache))
|
||||
return $this->activeBansCache[$userId];
|
||||
if(!array_key_exists($userId, $this->activeBansCache))
|
||||
$this->activeBansCache[$userId] = $this->bans->tryGetActiveBan($userId);
|
||||
|
||||
return $this->activeBansCache[$userId] = $this->bans->tryGetActiveBan($userId);
|
||||
return $this->activeBansCache[$userId];
|
||||
}
|
||||
|
||||
public function hasActiveBan(UserInfo|string|null $userInfo = null): bool {
|
||||
|
@ -241,125 +243,51 @@ class MisuzuContext {
|
|||
);
|
||||
}
|
||||
|
||||
public function getHeaderMenu(?UserInfo $userInfo): array {
|
||||
$hasUserInfo = $userInfo?->isDeleted() === false;
|
||||
$menu = [];
|
||||
|
||||
$home = [
|
||||
'title' => 'Home',
|
||||
'url' => url('index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($hasUserInfo)
|
||||
$home['menu'][] = [
|
||||
'title' => 'Members',
|
||||
'url' => url('user-list'),
|
||||
];
|
||||
|
||||
$home['menu'][] = [
|
||||
'title' => 'Changelog',
|
||||
'url' => url('changelog-index'),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Contact',
|
||||
'url' => url('info', ['title' => 'contact']),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Rules',
|
||||
'url' => url('info', ['title' => 'rules']),
|
||||
];
|
||||
|
||||
$menu[] = $home;
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'News',
|
||||
'url' => url('news-index'),
|
||||
];
|
||||
|
||||
$forum = [
|
||||
'title' => 'Forum',
|
||||
'url' => url('forum-index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($this->authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
|
||||
$forum['menu'][] = [
|
||||
'title' => 'Leaderboard',
|
||||
'url' => url('forum-leaderboard'),
|
||||
];
|
||||
|
||||
$menu[] = $forum;
|
||||
|
||||
$chatPath = $this->config->getString('sockChat.chatPath.normal');
|
||||
if(!empty($chatPath))
|
||||
$menu[] = [
|
||||
'title' => 'Chat',
|
||||
'url' => $chatPath,
|
||||
];
|
||||
|
||||
return $menu;
|
||||
private ?bool $hasManageAccess = null;
|
||||
public function hasManageAccess(): bool {
|
||||
$this->hasManageAccess ??= $this->authInfo->isLoggedIn() && !$this->hasActiveBan()
|
||||
&& $this->getAuthInfo()->getPerms('global')->check(Perm::G_IS_JANITOR);
|
||||
return $this->hasManageAccess;
|
||||
}
|
||||
|
||||
public function getUserMenu(?UserInfo $userInfo, bool $inBroomCloset): array {
|
||||
$menu = [];
|
||||
|
||||
if($userInfo === null) {
|
||||
$menu[] = [
|
||||
'title' => 'Register',
|
||||
'url' => url('auth-register'),
|
||||
'icon' => 'fas fa-user-plus fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Log in',
|
||||
'url' => url('auth-login'),
|
||||
'icon' => 'fas fa-sign-in-alt fa-fw',
|
||||
];
|
||||
} else {
|
||||
$menu[] = [
|
||||
'title' => 'Profile',
|
||||
'url' => url('user-profile', ['user' => $userInfo->getId()]),
|
||||
'icon' => 'fas fa-user fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Settings',
|
||||
'url' => url('settings-index'),
|
||||
'icon' => 'fas fa-cog fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Search',
|
||||
'url' => url('search-index'),
|
||||
'icon' => 'fas fa-search fa-fw',
|
||||
];
|
||||
|
||||
if(!$this->hasActiveBan($userInfo) && $this->authInfo->getPerms('global')->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' => url('index'),
|
||||
'icon' => 'fas fa-door-open fa-fw',
|
||||
];
|
||||
else
|
||||
$menu[] = [
|
||||
'title' => 'Enter Broom Closet',
|
||||
'url' => url('manage-index'),
|
||||
'icon' => 'fas fa-door-closed fa-fw',
|
||||
];
|
||||
}
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'Log out',
|
||||
'url' => url('auth-logout'),
|
||||
'icon' => 'fas fa-sign-out-alt fa-fw',
|
||||
];
|
||||
}
|
||||
|
||||
return $menu;
|
||||
public function getWebAssetInfo(): ?object {
|
||||
return json_decode(file_get_contents(MSZ_ASSETS . '/current.json'));
|
||||
}
|
||||
|
||||
public function setUpHttp(): void {
|
||||
private ?string $chatUrl = null;
|
||||
public function getChatURL(): string {
|
||||
$this->chatUrl ??= $this->config->getString('sockChat.chatPath.normal');
|
||||
return $this->chatUrl;
|
||||
}
|
||||
|
||||
public function startTemplating(): void {
|
||||
$globals = $this->config->getValues([
|
||||
['site.name:s', 'Misuzu', 'site_name'],
|
||||
['site.desc:s', '', 'site_description'],
|
||||
['site.url:s', '', 'site_url'],
|
||||
['eeprom.path:s', '', 'eeprom_path'],
|
||||
['eeprom.app:s', '', 'eeprom_app'],
|
||||
]);
|
||||
|
||||
$authInfo = $this->getAuthInfo();
|
||||
$globals['assets'] = $this->getWebAssetInfo();
|
||||
$globals['auth_info'] = $authInfo;
|
||||
$globals['active_ban_info'] = $this->tryGetActiveBan();
|
||||
$globals['display_timings_info'] = MSZ_DEBUG
|
||||
|| $authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW);
|
||||
|
||||
$templating = new SasaeEnvironment(
|
||||
MSZ_TEMPLATES,
|
||||
cache: MSZ_DEBUG ? null : ['Misuzu', GitInfo::hash(true)],
|
||||
debug: MSZ_DEBUG
|
||||
);
|
||||
$templating->addExtension(new MisuzuSasaeExtension($this));
|
||||
$templating->addGlobal('globals', $globals);
|
||||
|
||||
Template::init($templating);
|
||||
}
|
||||
|
||||
public function startRouter(): void {
|
||||
$this->router = new HttpFx;
|
||||
$this->router->use('/', function($response) {
|
||||
$response->setPoweredBy('Misuzu');
|
||||
|
@ -369,7 +297,7 @@ class MisuzuContext {
|
|||
$this->registerHttpRoutes();
|
||||
}
|
||||
|
||||
public function dispatchHttp(?HttpRequest $request = null): void {
|
||||
public function dispatchRouter(?HttpRequest $request = null): void {
|
||||
$this->router->dispatch($request);
|
||||
}
|
||||
|
||||
|
|
238
src/MisuzuSasaeExtension.php
Normal file
238
src/MisuzuSasaeExtension.php
Normal file
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Index\DateTime;
|
||||
use Misuzu\MisuzuContext;
|
||||
use Misuzu\Tools;
|
||||
use Misuzu\Parsers\Parser;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
final class MisuzuSasaeExtension extends AbstractExtension {
|
||||
private MisuzuContext $ctx;
|
||||
|
||||
public function __construct(MisuzuContext $ctx) {
|
||||
$this->ctx = $ctx;
|
||||
}
|
||||
|
||||
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('url_construct', 'url_construct'),
|
||||
new TwigFunction('url', 'url'),
|
||||
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 timeFormat(DateTime|string|int|null $dateTime): string {
|
||||
if($dateTime === null)
|
||||
return 'never';
|
||||
|
||||
if(is_string($dateTime))
|
||||
$dateTime = new DateTime($dateTime);
|
||||
elseif(is_int($dateTime))
|
||||
$dateTime = DateTime::fromUnixTimeSeconds($dateTime);
|
||||
|
||||
$string = '';
|
||||
$now = DateTime::now();
|
||||
|
||||
$isDiffYear = $now->getYear() !== $dateTime->getYear();
|
||||
if($isDiffYear || $now->getMonth() !== $dateTime->getMonth() || $now->getDay() !== $dateTime->getDay()) {
|
||||
$string .= $dateTime->format('M jS');
|
||||
if($isDiffYear)
|
||||
$string .= $dateTime->format(' Y');
|
||||
$string .= ', ';
|
||||
}
|
||||
|
||||
$string .= $dateTime->format('G:i ');
|
||||
$string .= $dateTime->isUTC() ? 'UTC' : $dateTime->format('T');
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function getHeaderMenu(): array {
|
||||
$menu = [];
|
||||
$authInfo = $this->ctx->getAuthInfo();
|
||||
|
||||
$home = [
|
||||
'title' => 'Home',
|
||||
'url' => url('index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($authInfo->isLoggedIn())
|
||||
$home['menu'][] = [
|
||||
'title' => 'Members',
|
||||
'url' => url('user-list'),
|
||||
];
|
||||
|
||||
$home['menu'][] = [
|
||||
'title' => 'Changelog',
|
||||
'url' => url('changelog-index'),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Contact',
|
||||
'url' => url('info', ['title' => 'contact']),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Rules',
|
||||
'url' => url('info', ['title' => 'rules']),
|
||||
];
|
||||
|
||||
$menu[] = $home;
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'News',
|
||||
'url' => url('news-index'),
|
||||
];
|
||||
|
||||
$forum = [
|
||||
'title' => 'Forum',
|
||||
'url' => url('forum-index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
|
||||
$forum['menu'][] = [
|
||||
'title' => 'Leaderboard',
|
||||
'url' => url('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 = [];
|
||||
$authInfo = $this->ctx->getAuthInfo();
|
||||
|
||||
if($authInfo->isLoggedIn()) {
|
||||
$userInfo = $authInfo->getUserInfo();
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'Profile',
|
||||
'url' => url('user-profile', ['user' => $userInfo->getId()]),
|
||||
'icon' => 'fas fa-user fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Settings',
|
||||
'url' => url('settings-index'),
|
||||
'icon' => 'fas fa-cog fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Search',
|
||||
'url' => url('search-index'),
|
||||
'icon' => 'fas fa-search fa-fw',
|
||||
];
|
||||
|
||||
if(!$this->ctx->hasActiveBan($userInfo) && $authInfo->getPerms('global')->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 === '' ? url('index') : $manageUrl,
|
||||
'icon' => 'fas fa-door-open fa-fw',
|
||||
];
|
||||
else
|
||||
$menu[] = [
|
||||
'title' => 'Enter Broom Closet',
|
||||
'url' => $manageUrl === '' ? url('manage-index') : $manageUrl,
|
||||
'icon' => 'fas fa-door-closed fa-fw',
|
||||
];
|
||||
}
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'Log out',
|
||||
'url' => url('auth-logout'),
|
||||
'icon' => 'fas fa-sign-out-alt fa-fw',
|
||||
];
|
||||
} else {
|
||||
$menu[] = [
|
||||
'title' => 'Register',
|
||||
'url' => url('auth-register'),
|
||||
'icon' => 'fas fa-user-plus fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Log in',
|
||||
'url' => url('auth-login'),
|
||||
'icon' => 'fas fa-sign-in-alt fa-fw',
|
||||
];
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
public function getManageMenu(): array {
|
||||
$authInfo = $this->ctx->getAuthInfo();
|
||||
$globalPerms = $authInfo->getPerms('global');
|
||||
if(!$authInfo->isLoggedIn() || !$globalPerms->check(Perm::G_IS_JANITOR))
|
||||
return [];
|
||||
|
||||
$menu = [
|
||||
'General' => [
|
||||
'Overview' => url('manage-general-overview'),
|
||||
],
|
||||
];
|
||||
|
||||
if($globalPerms->check(Perm::G_LOGS_VIEW))
|
||||
$menu['General']['Logs'] = url('manage-general-logs');
|
||||
if($globalPerms->check(Perm::G_EMOTES_MANAGE))
|
||||
$menu['General']['Emoticons'] = url('manage-general-emoticons');
|
||||
if($globalPerms->check(Perm::G_CONFIG_MANAGE))
|
||||
$menu['General']['Settings'] = url('manage-general-settings');
|
||||
|
||||
$userPerms = $authInfo->getPerms('user');
|
||||
if($userPerms->check(Perm::U_USERS_MANAGE))
|
||||
$menu['Users & Roles']['Users'] = url('manage-users');
|
||||
if($userPerms->check(Perm::U_ROLES_MANAGE))
|
||||
$menu['Users & Roles']['Roles'] = url('manage-roles');
|
||||
if($userPerms->check(Perm::U_NOTES_MANAGE))
|
||||
$menu['Users & Roles']['Notes'] = url('manage-users-notes');
|
||||
if($userPerms->check(Perm::U_WARNINGS_MANAGE))
|
||||
$menu['Users & Roles']['Warnings'] = url('manage-users-warnings');
|
||||
if($userPerms->check(Perm::U_BANS_MANAGE))
|
||||
$menu['Users & Roles']['Bans'] = url('manage-users-bans');
|
||||
|
||||
if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
|
||||
$menu['News']['Posts'] = url('manage-news-posts');
|
||||
if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
|
||||
$menu['News']['Categories'] = url('manage-news-categories');
|
||||
|
||||
if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
|
||||
$menu['Forum']['Permission Calculator'] = url('manage-forum-categories');
|
||||
if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
|
||||
$menu['Forum']['Topic Redirects'] = url('manage-forum-topic-redirs');
|
||||
|
||||
if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
|
||||
$menu['Changelog']['Changes'] = url('manage-changelog-changes');
|
||||
if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
|
||||
$menu['Changelog']['Tags'] = url('manage-changelog-tags');
|
||||
|
||||
return $menu;
|
||||
}
|
||||
}
|
|
@ -2,46 +2,30 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Twig\Environment as TwigEnvironment;
|
||||
use Twig\TwigFunction;
|
||||
use Twig_Extensions_Extension_Date;
|
||||
use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem;
|
||||
use Sasae\SasaeContext;
|
||||
use Sasae\SasaeEnvironment;
|
||||
use Misuzu\MisuzuContext;
|
||||
|
||||
final class Template {
|
||||
private const FILE_EXT = '.twig';
|
||||
|
||||
private static $loader;
|
||||
private static $env;
|
||||
private static $vars = [];
|
||||
private static SasaeEnvironment $env;
|
||||
private static array $vars = [];
|
||||
|
||||
public static function init(MisuzuContext $ctx, ?string $cache = null, bool $debug = false): void {
|
||||
self::$loader = new TwigLoaderFilesystem;
|
||||
self::$env = new TwigEnvironment(self::$loader, [
|
||||
'cache' => $cache ?? false,
|
||||
'strict_variables' => true,
|
||||
'auto_reload' => $debug,
|
||||
'debug' => $debug,
|
||||
]);
|
||||
self::$env->addExtension(new TwigMisuzu($ctx));
|
||||
}
|
||||
|
||||
public static function addPath(string $path): void {
|
||||
self::$loader->addPath($path);
|
||||
public static function init(SasaeEnvironment $env): void {
|
||||
self::$env = $env;
|
||||
}
|
||||
|
||||
public static function addFunction(string $name, callable $body): void {
|
||||
self::$env->addFunction(new TwigFunction($name, $body));
|
||||
self::$env->addFunction($name, $body);
|
||||
}
|
||||
|
||||
public static function renderRaw(string $file, array $vars = []): string {
|
||||
if(!defined('MSZ_TPL_RENDER')) {
|
||||
if(!defined('MSZ_TPL_RENDER'))
|
||||
define('MSZ_TPL_RENDER', microtime(true));
|
||||
}
|
||||
|
||||
if(!str_ends_with($file, self::FILE_EXT)) {
|
||||
if(!str_ends_with($file, self::FILE_EXT))
|
||||
$file = str_replace('.', DIRECTORY_SEPARATOR, $file) . self::FILE_EXT;
|
||||
}
|
||||
|
||||
return self::$env->render($file, array_merge(self::$vars, $vars));
|
||||
}
|
||||
|
@ -51,13 +35,12 @@ final class Template {
|
|||
}
|
||||
|
||||
public static function set($arrayOrKey, $value = null): void {
|
||||
if(is_string($arrayOrKey)) {
|
||||
if(is_string($arrayOrKey))
|
||||
self::$vars[$arrayOrKey] = $value;
|
||||
} elseif(is_array($arrayOrKey)) {
|
||||
elseif(is_array($arrayOrKey))
|
||||
self::$vars = array_merge(self::$vars, $arrayOrKey);
|
||||
} else {
|
||||
else
|
||||
throw new InvalidArgumentException('First parameter must be of type array or string.');
|
||||
}
|
||||
}
|
||||
|
||||
public static function displayInfo(?string $message, int $statusCode, ?string $template = null): never {
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Index\ByteFormat;
|
||||
use Index\DateTime;
|
||||
use Index\Environment;
|
||||
use Misuzu\MisuzuContext;
|
||||
use Misuzu\Tools;
|
||||
use Misuzu\Parsers\Parser;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Environment as TwigEnvironment;
|
||||
|
||||
final class TwigMisuzu extends AbstractExtension {
|
||||
private MisuzuContext $ctx;
|
||||
|
||||
public function __construct(MisuzuContext $ctx) {
|
||||
$this->ctx = $ctx;
|
||||
}
|
||||
|
||||
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('url_construct', 'url_construct'),
|
||||
new TwigFunction('url', 'url'),
|
||||
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('ndx_version', Environment::getIndexVersion(...)),
|
||||
new TwigFunction('byte_symbol', ByteFormat::format(...)),
|
||||
];
|
||||
}
|
||||
|
||||
public function timeFormat(DateTime|string|int|null $dateTime): string {
|
||||
if($dateTime === null)
|
||||
return 'never';
|
||||
|
||||
if(is_string($dateTime))
|
||||
$dateTime = new DateTime($dateTime);
|
||||
elseif(is_int($dateTime))
|
||||
$dateTime = DateTime::fromUnixTimeSeconds($dateTime);
|
||||
|
||||
$string = '';
|
||||
$now = DateTime::now();
|
||||
|
||||
$isDiffYear = $now->getYear() !== $dateTime->getYear();
|
||||
if($isDiffYear || $now->getMonth() !== $dateTime->getMonth() || $now->getDay() !== $dateTime->getDay()) {
|
||||
$string .= $dateTime->format('M jS');
|
||||
if($isDiffYear)
|
||||
$string .= $dateTime->format(' Y');
|
||||
$string .= ', ';
|
||||
}
|
||||
|
||||
$string .= $dateTime->format('G:i ');
|
||||
$string .= $dateTime->isUTC() ? 'UTC' : $dateTime->format('T');
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
<a href="https://git.flash.moe/flashii/misuzu/src/tag/{{ git_tag }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_tag }}</a>
|
||||
{% endif %}
|
||||
# <a href="https://git.flash.moe/flashii/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_commit_hash() }}</a>
|
||||
{% if display_timings_info %}
|
||||
{% if globals.display_timings_info %}
|
||||
/ Index {{ ndx_version() }}
|
||||
/ {{ sql_query_count()|number_format }} queries
|
||||
/ {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
{% from 'macros.twig' import avatar %}
|
||||
{% from '_layout/input.twig' import input_checkbox_raw %}
|
||||
|
||||
{% if current_user_real is defined %}
|
||||
{% if globals.auth_info.isImpersonating %}
|
||||
{% set real_user_info = globals.auth_info.realUserInfo %}
|
||||
<div class="impersonate">
|
||||
<div class="impersonate-content">
|
||||
<div class="impersonate-user" style="--user-colour: {{ current_user_real_colour }}">
|
||||
You are <a href="{{ url('user-profile', {'user': current_user_real.id}) }}" class="impersonate-user-link">
|
||||
<div class="avatar impersonate-user-avatar">{{ avatar(current_user_real.id, 20, current_user_real.name) }}</div>
|
||||
{{ current_user_real.name }}
|
||||
<div class="impersonate-user">
|
||||
You are <a href="{{ url('user-profile', {'user': real_user_info.id}) }}" class="impersonate-user-link">
|
||||
<div class="avatar impersonate-user-avatar">{{ avatar(real_user_info.id, 20, real_user_info.name) }}</div>
|
||||
{{ real_user_info.name }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="impersonate-options">
|
||||
|
@ -17,6 +18,10 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set is_in_manage = is_in_manage|default(false) %}
|
||||
{% set header_menu = msz_header_menu() %}
|
||||
{% set user_menu = msz_user_menu(is_in_manage, (is_in_manage ? site_link|default('') : manage_link|default(''))) %}
|
||||
|
||||
<nav class="header">
|
||||
<div class="header__background"></div>
|
||||
|
||||
|
@ -51,9 +56,10 @@
|
|||
</a>
|
||||
{% endfor %}
|
||||
|
||||
{% if current_user is defined %}
|
||||
<a href="{{ url('user-profile', {'user': current_user.id}) }}" class="avatar header__desktop__user__avatar" title="{{ current_user.name }}">
|
||||
{{ avatar(current_user.id, 60, current_user.name) }}
|
||||
{% if globals.auth_info.isLoggedIn %}
|
||||
{% set user_info = globals.auth_info.userInfo %}
|
||||
<a href="{{ url('user-profile', {'user': user_info.id}) }}" class="avatar header__desktop__user__avatar" title="{{ user_info.name }}">
|
||||
{{ avatar(user_info.id, 60, user_info.name) }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar">
|
||||
|
@ -74,7 +80,12 @@
|
|||
</a>
|
||||
|
||||
<label class="header__mobile__icon header__mobile__avatar" for="toggle-mobile-header">
|
||||
{{ avatar(current_user.id|default(0), 40, current_user.name|default('Log in')) }}
|
||||
{% if globals.auth_info.isLoggedIn %}
|
||||
{% set user_info = globals.auth_info.userInfo %}
|
||||
{{ avatar(user_info.id, 40, user_info.name) }}
|
||||
{% else %}
|
||||
{{ avatar(0, 40, 'Log in') }}
|
||||
{% endif %}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -176,9 +176,9 @@
|
|||
</div>
|
||||
</form>
|
||||
|
||||
{% if globals.eeprom.path is not empty %}
|
||||
{% if globals.eeprom_path is not empty and globals.eeprom_app is not empty %}
|
||||
<script type="text/javascript">
|
||||
const peepPath = '{{ globals.eeprom.path }}', peepApp = '{{ globals.eeprom.app }}';
|
||||
const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app }}';
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
},
|
||||
] %}
|
||||
|
||||
{% set header_menu = msz_header_menu() %}
|
||||
|
||||
{% block main_header %}
|
||||
<div class="landingv2-header">
|
||||
<div class="landingv2-header-background"></div>
|
||||
|
@ -87,7 +89,7 @@
|
|||
{% endif %}
|
||||
# <a href="https://github.com/flashwave/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener">{{ git_commit_hash() }}</a>
|
||||
</div>
|
||||
{% if display_timings_info %}
|
||||
{% if globals.display_timings_info %}
|
||||
<div class="landingv2-footer-copyright-line">
|
||||
{{ sql_query_count()|number_format }} queries / {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load / {{ startup_time(constant('MSZ_TPL_RENDER'))|number_format(5) }} template / {{ startup_time()|number_format(5) }} total
|
||||
</div>
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
{% from 'macros.twig' import container_title %}
|
||||
{% from 'manage/macros.twig' import manage_navigation %}
|
||||
|
||||
{% set is_in_manage = true %}
|
||||
{% set title = title|default('Broom Closet') %}
|
||||
{% set site_logo = '/images/logos/imouto-broom.png' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="manage">
|
||||
<nav class="manage__sidebar">
|
||||
{{ manage_navigation(manage_menu) }}
|
||||
{{ manage_navigation(msz_manage_menu()) }}
|
||||
</nav>
|
||||
|
||||
<div class="manage__content">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
{% include '_layout/meta.twig' %}
|
||||
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
|
||||
<link href="/vendor/highlightjs/styles/tomorrow-night.css" type="text/css" rel="stylesheet">
|
||||
<link href="{{ assets.mszcss|default() }}" type="text/css" rel="stylesheet">
|
||||
<link href="{{ globals.assets.mszcss|default() }}" type="text/css" rel="stylesheet">
|
||||
{% if site_background is defined %}
|
||||
<style>
|
||||
:root {
|
||||
|
@ -32,12 +32,12 @@
|
|||
{% endblock %}
|
||||
|
||||
<div class="main__wrapper">
|
||||
{% if current_user_ban_info is defined and current_user_ban_info is not null %}
|
||||
{% if globals.active_ban_info is not null %}
|
||||
<div class="warning warning--red">
|
||||
<div class="warning__content">
|
||||
<p>You have been banned {% if current_user_ban_info.isPermanent %}<strong>permanently</strong>{% else %}for <strong title="{{ current_user_ban_info.expiresTime|date('r') }}">{{ current_user_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ current_user_ban_info.createdTime|date('c') }}" title="{{ current_user_ban_info.createdTime|date('r') }}">{{ current_user_ban_info.createdTime|time_format }}</time></strong>.</p>
|
||||
{% if current_user_ban_info.hasPublicReason %}
|
||||
<p>Reason: {{ current_user_ban_info.publicReason }}</p>
|
||||
<p>You have been banned {% if globals.active_ban_info.isPermanent %}<strong>permanently</strong>{% else %}for <strong title="{{ globals.active_ban_info.expiresTime|date('r') }}">{{ globals.active_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ globals.active_ban_info.createdTime|date('c') }}" title="{{ globals.active_ban_info.createdTime|date('r') }}">{{ globals.active_ban_info.createdTime|time_format }}</time></strong>.</p>
|
||||
{% if globals.active_ban_info.hasPublicReason %}
|
||||
<p>Reason: {{ globals.active_ban_info.publicReason }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -58,6 +58,6 @@
|
|||
window.addEventListener('DOMContentLoaded', function() { Misuzu(); });
|
||||
</script>
|
||||
<script src="/vendor/highlightjs/highlight.pack.js" type="text/javascript"></script>
|
||||
<script src="{{ assets.mszjs|default() }}" type="text/javascript"></script>
|
||||
<script src="{{ globals.assets.mszjs|default() }}" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
{% if perms.edit_avatar %}
|
||||
<ul class="profile__guidelines__section">
|
||||
<li class="profile__guidelines__line profile__guidelines__line--header">Avatar</li>
|
||||
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ byte_symbol(profile_avatar_info.maxBytes) }}</span> file size limit.</li>
|
||||
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ profile_avatar_info.maxBytes|format_filesize }}</span> file size limit.</li>
|
||||
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_avatar_info.maxWidth }}x{{ profile_avatar_info.maxHeight }}</span>.</li>
|
||||
<li class="profile__guidelines__line">Will be centre cropped and scaled to at most <span class="profile__guidelines__emphasis">240x240</span>.</li>
|
||||
<li class="profile__guidelines__line">Animated GIF images are allowed.</li>
|
||||
|
@ -57,7 +57,7 @@
|
|||
{% if perms.edit_background %}
|
||||
<ul class="profile__guidelines__section">
|
||||
<li class="profile__guidelines__line profile__guidelines__line--header">Background</li>
|
||||
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ byte_symbol(profile_background_info.maxBytes) }}</span> file size limit.</li>
|
||||
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ profile_background_info.maxBytes|format_filesize }}</span> file size limit.</li>
|
||||
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_background_info.maxWidth }}x{{ profile_background_info.maxHeight }}</span>.</li>
|
||||
<li class="profile__guidelines__line">GIF images, in general, are only allowed when tiling.</li>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in a new issue