@@ -309,8 +309,9 @@ public function importContestData(mixed $data, ?string &$errorMessage = null, st
309309 * problems?: array{name?: string, short-name?: string, id?: string, label?: string,
310310 * letter?: string, label?: string, letter?: string}} $problems
311311 * @param string[]|null $ids
312+ * @param array<string, string[]> $messages
312313 */
313- public function importProblemsData (Contest $ contest , array $ problems , array &$ ids = null ): bool
314+ public function importProblemsData (Contest $ contest , array $ problems , array &$ ids = null , ? array & $ messages = [] ): bool
314315 {
315316 // For problemset.yaml the root key is called `problems`, so handle that case
316317 // TODO: Move this check away to make the $problems array shape easier
@@ -329,8 +330,20 @@ public function importProblemsData(Contest $contest, array $problems, array &$id
329330 ->setTimelimit ($ problemData ['time_limit ' ] ?? 10 )
330331 ->setExternalid ($ problemData ['id ' ] ?? $ problemData ['short-name ' ] ?? $ problemLabel ?? null );
331332
332- $ this ->em ->persist ($ problem );
333- $ this ->em ->flush ();
333+ $ hasErrors = false ;
334+ $ errors = $ this ->validator ->validate ($ problem );
335+ if ($ errors ->count ()) {
336+ $ hasErrors = true ;
337+ /** @var ConstraintViolationInterface $error */
338+ foreach ($ errors as $ error ) {
339+ $ messages ['danger ' ][] = sprintf (
340+ 'Error: problems.%s.%s: %s ' ,
341+ $ problem ->getExternalid (),
342+ $ error ->getPropertyPath (),
343+ $ error ->getMessage ()
344+ );
345+ }
346+ }
334347
335348 $ contestProblem = new ContestProblem ();
336349 $ contestProblem
@@ -339,14 +352,35 @@ public function importProblemsData(Contest $contest, array $problems, array &$id
339352 // We need to set both the entities and the IDs because of the composite primary key.
340353 ->setProblem ($ problem )
341354 ->setContest ($ contest );
355+
356+ $ errors = $ this ->validator ->validate ($ contestProblem );
357+ if ($ errors ->count ()) {
358+ $ hasErrors = true ;
359+ /** @var ConstraintViolationInterface $error */
360+ foreach ($ errors as $ error ) {
361+ $ messages ['danger ' ][] = sprintf (
362+ 'Error: problems.%s.contestproblem.%s: %s ' ,
363+ $ problem ->getExternalid (),
364+ $ error ->getPropertyPath (),
365+ $ error ->getMessage ()
366+ );
367+ }
368+ }
369+
370+ if ($ hasErrors ) {
371+ return false ;
372+
373+ }
374+
375+ $ this ->em ->persist ($ problem );
342376 $ this ->em ->persist ($ contestProblem );
377+ $ this ->em ->flush ();
343378
344379 $ ids [] = $ problem ->getApiId ($ this ->eventLogService );
345380 }
346381
347382 $ this ->em ->flush ();
348383
349- // For now this method will never fail so always return true.
350384 return true ;
351385 }
352386
0 commit comments