mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-24 23:48:41 +00:00
167 lines
4.5 KiB
PHP
167 lines
4.5 KiB
PHP
|
<?php
|
||
|
|
||
|
class UOJContestProblem extends UOJProblem {
|
||
|
public $contest = null;
|
||
|
public $problem_number = -1;
|
||
|
|
||
|
public static function query($id, UOJContest $contest = null) {
|
||
|
$problem = parent::query($id);
|
||
|
if ($problem === null) {
|
||
|
return $problem;
|
||
|
}
|
||
|
if ($contest === null) {
|
||
|
$contest = UOJContest::cur();
|
||
|
}
|
||
|
return new UOJContestProblem($problem->info, $contest);
|
||
|
}
|
||
|
|
||
|
public function __construct($info, UOJContest $contest) {
|
||
|
parent::__construct($info);
|
||
|
$this->contest = $contest;
|
||
|
}
|
||
|
|
||
|
public function valid() {
|
||
|
return $this->contest && $this->contest->hasProblem($this);
|
||
|
}
|
||
|
|
||
|
public function getProblemNumber() {
|
||
|
if ($this->problem_number !== -1) {
|
||
|
return $this->problem_number;
|
||
|
}
|
||
|
$contest_problems = DB::selectAll([
|
||
|
DB::lc(), "select problem_id from contests_problems",
|
||
|
"where", [
|
||
|
'contest_id' => $this->contest->info['id'],
|
||
|
],
|
||
|
"order by level, problem_id"
|
||
|
]);
|
||
|
return $this->problem_number = array_search(['problem_id' => $this->info['id']], $contest_problems);
|
||
|
}
|
||
|
|
||
|
public function getLetter() {
|
||
|
$num = $this->getProblemNumber();
|
||
|
if ($num === null) {
|
||
|
return null;
|
||
|
}
|
||
|
return chr(ord('A') + $num);
|
||
|
}
|
||
|
|
||
|
public function getTitle(array $cfg = []) {
|
||
|
$cfg += [
|
||
|
'with' => 'id',
|
||
|
'simplify' => false
|
||
|
];
|
||
|
$title = parent::getTitle(['with' => null] + $cfg);
|
||
|
if ($cfg['simplify']) {
|
||
|
$letter = $this->getLetter();
|
||
|
if (strStartWith($title, $letter)) {
|
||
|
if (strStartWith($title, $letter . '.')) {
|
||
|
$title = substr($title, strlen($letter) + 1);
|
||
|
} else if (strStartWith($title, $letter . ' - ')) {
|
||
|
$title = substr($title, strlen($letter) + 3);
|
||
|
}
|
||
|
$title = trim($title);
|
||
|
}
|
||
|
}
|
||
|
if ($cfg['with'] == 'letter') {
|
||
|
if (!isset($letter)) {
|
||
|
$letter = $this->getLetter();
|
||
|
}
|
||
|
return "{$letter}. {$title}";
|
||
|
} elseif ($cfg['with'] == 'id') {
|
||
|
return "#{$this->info['id']}. {$title}";
|
||
|
} else {
|
||
|
return $title;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function getUri($where = '') {
|
||
|
if (!$this->contest) {
|
||
|
return false;
|
||
|
}
|
||
|
return "/contest/{$this->contest->info['id']}/problem/{$this->info['id']}{$where}";
|
||
|
}
|
||
|
|
||
|
public function queryUserSubmissionCountInContest(array $user = null) {
|
||
|
if (!$user) {
|
||
|
return 0;
|
||
|
}
|
||
|
return DB::selectCount([
|
||
|
DB::lc(), "select count(*) from submissions",
|
||
|
"where", [
|
||
|
"submitter" => $user['username'],
|
||
|
"problem_id" => $this->info['id'],
|
||
|
"contest_id" => $this->contest->info['id'],
|
||
|
DB::lor([
|
||
|
[UOJSubmission::sqlForActualScore(), "is not", null],
|
||
|
['status', 'not like', 'Judged%']
|
||
|
])
|
||
|
]
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
public function getJudgeTypeInContest() {
|
||
|
if (!isset($this->contest->info['extra_config']["problem_{$this->info['id']}"])) {
|
||
|
return $this->contest->defaultProblemJudgeType();
|
||
|
} else {
|
||
|
return $this->contest->info['extra_config']["problem_{$this->info['id']}"];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function isBonus() {
|
||
|
return isset($this->contest->info['extra_config']['bonus']["problem_{$this->info['id']}"]);
|
||
|
}
|
||
|
|
||
|
public function submitTimeLimit() {
|
||
|
if (isset($this->contest->info['extra_config']['submit_time_limit']["problem_{$this->info['id']}"])) {
|
||
|
return $this->contest->info['extra_config']['submit_time_limit']["problem_{$this->info['id']}"];
|
||
|
} else {
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function userCanClickZan(array $user = null) {
|
||
|
return $this->userCanView($user) && $this->contest->progress() > CONTEST_IN_PROGRESS;
|
||
|
}
|
||
|
|
||
|
public function userCanView(array $user = null, array $cfg = []) {
|
||
|
$cfg += ['check-register' => true];
|
||
|
return $this->contest->userCanView($user, $cfg);
|
||
|
}
|
||
|
|
||
|
public function userCanDownloadAttachments(array $user = null) {
|
||
|
return $this->userCanView($user);
|
||
|
}
|
||
|
|
||
|
public function preHackCheck(array $user = null) {
|
||
|
return $this->info['hackable'] && !$this->info['is_hidden'];
|
||
|
}
|
||
|
|
||
|
public function preSubmitCheck() {
|
||
|
if ($this->contest->userCanManage(Auth::user())) {
|
||
|
return true;
|
||
|
}
|
||
|
if ($this->contest->progress() > CONTEST_IN_PROGRESS && !parent::userCanView(Auth::user())) {
|
||
|
return '比赛已结束,请耐心等待管理员在题库公开题目后再提交哦~';
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public function additionalSubmissionComponentsCannotBeSeenByUser(array $user = null, UOJSubmission $submission) {
|
||
|
// excluding manager_view, score; don't check whether $user is a manager
|
||
|
if ($this->contest->progress() == CONTEST_IN_PROGRESS) {
|
||
|
if ($submission->userIsSubmitter($user)) {
|
||
|
if ($this->getJudgeTypeInContest() == 'no-details') {
|
||
|
return ['low_level_details'];
|
||
|
} else {
|
||
|
return [];
|
||
|
}
|
||
|
} else {
|
||
|
return ['content', 'high_level_details', 'low_level_details'];
|
||
|
}
|
||
|
} else {
|
||
|
return [];
|
||
|
}
|
||
|
}
|
||
|
}
|