diff --git a/webapp/src/Controller/Team/ClarificationController.php b/webapp/src/Controller/Team/ClarificationController.php index 8134a4e2bd..6ed0260684 100644 --- a/webapp/src/Controller/Team/ClarificationController.php +++ b/webapp/src/Controller/Team/ClarificationController.php @@ -45,6 +45,61 @@ public function __construct( parent::__construct($em, $eventLogService, $dj, $kernel); } + #[Route(path: '/clarifications/by-problem/{probId<\d+>}', name: 'team_clarification_by_prob')] + public function viewByProblemAction(Request $request, int $probId): Response + { + $user = $this->dj->getUser(); + $team = $user->getTeam(); + $teamId = $team->getTeamid(); + $contest = $this->dj->getCurrentContest($teamId); + + $problem = $this->em->getRepository(Problem::class)->find($probId); + if ($problem === null) { + throw new NotFoundHttpException(sprintf('Problem %d not found', $probId)); + } + $contestProblem = $problem->getContestProblems(); + $foundProblemInContest = false; + foreach ($contestProblem as $cp) { + if ($cp->getContest()->getCid() === $contest->getCid()) { + $foundProblemInContest = true; + break; + } + } + if (!$foundProblemInContest) { + throw new NotFoundHttpException(sprintf('Problem %d not in current contest', $probId)); + } + + /** @var Clarification[] $clarifications */ + $clarifications = $this->em->createQueryBuilder() + ->from(Clarification::class, 'c') + ->leftJoin('c.problem', 'p') + ->leftJoin('c.sender', 's') + ->leftJoin('c.recipient', 'r') + ->select('c', 'p') + ->andWhere('c.contest = :contest') + ->andWhere('c.sender IS NULL') + ->andWhere('c.recipient = :team OR c.recipient IS NULL') + ->andWhere('c.problem = :problem') + ->setParameter('contest', $contest) + ->setParameter('team', $team) + ->setParameter('problem', $problem) + ->addOrderBy('c.submittime', 'DESC') + ->addOrderBy('c.clarid', 'DESC') + ->getQuery() + ->getResult(); + + $data = [ + 'clarifications' => $clarifications, + 'team' => $team, + 'problem' => $problem, + ]; + if ($request->isXmlHttpRequest()) { + return $this->render('team/clarifications_by_problem_modal.html.twig', $data); + } else { + return $this->render('team/clarifications_by_problem.html.twig', $data); + } + } + /** * @throws NonUniqueResultException */ diff --git a/webapp/src/Service/DOMJudgeService.php b/webapp/src/Service/DOMJudgeService.php index 1603e6dd0b..74f699ffba 100644 --- a/webapp/src/Service/DOMJudgeService.php +++ b/webapp/src/Service/DOMJudgeService.php @@ -1028,6 +1028,7 @@ public function getTwigDataForProblemsAction( $problems = []; $samples = []; + $clars = []; if ($contest && ($forJury || $contest->getFreezeData()->started())) { $problems = $this->em->createQueryBuilder() ->from(ContestProblem::class, 'cp') @@ -1057,6 +1058,27 @@ public function getTwigDataForProblemsAction( foreach ($samplesData as $sample) { $samples[$sample['probid']] = $sample['numsamples']; } + + $raw_clars = $this->em->createQueryBuilder() + ->from(Clarification::class, 'clar') + ->select('clar') + ->andWhere('clar.contest = :cid') + // Only clars associated with a problem. + ->andWhere('clar.problem IS NOT NULL') + // Only clars send from the jury. + ->andWhere('clar.sender IS NULL') + // Only clars send to all teams or just this team. + ->andWhere('clar.recipient IS NULL OR clar.recipient = :teamid') + ->setParameter('cid', $contest->getCid()) + ->setParameter('teamid', $teamId) + ->orderBy('clar.submittime', 'DESC') + ->getQuery() + ->getResult(); + + // Group clarifications by problem id. + foreach ($raw_clars as $clar) { + $clars[$clar->getProblem()->getProbid()][] = $clar; + } } $data = [ @@ -1065,6 +1087,8 @@ public function getTwigDataForProblemsAction( 'showLimits' => $showLimits, 'defaultMemoryLimit' => $defaultMemoryLimit, 'timeFactorDiffers' => $timeFactorDiffers, + 'clarifications' => $clars, + 'team' => $teamId ? $this->em->getRepository(Team::class)->find($teamId) : null, ]; if ($contest && $this->config->get('show_public_stats')) { diff --git a/webapp/templates/partials/problem_list.html.twig b/webapp/templates/partials/problem_list.html.twig index 6d7a3f0298..8414498602 100644 --- a/webapp/templates/partials/problem_list.html.twig +++ b/webapp/templates/partials/problem_list.html.twig @@ -109,21 +109,6 @@ {% endif %}
No clarifications.
+ {% else %} + {% include 'team/partials/clarification_list.html.twig' with {clarifications: clarifications} %} + {% endif %} +{% endblock %} diff --git a/webapp/templates/team/clarifications_by_problem_modal.html.twig b/webapp/templates/team/clarifications_by_problem_modal.html.twig new file mode 100644 index 0000000000..a48d09d1aa --- /dev/null +++ b/webapp/templates/team/clarifications_by_problem_modal.html.twig @@ -0,0 +1,31 @@ +{% extends "partials/modal.html.twig" %} + +{% block title %}View clarifications for problem {{ problem | problemBadgeForContest }} {{ problem.name }}{% endblock %} + +{% block extrahead %} + {{ parent() }} + +{% endblock %} + +{% block content %} + {% if clarifications is empty %} +No clarifications.
+ {% else %} + {% include 'team/partials/clarification_list.html.twig' with {clarifications: clarifications, subject: false} %} + {% endif %} +{% endblock %} diff --git a/webapp/templates/team/partials/clarification_list.html.twig b/webapp/templates/team/partials/clarification_list.html.twig index 47b154c542..1095704126 100644 --- a/webapp/templates/team/partials/clarification_list.html.twig +++ b/webapp/templates/team/partials/clarification_list.html.twig @@ -1,3 +1,8 @@ +{% set includeSubject = true %} +{% if subject is defined and not subject %} + {% set includeSubject = false %} +{% endif %} +