diff --git a/webapp/src/Controller/Jury/ShadowDifferencesController.php b/webapp/src/Controller/Jury/ShadowDifferencesController.php index f8e1e64128..576c4cbfb3 100644 --- a/webapp/src/Controller/Jury/ShadowDifferencesController.php +++ b/webapp/src/Controller/Jury/ShadowDifferencesController.php @@ -104,6 +104,7 @@ public function indexAction( ->select('s', 'ej', 'j') ->andWhere('s.contest = :contest') ->andWhere('s.externalid IS NOT NULL') + ->andWhere('s.expected_results IS NULL') ->setParameter('contest', $contest) ->getQuery() ->getResult(); diff --git a/webapp/src/Service/ExternalContestSourceService.php b/webapp/src/Service/ExternalContestSourceService.php index 3d0212d523..bad3824ab9 100644 --- a/webapp/src/Service/ExternalContestSourceService.php +++ b/webapp/src/Service/ExternalContestSourceService.php @@ -50,6 +50,8 @@ use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException; use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; @@ -107,7 +109,7 @@ public function __construct( protected readonly EventLogService $eventLog, protected readonly SubmissionService $submissionService, protected readonly ScoreboardService $scoreboardService, - protected readonly SerializerInterface $serializer, + protected readonly SerializerInterface&DenormalizerInterface&NormalizerInterface $serializer, #[Autowire('%domjudge.version%')] string $domjudgeVersion ) { @@ -1886,7 +1888,8 @@ protected function addPendingEvent(string $type, string|int $id, Event $event, C objectId: $id, data: [$data], ); - $dependencies[$type . '-' . $id] = ['type' => $type, 'id' => $id, 'event' => $event]; + $normalizedEvent = $this->serializer->normalize($event, Event::class, ['api_version' => $this->getApiVersion()]); + $dependencies[$type . '-' . $id] = ['type' => $type, 'id' => $id, 'event' => $normalizedEvent]; $this->addOrUpdateWarning($event, $data->id, ExternalSourceWarning::TYPE_DEPENDENCY_MISSING, [ 'dependencies' => $dependencies, ]); @@ -1917,7 +1920,7 @@ protected function loadPendingEvents(): void $type = $dependency['type']; $id = $dependency['id']; - $event = $dependency['event']; + $event = $this->serializer->denormalize($dependency['event'], Event::class, 'json', ['api_version' => $this->getApiVersion()]); if (!isset($this->pendingEvents[$type][$id])) { $this->pendingEvents[$type][$id] = []; diff --git a/webapp/src/Service/SubmissionService.php b/webapp/src/Service/SubmissionService.php index b800049a1a..e6f63205b5 100644 --- a/webapp/src/Service/SubmissionService.php +++ b/webapp/src/Service/SubmissionService.php @@ -89,7 +89,9 @@ public function getSubmissionList( } if ($restrictions->withExternalId ?? false) { - $queryBuilder->andWhere('s.externalid IS NOT NULL'); + $queryBuilder + ->andWhere('s.externalid IS NOT NULL') + ->andWhere('s.expected_results IS NULL'); } if (isset($restrictions->rejudgingId)) { @@ -163,7 +165,16 @@ public function getSubmissionList( if (isset($restrictions->externalDifference)) { if ($restrictions->externalDifference) { - $queryBuilder->andWhere('j.result != ej.result'); + if ($restrictions->result === 'judging' || $restrictions->externalResult === 'judging') { + // When either the local or external result is set to judging explicitly, + // coalesce the result with a known non-null value, because in MySQL + // 'correct' <> null is not true. By coalescing with '-' we prevent this. + $queryBuilder + ->andWhere('COALESCE(j.result, :dash) != COALESCE(ej.result, :dash)') + ->setParameter('dash', '-'); + } else { + $queryBuilder->andWhere('j.result != ej.result'); + } } else { $queryBuilder->andWhere('j.result = ej.result'); } diff --git a/webapp/templates/jury/partials/submission_graph.html.twig b/webapp/templates/jury/partials/submission_graph.html.twig index d33220e2a9..8be33868d1 100644 --- a/webapp/templates/jury/partials/submission_graph.html.twig +++ b/webapp/templates/jury/partials/submission_graph.html.twig @@ -18,7 +18,7 @@ {% endif %} - {% if externalJudgement is not null and externalJudgement.result is not null %} + {% if externalJudgement is not null and externalJudgement.result is not null and externalJudging is defined %}
External Testcase CPU times diff --git a/webapp/templates/jury/submission.html.twig b/webapp/templates/jury/submission.html.twig index 6232830d8f..4b04e74b3a 100644 --- a/webapp/templates/jury/submission.html.twig +++ b/webapp/templates/jury/submission.html.twig @@ -551,11 +551,11 @@ {{ externalRuns | displayTestcaseResults(externalJudgement.endtime is not empty, true) }} - {% if externalSubmissionUrl and externalSubmissionUrl is not empty %} + {% if externalSubmissionUrl is defined and externalSubmissionUrl is not empty %} {% endif %} external {{ externalJudgement.extjudgementid }} - {% if externalSubmissionUrl and externalSubmissionUrl is not empty %} + {% if externalSubmissionUrl is defined and externalSubmissionUrl is not empty %} {% endif %}