@@ -49,6 +49,32 @@ public function __construct(
4949 parent ::__construct ($ em , $ eventLog , $ dj , $ kernel );
5050 }
5151
52+ /**
53+ * @return Clarification[]
54+ */
55+ protected function getGlobalClarifications (?Contest $ contest ): array
56+ {
57+ if ($ contest ) {
58+ return $ this ->em ->createQueryBuilder ()
59+ ->from (Clarification::class, 'c ' )
60+ ->leftJoin ('c.problem ' , 'p ' )
61+ ->leftJoin ('c.sender ' , 's ' )
62+ ->leftJoin ('c.recipient ' , 'r ' )
63+ ->select ('c ' , 'p ' )
64+ ->andWhere ('c.contest = :contest ' )
65+ ->andWhere ('c.sender IS NULL ' )
66+ ->andWhere ('c.recipient IS NULL ' )
67+ ->andWhere ('c.submittime <= :time ' )
68+ ->andWhere ('c.problem IS NULL ' )
69+ ->setParameter ('contest ' , $ contest )
70+ ->setparameter ('time ' , time ())
71+ ->addOrderBy ('c.submittime ' , 'DESC ' )
72+ ->addOrderBy ('c.clarid ' , 'DESC ' )
73+ ->getQuery ()->getResult ();
74+ }
75+ return [];
76+ }
77+
5278 #[Route(path: '' , name: 'public_index ' )]
5379 #[Route(path: '/scoreboard ' )]
5480 public function scoreboardAction (
@@ -68,7 +94,6 @@ public function scoreboardAction(
6894 return $ this ->redirectToRoute ('register ' );
6995 }
7096
71-
7297 if ($ static ) {
7398 $ refreshParams = [
7499 'static ' => 1 ,
@@ -88,6 +113,8 @@ public function scoreboardAction(
88113
89114 if ($ static ) {
90115 $ data ['hide_menu ' ] = true ;
116+ } else {
117+ $ data ['global_clarifications ' ] = $ this ->getGlobalClarifications ($ contest );
91118 }
92119
93120 $ data ['current_contest ' ] = $ contest ;
@@ -98,6 +125,51 @@ public function scoreboardAction(
98125 return $ this ->render ('public/scoreboard.html.twig ' , $ data , $ response );
99126 }
100127
128+ #[Route(path: '/clarifications ' , name: 'public_clarifications ' )]
129+ public function clarificationsAction (
130+ RequestStack $ requestStack ,
131+ Request $ request ,
132+ #[MapQueryParameter(name: 'contest ' )]
133+ ?string $ contestId = null
134+ ): Response {
135+ $ contest = $ this ->getContestFromRequest ($ contestId ) ?? $ this ->dj ->getCurrentContest (onlyPublic: true );
136+ if (!$ contest ) {
137+ throw new NotFoundHttpException ('No active contest ' );
138+ }
139+
140+ /** @var Clarification[] $clarifications */
141+ $ clarifications = [];
142+ if ($ contest ->getStartTimeObject ()?->getTimestamp() <= time ()) {
143+ $ clarifications = $ this ->em ->createQueryBuilder ()
144+ ->from (Clarification::class, 'c ' )
145+ ->leftJoin ('c.problem ' , 'p ' )
146+ ->leftJoin ('c.sender ' , 's ' )
147+ ->leftJoin ('c.recipient ' , 'r ' )
148+ ->select ('c ' , 'p ' )
149+ ->andWhere ('c.contest = :contest ' )
150+ ->andWhere ('c.sender IS NULL ' )
151+ ->andWhere ('c.recipient IS NULL ' )
152+ ->andWhere ('c.problem IS NULL ' )
153+ ->andWhere ('c.submittime <= :time ' )
154+ ->setParameter ('contest ' , $ contest )
155+ ->setParameter ('time ' , time ())
156+ ->addOrderBy ('c.submittime ' , 'DESC ' )
157+ ->addOrderBy ('c.clarid ' , 'DESC ' )
158+ ->getQuery ()
159+ ->getResult ();
160+ }
161+
162+ $ data = [
163+ 'contest ' => $ contest ,
164+ 'global_clarifications ' => $ clarifications
165+ ];
166+ if ($ request ->isXmlHttpRequest ()) {
167+ return $ this ->render ('public/clarifications_general_modal.html.twig ' , $ data );
168+ } else {
169+ return $ this ->render ('public/clarifications_general.html.twig ' , $ data );
170+ }
171+ }
172+
101173 #[Route(path: '/scoreboard.zip ' , name: 'public_scoreboard_data_zip ' )]
102174 public function scoreboardDataZipAction (
103175 RequestStack $ requestStack ,
@@ -194,6 +266,7 @@ public function teamAction(Request $request, string $teamId): Response
194266 'team ' => $ team ,
195267 'showFlags ' => $ showFlags ,
196268 'showAffiliations ' => $ showAffiliations ,
269+ 'global_clarifications ' => $ this ->getGlobalClarifications ($ this ->dj ->getCurrentContest ()),
197270 ];
198271
199272 if ($ request ->isXmlHttpRequest ()) {
@@ -474,6 +547,10 @@ public function viewAction(Request $request, string $clarId): Response
474547 {
475548 $ categories = $ this ->config ->get ('clar_categories ' );
476549 $ contest = $ this ->dj ->getCurrentContest ();
550+ if (!$ contest ) {
551+ throw new NotFoundHttpException ('No active contest ' );
552+ }
553+
477554 /** @var Clarification|null $clarification */
478555 $ clarification = $ this ->em ->createQueryBuilder ()
479556 ->from (Clarification::class, 'c ' )
0 commit comments