mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-12-23 08:31:52 +00:00
feat(web): new user permissions (#10) (#18)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
ab5d54e4ae
@ -692,6 +692,7 @@ CREATE TABLE `problems_solutions` (
|
||||
`problem_id` int NOT NULL,
|
||||
`blog_id` int NOT NULL,
|
||||
PRIMARY KEY (`problem_id`, `blog_id`),
|
||||
UNIQUE KEY `unique__blog_id` (`blog_id`),
|
||||
KEY `problem_id` (`problem_id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
@ -986,7 +987,7 @@ UNLOCK TABLES;
|
||||
CREATE TABLE `user_info` (
|
||||
`usergroup` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'U',
|
||||
`username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`usertype` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'student',
|
||||
`usertype` enum('student','teacher','system','banned') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'student',
|
||||
`realname` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
||||
`school` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
||||
`email` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
|
@ -3,7 +3,7 @@ requireLib('bootstrap5');
|
||||
requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
isSuperUser(Auth::user()) || UOJResponse::page403();
|
||||
UOJContest::userCanCreateContest(Auth::user()) || UOJResponse::page403();
|
||||
|
||||
$time_form = new UOJBs4Form('time');
|
||||
$time_form->addVInput(
|
||||
|
@ -32,7 +32,7 @@ EOD,
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td>' . $blog->getLink(['show_level' => true, 'show_new_tag' => true]) . '</td>';
|
||||
echo '<td>' . getUserLink($blog->info['poster']) . '</td>';
|
||||
echo '<td>' . UOJUser::getLink($blog->info['poster']) . '</td>';
|
||||
echo '<td>' . $blog->info['post_time'] . '</td>';
|
||||
echo '</tr>';
|
||||
},
|
||||
|
@ -21,10 +21,12 @@ Auth::check() || redirectToLogin();
|
||||
<a href="<?= HTML::blog_url(Auth::id(), '/') ?>" class="btn btn-secondary btn-sm">
|
||||
我的博客首页
|
||||
</a>
|
||||
<a href="<?= HTML::blog_url(Auth::id(), '/post/new/write') ?>" class="btn btn-primary btn-sm">
|
||||
<i class="bi bi-pencil"></i>
|
||||
写新博客
|
||||
</a>
|
||||
<?php if (UOJUser::checkPermission(Auth::user(), 'blogs.create')) : ?>
|
||||
<a href="<?= HTML::blog_url(Auth::id(), '/post/new/write') ?>" class="btn btn-primary btn-sm">
|
||||
<i class="bi bi-pencil"></i>
|
||||
写新博客
|
||||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
@ -35,16 +37,16 @@ Auth::check() || redirectToLogin();
|
||||
echoLongTable(
|
||||
['id', 'poster', 'title', 'post_time', 'zan', 'is_hidden'],
|
||||
'blogs',
|
||||
isSuperUser($myUser) ? "1" : "is_hidden = 0 or poster = '{$myUser['username']}'",
|
||||
'1',
|
||||
'order by post_time desc',
|
||||
<<<EOD
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th style="width:200px">发表者</th>
|
||||
<th style="width:200px">发表日期</th>
|
||||
<th style="width:50px" class="text-center">评价</th>
|
||||
</tr>
|
||||
EOD,
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th style="width:200px">发表者</th>
|
||||
<th style="width:200px">发表日期</th>
|
||||
<th style="width:50px" class="text-center">评价</th>
|
||||
</tr>
|
||||
EOD,
|
||||
function ($info) {
|
||||
$blog = new UOJBlog($info);
|
||||
|
||||
@ -55,7 +57,7 @@ EOD,
|
||||
echo ' <span class="badge text-bg-danger"><i class="bi bi-eye-slash-fill"></i> ', UOJLocale::get('hidden'), '</span> ';
|
||||
}
|
||||
echo '</td>';
|
||||
echo '<td>' . getUserLink($blog->info['poster']) . '</td>';
|
||||
echo '<td>' . UOJUser::getLink($blog->info['poster']) . '</td>';
|
||||
echo '<td>' . $blog->info['post_time'] . '</td>';
|
||||
echo '<td class="text-center">' . ClickZans::getCntBlock($blog->info['zan']) . '</td>';
|
||||
echo '</tr>';
|
||||
@ -64,6 +66,9 @@ EOD,
|
||||
'page_len' => 10,
|
||||
'div_classes' => ['card', 'my-3', 'table-responsive'],
|
||||
'table_classes' => ['table', 'uoj-table', 'mb-0'],
|
||||
'post_filter' => function ($info) {
|
||||
return (new UOJBlog($info))->userCanView(Auth::user());
|
||||
},
|
||||
]
|
||||
);
|
||||
?>
|
||||
|
@ -40,7 +40,7 @@ $confirm_form->runAtServer();
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">参赛选手</td>
|
||||
<td><?= getUserLink(Auth::id()) ?></td>
|
||||
<td><?= UOJUser::getLink(Auth::user()) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">开始时间</td>
|
||||
|
@ -53,7 +53,7 @@ if ($is_manager) {
|
||||
|
||||
isset($tabs_info[$cur_tab]) || UOJResponse::page404();
|
||||
|
||||
if (isSuperUser($myUser) || isContestJudger($myUser)) {
|
||||
if (UOJContest::cur()->userCanStartFinalTest(Auth::user())) {
|
||||
if (CONTEST_PENDING_FINAL_TEST <= $contest['cur_progress']) {
|
||||
$start_test_form = new UOJBs4Form('start_test');
|
||||
$start_test_form->handle = function () {
|
||||
@ -113,7 +113,7 @@ if ($cur_tab == 'dashboard') {
|
||||
$post_question = null;
|
||||
}
|
||||
} elseif ($cur_tab == 'backstage') {
|
||||
if (isSuperUser(Auth::user())) {
|
||||
if ($is_manager) {
|
||||
$post_notice = new UOJBs4Form('post_notice');
|
||||
$post_notice->addInput(
|
||||
'title',
|
||||
@ -158,7 +158,6 @@ if ($cur_tab == 'dashboard') {
|
||||
$post_notice = null;
|
||||
}
|
||||
|
||||
|
||||
if ($is_manager) {
|
||||
$reply_question = new UOJBs4Form('reply_question');
|
||||
$reply_question->addHidden(
|
||||
@ -486,10 +485,8 @@ function echoSelfReviews() {
|
||||
|
||||
uojIncludeView('contest-reviews', ['contest' => $contest] + UOJContest::cur()->queryResult());
|
||||
}
|
||||
|
||||
$page_header = HTML::stripTags($contest['name']) . ' - ';
|
||||
?>
|
||||
<?php echoUOJPageHeader(HTML::stripTags($contest['name']) . ' - ' . $tabs_info[$cur_tab]['name'] . ' - ' . UOJLocale::get('contests::contest')) ?>
|
||||
<?php echoUOJPageHeader($tabs_info[$cur_tab]['name'] . ' - ' . UOJContest::info('name') . ' - ' . UOJLocale::get('contests::contest')) ?>
|
||||
|
||||
<div class="text-center d-md-none mb-3">
|
||||
<h1><?= $contest['name'] ?></h1>
|
||||
@ -600,7 +597,7 @@ $page_header = HTML::stripTags($contest['name']) . ' - ';
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent">
|
||||
比赛评价:<?= ClickZans::getBlock('C', $contest['id'], $contest['zan']) ?>
|
||||
比赛评价:<?= UOJContest::cur()->getZanBlock() ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -618,7 +615,7 @@ $page_header = HTML::stripTags($contest['name']) . ' - ';
|
||||
<a href="/contest/<?= $contest['id'] ?>/registrants" class="btn btn-secondary d-block mt-2">
|
||||
<?= UOJLocale::get('contests::contest registrants') ?>
|
||||
</a>
|
||||
<?php if (isSuperUser($myUser)) : ?>
|
||||
<?php if ($is_manager) : ?>
|
||||
<a href="/contest/<?= $contest['id'] ?>/manage" class="btn btn-primary d-block mt-2">
|
||||
管理
|
||||
</a>
|
||||
|
@ -4,7 +4,7 @@ requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJContest::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
isSuperUser(Auth::user()) || UOJResponse::page403();
|
||||
UOJContest::cur()->userCanManage(Auth::user()) || UOJResponse::page403();
|
||||
$contest = UOJContest::info();
|
||||
|
||||
if (isset($_GET['tab'])) {
|
||||
@ -687,22 +687,38 @@ EOD,
|
||||
"contest_id = {$contest['id']}",
|
||||
'ORDER BY username',
|
||||
<<<EOD
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th style="width:6em">操作</th>
|
||||
</tr>
|
||||
EOD,
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th style="width:6em">操作</th>
|
||||
</tr>
|
||||
EOD,
|
||||
function ($row) {
|
||||
echo '<tr>';
|
||||
echo '<td>', getUserLink($row['username']), '</td>';
|
||||
echo '<td>';
|
||||
echo '<form method="POST" target="_self" class="d-inline-block" onsubmit=\'return confirm("你确定要将 ', $row['username'], ' 从比赛管理员列表中移除吗?")\'>';
|
||||
echo '<input type="hidden" name="_token" value="', crsf_token(), '">';
|
||||
echo '<input type="hidden" name="username" value="', $row['username'], '">';
|
||||
echo '<button type="submit" class="btn btn-link text-danger text-decoration-none p-0" name="submit-remove_manager" value="remove_manager">移除</button>';
|
||||
echo '</form>';
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
$user = UOJUser::query($row['username']);
|
||||
|
||||
echo HTML::tag_begin('tr');
|
||||
echo HTML::tag('td', [], UOJUser::getLink($user));
|
||||
echo HTML::tag('td', [], [
|
||||
HTML::tag('form', [
|
||||
'method' => 'POST',
|
||||
'target' => '_self',
|
||||
'class' => 'd-inline-block',
|
||||
'onsubmit' => "return confirm('你确定要将 {$user['username']} 从比赛管理员列表中移除吗?');",
|
||||
], [
|
||||
HTML::hiddenToken(),
|
||||
HTML::empty_tag('input', [
|
||||
'type' => 'hidden',
|
||||
'name' => 'username',
|
||||
'value' => $user['username'],
|
||||
]),
|
||||
HTML::tag('button', [
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-link text-danger text-decoration-none p-0',
|
||||
'name' => 'submit-remove_manager',
|
||||
'value' => 'remove_manager',
|
||||
], '移除'),
|
||||
]),
|
||||
]);
|
||||
echo HTML::tag_end('tr');
|
||||
},
|
||||
[
|
||||
'echo_full' => true,
|
||||
|
@ -197,7 +197,7 @@ echoLongTable(
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td>' . $num . '</td>';
|
||||
echo '<td>' . getUserLink($user['username']) . '</td>';
|
||||
echo '<td>' . UOJUser::getLink($user) . '</td>';
|
||||
if ($show_ip) {
|
||||
echo '<td>' . $user['remote_addr'] . '</td>';
|
||||
echo '<td>' . $user['http_x_forwarded_for'] . '</td>';
|
||||
|
@ -52,7 +52,7 @@ function echoContest($info) {
|
||||
echo '<td>', '<a class="text-decoration-none" href="' . HTML::timeanddate_url($contest->info['start_time'], ['duration' => $contest->info['last_min']]) . '">' . $contest->info['start_time_str'] . '</a>', '</td>';
|
||||
echo '<td>', UOJLocale::get('hours', $last_hour), '</td>';
|
||||
echo '<td>', '<a class="text-decoration-none" href="/contest/' . $contest->info['id'] . '/registrants">', '<i class="bi bi-person-fill"></i>', ' ×' . $contest->info['player_num'] . '</a>', '</td>';
|
||||
echo '<td>', '<div class="text-left">' . ClickZans::getBlock('C', $contest->info['id'], $contest->info['zan']) . '</div>', '</td>';
|
||||
echo HTML::tag('td', [], $contest->getZanBlock());
|
||||
echo '</tr>';
|
||||
}
|
||||
?>
|
||||
@ -64,7 +64,7 @@ function echoContest($info) {
|
||||
<?= UOJLocale::get('contests') ?>
|
||||
</h1>
|
||||
|
||||
<?php if (isSuperUser($myUser)) : ?>
|
||||
<?php if (UOJContest::userCanCreateContest(Auth::user())) : ?>
|
||||
<div class="text-end">
|
||||
<a href="/contest/new" class="btn btn-primary"><?= UOJLocale::get('contests::add new contest') ?></a>
|
||||
</div>
|
||||
@ -92,6 +92,12 @@ $table_config = [
|
||||
'table_classes' => ['table', 'uoj-table', 'mb-0', 'text-center'],
|
||||
];
|
||||
|
||||
if (!UOJUser::checkPermission(Auth::user(), 'contests.view')) {
|
||||
$table_config['post_filter'] = function ($info) {
|
||||
return (new UOJContest($info))->userCanView(Auth::user());
|
||||
};
|
||||
}
|
||||
|
||||
echoLongTable(
|
||||
['*'],
|
||||
'contests',
|
||||
|
@ -7,7 +7,7 @@
|
||||
if (!validateUsername($username)) {
|
||||
return '用户名不合法';
|
||||
}
|
||||
$vdata['user'] = queryUser($username);
|
||||
$vdata['user'] = UOJUser::query($username);
|
||||
if (!$vdata['user']) {
|
||||
return '该用户不存在';
|
||||
}
|
||||
|
@ -4,11 +4,9 @@ requirePHPLib('form');
|
||||
requirePHPLib('judger');
|
||||
requirePHPLib('data');
|
||||
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
Auth::check() || redirectToLogin();
|
||||
|
||||
if (isSuperUser($myUser)) {
|
||||
if (UOJGroup::userCanCreateGroup(Auth::user())) {
|
||||
$new_group_form = new UOJBs4Form('new_group');
|
||||
$new_group_form->handle = function () {
|
||||
DB::query("insert into `groups` (title, is_hidden) values ('新小组', 1)");
|
||||
@ -33,7 +31,7 @@ if (isSuperUser($myUser)) {
|
||||
</h1>
|
||||
|
||||
<?php if (isset($new_group_form)) : ?>
|
||||
<div class="text-end mb-2">
|
||||
<div class="text-end">
|
||||
<?php $new_group_form->printHTML(); ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
@ -45,23 +43,17 @@ if (isSuperUser($myUser)) {
|
||||
$groups_caption = UOJLocale::get('groups');
|
||||
$users_caption = UOJLocale::get('users count');
|
||||
$header = <<<EOD
|
||||
<tr>
|
||||
<th class="text-center" style="width:5em;">ID</th>
|
||||
<th>{$groups_caption}</th>
|
||||
<th class="text-center" style="width:8em;">{$users_caption}</th>
|
||||
</tr>
|
||||
EOD;
|
||||
|
||||
if (isSuperUser(Auth::user())) {
|
||||
$cond = "1";
|
||||
} else {
|
||||
$cond = ["is_hidden" => false];
|
||||
}
|
||||
<tr>
|
||||
<th class="text-center" style="width:5em;">ID</th>
|
||||
<th>{$groups_caption}</th>
|
||||
<th class="text-center" style="width:8em;">{$users_caption}</th>
|
||||
</tr>
|
||||
EOD;
|
||||
|
||||
echoLongTable(
|
||||
['id', 'title', 'is_hidden'],
|
||||
['*'],
|
||||
"`groups`",
|
||||
$cond,
|
||||
'1',
|
||||
'order by id asc',
|
||||
$header,
|
||||
function ($group) {
|
||||
@ -93,6 +85,9 @@ EOD;
|
||||
'div_classes' => ['card', 'my-3'],
|
||||
'table_classes' => ['table', 'uoj-table', 'mb-0'],
|
||||
'head_pagination' => true,
|
||||
'post_filter' => function ($info) {
|
||||
return (new UOJGroup($info))->userCanView(Auth::user());
|
||||
}
|
||||
]
|
||||
);
|
||||
?>
|
||||
|
@ -6,6 +6,7 @@ requirePHPLib('form');
|
||||
requireLib('bootstrap5');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUser::checkPermission(Auth::user(), 'users.upload_image') || UOJResponse::page403();
|
||||
|
||||
$extra = UOJUser::getExtra($user);
|
||||
$limit = $extra['image_hosting']['total_size_limit'];
|
||||
@ -56,18 +57,18 @@ if ($_POST['image_upload_file_submit'] == 'submit') {
|
||||
throwError('not_a_image');
|
||||
}
|
||||
|
||||
list($width, $height, $type) = $size;
|
||||
$hash = hash_file("sha256", $_FILES['image_upload_file']['tmp_name']) . Auth::id();
|
||||
$scale = ceil($height / 600.0);
|
||||
list($width, $height, $type) = $size;
|
||||
$hash = hash_file("sha256", $_FILES['image_upload_file']['tmp_name']) . Auth::id();
|
||||
$scale = ceil($height / 600.0);
|
||||
|
||||
$watermark_text = UOJConfig::$data['profile']['oj-name-short'];
|
||||
if (isSuperUser($myUser) && $_POST['watermark'] == 'no_watermark') {
|
||||
$watermark_text = "";
|
||||
$hash .= "__no_watermark";
|
||||
} elseif ($_POST['watermark'] == 'site_shortname_and_username') {
|
||||
$watermark_text .= ' @' . Auth::id();
|
||||
$hash .= "__id";
|
||||
}
|
||||
$watermark_text = UOJConfig::$data['profile']['oj-name-short'];
|
||||
if (isSuperUser(Auth::user()) && $_POST['watermark'] == 'no_watermark') {
|
||||
$watermark_text = "";
|
||||
$hash .= "__no_watermark";
|
||||
} elseif ($_POST['watermark'] == 'site_shortname_and_username') {
|
||||
$watermark_text .= ' @' . Auth::id();
|
||||
$hash .= "__id";
|
||||
}
|
||||
|
||||
$existing_image = DB::selectFirst("SELECT * FROM users_images WHERE `hash` = '$hash'");
|
||||
|
||||
@ -96,7 +97,19 @@ if ($_POST['image_upload_file_submit'] == 'submit') {
|
||||
throwError('unknown error');
|
||||
}
|
||||
|
||||
DB::insert("INSERT INTO users_images (`path`, uploader, width, height, upload_time, size, `hash`) VALUES ('$filename', '{$myUser['username']}', $width, $height, now(), {$_FILES["image_upload_file"]["size"]}, '$hash')");
|
||||
DB::insert([
|
||||
"insert into users_images",
|
||||
DB::bracketed_fields(["path", "uploader", "width", "height", "upload_time", "size", "hash"]),
|
||||
"values", DB::tuple([
|
||||
$filename,
|
||||
Auth::id(),
|
||||
$width,
|
||||
$height,
|
||||
DB::now(),
|
||||
$_FILES["image_upload_file"]["size"],
|
||||
$hash,
|
||||
]),
|
||||
]);
|
||||
|
||||
dieWithJsonData(['status' => 'success', 'path' => $filename]);
|
||||
} elseif ($_POST['image_delete_submit'] == 'submit') {
|
||||
|
@ -41,7 +41,7 @@ $friend_links = DB::selectAll([
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $blog->getLink(['show_new_tag' => true]) ?></td>
|
||||
<td>by <?= getUserLink($blog->info['poster']) ?></td>
|
||||
<td>by <?= UOJUser::getLink($blog->info['poster']) ?></td>
|
||||
<td><small><?= $blog->info['post_time'] ?></small></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
|
@ -301,21 +301,10 @@ EOD);
|
||||
<div class="tab-pane active" id="problems">
|
||||
<?php
|
||||
echoLongTable(
|
||||
[
|
||||
'problems.id as id',
|
||||
'problems.title as title',
|
||||
'problems.is_hidden as is_hidden',
|
||||
],
|
||||
[
|
||||
"problems",
|
||||
"inner join lists_problems",
|
||||
"on", [
|
||||
"lists_problems.list_id" => UOJList::info('id'),
|
||||
"lists_problems.problem_id" => DB::raw("problems.id")
|
||||
]
|
||||
],
|
||||
"1",
|
||||
"order by id asc",
|
||||
['problem_id'],
|
||||
"lists_problems",
|
||||
["list_id" => UOJList::info('id')],
|
||||
"order by problem_id asc",
|
||||
<<<EOD
|
||||
<tr>
|
||||
<th class="text-center" style="width:5em">ID</th>
|
||||
@ -324,23 +313,31 @@ EOD);
|
||||
</tr>
|
||||
EOD,
|
||||
function ($row) {
|
||||
echo HTML::tag_begin('tr');
|
||||
$problem = UOJProblem::query($row['problem_id']);
|
||||
|
||||
echo HTML::tag('td', ['class' => 'text-center'], $row['id']);
|
||||
echo HTML::tag_begin('tr');
|
||||
echo HTML::tag('td', ['class' => 'text-center'], $problem->info['id']);
|
||||
echo HTML::tag_begin('td');
|
||||
echo getProblemLink($row);
|
||||
if ($row['is_hidden']) {
|
||||
echo $problem->getLink();
|
||||
if ($problem->info['is_hidden']) {
|
||||
echo ' <span class="badge text-bg-danger"><i class="bi bi-eye-slash-fill"></i> ', UOJLocale::get('hidden'), '</span> ';
|
||||
}
|
||||
echo HTML::tag_end('td');
|
||||
echo HTML::tag_begin('td');
|
||||
echo '<form target="_self" method="POST" class="d-inline-block" onsubmit=\'return confirm("你确定要将题目 #', $row['id'], ' 从题单中移除吗?")\'>';
|
||||
echo '<input type="hidden" name="_token" value="', crsf_token(), '">';
|
||||
echo '<input type="hidden" name="problem_id" value="', $row['id'], '">';
|
||||
echo '<button class="btn btn-link text-danger text-decoration-none p-0" name="submit-remove_problem" value="remove_problem">移除</button>';
|
||||
echo '</form>';
|
||||
echo HTML::tag_end('td');
|
||||
|
||||
echo HTML::tag('td', [], HTML::tag('form', [
|
||||
'target' => '_self',
|
||||
'method' => 'POST',
|
||||
'class' => 'd-inline-block',
|
||||
'onsubmit' => "return confirm('你确定要将 {$problem->info['id']} 从题单中移除吗?');",
|
||||
], [
|
||||
HTML::hiddenToken(),
|
||||
HTML::empty_tag('input', ['type' => 'hidden', 'name' => 'problem_id', 'value' => $problem->info['id']]),
|
||||
html::tag('button', [
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-link text-danger text-decoration-none p-0',
|
||||
'name' => 'submit-remove_problem',
|
||||
'value' => 'remove_problem',
|
||||
], '移除'),
|
||||
]));
|
||||
echo HTML::tag_end('tr');
|
||||
},
|
||||
[
|
||||
|
@ -6,17 +6,17 @@ requirePHPLib('judger');
|
||||
requirePHPLib('data');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUser::checkPermission(Auth::user(), 'lists.view') || UOJResponse::page403();
|
||||
|
||||
if (isSuperUser($myUser)) {
|
||||
if (UOJList::userCanCreateList(Auth::user())) {
|
||||
$new_list_form = new UOJBs4Form('new_list');
|
||||
$new_list_form->handle = function () {
|
||||
DB::query("insert into lists (title, is_hidden) values ('未命名题单', 1)");
|
||||
DB::insert("insert into lists (title, is_hidden) values ('未命名题单', 1)");
|
||||
};
|
||||
$new_list_form->submit_button_config['align'] = 'right';
|
||||
$new_list_form->submit_button_config['class_str'] = 'btn btn-primary';
|
||||
$new_list_form->submit_button_config['text'] = UOJLocale::get('problems::add new list');
|
||||
$new_list_form->submit_button_config['smart_confirm'] = '';
|
||||
|
||||
$new_list_form->runAtServer();
|
||||
}
|
||||
|
||||
@ -92,14 +92,14 @@ $pag = new Paginator([
|
||||
<div class="row">
|
||||
<!-- left col -->
|
||||
<div class="col-lg-9">
|
||||
|
||||
<!-- title container -->
|
||||
<div class="d-flex justify-content-between">
|
||||
<h1>
|
||||
<?= UOJLocale::get('problems lists') ?>
|
||||
</h1>
|
||||
|
||||
<?php if (isset($new_list_form)) : ?>
|
||||
<div class="text-end mb-2">
|
||||
<div class="text-end">
|
||||
<?php $new_list_form->printHTML(); ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
@ -313,7 +313,7 @@ if (UOJContest::cur()) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent">
|
||||
比赛评价:<?= ClickZans::getBlock('C', UOJContest::info('id'), UOJContest::info('zan')) ?>
|
||||
比赛评价:<?= UOJContest::cur()->getZanBlock() ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
|
||||
|
@ -127,7 +127,7 @@ if ($_POST['problem_settings_file_submit'] == 'submit') {
|
||||
|
||||
$info_form = new UOJBs4Form('info');
|
||||
$http_host = HTML::escape(UOJContext::httpHost());
|
||||
$attachment_url = HTML::url("/download.php?type=attachment&id={$problem['id']}");
|
||||
$attachment_url = UOJProblem::cur()->getAttachmentUri();
|
||||
$info_form->appendHTML(
|
||||
<<<EOD
|
||||
<div class="form-group row">
|
||||
@ -140,7 +140,7 @@ $info_form->appendHTML(
|
||||
</div>
|
||||
EOD
|
||||
);
|
||||
$download_url = HTML::url("/download.php?type=problem&id={$problem['id']}");
|
||||
$download_url = UOJProblem::cur()->getMainDataUri();
|
||||
$info_form->appendHTML(
|
||||
<<<EOD
|
||||
<div class="form-group row">
|
||||
@ -194,7 +194,7 @@ $esc_extra_config
|
||||
</div>
|
||||
EOD
|
||||
);
|
||||
if (isSuperUser($myUser)) {
|
||||
if (isSuperUser(Auth::user())) {
|
||||
$info_form->addVInput(
|
||||
'submission_requirement',
|
||||
'text',
|
||||
|
@ -31,7 +31,7 @@ $managers_form = newAddDelCmdForm(
|
||||
|
||||
$managers_form->runAtServer();
|
||||
|
||||
if (isSuperUser($myUser)) {
|
||||
if (isSuperUser(Auth::user())) {
|
||||
$update_uploader_form = new UOJBs4Form('update_uploader');
|
||||
$update_uploader_form->addInput(
|
||||
'new_uploader_username',
|
||||
@ -108,7 +108,7 @@ if (isSuperUser($myUser)) {
|
||||
]);
|
||||
foreach ($res as $row) {
|
||||
$row_id++;
|
||||
echo '<tr>', '<td>', $row_id, '</td>', '<td>', getUserLink($row['username']), '</td>', '</tr>';
|
||||
echo '<tr>', '<td>', $row_id, '</td>', '<td>', UOJUser::getLink($row['username']), '</td>', '</tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
|
@ -5,8 +5,9 @@ requirePHPLib('judger');
|
||||
requirePHPLib('data');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUser::checkPermission(Auth::user(), 'problems.view') || UOJResponse::page403();
|
||||
|
||||
if (isSuperUser($myUser) || isProblemManager($myUser) || isProblemUploader($myUser)) {
|
||||
if (UOJProblem::userCanCreateProblem(Auth::user())) {
|
||||
$default_statement = <<<'EOD'
|
||||
<!-- 题目中如有图片,请点击页面顶部的「应用」菜单,打开「图床」,上传至 S2OJ 图床中。 -->
|
||||
|
||||
@ -240,12 +241,11 @@ $pag = new Paginator([
|
||||
|
||||
<!-- title -->
|
||||
<div class="d-flex justify-content-between">
|
||||
|
||||
<h1>
|
||||
<?= UOJLocale::get('problems') ?>
|
||||
</h1>
|
||||
|
||||
<?php if (isSuperUser($myUser) || isProblemManager($myUser) || isProblemUploader($myUser)) : ?>
|
||||
<?php if (isset($new_problem_form)) : ?>
|
||||
<div class="text-end">
|
||||
<?php $new_problem_form->printHTML(); ?>
|
||||
</div>
|
||||
@ -360,7 +360,7 @@ $pag = new Paginator([
|
||||
</label>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php if (isProblemManager(Auth::user())) : ?>
|
||||
<?php if (UOJProblem::userCanManageSomeProblem(Auth::user())) : ?>
|
||||
<div class="form-check d-inline-block ms-2">
|
||||
<input type="checkbox" name="is_hidden" <?= isset($_GET['is_hidden']) ? 'checked="checked"' : '' ?> class="form-check-input" id="input-is_hidden">
|
||||
<label class="form-check-label" for="input-is_hidden">
|
||||
|
@ -7,7 +7,7 @@ requirePHPLib('judger');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJProblem::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
UOJProblem::cur()->userCanView(Auth::user()) || UOJResponse::page403();
|
||||
UOJProblem::cur()->userCanView(Auth::user(), ['ensure' => true]);
|
||||
|
||||
if (!UOJProblem::cur()->userCanManage(Auth::user())) {
|
||||
UOJProblem::cur()->userPermissionCodeCheck(Auth::user(), UOJProblem::cur()->getExtraConfig('view_solution_type')) || UOJResponse::page403();
|
||||
@ -81,8 +81,8 @@ if (UOJProblem::cur()->userCanManage(Auth::user()) || UOJProblem::cur()->userPer
|
||||
}
|
||||
}
|
||||
|
||||
if (querySolution(UOJProblem::info('id'), $blog_id)) {
|
||||
return '该题解已提交';
|
||||
if ($problem_id = $blog->getSolutionProblemId()) {
|
||||
return "该博客已经是题目 #$problem_id 的题解";
|
||||
}
|
||||
|
||||
return '';
|
||||
@ -200,15 +200,12 @@ $pag = new Paginator($pag_config);
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<?= $pag->pagination() ?>
|
||||
|
||||
</div>
|
||||
<!-- End left col -->
|
||||
<!-- end left col -->
|
||||
|
||||
<!-- Right col -->
|
||||
<!-- right col -->
|
||||
<aside class="col-lg-3 mt-3 mt-lg-0">
|
||||
|
||||
<div class="card card-default mb-2">
|
||||
<ul class="nav nav-pills nav-fill flex-column" role="tablist">
|
||||
<li class="nav-item text-start">
|
||||
|
@ -4,9 +4,6 @@ requireLib('morris');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJProblem::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
|
||||
$problem = UOJProblem::cur()->info;
|
||||
|
||||
if (UOJRequest::get('contest_id')) {
|
||||
UOJContest::init(UOJRequest::get('contest_id')) || UOJResponse::page404();
|
||||
UOJProblem::upgradeToContestProblem() || UOJResponse::page404();
|
||||
@ -183,7 +180,7 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
hoverCallback: function(index, options, content, row) {
|
||||
var scr = row.score;
|
||||
return '<div class="morris-hover-row-label">' + 'score: ' + scr + '</div>' +
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= $problem['id'] ?> + '&min_score=' + scr + '&max_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= UOJProblem::info('id') ?> + '&min_score=' + scr + '&max_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
},
|
||||
resize: true
|
||||
});
|
||||
@ -212,7 +209,7 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
hoverCallback: function(index, options, content, row) {
|
||||
var scr = row.score / 100;
|
||||
return '<div class="morris-hover-row-label">' + 'score: ≤' + scr + '</div>' +
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= $problem['id'] ?> + '&max_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= UOJProblem::info('id') ?> + '&max_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
},
|
||||
resize: true
|
||||
});
|
||||
@ -241,7 +238,7 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
hoverCallback: function(index, options, content, row) {
|
||||
var scr = row.score / 100;
|
||||
return '<div class="morris-hover-row-label">' + 'score: ≥' + scr + '</div>' +
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= $problem['id'] ?> + '&min_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
'<div class="morris-hover-point">' + '<a href="/submissions?problem_id=' + <?= UOJProblem::info('id') ?> + '&min_score=' + scr + '">' + 'number: ' + row.count + '</a>' + '</div>';
|
||||
},
|
||||
resize: true
|
||||
});
|
||||
@ -252,20 +249,17 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
<!-- end left col -->
|
||||
</div>
|
||||
|
||||
<!-- Right col -->
|
||||
<!-- right col -->
|
||||
<aside class="col-lg-3 mt-3 mt-lg-0">
|
||||
|
||||
<?php if ($contest) : ?>
|
||||
<?php if (UOJContest::cur()) : ?>
|
||||
<!-- Contest card -->
|
||||
<div class="card card-default mb-2">
|
||||
<div class="card-body">
|
||||
<h3 class="h4 card-title text-center">
|
||||
<a class="text-decoration-none text-body" href="/contest/<?= $contest['id'] ?>">
|
||||
<?= $contest['name'] ?>
|
||||
</a>
|
||||
<?= UOJContest::cur()->getLink(['class' => 'text-body']) ?>
|
||||
</h3>
|
||||
<div class="card-text text-center text-muted">
|
||||
<?php if ($contest['cur_progress'] <= CONTEST_IN_PROGRESS) : ?>
|
||||
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
|
||||
<span id="contest-countdown"></span>
|
||||
<?php else : ?>
|
||||
<?= UOJLocale::get('contests::contest ended') ?>
|
||||
@ -273,12 +267,12 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent">
|
||||
比赛评价:<?= ClickZans::getBlock('C', $contest['id'], $contest['zan']) ?>
|
||||
比赛评价:<?= UOJContest::cur()->getZanBlock() ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($contest['cur_progress'] <= CONTEST_IN_PROGRESS) : ?>
|
||||
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
|
||||
<script type="text/javascript">
|
||||
$('#contest-countdown').countdown(<?= $contest['end_time']->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>, function() {}, '1.75rem', false);
|
||||
$('#contest-countdown').countdown(<?= UOJContest::info('end_time')->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>, function() {}, '1.75rem', false);
|
||||
</script>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
@ -286,14 +280,14 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
<div class="card card-default mb-2">
|
||||
<ul class="nav nav-pills nav-fill flex-column" role="tablist">
|
||||
<li class="nav-item text-start">
|
||||
<a class="nav-link" role="tab" <?php if ($contest) : ?> href="/contest/<?= $contest['id'] ?>/problem/<?= $problem['id'] ?>" <?php else : ?> href="/problem/<?= $problem['id'] ?>" <?php endif ?>>
|
||||
<a class="nav-link" role="tab" <?php if (UOJContest::cur()) : ?> href="/contest/<?= UOJContest::info('id') ?>/problem/<?= UOJProblem::info('id') ?>" <?php else : ?> href="/problem/<?= UOJProblem::info('id') ?>" <?php endif ?>>
|
||||
<i class="bi bi-journal-text"></i>
|
||||
<?= UOJLocale::get('problems::statement') ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (!$contest || $contest['cur_progress'] >= CONTEST_FINISHED) : ?>
|
||||
<?php if (!UOJContest::cur() || UOJContest::cur()->progress() >= CONTEST_FINISHED) : ?>
|
||||
<li class="nav-item text-start">
|
||||
<a href="/problem/<?= $problem['id'] ?>/solutions" class="nav-link" role="tab">
|
||||
<a href="/problem/<?= UOJProblem::info('id') ?>/solutions" class="nav-link" role="tab">
|
||||
<i class="bi bi-journal-bookmark"></i>
|
||||
<?= UOJLocale::get('problems::solutions') ?>
|
||||
</a>
|
||||
@ -305,9 +299,9 @@ $submissions_sort_by_choice = !isset($_COOKIE['submissions-sort-by-code-length']
|
||||
<?= UOJLocale::get('problems::statistics') ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (hasProblemPermission($myUser, $problem)) : ?>
|
||||
<?php if (UOJProblem::cur()->userCanManage(Auth::user())) : ?>
|
||||
<li class="nav-item text-start">
|
||||
<a class="nav-link" href="/problem/<?= $problem['id'] ?>/manage/statement" role="tab">
|
||||
<a class="nav-link" href="/problem/<?= UOJProblem::info('id') ?>/manage/statement" role="tab">
|
||||
<i class="bi bi-sliders"></i>
|
||||
<?= UOJLocale::get('problems::manage') ?>
|
||||
</a>
|
||||
|
@ -2,6 +2,7 @@
|
||||
requireLib('bootstrap5');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUser::checkPermission(Auth::user(), 'users.view') || UOJResponse::page403();
|
||||
|
||||
$config = [
|
||||
'page_len' => 50,
|
||||
@ -34,7 +35,6 @@ if (isset($_GET['type']) && $_GET['type'] == 'accepted') {
|
||||
<?php uojIncludeView('sidebar') ?>
|
||||
</aside>
|
||||
<!-- end right col -->
|
||||
|
||||
</div>
|
||||
|
||||
<?php echoUOJPageFooter() ?>
|
||||
|
@ -40,7 +40,7 @@ if (isset($_POST['register'])) {
|
||||
die();
|
||||
} elseif (isset($_POST['check_username'])) {
|
||||
$username = $_POST['username'];
|
||||
if (validateUsername($username) && !queryUser($username)) {
|
||||
if (validateUsername($username) && !UOJUser::query($username)) {
|
||||
die('{"ok": true}');
|
||||
} else {
|
||||
die('{"ok": false}');
|
||||
|
@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
$newPW = $_POST['newPW'];
|
||||
$user = queryUser($username);
|
||||
$user = UOJUser::query($username);
|
||||
if ($user == null) {
|
||||
return '不明错误';
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ requireLib('bootstrap5');
|
||||
requireLib('calendar_heatmap');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUserBlog::userIsOwner(Auth::user()) || UOJUser::checkPermission(Auth::user(), 'blogs.view') || UOJResponse::page403();
|
||||
Auth::id() == $user['username'] || UOJUser::checkPermission(Auth::user(), 'users.view') || UOJResponse::page403();
|
||||
?>
|
||||
<?php echoUOJPageHeader('关于我') ?>
|
||||
|
||||
|
@ -5,6 +5,7 @@ requireLib('hljs');
|
||||
requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUserBlog::userIsOwner(Auth::user()) || UOJUser::checkPermission(Auth::user(), 'blogs.view') || UOJResponse::page403();
|
||||
|
||||
$blogs_conds = [
|
||||
"poster" => UOJUserBlog::id(),
|
||||
@ -144,7 +145,7 @@ $all_tags = DB::selectAll([
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<?php if (UOJUserBlog::userCanManage(Auth::user())) : ?>
|
||||
<?php if (UOJUserBlog::userCanManage(Auth::user()) && UOJUser::checkPermission(Auth::user(), 'blogs.create')) : ?>
|
||||
<div class="btn-group d-flex">
|
||||
<a href="<?= HTML::blog_url(UOJUserBlog::id(), '/post/new/write') ?>" class="btn btn-primary">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
|
@ -4,6 +4,7 @@ requireLib('mathjax');
|
||||
requireLib('hljs');
|
||||
requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJBlog::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
UOJBlog::cur()->belongsToUserBlog() || UOJResponse::page404();
|
||||
UOJBlog::cur()->userCanView(Auth::user()) || UOJResponse::page403();
|
||||
@ -18,21 +19,6 @@ function getCommentContentToDisplay($comment) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
$solutions = DB::selectAll("select * from problems_solutions where blog_id = {$blog['id']}");
|
||||
if ($solutions) {
|
||||
foreach ($solutions as $solution) {
|
||||
$problem = queryProblemBrief($solution['problem_id']);
|
||||
|
||||
if (!hasProblemPermission($myUser, $problem) && isRegisteredRunningContestProblem($myUser, $problem)) {
|
||||
become403Page();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$comment_form = new UOJBs4Form('comment');
|
||||
$comment_form->addVTextArea(
|
||||
'comment',
|
||||
@ -76,7 +62,7 @@ $comment_form->handle = function () {
|
||||
$page = floor($rank / 20) + 1;
|
||||
|
||||
$uri = getLongTablePageUri($page) . '#' . "comment-{$comment_id}";
|
||||
$user_link = getUserLink($myUser['username']);
|
||||
$user_link = UOJUser::getLink(Auth::user());
|
||||
|
||||
foreach ($referrers as $referrer) {
|
||||
$content = $user_link . ' 在博客 ' . $blog['title'] . ' 的评论里提到你:<a href="' . $uri . '">点击此处查看</a>';
|
||||
@ -156,7 +142,7 @@ $reply_form->handle = function (&$vdata) {
|
||||
$page = floor($rank / 20) + 1;
|
||||
|
||||
$uri = getLongTablePageUri($page) . '#' . "comment-{$reply_id}";
|
||||
$user_link = getUserLink($myUser['username']);
|
||||
$user_link = UOJUser::getLink(Auth::user());
|
||||
|
||||
foreach ($referrers as $referrer) {
|
||||
$content = $user_link . ' 在博客 ' . $blog['title'] . ' 的评论里提到你:<a href="' . $uri . '">点击此处查看</a>';
|
||||
@ -229,7 +215,7 @@ $comments_pag = new Paginator([
|
||||
</div>
|
||||
<div id="comment-body-<?= $comment['id'] ?>" class="comtbox flex-grow-1 ms-3">
|
||||
<div class="row">
|
||||
<div class="col-sm-6"><?= getUserLink($poster['username']) ?></div>
|
||||
<div class="col-sm-6"><?= UOJUser::getLink($poster['username']) ?></div>
|
||||
<div class="col-sm-6 text-end"><?= ClickZans::getBlock('BC', $comment['id'], $comment['zan']) ?></div>
|
||||
</div>
|
||||
<div class="comtbox1"><?= $comment['content'] ?></div>
|
||||
|
@ -2,12 +2,9 @@
|
||||
requireLib('bootstrap5');
|
||||
requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUserBlog::userCanManage(Auth::user()) || UOJResponse::page403();
|
||||
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
if (isset($_GET['id'])) {
|
||||
UOJBlog::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
UOJBlog::cur()->belongsToUserBlog() || UOJResponse::page404();
|
||||
@ -15,6 +12,9 @@ if (isset($_GET['id'])) {
|
||||
$blog = UOJBlog::info();
|
||||
$blog['content'] = UOJBlog::cur()->queryContent()['content'];
|
||||
$blog['content_md'] = UOJBlog::cur()->queryContent()['content_md'];
|
||||
} else {
|
||||
UOJUser::checkPermission(Auth::user(), 'blogs.create') || UOJResponse::page403();
|
||||
isSuperUser(Auth::user()) || UOJUserBlog::userIsOwner(Auth::user()) || UOJResponse::page403();
|
||||
}
|
||||
|
||||
$blog_editor = new UOJBlogEditor();
|
||||
|
@ -4,6 +4,7 @@ requireLib('hljs');
|
||||
requireLib('mathjax');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUserBlog::userIsOwner(Auth::user()) || UOJUser::checkPermission(Auth::user(), 'blogs.view') || UOJResponse::page403();
|
||||
|
||||
$blogs_pag = new Paginator([
|
||||
'col_names' => ['*'],
|
||||
@ -33,7 +34,7 @@ $all_tags = DB::selectAll("select distinct tag from blogs_tags where blog_id in
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<img class="media-object img-thumbnail center-block" alt="<?= UOJUserBlog::id() ?> Avatar" src="<?= HTML::avatar_addr(UOJUserBlog::user(), 512) ?>" />
|
||||
<?php if (UOJUserBlog::userCanManage(Auth::user())) : ?>
|
||||
<?php if (UOJUserBlog::userCanManage(Auth::user()) && UOJUser::checkPermission(Auth::user(), 'blogs.create')) : ?>
|
||||
<div class="btn-group d-flex mt-3">
|
||||
<a href="<?= HTML::blog_url(UOJUserBlog::id(), '/post/new/write') ?>" class="btn btn-primary">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
|
@ -4,6 +4,7 @@ requireLib('mathjax');
|
||||
requirePHPLib('form');
|
||||
|
||||
Auth::check() || redirectToLogin();
|
||||
UOJUserBlog::userIsOwner(Auth::user()) || UOJUser::checkPermission(Auth::user(), 'blogs.view') || UOJResponse::page403();
|
||||
?>
|
||||
|
||||
<?php echoUOJPageHeader(UOJLocale::get('contests::contest self reviews')) ?>
|
||||
|
@ -6,7 +6,7 @@ UOJBlog::init(UOJRequest::get('id')) || UOJResponse::page404();
|
||||
UOJBlog::cur()->belongsToUserBlog() || UOJResponse::page404();
|
||||
UOJBlog::cur()->userCanView(Auth::user()) || UOJResponse::page403();
|
||||
UOJBlog::cur()->isTypeS() || UOJResponse::page404();
|
||||
|
||||
UOJUserBlog::userIsOwner(Auth::user()) || UOJUser::checkPermission(Auth::user(), 'blogs.view') || UOJResponse::page403();
|
||||
|
||||
$page_config = UOJContext::pageConfig();
|
||||
$page_config += [
|
||||
|
@ -12,6 +12,9 @@ if (isset($_GET['id'])) {
|
||||
$blog = UOJBlog::info();
|
||||
$blog['content'] = UOJBlog::cur()->queryContent()['content'];
|
||||
$blog['content_md'] = UOJBlog::cur()->queryContent()['content_md'];
|
||||
} else {
|
||||
UOJUser::checkPermission(Auth::user(), 'blogs.create') || UOJResponse::page403();
|
||||
isSuperUser(Auth::user()) || UOJUserBlog::userIsOwner(Auth::user()) || UOJResponse::page403();
|
||||
}
|
||||
|
||||
$blog_editor = new UOJBlogEditor();
|
||||
|
@ -9,7 +9,7 @@ if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
if (!isSuperUser($myUser)) {
|
||||
if (!isSuperUser(Auth::user())) {
|
||||
become403Page();
|
||||
}
|
||||
|
||||
@ -325,9 +325,6 @@ if ($cur_tab == 'index') {
|
||||
if (isset($_GET['usergroup']) && $_GET['usergroup'] != "") {
|
||||
$user_list_cond[] = "usergroup = '" . DB::escape($_GET['usergroup']) . "'";
|
||||
}
|
||||
if (isset($_GET['usertype']) && $_GET['usertype'] != "") {
|
||||
$user_list_cond[] = "usertype like '%" . DB::escape($_GET['usertype']) . "%'";
|
||||
}
|
||||
|
||||
if ($user_list_cond) {
|
||||
$user_list_cond = implode(' and ', $user_list_cond);
|
||||
@ -346,7 +343,7 @@ if ($cur_tab == 'index') {
|
||||
return '用户名不合法';
|
||||
}
|
||||
|
||||
if (queryUser($username)) {
|
||||
if (UOJUser::query($username)) {
|
||||
return '该用户已存在';
|
||||
}
|
||||
|
||||
@ -453,7 +450,7 @@ EOD);
|
||||
return '用户名不合法';
|
||||
}
|
||||
|
||||
if (!queryUser($username)) {
|
||||
if (!UOJUser::query($username)) {
|
||||
return '用户不存在';
|
||||
}
|
||||
|
||||
@ -524,7 +521,7 @@ EOD);
|
||||
return '用户名不合法';
|
||||
}
|
||||
|
||||
if (!queryUser($username)) {
|
||||
if (!UOJUser::query($username)) {
|
||||
return '用户不存在';
|
||||
}
|
||||
|
||||
@ -580,6 +577,206 @@ EOD);
|
||||
}
|
||||
EOD);
|
||||
$change_usergroup_form->runAtServer();
|
||||
|
||||
$users_default_permissions = UOJContext::getMeta('users_default_permissions');
|
||||
$update_users_default_permissions_form = new UOJForm('update_users_default_permissions');
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5'], '题目'));
|
||||
$update_users_default_permissions_form->addCheckbox('problems__view', [
|
||||
'checked' => $users_default_permissions['problems']['view'],
|
||||
'label' => '查看题目',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('problems__download_testdata', [
|
||||
'checked' => $users_default_permissions['problems']['download_testdata'],
|
||||
'label' => '下载测试数据',
|
||||
'role' => 'switch',
|
||||
'help' => '请谨慎开启此权限,以防数据泄露。',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('problems__create', [
|
||||
'checked' => $users_default_permissions['problems']['create'],
|
||||
'label' => '新建题目',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('problems__manage', [
|
||||
'checked' => $users_default_permissions['problems']['manage'],
|
||||
'label' => '管理题目',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '比赛'));
|
||||
$update_users_default_permissions_form->addCheckbox('contests__view', [
|
||||
'checked' => $users_default_permissions['contests']['view'],
|
||||
'label' => '查看比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则只显示已报名过的比赛列表及详情。',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('contests__register', [
|
||||
'checked' => $users_default_permissions['contests']['register'],
|
||||
'label' => '报名比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('contests__create', [
|
||||
'checked' => $users_default_permissions['contests']['create'],
|
||||
'label' => '新建比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('contests__start_final_test', [
|
||||
'checked' => $users_default_permissions['contests']['start_final_test'],
|
||||
'label' => '开始比赛最终测试',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('contests__manage', [
|
||||
'checked' => $users_default_permissions['contests']['manage'],
|
||||
'label' => '管理比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '题单'));
|
||||
$update_users_default_permissions_form->addCheckbox('lists__view', [
|
||||
'checked' => $users_default_permissions['lists']['view'],
|
||||
'label' => '查看题单',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('lists__create', [
|
||||
'checked' => $users_default_permissions['lists']['create'],
|
||||
'label' => '新建题单',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('lists__manage', [
|
||||
'checked' => $users_default_permissions['lists']['manage'],
|
||||
'label' => '管理题单',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '小组'));
|
||||
$update_users_default_permissions_form->addCheckbox('groups__view', [
|
||||
'checked' => $users_default_permissions['groups']['view'],
|
||||
'label' => '查看小组',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('groups__create', [
|
||||
'checked' => $users_default_permissions['groups']['create'],
|
||||
'label' => '新建小组',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('groups__manage', [
|
||||
'checked' => $users_default_permissions['groups']['manage'],
|
||||
'label' => '管理小组',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '博客'));
|
||||
$update_users_default_permissions_form->addCheckbox('blogs__view', [
|
||||
'checked' => $users_default_permissions['blogs']['view'],
|
||||
'label' => '查看博客',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('blogs__create', [
|
||||
'checked' => $users_default_permissions['blogs']['create'],
|
||||
'label' => '新建博客',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('blogs__manage', [
|
||||
'checked' => $users_default_permissions['blogs']['manage'],
|
||||
'label' => '管理博客',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => true,
|
||||
]);
|
||||
$update_users_default_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '用户'));
|
||||
$update_users_default_permissions_form->addCheckbox('users__view', [
|
||||
'checked' => $users_default_permissions['users']['view'],
|
||||
'label' => '查看用户',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则不能查看他人的个人资料。',
|
||||
]);
|
||||
$update_users_default_permissions_form->addCheckbox('users__upload_image', [
|
||||
'checked' => $users_default_permissions['users']['upload_image'],
|
||||
'label' => '上传图片',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则不能使用图床功能。',
|
||||
]);
|
||||
$update_users_default_permissions_form->setAjaxSubmit(<<<EOD
|
||||
function(res) {
|
||||
if (res.status === 'success') {
|
||||
$('#result-alert-update_users_default_permission')
|
||||
.html('修改成功!' + (res.message || ''))
|
||||
.addClass('alert-success')
|
||||
.removeClass('alert-danger')
|
||||
.show();
|
||||
} else {
|
||||
$('#result-alert-update_users_default_permission')
|
||||
.html('修改失败。' + (res.message || ''))
|
||||
.removeClass('alert-success')
|
||||
.addClass('alert-danger')
|
||||
.show();
|
||||
}
|
||||
|
||||
$(window).scrollTop(0);
|
||||
}
|
||||
EOD);
|
||||
$update_users_default_permissions_form->config['confirm']['text'] = '你确定要修改所有用户的默认权限吗?';
|
||||
$update_users_default_permissions_form->handle = function () {
|
||||
$new_permissions = [
|
||||
'problems' => [
|
||||
'view' => isset($_POST['problems__view']),
|
||||
'download_testdata' => isset($_POST['problems__download_testdata']),
|
||||
'create' => false, // isset($_POST['problems__create']),
|
||||
'manage' => false, // isset($_POST['problems__manage']),
|
||||
],
|
||||
'contests' => [
|
||||
'view' => isset($_POST['contests__view']),
|
||||
'register' => isset($_POST['contests__register']),
|
||||
'create' => false, // isset($_POST['contests__create']),
|
||||
'start_final_test' => false, // isset($_POST['contests__start_final_test']),
|
||||
'manage' => false, // isset($_POST['contests__manage']),
|
||||
],
|
||||
'lists' => [
|
||||
'view' => isset($_POST['lists__view']),
|
||||
'create' => false, // isset($_POST['lists__create']),
|
||||
'manage' => false, // isset($_POST['lists__manage']),
|
||||
],
|
||||
'groups' => [
|
||||
'view' => isset($_POST['groups__view']),
|
||||
'create' => false, // isset($_POST['groups__create']),
|
||||
'manage' => false, // isset($_POST['groups__manage']),
|
||||
],
|
||||
'blogs' => [
|
||||
'view' => isset($_POST['blogs__view']),
|
||||
'create' => isset($_POST['blogs__create']),
|
||||
'manage' => false, // isset($_POST['blogs__manage']),
|
||||
],
|
||||
'users' => [
|
||||
'view' => isset($_POST['users__view']),
|
||||
'upload_image' => isset($_POST['users__upload_image']),
|
||||
],
|
||||
];
|
||||
|
||||
UOJContext::setMeta('users_default_permissions', $new_permissions);
|
||||
|
||||
dieWithJsonData(['status' => 'success', 'message' => '']);
|
||||
};
|
||||
$update_users_default_permissions_form->runAtServer();
|
||||
} elseif ($cur_tab == 'submissions') {
|
||||
} elseif ($cur_tab == 'custom_test') {
|
||||
requireLib('hljs');
|
||||
@ -698,7 +895,7 @@ EOD);
|
||||
return '用户名不合法';
|
||||
}
|
||||
|
||||
if (!queryUser($x)) {
|
||||
if (!UOJUser::query($x)) {
|
||||
return '用户不存在';
|
||||
}
|
||||
|
||||
@ -960,6 +1157,9 @@ EOD);
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#user-group" data-bs-toggle="tab" data-bs-target="#user-group">用户类别</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#users-default-permissions" data-bs-toggle="tab" data-bs-target="#users-default-permissions">默认权限</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@ -986,24 +1186,6 @@ EOD);
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="user-query-usertype" class="form-label">用户权限</label>
|
||||
<select class="form-select" id="user-query-usertype" name="usertype">
|
||||
<?php
|
||||
$usertypes = [
|
||||
'' => '*: 所有',
|
||||
'student' => 'student: 学生',
|
||||
'teacher' => 'teacher: 老师',
|
||||
'problem_uploader' => 'problem_uploader: 题目上传者',
|
||||
'problem_manager' => 'problem_manager: 题目管理员',
|
||||
'contest_judger' => 'contest_judger: 比赛评测员',
|
||||
];
|
||||
?>
|
||||
<?php foreach ($usertypes as $name => $type) : ?>
|
||||
<option value="<?= $name ?>" <?php if ($_GET['usertype'] == $name) : ?> selected <?php endif ?>><?= $type ?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" id="user-query-submit" class="mt-2 btn btn-secondary">查询</button>
|
||||
</div>
|
||||
@ -1015,15 +1197,15 @@ EOD);
|
||||
$user_list_cond,
|
||||
'order by username asc',
|
||||
<<<EOD
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th>学校</th>
|
||||
<th>用户类别</th>
|
||||
<th>权限</th>
|
||||
<th>注册时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
EOD,
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th>学校</th>
|
||||
<th>用户类别</th>
|
||||
<th>权限</th>
|
||||
<th>注册时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
EOD,
|
||||
function ($row) {
|
||||
echo '<tr>';
|
||||
echo '<td>', '<span class="uoj-username" data-realname="', HTML::escape($row['realname']), '">', $row['username'], '</span>', '</td>';
|
||||
@ -1036,18 +1218,16 @@ EOD,
|
||||
case 'B':
|
||||
echo UOJLocale::get('user::banned user');
|
||||
break;
|
||||
case 'T':
|
||||
echo UOJLocale::get('user::tmp user');
|
||||
break;
|
||||
default:
|
||||
echo UOJLocale::get('user::normal user');
|
||||
break;
|
||||
}
|
||||
echo '</td>';
|
||||
echo '<td>';
|
||||
foreach (explode(',', $row['usertype']) as $idx => $type) {
|
||||
if ($idx) {
|
||||
echo ', ';
|
||||
}
|
||||
echo UOJLocale::get('user::' . str_replace('_', ' ', $type)) ?: HTML::escape($type);
|
||||
}
|
||||
echo UOJLocale::get('user::' . $row['usertype']) ?: HTML::escape($row['usertype']);
|
||||
echo '</td>';
|
||||
echo '<td>', $row['register_time'], '</td>';
|
||||
echo '<td>', '<a class="text-decoration-none d-inline-block align-middle" href="/user/', $row['username'], '/edit">编辑</a>', '</td>';
|
||||
@ -1111,6 +1291,24 @@ EOD,
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="users-default-permissions">
|
||||
<div id="result-alert-update_users_default_permission" class="alert" role="alert" style="display: none"></div>
|
||||
<div class="row row-cols-1 row-cols-md-2">
|
||||
<div class="col">
|
||||
<?php $update_users_default_permissions_form->printHTML() ?>
|
||||
</div>
|
||||
<div class="col mt-3 mt-md-0">
|
||||
<h5>注意事项</h5>
|
||||
<ul class="mb-0">
|
||||
<li>此处修改的是 <b>所有用户</b> 的默认权限。</li>
|
||||
<li>如果某用户的 A 权限启闭状态与为该用户修改 A 权限时的默认权限状态不同,则在此处修改用户默认权限后该用户的 A 权限状态不会受到影响。</li>
|
||||
<li>对于每一个权限分类,若用户不具有新建项目权限,则只能对现有内容进行管理。</li>
|
||||
<li>如需为单个用户设置增加/移除特定权限,请前往对应用户的个人资料编辑页面,点击「特权」选项卡修改。</li>
|
||||
<li>出于安全考虑,部分权限不能被设置为默认权限。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1166,7 +1364,7 @@ EOD,
|
||||
<tr style="cursor: pointer" data-bs-toggle="collapse" data-bs-target="#custom_test__<?= $submission['id'] ?>">
|
||||
<td class="text-center text-primary">#<?= $submission['id'] ?></td>
|
||||
<td class="text-center">#<?= $submission['problem_id'] ?></td>
|
||||
<td><?= getUserLink($submission['submitter']) ?></td>
|
||||
<td><?= UOJUser::getLink($submission['submitter']) ?></td>
|
||||
<td><?= $submission['submit_time'] ?></td>
|
||||
<td><?= $submission['judge_time'] ?></td>
|
||||
</tr>
|
||||
@ -1251,7 +1449,7 @@ EOD;
|
||||
</tr>
|
||||
EOD,
|
||||
function ($row) {
|
||||
$user_link = getUserLink($row['uploader']);
|
||||
$user_link = UOJUser::getLink($row['uploader']);
|
||||
if ($row['size'] < 1024 * 512) {
|
||||
$size = strval(round($row['size'] * 1.0 / 1024, 1)) . ' KB';
|
||||
} else {
|
||||
|
@ -1,13 +1,11 @@
|
||||
<?php
|
||||
requireLib('bootstrap5');
|
||||
requireLib('calendar_heatmap');
|
||||
requireLib('bootstrap5');
|
||||
requireLib('calendar_heatmap');
|
||||
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
($user = UOJUser::query($_GET['username'])) || UOJResponse::page404();
|
||||
?>
|
||||
Auth::check() || redirectToLogin();
|
||||
($user = UOJUser::query($_GET['username'])) || UOJResponse::page404();
|
||||
Auth::id() == $user['username'] || UOJUser::checkPermission(Auth::user(), 'users.view') || UOJResponse::page403();
|
||||
?>
|
||||
|
||||
<?php echoUOJPageHeader($user['username'] . ' - ' . UOJLocale::get('user profile')) ?>
|
||||
|
||||
|
@ -293,32 +293,363 @@ EOD);
|
||||
dieWithJsonData(['status' => 'success', 'message' => '密码修改成功']);
|
||||
}
|
||||
} elseif ($cur_tab == 'privilege') {
|
||||
if (isset($_POST['submit-privilege']) && $_POST['submit-privilege'] == 'privilege' && isSuperUser(Auth::user())) {
|
||||
$user['usertype'] = 'student';
|
||||
|
||||
if ($_POST['user_type'] == 'teacher') {
|
||||
addUserType($user, 'teacher');
|
||||
removeUserType($user, 'student');
|
||||
} else {
|
||||
addUserType($user, 'student');
|
||||
}
|
||||
|
||||
if ($_POST['problem_uploader'] == 'yes') {
|
||||
addUserType($user, 'problem_uploader');
|
||||
}
|
||||
|
||||
if ($_POST['problem_manager'] == 'yes') {
|
||||
addUserType($user, 'problem_manager');
|
||||
}
|
||||
|
||||
if ($_POST['contest_judger'] == 'yes') {
|
||||
addUserType($user, 'contest_judger');
|
||||
}
|
||||
|
||||
DB::update("UPDATE `user_info` SET `usertype` = '{$user['usertype']}' where `username` = '{$user['username']}'");
|
||||
|
||||
dieWithJsonData(['status' => 'success', 'message' => '权限修改成功']);
|
||||
$users_default_permissions = UOJContext::getMeta('users_default_permissions');
|
||||
$type_text = UOJLocale::get('user::normal user');
|
||||
if ($user['usergroup'] == 'S') {
|
||||
$type_text = UOJLocale::get('user::super user');
|
||||
} elseif ($user['usergroup'] == 'T') {
|
||||
$type_text = UOJLocale::get('user::tmp user');
|
||||
} elseif ($user['usergroup'] == 'B') {
|
||||
$type_text = UOJLocale::get('user::banned user');
|
||||
}
|
||||
$disabled = !isSuperUser(Auth::user());
|
||||
$update_user_permissions_form = new UOJForm('update_user_permissions');
|
||||
if ($disabled) {
|
||||
$update_user_permissions_form->config['no_submit'] = true;
|
||||
}
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('span', [], UOJLocale::get('user::user group')));
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('span', ['class' => 'd-inline-block ms-3'], $type_text));
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '题目'));
|
||||
$update_user_permissions_form->addCheckbox('problems__view', [
|
||||
'checked' => $extra['permissions']['problems']['view'],
|
||||
'label' => '查看题目',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('problems__download_testdata', [
|
||||
'checked' => $extra['permissions']['problems']['download_testdata'],
|
||||
'label' => '下载测试数据',
|
||||
'role' => 'switch',
|
||||
'help' => '请谨慎开启此权限,以防数据泄露。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('problems__create', [
|
||||
'checked' => $extra['permissions']['problems']['create'],
|
||||
'label' => '新建题目',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('problems__manage', [
|
||||
'checked' => $extra['permissions']['problems']['manage'],
|
||||
'label' => '管理题目',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有「新建题目」权限,则只能对现有题目进行管理。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '比赛'));
|
||||
$update_user_permissions_form->addCheckbox('contests__view', [
|
||||
'checked' => $extra['permissions']['contests']['view'],
|
||||
'label' => '查看比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则只显示已报名过的比赛列表及详情。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('contests__register', [
|
||||
'checked' => $extra['permissions']['contests']['register'],
|
||||
'label' => '报名比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('contests__create', [
|
||||
'checked' => $extra['permissions']['contests']['create'],
|
||||
'label' => '新建比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('contests__start_final_test', [
|
||||
'checked' => $extra['permissions']['contests']['start_final_test'],
|
||||
'label' => '开始比赛最终测试',
|
||||
'role' => 'switch',
|
||||
'help' => '拥有此权限的用户可以代为开始比赛最终测试。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('contests__manage', [
|
||||
'checked' => $extra['permissions']['contests']['manage'],
|
||||
'label' => '管理比赛',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有「新建比赛」权限,则只能对现有比赛进行管理。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '题单'));
|
||||
$update_user_permissions_form->addCheckbox('lists__view', [
|
||||
'checked' => $extra['permissions']['lists']['view'],
|
||||
'label' => '查看题单',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('lists__create', [
|
||||
'checked' => $extra['permissions']['lists']['create'],
|
||||
'label' => '新建题单',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('lists__manage', [
|
||||
'checked' => $extra['permissions']['lists']['manage'],
|
||||
'label' => '管理题单',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有「新建题单」权限,则只能对现有题单进行管理。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '小组'));
|
||||
$update_user_permissions_form->addCheckbox('groups__view', [
|
||||
'checked' => $extra['permissions']['groups']['view'],
|
||||
'label' => '查看小组',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('groups__create', [
|
||||
'checked' => $extra['permissions']['groups']['create'],
|
||||
'label' => '新建小组',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('groups__manage', [
|
||||
'checked' => $extra['permissions']['groups']['manage'],
|
||||
'label' => '管理小组',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有「新建小组」权限,则只能对现有小组进行管理。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '博客'));
|
||||
$update_user_permissions_form->addCheckbox('blogs__view', [
|
||||
'checked' => $extra['permissions']['blogs']['view'],
|
||||
'label' => '查看博客',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('blogs__create', [
|
||||
'checked' => $extra['permissions']['blogs']['create'],
|
||||
'label' => '新建博客',
|
||||
'role' => 'switch',
|
||||
'help' => '',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('blogs__manage', [
|
||||
'checked' => $extra['permissions']['blogs']['manage'],
|
||||
'label' => '管理博客',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有「新建博客」权限,则只能对现有博客进行管理。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->appendHTML(HTML::tag('h3', ['class' => 'h5 mt-3'], '用户'));
|
||||
$update_user_permissions_form->addCheckbox('users__view', [
|
||||
'checked' => $extra['permissions']['users']['view'],
|
||||
'label' => '查看用户',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则不能查看他人的个人资料。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->addCheckbox('users__upload_image', [
|
||||
'checked' => $extra['permissions']['users']['upload_image'],
|
||||
'label' => '上传图片',
|
||||
'role' => 'switch',
|
||||
'help' => '若用户不具有此权限,则不能使用图床功能。',
|
||||
'disabled' => $disabled,
|
||||
]);
|
||||
$update_user_permissions_form->setAjaxSubmit(<<<EOD
|
||||
function(res) {
|
||||
if (res.status === 'success') {
|
||||
$('#result-alert')
|
||||
.html('修改成功!' + (res.message || ''))
|
||||
.addClass('alert-success')
|
||||
.removeClass('alert-danger')
|
||||
.show();
|
||||
} else {
|
||||
$('#result-alert')
|
||||
.html('修改失败。' + (res.message || ''))
|
||||
.removeClass('alert-success')
|
||||
.addClass('alert-danger')
|
||||
.show();
|
||||
}
|
||||
|
||||
$(window).scrollTop(0);
|
||||
}
|
||||
EOD);
|
||||
$update_user_permissions_form->handle = function () use ($user, $extra, $users_default_permissions) {
|
||||
$new_permissions = [
|
||||
'_placeholder' => '',
|
||||
'problems' => [
|
||||
'_placeholder' => '',
|
||||
// 'view' => isset($_POST['problems__view']),
|
||||
// 'download_testdata' => isset($_POST['problems__download_testdata']),
|
||||
// 'create' => isset($_POST['problems__create']),
|
||||
// 'manage' => isset($_POST['problems__manage']),
|
||||
],
|
||||
'contests' => [
|
||||
'_placeholder' => '',
|
||||
// 'view' => isset($_POST['contests__view']),
|
||||
// 'register' => isset($_POST['contests__register']),
|
||||
// 'create' => isset($_POST['contests__create']),
|
||||
// 'start_final_test' => isset($_POST['contests__start_final_test']),
|
||||
// 'manage' => isset($_POST['contests__manage']),
|
||||
],
|
||||
'lists' => [
|
||||
'_placeholder' => '',
|
||||
// 'view' => isset($_POST['lists__view']),
|
||||
// 'create' => isset($_POST['lists__create']),
|
||||
// 'manage' => isset($_POST['lists__manage']),
|
||||
],
|
||||
'groups' => [
|
||||
'_placeholder' => '',
|
||||
// 'view' => isset($_POST['groups__view']),
|
||||
// 'create' => isset($_POST['groups__create']),
|
||||
// 'manage' => isset($_POST['groups__manage']),
|
||||
],
|
||||
'blogs' => [
|
||||
'_placeholder' => '',
|
||||
// 'view' => isset($_POST['blogs__view']),
|
||||
// 'create' => isset($_POST['blogs__create']),
|
||||
// 'manage' => isset($_POST['blogs__manage']),
|
||||
],
|
||||
'users' => [
|
||||
'_placeholder' => '',
|
||||
]
|
||||
];
|
||||
|
||||
if (isset($_POST['problems__view']) && !$users_default_permissions['problems']['view']) {
|
||||
$new_permissions['problems']['view'] = true;
|
||||
} elseif (!isset($_POST['problems__view']) && $users_default_permissions['problems']['view']) {
|
||||
$new_permissions['problems']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['problems__download_testdata']) && !$users_default_permissions['problems']['download_testdata']) {
|
||||
$new_permissions['problems']['download_testdata'] = true;
|
||||
} elseif (!isset($_POST['problems__download_testdata']) && $users_default_permissions['problems']['download_testdata']) {
|
||||
$new_permissions['problems']['download_testdata'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['problems__create']) && !$users_default_permissions['problems']['create']) {
|
||||
$new_permissions['problems']['create'] = true;
|
||||
} elseif (!isset($_POST['problems__create']) && $users_default_permissions['problems']['create']) {
|
||||
$new_permissions['problems']['create'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['problems__manage']) && !$users_default_permissions['problems']['manage']) {
|
||||
$new_permissions['problems']['manage'] = true;
|
||||
} elseif (!isset($_POST['problems__manage']) && $users_default_permissions['problems']['manage']) {
|
||||
$new_permissions['problems']['manage'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['contests__view']) && !$users_default_permissions['contests']['view']) {
|
||||
$new_permissions['contests']['view'] = true;
|
||||
} elseif (!isset($_POST['contests__view']) && $users_default_permissions['contests']['view']) {
|
||||
$new_permissions['contests']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['contests__register']) && !$users_default_permissions['contests']['register']) {
|
||||
$new_permissions['contests']['register'] = true;
|
||||
} elseif (!isset($_POST['contests__register']) && $users_default_permissions['contests']['register']) {
|
||||
$new_permissions['contests']['register'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['contests__create']) && !$users_default_permissions['contests']['create']) {
|
||||
$new_permissions['contests']['create'] = true;
|
||||
} elseif (!isset($_POST['contests__create']) && $users_default_permissions['contests']['create']) {
|
||||
$new_permissions['contests']['create'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['contests__start_final_test']) && !$users_default_permissions['contests']['start_final_test']) {
|
||||
$new_permissions['contests']['start_final_test'] = true;
|
||||
} elseif (!isset($_POST['contests__start_final_test']) && $users_default_permissions['contests']['start_final_test']) {
|
||||
$new_permissions['contests']['start_final_test'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['contests__manage']) && !$users_default_permissions['contests']['manage']) {
|
||||
$new_permissions['contests']['manage'] = true;
|
||||
} elseif (!isset($_POST['contests__manage']) && $users_default_permissions['contests']['manage']) {
|
||||
$new_permissions['contests']['manage'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['lists__view']) && !$users_default_permissions['lists']['view']) {
|
||||
$new_permissions['lists']['view'] = true;
|
||||
} elseif (!isset($_POST['lists__view']) && $users_default_permissions['lists']['view']) {
|
||||
$new_permissions['lists']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['lists__create']) && !$users_default_permissions['lists']['create']) {
|
||||
$new_permissions['lists']['create'] = true;
|
||||
} elseif (!isset($_POST['lists__create']) && $users_default_permissions['lists']['create']) {
|
||||
$new_permissions['lists']['create'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['lists__manage']) && !$users_default_permissions['lists']['manage']) {
|
||||
$new_permissions['lists']['manage'] = true;
|
||||
} elseif (!isset($_POST['lists__manage']) && $users_default_permissions['lists']['manage']) {
|
||||
$new_permissions['lists']['manage'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['groups__view']) && !$users_default_permissions['groups']['view']) {
|
||||
$new_permissions['groups']['view'] = true;
|
||||
} elseif (!isset($_POST['groups__view']) && $users_default_permissions['groups']['view']) {
|
||||
$new_permissions['groups']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['groups__create']) && !$users_default_permissions['groups']['create']) {
|
||||
$new_permissions['groups']['create'] = true;
|
||||
} elseif (!isset($_POST['groups__create']) && $users_default_permissions['groups']['create']) {
|
||||
$new_permissions['groups']['create'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['groups__manage']) && !$users_default_permissions['groups']['manage']) {
|
||||
$new_permissions['groups']['manage'] = true;
|
||||
} elseif (!isset($_POST['groups__manage']) && $users_default_permissions['groups']['manage']) {
|
||||
$new_permissions['groups']['manage'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['blogs__view']) && !$users_default_permissions['blogs']['view']) {
|
||||
$new_permissions['blogs']['view'] = true;
|
||||
} elseif (!isset($_POST['blogs__view']) && $users_default_permissions['blogs']['view']) {
|
||||
$new_permissions['blogs']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['blogs__create']) && !$users_default_permissions['blogs']['create']) {
|
||||
$new_permissions['blogs']['create'] = true;
|
||||
} elseif (!isset($_POST['blogs__create']) && $users_default_permissions['blogs']['create']) {
|
||||
$new_permissions['blogs']['create'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['blogs__manage']) && !$users_default_permissions['blogs']['manage']) {
|
||||
$new_permissions['blogs']['manage'] = true;
|
||||
} elseif (!isset($_POST['blogs__manage']) && $users_default_permissions['blogs']['manage']) {
|
||||
$new_permissions['blogs']['manage'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['users__view']) && !$users_default_permissions['users']['view']) {
|
||||
$new_permissions['users']['view'] = true;
|
||||
} elseif (!isset($_POST['users__view']) && $users_default_permissions['users']['view']) {
|
||||
$new_permissions['users']['view'] = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['users__upload_image']) && !$users_default_permissions['users']['upload_image']) {
|
||||
$new_permissions['users']['upload_image'] = true;
|
||||
} elseif (!isset($_POST['users__upload_image']) && $users_default_permissions['users']['upload_image']) {
|
||||
$new_permissions['users']['upload_image'] = false;
|
||||
}
|
||||
|
||||
$extra['permissions'] = $new_permissions;
|
||||
|
||||
DB::update([
|
||||
"update user_info",
|
||||
"set", [
|
||||
"extra" => json_encode($extra),
|
||||
],
|
||||
"where", [
|
||||
"username" => $user['username'],
|
||||
],
|
||||
]);
|
||||
|
||||
dieWithJsonData(['status' => 'success', 'message' => '']);
|
||||
};
|
||||
$update_user_permissions_form->runAtServer();
|
||||
}
|
||||
|
||||
$pageTitle = $user['username'] == Auth::id()
|
||||
@ -386,7 +717,7 @@ $pageTitle = $user['username'] == Auth::id()
|
||||
<input type="password" class="form-control" id="input-confirm_password" placeholder="<?= UOJLocale::get('re-enter your new password') ?>" maxlength="20">
|
||||
<div id="help-confirm_password" class="invalid-feedback"></div>
|
||||
</div>
|
||||
<?php if (isSuperUser(Auth::user()) && $user['username'] != $myUser['username']) : ?>
|
||||
<?php if (isSuperUser(Auth::user()) && $user['username'] != Auth::id()) : ?>
|
||||
<div class="alert alert-warning mb-0" role="alert">
|
||||
如需重置其他用户的密码,请前往 <a href="/super_manage/users" class="alert-link">系统管理</a> 页面操作。
|
||||
</div>
|
||||
@ -451,105 +782,7 @@ $pageTitle = $user['username'] == Auth::id()
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div id="result-alert" class="alert" role="alert" style="display: none"></div>
|
||||
<form id="form-privilege" method="post">
|
||||
<?php if (isSuperUser(Auth::user())) : ?>
|
||||
<fieldset>
|
||||
<?php else : ?>
|
||||
<fieldset disabled>
|
||||
<?php endif ?>
|
||||
<div class="mb-3">
|
||||
<span>
|
||||
<?= UOJLocale::get('user::user group') ?>
|
||||
</span>
|
||||
<span class="d-inline-block ms-3">
|
||||
<?php if ($user['usergroup'] == 'S') : ?>
|
||||
<?= UOJLocale::get('user::super user') ?>
|
||||
<?php elseif ($user['usergroup'] == 'B') : ?>
|
||||
<?= UOJLocale::get('user::banned user') ?>
|
||||
<?php else : ?>
|
||||
<?= UOJLocale::get('user::normal user') ?>
|
||||
<?php endif ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<label for="input-user_type" class="form-label">
|
||||
<?= UOJLocale::get('user::user type') ?>
|
||||
</label>
|
||||
<div class="form-check ms-3">
|
||||
<input class="form-check-input" type="radio" name="user_type" value="student" id="input-user_type" <?= hasUserType($user, 'student') && !hasUserType($user, 'teacher') ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="input-user_type">
|
||||
<?= UOJLocale::get('user::student') ?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check ms-2">
|
||||
<input class="form-check-input" type="radio" name="user_type" value="teacher" id="input-user_type_2" <?= hasUserType($user, 'teacher') ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="input-user_type_2">
|
||||
<?= UOJLocale::get('user::teacher') ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="problem_uploader" id="input-problem_uploader" <?= hasUserType($user, 'problem_uploader') ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="input-problem_uploader">
|
||||
<?= UOJLocale::get('user::problem uploader') ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="problem_manager" id="input-problem_manager" <?= hasUserType($user, 'problem_manager') ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="input-problem_manager">
|
||||
<?= UOJLocale::get('user::problem manager') ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="contest_judger" id="input-contest_judger" <?= hasUserType($user, 'contest_judger') ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="input-contest_judger">
|
||||
<?= UOJLocale::get('user::contest judger') ?>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<?php if (isSuperUser(Auth::user())) : ?>
|
||||
<div class="text-center">
|
||||
<button type="submit" id="button-submit-privilege" name="submit-privilege" value="privilege" class="mt-3 btn btn-secondary">更新</button>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
<script>
|
||||
$('#form-privilege').submit(function(e) {
|
||||
$('#result-alert').hide();
|
||||
|
||||
$.post('', {
|
||||
user_type: $('input[name=user_type]:checked').val(),
|
||||
problem_uploader: $('input[name=problem_uploader]').prop('checked') ? 'yes' : 'no',
|
||||
problem_manager: $('input[name=problem_manager]').prop('checked') ? 'yes' : 'no',
|
||||
contest_judger: $('input[name=contest_judger]').prop('checked') ? 'yes' : 'no',
|
||||
'submit-privilege': 'privilege',
|
||||
}, function(res) {
|
||||
if (res && res.status === 'success') {
|
||||
$('#result-alert')
|
||||
.html('权限修改成功!')
|
||||
.addClass('alert-success')
|
||||
.removeClass('alert-danger')
|
||||
.show();
|
||||
|
||||
$(window).scrollTop(0);
|
||||
} else {
|
||||
$('#result-alert')
|
||||
.html('权限修改失败。' + (res.message || ''))
|
||||
.removeClass('alert-success')
|
||||
.addClass('alert-danger')
|
||||
.show();
|
||||
|
||||
$(window).scrollTop(0);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
<?php $update_user_permissions_form->printHTML() ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
@ -1,83 +1,80 @@
|
||||
<?php
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
if (!Auth::check()) {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
function handleMsgPost() {
|
||||
if (!isset($_POST['receiver'])) {
|
||||
return 'fail';
|
||||
}
|
||||
if (!isset($_POST['message'])) {
|
||||
return 'fail';
|
||||
}
|
||||
if (0 > strlen($_POST['message']) || strlen($_POST['message']) > 65535) {
|
||||
return 'fail';
|
||||
}
|
||||
$receiver = $_POST['receiver'];
|
||||
$esc_message = DB::escape($_POST['message']);
|
||||
$sender = Auth::id();
|
||||
|
||||
if (!validateUsername($receiver) || !UOJUser::query($receiver)) {
|
||||
return 'fail';
|
||||
}
|
||||
|
||||
function handleMsgPost() {
|
||||
global $myUser;
|
||||
if (!isset($_POST['receiver'])) {
|
||||
return 'fail';
|
||||
}
|
||||
if (!isset($_POST['message'])) {
|
||||
return 'fail';
|
||||
}
|
||||
if (0 > strlen($_POST['message']) || strlen($_POST['message']) > 65535) {
|
||||
return 'fail';
|
||||
}
|
||||
$receiver = $_POST['receiver'];
|
||||
$esc_message = DB::escape($_POST['message']);
|
||||
$sender = $myUser['username'];
|
||||
DB::query("insert into user_msg (sender, receiver, message, send_time) values ('$sender', '$receiver', '$esc_message', now())");
|
||||
return "ok";
|
||||
}
|
||||
|
||||
if (!validateUsername($receiver) || !queryUser($receiver)) {
|
||||
return 'fail';
|
||||
}
|
||||
|
||||
DB::query("insert into user_msg (sender, receiver, message, send_time) values ('$sender', '$receiver', '$esc_message', now())");
|
||||
return "ok";
|
||||
}
|
||||
|
||||
function getConversations() {
|
||||
global $myUser;
|
||||
$username = $myUser['username'];
|
||||
$result = DB::query( "select * from user_msg where sender = '$username' or receiver = '$username' order by send_time DESC" );
|
||||
$ret = array();
|
||||
while ($msg = DB::fetch($result)) {
|
||||
if ($msg['sender'] !== $username) {
|
||||
if (isset($ret[$msg['sender']])) {
|
||||
$ret[$msg['sender']][1] |= ($msg['read_time'] == null);
|
||||
continue;
|
||||
}
|
||||
$ret[$msg['sender']] = array($msg['send_time'], ($msg['read_time'] == null));
|
||||
} else {
|
||||
if (isset($ret[$msg['receiver']])) {
|
||||
continue;
|
||||
}
|
||||
$ret[$msg['receiver']] = array($msg['send_time'], 0);
|
||||
function getConversations() {
|
||||
$username = Auth::id();
|
||||
$result = DB::query("select * from user_msg where sender = '$username' or receiver = '$username' order by send_time DESC");
|
||||
$ret = array();
|
||||
while ($msg = DB::fetch($result)) {
|
||||
if ($msg['sender'] !== $username) {
|
||||
if (isset($ret[$msg['sender']])) {
|
||||
$ret[$msg['sender']][1] |= ($msg['read_time'] == null);
|
||||
continue;
|
||||
}
|
||||
$ret[$msg['sender']] = array($msg['send_time'], ($msg['read_time'] == null));
|
||||
} else {
|
||||
if (isset($ret[$msg['receiver']])) {
|
||||
continue;
|
||||
}
|
||||
$ret[$msg['receiver']] = array($msg['send_time'], 0);
|
||||
}
|
||||
$res = [];
|
||||
foreach ($ret as $name => $con) {
|
||||
$res[] = [$con[0], $con[1], $name];
|
||||
}
|
||||
usort($res, function($a, $b) {
|
||||
return -strcmp($a[0], $b[0]);
|
||||
});
|
||||
return json_encode($res);
|
||||
}
|
||||
$res = [];
|
||||
foreach ($ret as $name => $con) {
|
||||
$res[] = [$con[0], $con[1], $name];
|
||||
}
|
||||
usort($res, function ($a, $b) {
|
||||
return -strcmp($a[0], $b[0]);
|
||||
});
|
||||
return json_encode($res);
|
||||
}
|
||||
|
||||
function getHistory() {
|
||||
$username = Auth::id();
|
||||
if (!isset($_GET['conversationName']) || !validateUsername($_GET['conversationName'])) {
|
||||
return '[]';
|
||||
}
|
||||
if (!isset($_GET['pageNumber']) || !validateUInt($_GET['pageNumber'])) {
|
||||
return '[]';
|
||||
}
|
||||
|
||||
function getHistory() {
|
||||
global $myUser;
|
||||
$username = $myUser['username'];
|
||||
if (!isset($_GET['conversationName']) || !validateUsername($_GET['conversationName'])) {
|
||||
return '[]';
|
||||
}
|
||||
if (!isset($_GET['pageNumber']) || !validateUInt($_GET['pageNumber'])) {
|
||||
return '[]';
|
||||
}
|
||||
$conversationName = $_GET['conversationName'];
|
||||
$pageNumber = ($_GET['pageNumber'] - 1) * 10;
|
||||
DB::query("update user_msg set read_time = now() where sender = '$conversationName' and receiver = '$username' and read_time is null");
|
||||
|
||||
$conversationName = $_GET['conversationName'];
|
||||
$pageNumber = ($_GET['pageNumber'] - 1) * 10;
|
||||
DB::query("update user_msg set read_time = now() where sender = '$conversationName' and receiver = '$username' and read_time is null");
|
||||
|
||||
$result = DB::query("select * from user_msg where (sender = '$username' and receiver = '$conversationName') or (sender = '$conversationName' and receiver = '$username') order by send_time DESC limit $pageNumber, 11");
|
||||
$ret = array();
|
||||
while ($msg = DB::fetch($result)) {
|
||||
$ret[] = array($msg['message'], $msg['send_time'], $msg['read_time'], $msg['id'], ($msg['sender'] == $username));
|
||||
}
|
||||
return json_encode($ret);
|
||||
$result = DB::query("select * from user_msg where (sender = '$username' and receiver = '$conversationName') or (sender = '$conversationName' and receiver = '$username') order by send_time DESC limit $pageNumber, 11");
|
||||
$ret = array();
|
||||
while ($msg = DB::fetch($result)) {
|
||||
$ret[] = array($msg['message'], $msg['send_time'], $msg['read_time'], $msg['id'], ($msg['sender'] == $username));
|
||||
}
|
||||
return json_encode($ret);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
function deleteMsg($msgId) {
|
||||
return 1;
|
||||
$str = <<<EOD
|
||||
@ -98,21 +95,20 @@
|
||||
}
|
||||
*/
|
||||
|
||||
if (isset($_POST['user_msg'])) {
|
||||
die(handleMsgPost());
|
||||
} elseif (isset($_GET['getConversations'])) {
|
||||
die(getConversations());
|
||||
} elseif (isset($_GET['getHistory'])) {
|
||||
die(getHistory());
|
||||
}
|
||||
?>
|
||||
if (isset($_POST['user_msg'])) {
|
||||
die(handleMsgPost());
|
||||
} elseif (isset($_GET['getConversations'])) {
|
||||
die(getConversations());
|
||||
} elseif (isset($_GET['getHistory'])) {
|
||||
die(getHistory());
|
||||
}
|
||||
?>
|
||||
|
||||
<?php echoUOJPageHeader('私信') ?>
|
||||
|
||||
<h1 class="page-header">私信</h1>
|
||||
|
||||
<div id="conversations">
|
||||
</div>
|
||||
<div id="conversations"></div>
|
||||
|
||||
<div id="history" style="display:none">
|
||||
<div class="card border-primary">
|
||||
@ -147,103 +143,110 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$.ajaxSetup({async:false});
|
||||
refreshConversations();
|
||||
<?php if (isset($_GET['enter'])): ?>
|
||||
enterConversation(<?= json_encode($_GET['enter']) ?>);
|
||||
<?php endif ?>
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$.ajaxSetup({
|
||||
async: false
|
||||
});
|
||||
refreshConversations();
|
||||
<?php if (isset($_GET['enter'])) : ?>
|
||||
enterConversation(<?= json_encode($_GET['enter']) ?>);
|
||||
<?php endif ?>
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function addButton(conversationName, send_time, type) {
|
||||
$("#conversations").append(
|
||||
'<div class="row top-buffer-sm">' +
|
||||
function addButton(conversationName, send_time, type) {
|
||||
$("#conversations").append(
|
||||
'<div class="row top-buffer-sm">' +
|
||||
'<div class="col-sm-3">' +
|
||||
'<button type="button" class="btn btn-' + ( type ? 'warning' : 'primary' ) + ' btn-block" ' +
|
||||
'onclick="enterConversation(\'' + conversationName + '\')">' +
|
||||
conversationName +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn btn-' + (type ? 'warning' : 'primary') + ' btn-block" ' +
|
||||
'onclick="enterConversation(\'' + conversationName + '\')">' +
|
||||
conversationName +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'<div class="col-sm-9" style="line-height:34px">' +
|
||||
'最后发送时间:' + send_time +
|
||||
'最后发送时间:' + send_time +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function addBubble(content, send_time, read_time, msgId, conversation, page, type) {
|
||||
$("#history-list").append(
|
||||
'<div style=' + (!type ? "margin-left:0%;margin-right:20%;" : "margin-left:20%;margin-right:0%;") + '>' +
|
||||
'<div class="card border-info mb-4">' +
|
||||
'<div class="card-body" style="background:#17a2b8; word-break: break-all">' +
|
||||
'<div style="white-space:pre-wrap">' +
|
||||
htmlspecialchars(content) +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div>' +
|
||||
'<div class="row">' +
|
||||
'<div class="col-sm-6">' +
|
||||
'发送时间:' + send_time +
|
||||
'</div>' +
|
||||
'<div class="col-sm-6 text-right">' +
|
||||
'查看时间:' + (read_time == null ? '<strong>未查看</strong>' : read_time) +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function submitMessagePost(conversationName) {
|
||||
if ($('#input-message').val().length == 0 || $('#input-message').val().length >= 65536) {
|
||||
$('#help-message').text('私信长度必须在1~65535之间。');
|
||||
$('#form-group-message').addClass('has-error');
|
||||
return;
|
||||
function addBubble(content, send_time, read_time, msgId, conversation, page, type) {
|
||||
$("#history-list").append(
|
||||
'<div style=' + (!type ? "margin-left:0%;margin-right:20%;" : "margin-left:20%;margin-right:0%;") + '>' +
|
||||
'<div class="card border-info mb-4">' +
|
||||
'<div class="card-body" style="background:#17a2b8; word-break: break-all">' +
|
||||
'<div style="white-space:pre-wrap">' +
|
||||
htmlspecialchars(content) +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div>' +
|
||||
'<div class="row">' +
|
||||
'<div class="col-sm-6">' +
|
||||
'发送时间:' + send_time +
|
||||
'</div>' +
|
||||
'<div class="col-sm-6 text-right">' +
|
||||
'查看时间:' + (read_time == null ? '<strong>未查看</strong>' : read_time) +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function submitMessagePost(conversationName) {
|
||||
if ($('#input-message').val().length == 0 || $('#input-message').val().length >= 65536) {
|
||||
$('#help-message').text('私信长度必须在1~65535之间。');
|
||||
$('#form-group-message').addClass('has-error');
|
||||
return;
|
||||
}
|
||||
$('#help-message').text('');
|
||||
$('#form-group-message').removeClass('has-error');
|
||||
|
||||
$.post('', {
|
||||
user_msg : 1,
|
||||
receiver : conversationName,
|
||||
message : $('#input-message').val()
|
||||
}, function(msg) {
|
||||
$('#input-message').val("");
|
||||
user_msg: 1,
|
||||
receiver: conversationName,
|
||||
message: $('#input-message').val()
|
||||
}, function(msg) {
|
||||
$('#input-message').val("");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function refreshHistory(conversation, page) {
|
||||
function refreshHistory(conversation, page) {
|
||||
$("#history-list").empty();
|
||||
var ret = false;
|
||||
$('#conversation-name').text(conversation);
|
||||
$('#pageShow').text("第" + page.toString() + "页");
|
||||
$.get('', {
|
||||
getHistory : '',
|
||||
conversationName : conversation,
|
||||
pageNumber : page
|
||||
getHistory: '',
|
||||
conversationName: conversation,
|
||||
pageNumber: page
|
||||
}, function(msg) {
|
||||
var result = JSON.parse(msg);
|
||||
var cnt = 0, flag = 0, F = 0;
|
||||
if (result.length == 11) flag = 1, F = 1;
|
||||
result.reverse();
|
||||
for (msg in result) {
|
||||
if (flag) {flag = 0; continue;}
|
||||
var message = result[msg];
|
||||
addBubble(message[0], message[1], message[2], message[3], conversation, page, message[4]);
|
||||
if ((++cnt) + 1 == result.length && F) break;
|
||||
var result = JSON.parse(msg);
|
||||
var cnt = 0,
|
||||
flag = 0,
|
||||
F = 0;
|
||||
if (result.length == 11) flag = 1, F = 1;
|
||||
result.reverse();
|
||||
for (msg in result) {
|
||||
if (flag) {
|
||||
flag = 0;
|
||||
continue;
|
||||
}
|
||||
if (result.length == 11) ret = true;
|
||||
var message = result[msg];
|
||||
addBubble(message[0], message[1], message[2], message[3], conversation, page, message[4]);
|
||||
if ((++cnt) + 1 == result.length && F) break;
|
||||
}
|
||||
if (result.length == 11) ret = true;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
function refreshConversations() {
|
||||
$("#conversations").empty();
|
||||
$.get('', {
|
||||
getConversations : ""
|
||||
function refreshConversations() {
|
||||
$("#conversations").empty();
|
||||
$.get('', {
|
||||
getConversations: ""
|
||||
}, function(msg) {
|
||||
var result = JSON.parse(msg);
|
||||
for (i in result) {
|
||||
@ -258,49 +261,47 @@ function refreshConversations() {
|
||||
addButton(conversation[2], conversation[0], conversation[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function enterConversation(conversationName) {
|
||||
var slideTime = 300;
|
||||
var page = 1;
|
||||
$("#conversations").hide(slideTime);
|
||||
var changeAble = refreshHistory(conversationName, page);
|
||||
$("#history").slideDown(slideTime);
|
||||
$('#form-message').unbind("submit").submit(function() {
|
||||
submitMessagePost(conversationName);
|
||||
page = 1;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
refreshConversations();
|
||||
return false;
|
||||
});
|
||||
$('#goBack').unbind("click").click(function() {
|
||||
refreshConversations();
|
||||
$("#history").slideUp(slideTime);
|
||||
$("#conversations").show(slideTime);
|
||||
return;
|
||||
});
|
||||
$('#pageLeft').unbind("click").click(function() {
|
||||
if (changeAble) page++;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
return false;
|
||||
});
|
||||
$('#pageLeft2').unbind("click").click(function() {
|
||||
if (changeAble) page++;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
});
|
||||
$('#pageRight').unbind("click").click(function() {
|
||||
if (page > 1) page--;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
return false;
|
||||
});
|
||||
$('#pageRight2').unbind("click").click(function() {
|
||||
if (page > 1) page--;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function enterConversation(conversationName) {
|
||||
var slideTime = 300;
|
||||
var page = 1;
|
||||
$("#conversations").hide(slideTime);
|
||||
var changeAble = refreshHistory(conversationName, page);
|
||||
$("#history").slideDown(slideTime);
|
||||
$('#form-message').unbind("submit").submit(function() {
|
||||
submitMessagePost(conversationName);
|
||||
page = 1;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
refreshConversations();
|
||||
return false;
|
||||
});
|
||||
$('#goBack').unbind("click").click(function() {
|
||||
refreshConversations();
|
||||
$("#history").slideUp(slideTime);
|
||||
$("#conversations").show(slideTime);
|
||||
return;
|
||||
});
|
||||
$('#pageLeft').unbind("click").click(function() {
|
||||
if (changeAble) page++;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
return false;
|
||||
});
|
||||
$('#pageLeft2').unbind("click").click(function() {
|
||||
if (changeAble) page++;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
});
|
||||
$('#pageRight').unbind("click").click(function() {
|
||||
if (page > 1) page--;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
return false;
|
||||
});
|
||||
$('#pageRight2').unbind("click").click(function() {
|
||||
if (page > 1) page--;
|
||||
changeAble = refreshHistory(conversationName, page);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php echoUOJPageFooter() ?>
|
||||
|
@ -55,7 +55,7 @@ $system_msgs = [];
|
||||
foreach ($pag->get() as $idx => $msg) {
|
||||
$system_msgs[$idx] = $msg;
|
||||
|
||||
if (isSuperUser($myUser)) {
|
||||
if (isSuperUser(Auth::user())) {
|
||||
$delete_form = newDeleteSystemMsgForm($msg['id']);
|
||||
$delete_form->runAtServer();
|
||||
$system_msgs[$idx]['delete_form'] = $delete_form;
|
||||
@ -73,7 +73,11 @@ foreach ($pag->get() as $idx => $msg) {
|
||||
<div class="card mb-3">
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php foreach ($system_msgs as $msg) : ?>
|
||||
<li class="list-group-item">
|
||||
<li class="list-group-item
|
||||
<?php if ($msg['read_time'] == null) : ?>
|
||||
bg-warning bg-opacity-25
|
||||
<?php endif ?>
|
||||
">
|
||||
<div class="mb-2 d-flex justify-content-between">
|
||||
<div>
|
||||
<?php if ($msg['title']) : ?>
|
||||
|
@ -6,7 +6,7 @@ function uojHandleAtSign($str, $uri) {
|
||||
if ($matches[1] === '@') {
|
||||
return '@';
|
||||
} else {
|
||||
$user = queryUser($matches[1]);
|
||||
$user = UOJUser::query($matches[1]);
|
||||
if ($user == null) {
|
||||
return $matches[0];
|
||||
} else {
|
||||
@ -98,71 +98,6 @@ function become403Page($message = '访问被拒绝,您可能需要适当的权
|
||||
becomeMsgPage('<div class="text-center"><div style="font-size:150px">403</div><p>' . $message . '</p></div>', '403');
|
||||
}
|
||||
|
||||
function getUserLink($username) {
|
||||
if (validateUsername($username) && ($user = queryUser($username)) && $user['usergroup'] != 'B') {
|
||||
$realname = $user['realname'];
|
||||
|
||||
if ($realname == "") {
|
||||
return '<span class="uoj-username">' . $username . '</span>';
|
||||
} else {
|
||||
return '<span class="uoj-username" data-realname="' . HTML::escape($realname) . '">' . $username . '</span>';
|
||||
}
|
||||
} else {
|
||||
$esc_username = HTML::escape($username);
|
||||
return '<span>' . $esc_username . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
function getUserName($username, $realname = null) {
|
||||
if ($realname == null) {
|
||||
if (validateUsername($username) && ($user = queryUser($username))) {
|
||||
$realname = $user['realname'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($realname == "") {
|
||||
return "$username";
|
||||
} else {
|
||||
return "$username ($realname)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getProblemLink($problem, $problem_title = '!title_only') {
|
||||
global $REQUIRE_LIB;
|
||||
|
||||
if ($problem_title == '!title_only') {
|
||||
$problem_title = $problem['title'];
|
||||
} elseif ($problem_title == '!id_and_title') {
|
||||
$problem_title = "#${problem['id']}. ${problem['title']}";
|
||||
}
|
||||
$result = '<a ';
|
||||
if (isset($REQUIRE_LIB['bootstrap5'])) {
|
||||
$result .= ' class="text-decoration-none" ';
|
||||
}
|
||||
$result .= ' href="/problem/' . $problem['id'] . '">' . $problem_title . '</a>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
function getContestProblemLink($problem, $contest_id, $problem_title = '!title_only') {
|
||||
if ($problem_title == '!title_only') {
|
||||
$problem_title = $problem['title'];
|
||||
} elseif ($problem_title == '!id_and_title') {
|
||||
$problem_title = "#{$problem['id']}. {$problem['title']}";
|
||||
}
|
||||
$result = '<a class="text-decoration-none" href="/contest/' . $contest_id . '/problem/' . $problem['id'] . '">' . $problem_title . '</a>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
function getBlogLink($id) {
|
||||
$result = '';
|
||||
if (validateUInt($id) && $blog = queryBlog($id)) {
|
||||
$result = '<a class="text-decoration-none" href="/blogs/' . $id . '">' . $blog['title'] . '</a>';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getLongTablePageRawUri($page) {
|
||||
$path = strtok(UOJContext::requestURI(), '?');
|
||||
$query_string = strtok('?');
|
||||
@ -294,7 +229,6 @@ function echoSubmission($submission, $config, $viewer) {
|
||||
$usubm->echoStatusTableRow($config, $viewer);
|
||||
}
|
||||
|
||||
|
||||
function echoSubmissionsListOnlyOne($submission, $config, $user) {
|
||||
echo '<div class="card mb-3 table-responsive">';
|
||||
echo '<table class="table text-center uoj-table mb-0">';
|
||||
@ -389,27 +323,15 @@ function echoSubmissionsList($cond, $tail, $config, $user) {
|
||||
|
||||
$table_name = isset($config['table_name']) ? $config['table_name'] : 'submissions';
|
||||
|
||||
if (!isProblemManager($user)) {
|
||||
if ($user != null) {
|
||||
$permission_cond = DB::lor([
|
||||
"submissions.is_hidden" => false,
|
||||
"submissions.submitter" => $user['username'],
|
||||
DB::land([
|
||||
"submissions.is_hidden" => true,
|
||||
DB::lor([
|
||||
"submissions.problem_id in (select problem_id from problems_permissions where username = '{$user['username']}')",
|
||||
"submissions.problem_id in (select id from problems where uploader = '{$user['username']}')",
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
} else {
|
||||
$permission_cond = ["submissions.is_hidden" => "false"];
|
||||
}
|
||||
if ($cond !== '1') {
|
||||
$cond = DB::land($cond, $permission_cond);
|
||||
} else {
|
||||
$cond = $permission_cond;
|
||||
}
|
||||
$cond = $cond === '1' ? [] : [DB::conds($cond)];
|
||||
$cond[] = UOJSubmission::sqlForUserCanView($user, $config['problem']);
|
||||
if ($config['problem']) {
|
||||
$cond[] = ['submissions.problem_id', '=', $config['problem']->info['id']];
|
||||
}
|
||||
if (count($cond) == 1) {
|
||||
$cond = $cond[0];
|
||||
} else {
|
||||
$cond = DB::land($cond);
|
||||
}
|
||||
|
||||
$table_config = isset($config['table_config']) ? $config['table_config'] : null;
|
||||
@ -916,49 +838,13 @@ function echoHackDetails($hack_details, $name) {
|
||||
echoJudgementDetails($hack_details, new HackDetailsStyler(), $name);
|
||||
}
|
||||
|
||||
function echoHack($hack, $config, $user) {
|
||||
$problem = queryProblemBrief($hack['problem_id']);
|
||||
echo '<tr>';
|
||||
if (!isset($config['id_hidden'])) {
|
||||
echo '<td><a href="/hack/', $hack['id'], '">#', $hack['id'], '</a></td>';
|
||||
}
|
||||
if (!isset($config['submission_hidden'])) {
|
||||
echo '<td><a href="/submission/', $hack['submission_id'], '">#', $hack['submission_id'], '</a></td>';
|
||||
}
|
||||
if (!isset($config['problem_hidden'])) {
|
||||
if ($hack['contest_id']) {
|
||||
echo '<td>', getContestProblemLink($problem, $hack['contest_id'], '!id_and_title'), '</td>';
|
||||
} else {
|
||||
echo '<td>', getProblemLink($problem, '!id_and_title'), '</td>';
|
||||
}
|
||||
}
|
||||
if (!isset($config['hacker_hidden'])) {
|
||||
echo '<td>', getUserLink($hack['hacker']), '</td>';
|
||||
}
|
||||
if (!isset($config['owner_hidden'])) {
|
||||
echo '<td>', getUserLink($hack['owner']), '</td>';
|
||||
}
|
||||
if (!isset($config['result_hidden'])) {
|
||||
if ($hack['judge_time'] == null) {
|
||||
echo '<td><a href="/hack/', $hack['id'], '">Waiting</a></td>';
|
||||
} elseif ($hack['success'] == null) {
|
||||
echo '<td><a href="/hack/', $hack['id'], '">Judging</a></td>';
|
||||
} elseif ($hack['success']) {
|
||||
echo '<td><a href="/hack/', $hack['id'], '" class="uoj-status" data-success="1"><strong>Success!</strong></a></td>';
|
||||
} else {
|
||||
echo '<td><a href="/hack/', $hack['id'], '" class="uoj-status" data-success="0"><strong>Failed.</strong></a></td>';
|
||||
}
|
||||
} else {
|
||||
echo '<td>Hidden</td>';
|
||||
}
|
||||
if (!isset($config['submit_time_hidden'])) {
|
||||
echo '<td>', $hack['submit_time'], '</td>';
|
||||
}
|
||||
if (!isset($config['judge_time_hidden'])) {
|
||||
echo '<td>', $hack['judge_time'], '</td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
function echoHack($hack, $config, $viewer) {
|
||||
$uhack = new UOJHack($hack);
|
||||
$uhack->setProblem();
|
||||
$uhack->setSubmission();
|
||||
$uhack->echoStatusTableRow($config, $viewer);
|
||||
}
|
||||
|
||||
function echoHackListOnlyOne($hack, $config, $user) {
|
||||
echo '<div class="card mb-3 table-responsive">';
|
||||
echo '<table class="table text-center uoj-table mb-0">';
|
||||
@ -1150,7 +1036,7 @@ function echoRanklist($config = []) {
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td>' . $user['rank'] . '</td>';
|
||||
echo '<td>' . getUserLink($user['username']) . '</td>';
|
||||
echo '<td>' . UOJUser::getLink($user['username']) . '</td>';
|
||||
echo "<td>";
|
||||
echo $purifier->purify($parsedown->line($user['motto']));
|
||||
echo "</td>";
|
||||
|
@ -1,85 +1,9 @@
|
||||
<?php
|
||||
|
||||
function hasProblemPermission($user, $problem) {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
if (isSuperUser($user) || isProblemManager($user)) {
|
||||
return true;
|
||||
}
|
||||
if ($problem['uploader'] == $user['username']) {
|
||||
return true;
|
||||
}
|
||||
return DB::selectFirst("select * from problems_permissions where username = '{$user['username']}' and problem_id = {$problem['id']}") != null;
|
||||
}
|
||||
|
||||
function hasContestPermission($user, $contest) {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
if (isSuperUser($user)) {
|
||||
return true;
|
||||
}
|
||||
return DB::selectFirst("select * from contests_permissions where username = '{$user['username']}' and contest_id = {$contest['id']}") != null;
|
||||
}
|
||||
|
||||
function hasRegistered($user, $contest) {
|
||||
return DB::selectFirst("select * from contests_registrants where username = '${user['username']}' and contest_id = ${contest['id']}") != null;
|
||||
}
|
||||
|
||||
function queryUser($username) {
|
||||
if (!validateUsername($username)) {
|
||||
return null;
|
||||
}
|
||||
return DB::selectFirst("select * from user_info where username='$username'", MYSQLI_ASSOC);
|
||||
}
|
||||
function queryProblemBrief($id) {
|
||||
return DB::selectFirst("select * from problems where id = $id", MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
function querySolution($problem_id, $blog_id) {
|
||||
return DB::selectFirst("select * from problems_solutions where blog_id='$blog_id' and problem_id='$problem_id'", MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
function queryContestProblemRank($contest, $problem) {
|
||||
if (!DB::selectFirst("select * from contests_problems where contest_id = {$contest['id']} and problem_id = {$problem['id']}")) {
|
||||
return null;
|
||||
}
|
||||
$contest_problems = DB::selectAll("select problem_id from contests_problems where contest_id = {$contest['id']} order by level, problem_id");
|
||||
return array_search(array('problem_id' => $problem['id']), $contest_problems) + 1;
|
||||
}
|
||||
function queryContest($id) {
|
||||
return DB::selectFirst("select * from contests where id = $id", MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
function queryBlog($id) {
|
||||
return DB::selectFirst("select * from blogs where id='$id'", MYSQLI_ASSOC);
|
||||
}
|
||||
function queryBlogComment($id) {
|
||||
return DB::selectFirst("select * from blogs_comments where id='$id'", MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
function isProblemVisibleToUser($problem, $user) {
|
||||
return !$problem['is_hidden'] || hasProblemPermission($user, $problem);
|
||||
}
|
||||
function isListVisibleToUser($list, $user) {
|
||||
return !$list['is_hidden'] || isSuperUser($user);
|
||||
}
|
||||
|
||||
function isRegisteredRunningContestProblem($user, $problem) {
|
||||
$result = DB::query("select contest_id from contests_problems where problem_id = {$problem['id']}");
|
||||
while (list($contest_id) = DB::fetch($result, MYSQLI_NUM)) {
|
||||
$contest = queryContest($contest_id);
|
||||
genMoreContestInfo($contest);
|
||||
if (
|
||||
$contest['cur_progress'] == CONTEST_IN_PROGRESS
|
||||
&& hasRegistered($user, $contest)
|
||||
&& !hasContestPermission($user, $contest)
|
||||
&& queryContestProblemRank($contest, $problem)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -150,49 +150,6 @@ function camelize($str, $delimiters = '-_') {
|
||||
return $str;
|
||||
}
|
||||
|
||||
function addUserType(&$user, $type) {
|
||||
$usertype = explode(',', $user['usertype']);
|
||||
if (!in_array($type, $usertype)) {
|
||||
$usertype[] = $type;
|
||||
}
|
||||
$user['usertype'] = implode(',', $usertype);
|
||||
return $user;
|
||||
}
|
||||
function removeUserType(&$user, $type) {
|
||||
$usertype = explode(',', $user['usertype']);
|
||||
if (in_array($type, $usertype)) {
|
||||
$usertype = array_diff($usertype, array($type));
|
||||
}
|
||||
$user['usertype'] = implode(',', $usertype);
|
||||
return $user;
|
||||
}
|
||||
function hasUserType($user, $type) {
|
||||
$usertype = explode(',', $user['usertype']);
|
||||
return in_array($type, $usertype);
|
||||
}
|
||||
|
||||
function isProblemUploader($user) {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
return hasUserType($user, 'problem_uploader');
|
||||
}
|
||||
function isProblemManager($user) {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
if (isSuperUser($user)) {
|
||||
return true;
|
||||
}
|
||||
return hasUserType($user, 'problem_manager');
|
||||
}
|
||||
function isContestJudger($user) {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
return hasUserType($user, 'contest_judger');
|
||||
}
|
||||
|
||||
function isSuperUser($user) {
|
||||
return $user != null && $user['usergroup'] == 'S';
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ return [
|
||||
'super user' => 'Super User',
|
||||
'normal user' => 'Normal User',
|
||||
'banned user' => 'Banned User',
|
||||
'tmp user' => 'Temporary User',
|
||||
'real name' => 'Real name',
|
||||
'belongs to these groups' => 'Belongs to these groups:',
|
||||
'avatar source' => 'Avatar source',
|
||||
|
@ -4,6 +4,7 @@ return [
|
||||
'super user' => '超级用户',
|
||||
'normal user' => '普通用户',
|
||||
'banned user' => '封禁用户',
|
||||
'tmp user' => '临时用户',
|
||||
'real name' => '真实姓名',
|
||||
'belongs to these groups' => '属于这些小组:',
|
||||
'avatar source' => '头像来源',
|
||||
|
@ -46,6 +46,7 @@ class HTML {
|
||||
public static function attr($attr) {
|
||||
$html = '';
|
||||
foreach ($attr as $key => $val) {
|
||||
if ($val === null) continue;
|
||||
$html .= ' ' . $key . '="';
|
||||
$html .= HTML::escape(is_array($val) ? implode(' ', $val) : $val);
|
||||
$html .= '"';
|
||||
@ -104,7 +105,7 @@ class HTML {
|
||||
}
|
||||
|
||||
public static function hiddenToken() {
|
||||
return '<input type="hidden" name="_token" value="' . crsf_token() . '" />';
|
||||
return HTML::empty_tag('input', ['type' => 'hidden', 'name' => '_token', 'value' => crsf_token()]);
|
||||
}
|
||||
public static function div_vinput($name, $type, $label_text, $default_value) {
|
||||
return '<div id="' . "div-$name" . '" class="mb-3">'
|
||||
|
@ -10,7 +10,7 @@ class UOJBlog {
|
||||
}
|
||||
$info = DB::selectFirst([
|
||||
"select id, title, post_time, active_time, poster, zan, is_hidden, type from blogs",
|
||||
"where", ['id' => $id]
|
||||
"where", ['id' => $id]
|
||||
]);
|
||||
if (!$info) {
|
||||
return null;
|
||||
@ -21,7 +21,7 @@ class UOJBlog {
|
||||
public function __construct($info) {
|
||||
$this->info = $info;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the blog belongs to the current user blog
|
||||
*/
|
||||
@ -30,7 +30,25 @@ class UOJBlog {
|
||||
}
|
||||
|
||||
public function userCanView(array $user = null) {
|
||||
return !$this->info['is_hidden'] || $this->userCanManage($user);
|
||||
if ($this->userCanManage($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->info['poster'] != $user['username'] && !UOJUser::checkPermission($user, 'blogs.view')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($problem_id = $this->getSolutionProblemId()) {
|
||||
$contests = UOJContest::queryContestsHasProblem($problem_id);
|
||||
|
||||
foreach ($contests as $contest) {
|
||||
if ($contest->userHasRegistered($user) && $contest->progress() <= CONTEST_IN_PROGRESS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !$this->info['is_hidden'];
|
||||
}
|
||||
|
||||
public function userCanManage(array $user = null) {
|
||||
@ -70,7 +88,7 @@ class UOJBlog {
|
||||
$link .= "{$level_str} ";
|
||||
}
|
||||
}
|
||||
$link .= '<a href="'. $this->getBlogUri() .'">'.$this->getTitle($cfg).'</a>';
|
||||
$link .= '<a href="' . $this->getBlogUri() . '">' . $this->getTitle($cfg) . '</a>';
|
||||
if (!empty($cfg['show_new_tag'])) {
|
||||
if ($this->isNew()) {
|
||||
$link .= '<sup style="color:red"> new</sup>';
|
||||
@ -104,7 +122,7 @@ class UOJBlog {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function queryNewestComment() {
|
||||
return DB::selectFirst([
|
||||
"select * from blogs_comments",
|
||||
@ -116,15 +134,15 @@ class UOJBlog {
|
||||
DB::limit(1)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function updateActiveTime() {
|
||||
$active_time = $this->info['post_time'];
|
||||
|
||||
|
||||
$newest = $this->queryNewestComment();
|
||||
if ($newest) {
|
||||
$active_time = $newest['post_time'];
|
||||
}
|
||||
|
||||
|
||||
DB::update([
|
||||
"update blogs",
|
||||
"set", ['active_time' => $active_time],
|
||||
@ -191,6 +209,15 @@ class UOJBlog {
|
||||
];
|
||||
uojIncludeView('blog-preview', $cfg);
|
||||
}
|
||||
|
||||
public function getSolutionProblemId() {
|
||||
return DB::selectSingle([
|
||||
DB::lc(), "select 1 from problems_solutions",
|
||||
"where", [
|
||||
"blog_id" => $this->info['id'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
UOJBlog::$table_for_content = 'blogs';
|
||||
|
@ -28,12 +28,22 @@ class UOJContest {
|
||||
]));
|
||||
}
|
||||
|
||||
public static function queryContestsHasProblem(UOJProblem $problem) {
|
||||
return array_map(fn ($x) => UOJContest::query($x['contest_id']), DB::selectAll([
|
||||
"select contest_id from contests_problems",
|
||||
"where", [
|
||||
"problem_id" => $problem->info['id'],
|
||||
],
|
||||
"order by contest_id",
|
||||
]));
|
||||
}
|
||||
|
||||
public static function userCanManageSomeContest(array $user = null) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSuperUser($user)) {
|
||||
if (isSuperUser($user) || UOJUser::checkPermission($user, 'contests.manage')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -45,6 +55,14 @@ class UOJContest {
|
||||
]) != null;
|
||||
}
|
||||
|
||||
public static function userCanCreateContest(array $user = null) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'contests.create');
|
||||
}
|
||||
|
||||
public static function finalTest() {
|
||||
$contest = self::info();
|
||||
|
||||
@ -117,7 +135,7 @@ class UOJContest {
|
||||
calcStandings($contest, $data, $score, $standings, ['update_contests_submissions' => true]);
|
||||
|
||||
for ($i = 0; $i < count($standings); $i++) {
|
||||
$user_link = getUserLink($standings[$i][2][0]);
|
||||
$user_link = UOJUser::getLink($standings[$i][2][0]);
|
||||
$tail = $standings[$i][0] == $total_score ? ',请继续保持。' : ',请继续努力!';
|
||||
|
||||
$content = '<p>' . $user_link . ' 您好:</p>';
|
||||
@ -306,6 +324,10 @@ class UOJContest {
|
||||
$cfg['ensure'] && $this->redirectToAnnouncementBlog();
|
||||
return false;
|
||||
}
|
||||
if (!UOJUser::checkPermission($user, 'contests.register')) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
}
|
||||
if ($this->progress() == CONTEST_IN_PROGRESS && !$this->allowExtraRegistration()) {
|
||||
$cfg['ensure'] && redirectTo('/contests');
|
||||
return false;
|
||||
@ -351,6 +373,7 @@ class UOJContest {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($cfg['ensure']) {
|
||||
if ($this->info['extra_config']['extra_registration']) {
|
||||
redirectTo($this->getUri('/register'));
|
||||
@ -358,11 +381,17 @@ class UOJContest {
|
||||
UOJResponse::message("<h1>比赛正在进行中</h1><p>很遗憾,您尚未报名。比赛结束后再来看吧~</p>");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!$this->userHasRegistered($user) && !UOJUser::checkPermission($user, 'contests.view')) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -381,9 +410,11 @@ class UOJContest {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
if (isSuperUser($user)) {
|
||||
|
||||
if (isSuperUser($user) || UOJUser::checkPermission($user, 'contests.manage')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DB::selectFirst([
|
||||
DB::lc(), "select 1 from contests_permissions",
|
||||
"where", [
|
||||
@ -393,6 +424,10 @@ class UOJContest {
|
||||
]) != null;
|
||||
}
|
||||
|
||||
public function userCanStartFinalTest(array $user = null) {
|
||||
return $this->userCanManage($user) || UOJUser::checkPermission($user, 'contests.start_final_test');
|
||||
}
|
||||
|
||||
public function userHasRegistered(array $user = null) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
@ -473,6 +508,10 @@ class UOJContest {
|
||||
return HTML::tag('a', ['class' => $cfg['class'], 'href' => $this->getUri($cfg['where'])], $this->info['name']);
|
||||
}
|
||||
|
||||
public function getZanBlock() {
|
||||
return ClickZans::getBlock('C', $this->info['id'], $this->info['zan']);
|
||||
}
|
||||
|
||||
public function redirectToAnnouncementBlog() {
|
||||
$url = getContestBlogLink($this->info, '公告');
|
||||
if ($url !== null) {
|
||||
|
@ -2,13 +2,46 @@
|
||||
|
||||
class UOJContext {
|
||||
public static $meta_default = [
|
||||
'active_duration_M' => 12,
|
||||
'users_default_permissions' => [
|
||||
'problems' => [
|
||||
'view' => true,
|
||||
'download_testdata' => false,
|
||||
'create' => false,
|
||||
'manage' => false,
|
||||
],
|
||||
'contests' => [
|
||||
'view' => true,
|
||||
'register' => true,
|
||||
'create' => false,
|
||||
'start_final_test' => false,
|
||||
'manage' => false,
|
||||
],
|
||||
'lists' => [
|
||||
'view' => true,
|
||||
'create' => false,
|
||||
'manage' => false,
|
||||
],
|
||||
'groups' => [
|
||||
'view' => true,
|
||||
'create' => false,
|
||||
'manage' => false,
|
||||
],
|
||||
'blogs' => [
|
||||
'view' => true,
|
||||
'create' => true,
|
||||
'manage' => false,
|
||||
],
|
||||
'users' => [
|
||||
'view' => true,
|
||||
'upload_image' => true,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
public static $data = [
|
||||
'type' => 'main'
|
||||
];
|
||||
|
||||
|
||||
public static function pageConfig() {
|
||||
switch (self::$data['type']) {
|
||||
case 'main':
|
||||
@ -23,23 +56,23 @@ class UOJContext {
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function isAjax() {
|
||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
|
||||
}
|
||||
|
||||
|
||||
public static function contentLength() {
|
||||
if (!isset($_SERVER['CONTENT_LENGTH'])) {
|
||||
return null;
|
||||
}
|
||||
return (int)$_SERVER['CONTENT_LENGTH'];
|
||||
}
|
||||
|
||||
|
||||
public static function documentRoot() {
|
||||
return $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
public static function storagePath() {
|
||||
return $_SERVER['DOCUMENT_ROOT'].'/app/storage';
|
||||
return $_SERVER['DOCUMENT_ROOT'] . '/app/storage';
|
||||
}
|
||||
public static function remoteAddr() {
|
||||
return $_SERVER['REMOTE_ADDR'];
|
||||
@ -100,7 +133,7 @@ class UOJContext {
|
||||
if (validateIP($domain) || strpos($domain, '.') === false) {
|
||||
$domain = '';
|
||||
} else {
|
||||
$domain = '.'.$domain;
|
||||
$domain = '.' . $domain;
|
||||
}
|
||||
return $domain;
|
||||
}
|
||||
@ -112,7 +145,7 @@ class UOJContext {
|
||||
public static function type() {
|
||||
return self::$data['type'];
|
||||
}
|
||||
|
||||
|
||||
public static function setupBlog() {
|
||||
UOJUserBlog::init();
|
||||
self::$data['type'] = 'blog';
|
||||
|
@ -1,36 +1,41 @@
|
||||
<?php
|
||||
|
||||
class UOJForm {
|
||||
public $form_name;
|
||||
public $succ_href;
|
||||
public $back_href = null;
|
||||
public $no_submit = false;
|
||||
public $ctrl_enter_submit = false;
|
||||
public ?string $form_name;
|
||||
public ?string $succ_href;
|
||||
public $extra_validator = null;
|
||||
public $is_big = false;
|
||||
public $has_file = false;
|
||||
public $ajax_submit_js = null;
|
||||
public $run_at_server_handler = [];
|
||||
public $handle;
|
||||
private $ajax_submit_js = null;
|
||||
private $run_at_server_handler = [];
|
||||
private $data = [];
|
||||
private $vdata = [];
|
||||
private $main_html = '';
|
||||
public $max_post_size = 15728640; // 15M
|
||||
public $max_file_size_mb = 10; // 10M
|
||||
|
||||
public $handle;
|
||||
|
||||
public $config = [
|
||||
'container' => [
|
||||
'is_big' => false,
|
||||
'has_file' => false,
|
||||
'ctrl_enter_submit' => false,
|
||||
'max_post_size' => 15728640, // 15M
|
||||
'max_file_size_mb' => 10, // 10M
|
||||
'form' => [
|
||||
'class' => '',
|
||||
],
|
||||
'submit_container' => [
|
||||
'class' => 'mt-3 text-center',
|
||||
],
|
||||
'submit_button' => [
|
||||
'class' => 'btn btn-primary',
|
||||
'text' => '提交',
|
||||
],
|
||||
'back_button' => [
|
||||
'href' => null,
|
||||
'class' => 'btn btn-secondary',
|
||||
],
|
||||
'confirm' => [
|
||||
'smart' => false,
|
||||
'text' => null,
|
||||
]
|
||||
];
|
||||
public $submit_button_config = [];
|
||||
public $control_label_config = ['class' => 'col-sm-2'];
|
||||
public $input_config = ['class' => 'col-sm-3'];
|
||||
public $textarea_config = ['class' => 'col-sm-10'];
|
||||
|
||||
public function __construct($form_name) {
|
||||
$this->form_name = $form_name;
|
||||
@ -42,7 +47,7 @@ class UOJForm {
|
||||
die(json_encode($this->validateAtServer()));
|
||||
};
|
||||
$this->run_at_server_handler["submit-{$this->form_name}"] = function () {
|
||||
if ($this->no_submit) {
|
||||
if ($this->config['no_submit']) {
|
||||
UOJResponse::page404();
|
||||
}
|
||||
foreach ($this->data as $field) {
|
||||
@ -55,7 +60,7 @@ class UOJForm {
|
||||
$len = UOJContext::contentLength();
|
||||
if ($len === null) {
|
||||
UOJResponse::page403();
|
||||
} elseif ($len > $this->max_post_size) {
|
||||
} elseif ($len > $this->config['max_post_size']) {
|
||||
UOJResponse::message('The form is too large.');
|
||||
}
|
||||
}
|
||||
@ -87,14 +92,11 @@ class UOJForm {
|
||||
|
||||
public function add($name, $html, $validator_php, $validator_js) {
|
||||
$this->main_html .= $html;
|
||||
$this->data[] = array(
|
||||
$this->data[] = [
|
||||
'name' => $name,
|
||||
'validator_php' => $validator_php,
|
||||
'validator_js' => $validator_js
|
||||
);
|
||||
}
|
||||
public function appendHTML($html) {
|
||||
$this->main_html .= $html;
|
||||
];
|
||||
}
|
||||
|
||||
public function addNoVal($name, $html) {
|
||||
@ -106,6 +108,10 @@ class UOJForm {
|
||||
);
|
||||
}
|
||||
|
||||
public function appendHTML($html) {
|
||||
$this->main_html .= $html;
|
||||
}
|
||||
|
||||
public function addHidden($name, $default_value, $validator_php, $validator_js) {
|
||||
$default_value = HTML::escape($default_value);
|
||||
$html = <<<EOD
|
||||
@ -114,78 +120,102 @@ class UOJForm {
|
||||
$this->add($name, $html, $validator_php, $validator_js);
|
||||
}
|
||||
|
||||
public function printHTML() {
|
||||
$form_entype_str = $this->is_big ? ' enctype="multipart/form-data"' : '';
|
||||
public function addCheckbox($name, $config) {
|
||||
$config += [
|
||||
'checked' => false,
|
||||
'div_class' => 'form-check',
|
||||
'role' => 'checkbox',
|
||||
'input_class' => 'form-check-input',
|
||||
'label' => '',
|
||||
'label_class' => 'form-check-label',
|
||||
'help' => '',
|
||||
'help_class' => 'form-text',
|
||||
'disabled' => false,
|
||||
];
|
||||
|
||||
echo '<form action="', $_SERVER['REQUEST_URI'], '" method="post" class="" id="form-', $this->form_name, '"', $form_entype_str, '>';
|
||||
echo HTML::hiddenToken();
|
||||
echo $this->main_html;
|
||||
$html = '';
|
||||
$html .= HTML::tag_begin('div', ['class' => $config['div_class']]);
|
||||
$html .= HTML::empty_tag('input', [
|
||||
'class' => $config['input_class'],
|
||||
'type' => 'checkbox',
|
||||
'name' => $name,
|
||||
'id' => "input-$name",
|
||||
'checked' => $config['checked'] ? 'checked' : null,
|
||||
'value' => '1',
|
||||
'disabled' => $config['disabled'] ? 'disabled' : null,
|
||||
]);
|
||||
$html .= HTML::tag('label', [
|
||||
'class' => $config['label_class'],
|
||||
'for' => "input-$name",
|
||||
], $config['label']);
|
||||
|
||||
if (!$this->no_submit) {
|
||||
if (!isset($this->submit_button_config['align'])) {
|
||||
$this->submit_button_config['align'] = 'center';
|
||||
}
|
||||
if (!isset($this->submit_button_config['text'])) {
|
||||
$this->submit_button_config['text'] = UOJLocale::get('submit');
|
||||
}
|
||||
if (!isset($this->submit_button_config['class_str'])) {
|
||||
$this->submit_button_config['class_str'] = 'btn btn-secondary';
|
||||
}
|
||||
if ($this->submit_button_config['align'] == 'offset') {
|
||||
echo '<div class="form-group">';
|
||||
echo '<div class="col-sm-offset-2 col-sm-3">';
|
||||
} else {
|
||||
echo '<div class="text-', $this->submit_button_config['align'], '">';
|
||||
}
|
||||
|
||||
if ($this->back_href !== null) {
|
||||
echo '<div class="btn-toolbar">';
|
||||
}
|
||||
echo HTML::tag('button', [
|
||||
'type' => 'submit', 'id' => "button-submit-{$this->form_name}", 'name' => "submit-{$this->form_name}",
|
||||
'value' => $this->form_name, 'class' => $this->submit_button_config['class_str']
|
||||
], $this->submit_button_config['text']);
|
||||
if ($this->back_href !== null) {
|
||||
echo HTML::tag('a', [
|
||||
'class' => 'btn btn-secondary', 'href' => $this->back_href
|
||||
], '返回');
|
||||
}
|
||||
if ($this->back_href !== null) {
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if ($this->submit_button_config['align'] == 'offset') {
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
if ($config['help']) {
|
||||
$html .= HTML::tag('div', ['class' => $config['help_class']], $config['help']);
|
||||
}
|
||||
|
||||
echo '</form>';
|
||||
$html .= HTML::tag_end('div');
|
||||
|
||||
if ($this->no_submit) {
|
||||
$this->addNoVal($name, $html);
|
||||
}
|
||||
|
||||
public function printHTML() {
|
||||
echo HTML::tag_begin('form', [
|
||||
'action' => UOJContext::requestURI(),
|
||||
'method' => 'POST',
|
||||
'class' => $this->config['form']['class'],
|
||||
'id' => "form-{$this->form_name}",
|
||||
'enctype' => $this->config['is_big'] ? 'multipart/form-data' : 'application/x-www-form-urlencoded',
|
||||
]);
|
||||
|
||||
echo HTML::hiddenToken();
|
||||
|
||||
echo $this->main_html;
|
||||
|
||||
if (!$this->config['no_submit']) {
|
||||
echo HTML::tag_begin('div', ['class' => $this->config['submit_container']['class']]);
|
||||
|
||||
echo HTML::tag('button', [
|
||||
'type' => 'submit',
|
||||
'id' => "button-submit-{$this->form_name}",
|
||||
'name' => "submit-{$this->form_name}",
|
||||
'value' => $this->form_name,
|
||||
'class' => $this->config['submit_button']['class']
|
||||
], $this->config['submit_button']['text']);
|
||||
|
||||
if ($this->config['back_button']['href'] !== null) {
|
||||
echo HTML::tag('a', [
|
||||
'class' => $this->config['back_button']['class'],
|
||||
'href' => $this->config['back_button']['href']
|
||||
], '返回');
|
||||
}
|
||||
|
||||
echo HTML::tag_end('div');
|
||||
}
|
||||
|
||||
echo HTML::tag_end('form');
|
||||
|
||||
if ($this->config['no_submit']) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo <<<EOD
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
EOD;
|
||||
if ($this->ctrl_enter_submit) {
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
EOD;
|
||||
if ($this->config['ctrl_enter_submit']) {
|
||||
echo <<<EOD
|
||||
$('#form-{$this->form_name}').keydown(function(e) {
|
||||
if (e.keyCode == 13 && e.ctrlKey) {
|
||||
$('#button-submit-{$this->form_name}').click();
|
||||
}
|
||||
});
|
||||
|
||||
EOD;
|
||||
$('#form-{$this->form_name}').keydown(function(e) {
|
||||
if (e.keyCode == 13 && e.ctrlKey) {
|
||||
$('#button-submit-{$this->form_name}').click();
|
||||
}
|
||||
});
|
||||
EOD;
|
||||
}
|
||||
echo <<<EOD
|
||||
$('#form-{$this->form_name}').submit(function(e) {
|
||||
var ok = true;
|
||||
$('#form-{$this->form_name}').submit(function(e) {
|
||||
var ok = true;
|
||||
|
||||
EOD;
|
||||
EOD;
|
||||
$need_ajax = false;
|
||||
if ($this->extra_validator) {
|
||||
$need_ajax = true;
|
||||
@ -194,8 +224,7 @@ class UOJForm {
|
||||
if ($field['validator_js'] != null) {
|
||||
if ($field['validator_js'] != 'always_ok') {
|
||||
echo <<<EOD
|
||||
var {$field['name']}_err = ({$field['validator_js']})($('#input-{$field['name']}').val());
|
||||
|
||||
var {$field['name']}_err = ({$field['validator_js']})($('#input-{$field['name']}').val());
|
||||
EOD;
|
||||
}
|
||||
} else {
|
||||
@ -205,125 +234,116 @@ class UOJForm {
|
||||
|
||||
if ($need_ajax) {
|
||||
echo <<<EOD
|
||||
var post_data = {};
|
||||
|
||||
EOD;
|
||||
var post_data = {};
|
||||
EOD;
|
||||
foreach ($this->data as $field) {
|
||||
if ($field['validator_js'] == null) {
|
||||
echo <<<EOD
|
||||
var {$field['name']}_err = 'Unknown error';
|
||||
post_data.{$field['name']} = $('#input-{$field['name']}').val();
|
||||
|
||||
var {$field['name']}_err = 'Unknown error';
|
||||
post_data.{$field['name']} = $('#input-{$field['name']}').val();
|
||||
EOD;
|
||||
}
|
||||
}
|
||||
echo <<<EOD
|
||||
post_data['check-{$this->form_name}'] = "";
|
||||
$.ajax({
|
||||
url : '{$_SERVER['REQUEST_URI']}',
|
||||
type : 'POST',
|
||||
dataType : 'json',
|
||||
async : false,
|
||||
post_data['check-{$this->form_name}'] = "";
|
||||
$.ajax({
|
||||
url: '{$_SERVER['REQUEST_URI']}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
|
||||
data : post_data,
|
||||
success : function(data) {
|
||||
|
||||
EOD;
|
||||
data: post_data,
|
||||
success: function(data) {
|
||||
EOD;
|
||||
foreach ($this->data as $field) {
|
||||
if ($field['validator_js'] == null) {
|
||||
echo <<<EOD
|
||||
{$field['name']}_err = data.${field['name']};
|
||||
|
||||
{$field['name']}_err = data.${field['name']};
|
||||
EOD;
|
||||
}
|
||||
}
|
||||
echo <<<EOD
|
||||
if (data.extra != undefined) {
|
||||
alert(data.extra);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
EOD;
|
||||
if (data.extra != undefined) {
|
||||
alert(data.extra);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
EOD;
|
||||
}
|
||||
|
||||
foreach ($this->data as $field) {
|
||||
if ($field['validator_js'] != 'always_ok') {
|
||||
echo <<<EOD
|
||||
if (${field['name']}_err) {
|
||||
$('#div-${field['name']}').addClass('has-validation has-error');
|
||||
$('#div-${field['name']}').addClass('is-invalid');
|
||||
$('#input-${field['name']}').addClass('is-invalid');
|
||||
$('#help-${field['name']}').text(${field['name']}_err);
|
||||
ok = false;
|
||||
} else {
|
||||
$('#div-${field['name']}').removeClass('has-validation has-error');
|
||||
$('#div-${field['name']}').removeClass('is-invalid');
|
||||
$('#input-${field['name']}').removeClass('is-invalid');
|
||||
$('#help-${field['name']}').text('');
|
||||
}
|
||||
EOD;
|
||||
if (${field['name']}_err) {
|
||||
$('#div-${field['name']}').addClass('has-validation has-error');
|
||||
$('#div-${field['name']}').addClass('is-invalid');
|
||||
$('#input-${field['name']}').addClass('is-invalid');
|
||||
$('#help-${field['name']}').text(${field['name']}_err);
|
||||
ok = false;
|
||||
} else {
|
||||
$('#div-${field['name']}').removeClass('has-validation has-error');
|
||||
$('#div-${field['name']}').removeClass('is-invalid');
|
||||
$('#input-${field['name']}').removeClass('is-invalid');
|
||||
$('#help-${field['name']}').text('');
|
||||
}
|
||||
EOD;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->submit_button_config['smart_confirm'])) {
|
||||
$this->submit_button_config['confirm_text'] = '你真的要' . $this->submit_button_config['text'] . '吗?';
|
||||
if ($this->config['confirm']['smart']) {
|
||||
$this->config['confirm']['text'] = '你真的要' . $this->config['submit']['text'] . '吗?';
|
||||
}
|
||||
if (isset($this->submit_button_config['confirm_text'])) {
|
||||
if ($this->config['confirm']['text']) {
|
||||
echo <<<EOD
|
||||
if (!confirm('{$this->submit_button_config['confirm_text']}')) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
EOD;
|
||||
if (!confirm('{$this->config['confirm']['text']}')) {
|
||||
ok = false;
|
||||
}
|
||||
EOD;
|
||||
}
|
||||
if ($this->has_file) {
|
||||
if ($this->config['has_file']) {
|
||||
echo <<<EOD
|
||||
$(this).find("input[type='file']").each(function() {
|
||||
for (var i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].size > {$this->max_file_size_mb} * 1024 * 1024) {
|
||||
$('#div-' + $(this).attr('name')).addClass('has-validation has-error');
|
||||
$('#div-' + $(this).attr('name')).addClass('is-invalid');
|
||||
$('#input-' + $(this).attr('name')).addClass('is-invalid');
|
||||
$('#help-' + $(this).attr('name')).text('文件大小不能超过{$this->max_file_size_mb}M');
|
||||
ok = false;
|
||||
} else {
|
||||
$('#div-' + $(this).attr('name')).removeClass('has-validation has-error');
|
||||
$('#div-' + $(this).attr('name')).removeClass('is-invalid');
|
||||
$('#input-' + $(this).attr('name')).removeClass('is-invalid');
|
||||
$('#help-' + $(this).attr('name')).text('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
EOD;
|
||||
$(this).find("input[type='file']").each(function() {
|
||||
for (var i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].size > {$this->config['max_file_size_mb']} * 1024 * 1024) {
|
||||
$('#div-' + $(this).attr('name')).addClass('has-validation has-error');
|
||||
$('#div-' + $(this).attr('name')).addClass('is-invalid');
|
||||
$('#input-' + $(this).attr('name')).addClass('is-invalid');
|
||||
$('#help-' + $(this).attr('name')).text('文件大小不能超过 {$this->config['max_file_size_mb']} MB');
|
||||
ok = false;
|
||||
} else {
|
||||
$('#div-' + $(this).attr('name')).removeClass('has-validation has-error');
|
||||
$('#div-' + $(this).attr('name')).removeClass('is-invalid');
|
||||
$('#input-' + $(this).attr('name')).removeClass('is-invalid');
|
||||
$('#help-' + $(this).attr('name')).text('');
|
||||
}
|
||||
}
|
||||
});
|
||||
EOD;
|
||||
}
|
||||
|
||||
if ($this->ajax_submit_js !== null) {
|
||||
echo <<<EOD
|
||||
e.preventDefault();
|
||||
if (ok) {
|
||||
$(this).ajaxSubmit({
|
||||
beforeSubmit: function(formData) {
|
||||
formData.push({name: 'submit-{$this->form_name}', value: '{$this->form_name}', type: 'submit'});
|
||||
},
|
||||
success : {$this->ajax_submit_js}
|
||||
});
|
||||
}
|
||||
|
||||
EOD;
|
||||
e.preventDefault();
|
||||
if (ok) {
|
||||
$(this).ajaxSubmit({
|
||||
beforeSubmit: function(formData) {
|
||||
formData.push({name: 'submit-{$this->form_name}', value: '{$this->form_name}', type: 'submit'});
|
||||
},
|
||||
success: {$this->ajax_submit_js}
|
||||
});
|
||||
}
|
||||
EOD;
|
||||
} else {
|
||||
echo <<<EOD
|
||||
return ok;
|
||||
|
||||
EOD;
|
||||
return ok;
|
||||
EOD;
|
||||
}
|
||||
echo <<<EOD
|
||||
});
|
||||
});
|
||||
</script>
|
||||
EOD;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
EOD;
|
||||
}
|
||||
|
||||
private function validateAtServer() {
|
||||
|
@ -22,11 +22,19 @@ class UOJGroup {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_map(fn ($x) => UOJGroup::query($x['group_id']), DB::selectAll([
|
||||
return array_filter(array_map(fn ($x) => UOJGroup::query($x['group_id']), DB::selectAll([
|
||||
DB::lc(), "select group_id from groups_users",
|
||||
"where", ['username' => $user['username']],
|
||||
"order by group_id"
|
||||
]));
|
||||
])), fn ($group) => $group->userCanView($user));
|
||||
}
|
||||
|
||||
public static function userCanCreateGroup($user) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'groups.create');
|
||||
}
|
||||
|
||||
public function __construct($info) {
|
||||
@ -34,15 +42,22 @@ class UOJGroup {
|
||||
}
|
||||
|
||||
public function userCanManage(array $user = null) {
|
||||
return isSuperUser($user);
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'groups.manage');
|
||||
}
|
||||
|
||||
public function userCanView(array $user = null, array $cfg = []) {
|
||||
$cfg += ['ensure' => false];
|
||||
|
||||
if ($this->info['is_hidden'] && !$this->userCanManage($user)) {
|
||||
$cfg['ensure'] && UOJResponse::page404();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->hasUser($user) && !UOJUser::checkPermission($user, 'groups.view')) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,14 @@ class UOJList {
|
||||
return new UOJList($info);
|
||||
}
|
||||
|
||||
public static function userCanCreateList(array $user = null) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'lists.create');
|
||||
}
|
||||
|
||||
public function __construct($info) {
|
||||
$this->info = $info;
|
||||
}
|
||||
@ -59,15 +67,22 @@ class UOJList {
|
||||
}
|
||||
|
||||
public function userCanManage(array $user = null) {
|
||||
return isSuperUser($user);
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'lists.manage');
|
||||
}
|
||||
|
||||
public function userCanView(array $user = null, array $cfg = []) {
|
||||
$cfg += ['ensure' => false];
|
||||
|
||||
if ($this->info['is_hidden'] && !$this->userCanManage($user)) {
|
||||
$cfg['ensure'] && UOJResponse::page404();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!UOJUser::checkPermission($user, 'lists.view')) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class UOJMarkdown extends ParsedownMath {
|
||||
// https://gist.github.com/ShNURoK42/b5ce8baa570975db487c
|
||||
protected function inlineUserMention($Excerpt) {
|
||||
if (preg_match('/^@([^\s]+)/', $Excerpt['text'], $matches)) {
|
||||
if (validateUsername($matches[1]) && ($user = queryUser($matches[1])) && $user['usergroup'] != 'B') {
|
||||
if (($user = UOJUser::query($matches[1])) && $user['usergroup'] != 'B') {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
|
@ -31,6 +31,10 @@ class UOJProblem {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSuperUser($user) || UOJUser::checkPermission($user, 'problems.manage')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DB::selectFirst([
|
||||
DB::lc(), "select 1 from problems_permissions",
|
||||
"where", [
|
||||
@ -44,6 +48,14 @@ class UOJProblem {
|
||||
]) != null;
|
||||
}
|
||||
|
||||
public static function userCanCreateProblem(array $user = null) {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSuperUser($user) || UOJUser::checkPermission($user, 'problems.create');
|
||||
}
|
||||
|
||||
public function __construct($info) {
|
||||
$this->info = $info;
|
||||
}
|
||||
@ -83,7 +95,7 @@ class UOJProblem {
|
||||
}
|
||||
|
||||
public function getUploaderLink() {
|
||||
return getUserLink($this->info['uploader'] ?: "root");
|
||||
return UOJUser::getLink($this->info['uploader'] ?: "root");
|
||||
}
|
||||
|
||||
public function findInContests() {
|
||||
@ -162,10 +174,17 @@ class UOJProblem {
|
||||
|
||||
public function userCanView(array $user = null, array $cfg = []) {
|
||||
$cfg += ['ensure' => false];
|
||||
|
||||
if ($this->info['is_hidden'] && !$this->userCanManage($user)) {
|
||||
$cfg['ensure'] && UOJResponse::page404();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!UOJUser::checkPermission($user, 'problems.view')) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -174,7 +193,7 @@ class UOJProblem {
|
||||
* Need to be consistent with the member function userCanView
|
||||
*/
|
||||
public static function sqlForUserCanView(array $user = null) {
|
||||
if (isSuperUser($user)) {
|
||||
if (isSuperUser($user) || UOJUser::checkPermission($user, 'problems.manage')) {
|
||||
return "(1)";
|
||||
} elseif (UOJProblem::userCanManageSomeProblem($user)) {
|
||||
return DB::lor([
|
||||
@ -247,9 +266,11 @@ class UOJProblem {
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
if (isSuperUser($user) || $user['username'] == $this->info['poster'] || isProblemManager($user)) {
|
||||
|
||||
if (isSuperUser($user) || $this->isUserOwnProblem($user) || UOJUser::checkPermission($user, 'problems.manage')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DB::selectFirst([
|
||||
DB::lc(), "select 1 from problems_permissions",
|
||||
"where", [
|
||||
@ -260,7 +281,7 @@ class UOJProblem {
|
||||
}
|
||||
|
||||
public function userCanDownloadTestData(array $user = null) {
|
||||
return $this->userCanManage($user);
|
||||
return $this->userCanManage($user) || UOJUser::checkPermission($user, 'problems.download_testdata');
|
||||
}
|
||||
|
||||
public function preHackCheck(array $user = null) {
|
||||
|
@ -43,7 +43,7 @@ class UOJRanklist {
|
||||
$user['rank'] = $rank;
|
||||
|
||||
$userpro = HTML::url('/user/' . $user['username']);
|
||||
$userlink = getUserLink($user['username']);
|
||||
$userlink = UOJUser::getLink($user['username']);
|
||||
$asrc = HTML::avatar_addr($user, 100);
|
||||
$esc_motto = $purifier->purify($parsedown->line($user['motto']));
|
||||
$solved_text = UOJLocale::get('solved');
|
||||
@ -160,7 +160,7 @@ class UOJRanklist {
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td>' . $user['rank'] . '</td>';
|
||||
echo '<td>' . getUserLink($user['username']) . '</td>';
|
||||
echo '<td>' . UOJUser::getLink($user['username']) . '</td>';
|
||||
echo '<td>' . $purifier->purify($parsedown->line($user['motto'])) . '</td>';
|
||||
echo '<td>' . $user['ac_num'] . '</td>';
|
||||
echo '</tr>';
|
||||
|
@ -38,7 +38,7 @@ class UOJSubmission {
|
||||
* Need to be consistent with the member function userCanView
|
||||
*/
|
||||
public static function sqlForUserCanView(array $user = null, UOJProblem $problem = null) {
|
||||
if (isSuperUser($user) || isProblemManager($user)) {
|
||||
if (isSuperUser($user) || UOJUser::checkPermission($user, 'problems.manage')) {
|
||||
// MySQL can find appropriate keys to speed up the query if we write "true" in this way.
|
||||
return "(submissions.is_hidden = true or submissions.is_hidden = false)";
|
||||
} elseif ($problem) {
|
||||
|
@ -50,7 +50,11 @@ trait UOJSubmissionLikeTrait {
|
||||
|
||||
public function userCanView(array $user = null, array $cfg = []) {
|
||||
$cfg += ['ensure' => false];
|
||||
if (!$this->info['is_hidden']) {
|
||||
|
||||
if (!$this->problem->userCanView($user) && !$this->userIsSubmitter($user)) {
|
||||
$cfg['ensure'] && UOJResponse::page403();
|
||||
return false;
|
||||
} elseif (!$this->info['is_hidden']) {
|
||||
return true;
|
||||
} elseif ($this->userCanManageProblemOrContest($user)) {
|
||||
return true;
|
||||
@ -107,7 +111,7 @@ trait UOJSubmissionLikeTrait {
|
||||
return $this->info['id'];
|
||||
}
|
||||
public function getLink() {
|
||||
return '<a class="text-decoration-none" href="'.$this->getUri().'">#'.$this->info['id'].'</a></td>';
|
||||
return '<a class="text-decoration-none" href="' . $this->getUri() . '">#' . $this->info['id'] . '</a></td>';
|
||||
}
|
||||
|
||||
public function getResult($key = null) {
|
||||
@ -139,7 +143,7 @@ trait UOJSubmissionLikeTrait {
|
||||
}
|
||||
|
||||
$zip_file = new ZipArchive();
|
||||
if ($zip_file->open(UOJContext::storagePath().$content['file_name'], ZipArchive::RDONLY) !== true) {
|
||||
if ($zip_file->open(UOJContext::storagePath() . $content['file_name'], ZipArchive::RDONLY) !== true) {
|
||||
echo <<<EOD
|
||||
<div class="card mb-3">
|
||||
<div class="card-header text-bg-danger fw-bold">
|
||||
@ -152,12 +156,12 @@ trait UOJSubmissionLikeTrait {
|
||||
EOD;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$config = [];
|
||||
foreach ($content['config'] as $val) {
|
||||
$config[$val[0]] = $val[1];
|
||||
}
|
||||
|
||||
|
||||
foreach ($this->problem->getSubmissionRequirement() as $req) {
|
||||
if ($req['type'] == "source code") {
|
||||
$file_content = $zip_file->getFromName("{$req['name']}.code");
|
||||
@ -172,7 +176,7 @@ trait UOJSubmissionLikeTrait {
|
||||
}
|
||||
|
||||
$file_content = uojTextEncode($file_content, array('allow_CR' => true, 'html_escape' => true));
|
||||
$footer_text = UOJLocale::get('problems::source code').': ';
|
||||
$footer_text = UOJLocale::get('problems::source code') . ': ';
|
||||
$footer_text .= UOJLang::getLanguageDisplayName($file_language);
|
||||
$sh_class = UOJLang::getLanguagesCSSClass($file_language);
|
||||
echo <<<EOD
|
||||
@ -229,18 +233,18 @@ trait UOJSubmissionLikeTrait {
|
||||
case 'submitter':
|
||||
case 'owner':
|
||||
case 'hacker':
|
||||
echo getUserLink($this->info[$name]);
|
||||
echo UOJUser::getLink($this->info[$name]);
|
||||
break;
|
||||
case 'used_time':
|
||||
if ($cfg['show_actual_score']) {
|
||||
echo $this->info['used_time'].'ms';
|
||||
echo $this->info['used_time'] . 'ms';
|
||||
} else {
|
||||
echo '/';
|
||||
}
|
||||
break;
|
||||
case 'used_memory':
|
||||
if ($cfg['show_actual_score']) {
|
||||
echo $this->info['used_memory'].'kb';
|
||||
echo $this->info['used_memory'] . 'kb';
|
||||
} else {
|
||||
echo '/';
|
||||
}
|
||||
@ -254,7 +258,7 @@ trait UOJSubmissionLikeTrait {
|
||||
break;
|
||||
case 'submit_time':
|
||||
case 'judge_time':
|
||||
echo '<small>', $this->info[$name],'</small>';
|
||||
echo '<small>', $this->info[$name], '</small>';
|
||||
break;
|
||||
default:
|
||||
echo '?';
|
||||
|
@ -212,6 +212,7 @@ class UOJUser {
|
||||
$extra = [];
|
||||
}
|
||||
mergeConfig($extra, [
|
||||
'permissions' => UOJContext::getMeta('users_default_permissions'),
|
||||
'social' => [
|
||||
'codeforces' => null,
|
||||
'github' => null,
|
||||
@ -252,6 +253,24 @@ class UOJUser {
|
||||
];
|
||||
}
|
||||
|
||||
public static function checkPermission(array $user = null, string $perm = '') {
|
||||
if ($user == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$extra = UOJUser::getExtra($user);
|
||||
$cur = $extra['permissions'];
|
||||
|
||||
foreach (explode('.', $perm) as $p) {
|
||||
if (!is_assoc($cur) || !isset($cur[$p])) {
|
||||
return false;
|
||||
}
|
||||
$cur = $cur[$p];
|
||||
}
|
||||
|
||||
return $cur;
|
||||
}
|
||||
|
||||
public static function updateVisitHistory($user, $info) {
|
||||
$extra = UOJUser::getExtra($user);
|
||||
$cur = [
|
||||
|
@ -26,10 +26,17 @@ class UOJUserBlog {
|
||||
return self::$user;
|
||||
}
|
||||
|
||||
public static function userIsOwner(?array $user) {
|
||||
if ($user === null) {
|
||||
return false;
|
||||
}
|
||||
return self::$user['username'] === $user['username'];
|
||||
}
|
||||
|
||||
public static function userCanManage(?array $user, ?string $whose_blog = null) {
|
||||
if ($whose_blog === null) {
|
||||
$whose_blog = self::id();
|
||||
}
|
||||
return $user && (isSuperUser($user) || $user['username'] === $whose_blog);
|
||||
return $user && (isSuperUser($user) || UOJUser::checkPermission($user, 'blogs.manage') || $user['username'] === $whose_blog);
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,8 @@ Route::group(
|
||||
|
||||
Route::any('/super_manage(?:/{tab})?', '/super_manage.php');
|
||||
|
||||
Route::any('/download.php', '/download.php');
|
||||
Route::any('/download/problem/{id}/data.zip', '/download.php?type=problem');
|
||||
Route::any('/download/problem/{id}/attachment.zip', '/download.php?type=attachment');
|
||||
|
||||
Route::any('/check-notice', '/check_notice.php');
|
||||
Route::any('/click-zan', '/click_zan.php');
|
||||
|
2
web/app/upgrade/18_user_permissions/up.sql
Normal file
2
web/app/upgrade/18_user_permissions/up.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `problems_solutions` ADD UNIQUE KEY `unique__blog_id` (`blog_id`);
|
||||
ALTER TABLE `user_info` MODIFY `usertype` enum('student','teacher','system','banned') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'student';
|
69
web/app/upgrade/18_user_permissions/upgrade.php
Normal file
69
web/app/upgrade/18_user_permissions/upgrade.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
return function ($type) {
|
||||
if ($type === 'up') {
|
||||
DB::init();
|
||||
|
||||
$users = DB::selectAll("select * from user_info");
|
||||
|
||||
foreach ($users as $user) {
|
||||
$usertype = explode(',', $user['usertype']);
|
||||
$extra = UOJUser::getExtra($user);
|
||||
$new_permissions = [
|
||||
'_placeholder' => '',
|
||||
'problems' => [
|
||||
'_placeholder' => '',
|
||||
],
|
||||
'contests' => [
|
||||
'_placeholder' => '',
|
||||
],
|
||||
'lists' => [
|
||||
'_placeholder' => '',
|
||||
],
|
||||
'groups' => [
|
||||
'_placeholder' => '',
|
||||
],
|
||||
'blogs' => [
|
||||
'_placeholder' => '',
|
||||
],
|
||||
'users' => [
|
||||
'_placeholder' => '',
|
||||
]
|
||||
];
|
||||
|
||||
if (in_array('problem_uploader', $usertype)) {
|
||||
$new_permissions['problems']['create'] = true;
|
||||
}
|
||||
|
||||
if (in_array('problem_manager', $usertype)) {
|
||||
$new_permissions['problems']['create'] = true;
|
||||
$new_permissions['problems']['manage'] = true;
|
||||
}
|
||||
|
||||
if (in_array('contest_judger', $usertype)) {
|
||||
$new_permissions['contests']['start_final_test'] = true;
|
||||
}
|
||||
|
||||
if (in_array('teacher', $usertype)) {
|
||||
$usertype = 'teacher';
|
||||
} elseif (in_array('banned', $usertype)) {
|
||||
$usertype = 'banned';
|
||||
} else {
|
||||
$usertype = 'student';
|
||||
}
|
||||
|
||||
$extra['permissions'] = $new_permissions;
|
||||
|
||||
DB::update([
|
||||
"update user_info",
|
||||
"set", [
|
||||
"usertype" => $usertype,
|
||||
"extra" => json_encode($extra),
|
||||
],
|
||||
"where", [
|
||||
"username" => $user['username'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,83 +1,85 @@
|
||||
<?php
|
||||
if ($is_preview) {
|
||||
$readmore_pos = strpos($blog->content['content'], '<!-- readmore -->');
|
||||
if ($readmore_pos !== false) {
|
||||
$content = substr($blog->content['content'], 0, $readmore_pos).'<p><a href="/blog/'.$blog->info['id'].'">阅读更多……</a></p>';
|
||||
} else {
|
||||
$content = $blog->content['content'];
|
||||
}
|
||||
if ($is_preview) {
|
||||
$readmore_pos = strpos($blog->content['content'], '<!-- readmore -->');
|
||||
if ($readmore_pos !== false) {
|
||||
$content = substr($blog->content['content'], 0, $readmore_pos) . '<p><a href="/blog/' . $blog->info['id'] . '">阅读更多……</a></p>';
|
||||
} else {
|
||||
$content = $blog->content['content'];
|
||||
}
|
||||
|
||||
$extra_text = $blog->info['is_hidden'] ? '<span class="text-muted">[已隐藏]</span> ' : '';
|
||||
?>
|
||||
} else {
|
||||
$content = $blog->content['content'];
|
||||
}
|
||||
|
||||
$extra_text = $blog->info['is_hidden'] ? '<span class="text-muted">[已隐藏]</span> ' : '';
|
||||
?>
|
||||
|
||||
<h1>
|
||||
<?= $extra_text ?>
|
||||
<a class="header-a text-decoration-none text-body" href="<?= HTML::blog_url($blog->info['poster'], '/post/'.$blog->info['id']) ?>">
|
||||
<a class="header-a text-decoration-none text-body" href="<?= HTML::blog_url($blog->info['poster'], '/post/' . $blog->info['id']) ?>">
|
||||
<?= $blog->info['title'] ?>
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div><?= $blog->info['post_time'] ?> <strong>By</strong> <?= getUserLink($blog->info['poster']) ?> (<strong>博客 ID: </strong> <?= $blog->info['id'] ?>)</div>
|
||||
<?php if (!$show_title_only): ?>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<?php if ($blog->isTypeB()): ?>
|
||||
<div><?= $blog->info['post_time'] ?> <strong>By</strong> <?= UOJUser::getLink($blog->info['poster']) ?> (<strong>博客 ID: </strong> <?= $blog->info['id'] ?>)</div>
|
||||
<?php if (!$show_title_only) : ?>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<?php if ($blog->isTypeB()) : ?>
|
||||
|
||||
<!-- content -->
|
||||
<article class="markdown-body">
|
||||
<?= $content ?>
|
||||
</article>
|
||||
<!-- content end -->
|
||||
<!-- content -->
|
||||
<article class="markdown-body">
|
||||
<?= $content ?>
|
||||
</article>
|
||||
<!-- content end -->
|
||||
|
||||
<?php elseif ($blog->isTypeS()): ?>
|
||||
<?php elseif ($blog->isTypeS()) : ?>
|
||||
|
||||
<!-- slide -->
|
||||
<article>
|
||||
<div class="ratio ratio-16x9">
|
||||
<iframe class="embed-responsive-item" src="<?= HTML::blog_url($blog->info['poster'], '/slide/'.$blog->info['id']) ?>"></iframe>
|
||||
</div>
|
||||
<div class="text-end mt-2">
|
||||
<a class="btn btn-secondary btn-md" href="<?= HTML::blog_url($blog->info['poster'], '/slide/'.$blog->info['id']) ?>">
|
||||
<i class="bi bi-arrows-fullscreen"></i>
|
||||
全屏
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
<!-- slide end -->
|
||||
<!-- slide -->
|
||||
<article>
|
||||
<div class="ratio ratio-16x9">
|
||||
<iframe class="embed-responsive-item" src="<?= HTML::blog_url($blog->info['poster'], '/slide/' . $blog->info['id']) ?>"></iframe>
|
||||
</div>
|
||||
<div class="text-end mt-2">
|
||||
<a class="btn btn-secondary btn-md" href="<?= HTML::blog_url($blog->info['poster'], '/slide/' . $blog->info['id']) ?>">
|
||||
<i class="bi bi-arrows-fullscreen"></i>
|
||||
全屏
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
<!-- slide end -->
|
||||
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<div class="card-footer text-end text-right">
|
||||
<ul class="list-inline mb-0">
|
||||
<li class="list-inline-item">
|
||||
<?php foreach ($blog->tags as $tag): ?>
|
||||
<?php echoBlogTag($tag) ?>
|
||||
<?php endforeach ?>
|
||||
</li>
|
||||
<?php if ($is_preview): ?>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/post/'.$blog->info['id']) ?>">
|
||||
阅读全文
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php if (Auth::check() && (isSuperUser(Auth::user()) || Auth::id() == $blog->info['poster'])): ?>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/'.($blog->info['type'] == 'B' ? 'post' : 'slide').'/'.$blog->info['id'].'/write') ?>">
|
||||
修改
|
||||
</a>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/post/'.$blog->info['id'].'/delete') ?>">
|
||||
删除
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<li class="list-inline-item"><?= ClickZans::getBlock('B', $blog->info['id'], $blog->info['zan']) ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-footer text-end text-right">
|
||||
<ul class="list-inline mb-0">
|
||||
<li class="list-inline-item">
|
||||
<?php foreach ($blog->tags as $tag) : ?>
|
||||
<?php echoBlogTag($tag) ?>
|
||||
<?php endforeach ?>
|
||||
</li>
|
||||
<?php if ($is_preview) : ?>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/post/' . $blog->info['id']) ?>">
|
||||
阅读全文
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php if ($blog->userCanManage(Auth::user())) : ?>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/' . ($blog->info['type'] == 'B' ? 'post' : 'slide') . '/' . $blog->info['id'] . '/write') ?>">
|
||||
修改
|
||||
</a>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<a class="text-decoration-none" href="<?= HTML::blog_url($blog->info['poster'], '/post/' . $blog->info['id'] . '/delete') ?>">
|
||||
删除
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<li class="list-inline-item">
|
||||
<?= ClickZans::getBlock('B', $blog->info['id'], $blog->info['zan']) ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
@ -26,7 +26,7 @@ if (!isset($can_reply)) {
|
||||
<tr><td colspan="233"><?= UOJLocale::get('none') ?></td></tr>
|
||||
<?php else: foreach ($pag->get() as $question): ?>
|
||||
<tr>
|
||||
<td><?= getUserLink($question['username']) ?></td>
|
||||
<td><?= UOJUser::getLink($question['username']) ?></td>
|
||||
<td class="small"><?= $question['post_time'] ?></td>
|
||||
<td style="text-align: left" class="question" data-qid="<?=$question['id']?>">
|
||||
<div class="question-content uoj-readmore"><?= HTML::escape($question['question']) ?></div>
|
||||
|
@ -25,27 +25,25 @@
|
||||
</div>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php if ($user['realname']) : ?>
|
||||
<li class="list-group-item">
|
||||
<i class="bi bi-person-fill me-1"></i>
|
||||
<?= $user['realname'] ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<li class="list-group-item">
|
||||
<i class="bi bi-person-fill me-1"></i>
|
||||
<?= $user['realname'] ?>
|
||||
<?php if ($user['realname']) : ?>
|
||||
<span class="small text-secondary">
|
||||
(<?= UOJLocale::get('user::' . $user['usertype']) ?: HTML::escape($user['usertype']) ?>)
|
||||
</span>
|
||||
<?php else : ?>
|
||||
<span class="text-secondary">
|
||||
<?= UOJLocale::get('user::' . $user['usertype']) ?: HTML::escape($user['usertype']) ?>
|
||||
</span>
|
||||
<?php endif ?>
|
||||
</li>
|
||||
<?php if ($user['school']) : ?>
|
||||
<li class="list-group-item">
|
||||
<i class="bi bi-person-badge-fill me-1"></i>
|
||||
<?= $user['school'] ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php if ($user['usertype']) : ?>
|
||||
<li class="list-group-item">
|
||||
<i class="bi bi-key-fill me-1"></i>
|
||||
<?php foreach (explode(',', $user['usertype']) as $idx => $type) : ?>
|
||||
<?php if ($idx) : ?>,<?php endif ?>
|
||||
<span><?= UOJLocale::get('user::' . str_replace('_', ' ', $type)) ?: HTML::escape($type) ?></span>
|
||||
<?php endforeach ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php if ($user['email']) : ?>
|
||||
<li class="list-group-item">
|
||||
<i class="bi bi-envelope-fill me-1"></i>
|
||||
@ -56,9 +54,11 @@
|
||||
<?php endif ?>
|
||||
<?php if ($user['qq']) : ?>
|
||||
<li class="list-group-item">
|
||||
<i class="align-text-bottom me-1"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16">
|
||||
<i class="align-text-bottom me-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16">
|
||||
<path d="M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z" fill="currentColor" />
|
||||
</svg></i>
|
||||
</svg>
|
||||
</i>
|
||||
<a class="text-decoration-none text-body" href="http://wpa.qq.com/msgrd?v=3&uin=<?= HTML::escape($user['qq']) ?>&site=qq&menu=yes" target="_blank">
|
||||
<?= HTML::escape($user['qq']) ?>
|
||||
</a>
|
||||
@ -74,10 +74,14 @@
|
||||
<?php endif ?>
|
||||
<?php if ($extra['social']['codeforces']) : ?>
|
||||
<li class="list-group-item d-flex align-items-center">
|
||||
<div class="flex-shrink-0"><i class="align-text-bottom me-1"><svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" width="16" height="16">
|
||||
<div class="flex-shrink-0">
|
||||
<i class="align-text-bottom me-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" width="16" height="16">
|
||||
<title>Codeforces</title>
|
||||
<path d="M4.5 7.5C5.328 7.5 6 8.172 6 9v10.5c0 .828-.672 1.5-1.5 1.5h-3C.673 21 0 20.328 0 19.5V9c0-.828.673-1.5 1.5-1.5h3zm9-4.5c.828 0 1.5.672 1.5 1.5v15c0 .828-.672 1.5-1.5 1.5h-3c-.827 0-1.5-.672-1.5-1.5v-15c0-.828.673-1.5 1.5-1.5h3zm9 7.5c.828 0 1.5.672 1.5 1.5v7.5c0 .828-.672 1.5-1.5 1.5h-3c-.828 0-1.5-.672-1.5-1.5V12c0-.828.672-1.5 1.5-1.5h3z" fill="currentColor" />
|
||||
</svg></i> </div>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
<div>
|
||||
<a id="codeforces-profile-link" class="text-decoration-none" href="https://codeforces.com/profile/<?= $extra['social']['codeforces'] ?>" target="_blank" style="color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important;">
|
||||
<?= $extra['social']['codeforces'] ?>
|
||||
|
Loading…
Reference in New Issue
Block a user