contest_manage.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <?php
  2. requirePHPLib('form');
  3. if (!validateUInt($_GET['id']) || !($contest = queryContest($_GET['id']))) {
  4. become404Page();
  5. }
  6. genMoreContestInfo($contest);
  7. if (!isSuperUser($myUser)) {
  8. become403Page();
  9. }
  10. $time_form = new UOJForm('time');
  11. $time_form->addInput(
  12. 'name', 'text', '比赛标题', $contest['name'],
  13. function($str) {
  14. return '';
  15. },
  16. null
  17. );
  18. $time_form->addInput(
  19. 'start_time', 'text', '开始时间', $contest['start_time_str'],
  20. function($str, &$vdata) {
  21. try {
  22. $vdata['start_time'] = new DateTime($str);
  23. } catch (Exception $e) {
  24. return '无效时间格式';
  25. }
  26. return '';
  27. },
  28. null
  29. );
  30. $time_form->addInput(
  31. 'last_min', 'text', '时长(单位:分钟)', $contest['last_min'],
  32. function($str) {
  33. return !validateUInt($str) ? '必须为一个整数' : '';
  34. },
  35. null
  36. );
  37. $time_form->handle = function(&$vdata) {
  38. global $contest;
  39. $start_time_str = $vdata['start_time']->format('Y-m-d H:i:s');
  40. $purifier = HTML::pruifier();
  41. $esc_name = $_POST['name'];
  42. $esc_name = $purifier->purify($esc_name);
  43. $esc_name = DB::escape($esc_name);
  44. DB::update("update contests set start_time = '$start_time_str', last_min = {$_POST['last_min']}, name = '$esc_name' where id = {$contest['id']}");
  45. };
  46. $managers_form = newAddDelCmdForm('managers',
  47. function($username) {
  48. if (!validateUsername($username) || !queryUser($username)) {
  49. return "不存在名为{$username}的用户";
  50. }
  51. return '';
  52. },
  53. function($type, $username) {
  54. global $contest;
  55. if ($type == '+') {
  56. DB::query("insert into contests_permissions (contest_id, username) values (${contest['id']}, '$username')");
  57. } elseif ($type == '-') {
  58. DB::query("delete from contests_permissions where contest_id = ${contest['id']} and username = '$username'");
  59. }
  60. }
  61. );
  62. $problems_form = newAddDelCmdForm('problems',
  63. function($cmd) {
  64. if (!preg_match('/^(\d+)\s*(\[\S+\])?$/', $cmd, $matches)) {
  65. return "无效题号";
  66. }
  67. $problem_id = $matches[1];
  68. if (!validateUInt($problem_id) || !($problem = queryProblemBrief($problem_id))) {
  69. return "不存在题号为{$problem_id}的题";
  70. }
  71. if (!hasProblemCtrlPermission(Auth::user(), $problem)) {
  72. return "无权添加题号为{$problem_id}的题";
  73. }
  74. return '';
  75. },
  76. function($type, $cmd) {
  77. global $contest;
  78. if (!preg_match('/^(\d+)\s*(\[\S+\])?$/', $cmd, $matches)) {
  79. return "无效题号";
  80. }
  81. $problem_id = $matches[1];
  82. if ($type == '+') {
  83. DB::insert("insert into contests_problems (contest_id, problem_id) values ({$contest['id']}, '$problem_id')");
  84. } elseif ($type == '-') {
  85. DB::delete("delete from contests_problems where contest_id = {$contest['id']} and problem_id = '$problem_id'");
  86. }
  87. if (isset($matches[2])) {
  88. switch ($matches[2]) {
  89. case '[sample]':
  90. unset($contest['extra_config']["problem_$problem_id"]);
  91. break;
  92. case '[full]':
  93. $contest['extra_config']["problem_$problem_id"] = 'full';
  94. break;
  95. case '[no-details]':
  96. $contest['extra_config']["problem_$problem_id"] = 'no-details';
  97. break;
  98. }
  99. $esc_extra_config = json_encode($contest['extra_config']);
  100. $esc_extra_config = DB::escape($esc_extra_config);
  101. DB::update("update contests set extra_config = '$esc_extra_config' where id = {$contest['id']}");
  102. }
  103. }
  104. );
  105. if (isSuperUser($myUser)) {
  106. $rating_k_form = new UOJForm('rating_k');
  107. $rating_k_form->addInput('rating_k', 'text', 'rating 变化上限', isset($contest['extra_config']['rating_k']) ? $contest['extra_config']['rating_k'] : 400,
  108. function ($x) {
  109. if (!validateUInt($x) || $x < 1 || $x > 1000) {
  110. return '不合法的上限';
  111. }
  112. return '';
  113. },
  114. null
  115. );
  116. $rating_k_form->handle = function() {
  117. global $contest;
  118. $contest['extra_config']['rating_k'] = $_POST['rating_k'];
  119. $esc_extra_config = json_encode($contest['extra_config']);
  120. $esc_extra_config = DB::escape($esc_extra_config);
  121. DB::update("update contests set extra_config = '$esc_extra_config' where id = {$contest['id']}");
  122. };
  123. $rating_k_form->runAtServer();
  124. $rated_form = new UOJForm('rated');
  125. $rated_form->handle = function() {
  126. global $contest;
  127. if (isset($contest['extra_config']['unrated'])) {
  128. unset($contest['extra_config']['unrated']);
  129. } else {
  130. $contest['extra_config']['unrated'] = '';
  131. }
  132. $esc_extra_config = json_encode($contest['extra_config']);
  133. $esc_extra_config = DB::escape($esc_extra_config);
  134. DB::update("update contests set extra_config = '$esc_extra_config' where id = {$contest['id']}");
  135. };
  136. $rated_form->submit_button_config['class_str'] = 'btn btn-warning btn-block';
  137. $rated_form->submit_button_config['text'] = isset($contest['extra_config']['unrated']) ? '设置比赛为rated' : '设置比赛为unrated';
  138. $rated_form->submit_button_config['smart_confirm'] = '';
  139. $rated_form->runAtServer();
  140. $version_form = new UOJForm('version');
  141. $version_form->addInput('standings_version', 'text', '排名版本', $contest['extra_config']['standings_version'],
  142. function ($x) {
  143. if (!validateUInt($x) || $x < 1 || $x > 2) {
  144. return '不是合法的版本号';
  145. }
  146. return '';
  147. },
  148. null
  149. );
  150. $version_form->handle = function() {
  151. global $contest;
  152. $contest['extra_config']['standings_version'] = $_POST['standings_version'];
  153. $esc_extra_config = json_encode($contest['extra_config']);
  154. $esc_extra_config = DB::escape($esc_extra_config);
  155. DB::update("update contests set extra_config = '$esc_extra_config' where id = {$contest['id']}");
  156. };
  157. $version_form->runAtServer();
  158. $contest_type_form = new UOJForm('contest_type');
  159. $contest_type_form->addInput('contest_type', 'text', '赛制', $contest['extra_config']['contest_type'],
  160. function ($x) {
  161. if ($x != 'OI' && $x != 'ACM' && $x != 'IOI') {
  162. return '不是合法的赛制名';
  163. }
  164. return '';
  165. },
  166. null
  167. );
  168. $contest_type_form->handle = function() {
  169. global $contest;
  170. $contest['extra_config']['contest_type'] = $_POST['contest_type'];
  171. $esc_extra_config = json_encode($contest['extra_config']);
  172. $esc_extra_config = DB::escape($esc_extra_config);
  173. DB::update("update contests set extra_config = '$esc_extra_config' where id = {$contest['id']}");
  174. };
  175. $contest_type_form->runAtServer();
  176. }
  177. $time_form->runAtServer();
  178. $managers_form->runAtServer();
  179. $problems_form->runAtServer();
  180. ?>
  181. <?php echoUOJPageHeader(HTML::stripTags($contest['name']) . ' - 比赛管理') ?>
  182. <h1 class="page-header" align="center"><?=$contest['name']?> 管理</h1>
  183. <ul class="nav nav-tabs mb-3" role="tablist">
  184. <li class="nav-item"><a class="nav-link active" href="#tab-time" role="tab" data-toggle="tab">比赛时间</a></li>
  185. <li class="nav-item"><a class="nav-link" href="#tab-managers" role="tab" data-toggle="tab">管理者</a></li>
  186. <li class="nav-item"><a class="nav-link" href="#tab-problems" role="tab" data-toggle="tab">试题</a></li>
  187. <?php if (isSuperUser($myUser)): ?>
  188. <li class="nav-item"><a class="nav-link" href="#tab-others" role="tab" data-toggle="tab">其它</a></li>
  189. <?php endif ?>
  190. <li class="nav-item"><a class="nav-link" href="/contest/<?=$contest['id']?>" role="tab">返回</a></li>
  191. </ul>
  192. <div class="tab-content top-buffer-sm">
  193. <div class="tab-pane active" id="tab-time">
  194. <?php $time_form->printHTML(); ?>
  195. </div>
  196. <div class="tab-pane" id="tab-managers">
  197. <table class="table table-hover">
  198. <thead>
  199. <tr>
  200. <th>#</th>
  201. <th>用户名</th>
  202. </tr>
  203. </thead>
  204. <tbody>
  205. <?php
  206. $row_id = 0;
  207. $result = DB::query("select username from contests_permissions where contest_id = {$contest['id']}");
  208. while ($row = DB::fetch($result, MYSQLI_ASSOC)) {
  209. $row_id++;
  210. echo '<tr>', '<td>', $row_id, '</td>', '<td>', getUserLink($row['username']), '</td>', '</tr>';
  211. }
  212. ?>
  213. </tbody>
  214. </table>
  215. <p class="text-center">命令格式:命令一行一个,+mike表示把mike加入管理者,-mike表示把mike从管理者中移除</p>
  216. <?php $managers_form->printHTML(); ?>
  217. </div>
  218. <div class="tab-pane" id="tab-problems">
  219. <table class="table table-hover">
  220. <thead>
  221. <tr>
  222. <th>#</th>
  223. <th>试题名</th>
  224. </tr>
  225. </thead>
  226. <tbody>
  227. <?php
  228. $result = DB::query("select problem_id from contests_problems where contest_id = ${contest['id']} order by problem_id asc");
  229. while ($row = DB::fetch($result, MYSQLI_ASSOC)) {
  230. $problem = queryProblemBrief($row['problem_id']);
  231. $problem_config_str = isset($contest['extra_config']["problem_{$problem['id']}"]) ? $contest['extra_config']["problem_{$problem['id']}"] : 'sample';
  232. echo '<tr>', '<td>', $problem['id'], '</td>', '<td>', getProblemLink($problem), ' ', "[$problem_config_str]", '</td>', '</tr>';
  233. }
  234. ?>
  235. </tbody>
  236. </table>
  237. <p class="text-center">命令格式:命令一行一个,+233表示把题号为233的试题加入比赛,-233表示把题号为233的试题从比赛中移除</p>
  238. <?php $problems_form->printHTML(); ?>
  239. </div>
  240. <?php if (isSuperUser($myUser)): ?>
  241. <div class="tab-pane" id="tab-others">
  242. <div class="row">
  243. <div class="col-sm-12">
  244. <h3>Rating控制</h3>
  245. <div class="row">
  246. <div class="col-sm-3">
  247. <?php $rated_form->printHTML(); ?>
  248. </div>
  249. </div>
  250. <div class="top-buffer-sm"></div>
  251. <?php $rating_k_form->printHTML(); ?>
  252. </div>
  253. <div class="col-sm-12 top-buffer-sm">
  254. <h3>版本控制</h3>
  255. <?php $version_form->printHTML(); ?>
  256. </div>
  257. <div class="col-sm-12 top-buffer-sm">
  258. <h3>赛制</h3>
  259. <?php $contest_type_form->printHTML(); ?>
  260. </div>
  261. </div>
  262. </div>
  263. <?php endif ?>
  264. </div>
  265. <?php echoUOJPageFooter() ?>