|
27 | 27 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
28 | 28 | use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
29 | 29 | use Symfony\Component\PropertyAccess\PropertyAccess;
|
| 30 | +use Symfony\Component\PropertyAccess\PropertyAccessor; |
30 | 31 | use Symfony\Component\Validator\ConstraintViolationInterface;
|
31 | 32 | use Symfony\Component\Validator\Validator\ValidatorInterface;
|
32 | 33 | use Symfony\Component\Yaml\Yaml;
|
@@ -261,72 +262,12 @@ public function importZippedProblem(
|
261 | 262 | return null;
|
262 | 263 | }
|
263 | 264 |
|
264 |
| - if ($problemYaml !== false) { |
265 |
| - $yamlData = Yaml::parse($problemYaml); |
266 |
| - |
267 |
| - if (!empty($yamlData)) { |
268 |
| - $yamlProblemProperties = []; |
269 |
| - if (isset($yamlData['name'])) { |
270 |
| - if (is_array($yamlData['name'])) { |
271 |
| - foreach ($yamlData['name'] as $name) { |
272 |
| - // TODO: select a specific instead of the first language. |
273 |
| - $yamlProblemProperties['name'] = $name; |
274 |
| - break; |
275 |
| - } |
276 |
| - } else { |
277 |
| - $yamlProblemProperties['name'] = $yamlData['name']; |
278 |
| - } |
279 |
| - } |
280 |
| - |
281 |
| - if (isset($yamlData['type'])) { |
282 |
| - $types = explode(' ', $yamlData['type']); |
283 |
| - // Validation happens later when we set the properties. |
284 |
| - $yamlProblemProperties['typesAsString'] = $types; |
285 |
| - } else { |
286 |
| - $yamlProblemProperties['typesAsString'] = ['pass-fail']; |
287 |
| - } |
288 |
| - |
289 |
| - if (isset($yamlData['validator_flags'])) { |
290 |
| - $yamlProblemProperties['special_compare_args'] = $yamlData['validator_flags']; |
291 |
| - } |
292 |
| - |
293 |
| - if (isset($yamlData['validation']) |
294 |
| - && ($yamlData['validation'] == 'custom' || |
295 |
| - $yamlData['validation'] == 'custom interactive' || |
296 |
| - $yamlData['validation'] == 'custom multi-pass')) { |
297 |
| - if (!$this->searchAndAddValidator($zip, $messages, $externalId, $yamlData['validation'], $problem)) { |
298 |
| - return null; |
299 |
| - } |
300 |
| - |
301 |
| - if ($yamlData['validation'] == 'custom multi-pass') { |
302 |
| - $yamlProblemProperties['typesAsString'][] = 'multi-pass'; |
303 |
| - } |
304 |
| - if ($yamlData['validation'] == 'custom interactive') { |
305 |
| - $yamlProblemProperties['typesAsString'][] = 'interactive'; |
306 |
| - } |
307 |
| - } |
308 |
| - |
309 |
| - if (isset($yamlData['limits'])) { |
310 |
| - if (isset($yamlData['limits']['memory'])) { |
311 |
| - $yamlProblemProperties['memlimit'] = 1024 * $yamlData['limits']['memory']; |
312 |
| - } |
313 |
| - if (isset($yamlData['limits']['output'])) { |
314 |
| - $yamlProblemProperties['outputlimit'] = 1024 * $yamlData['limits']['output']; |
315 |
| - } |
316 |
| - if (isset($yamlData['limits']['validation_passes'])) { |
317 |
| - $problem->setMultipassLimit($yamlData['limits']['validation_passes']); |
318 |
| - } |
319 |
| - } |
320 |
| - |
321 |
| - foreach ($yamlProblemProperties as $key => $value) { |
322 |
| - try { |
323 |
| - $propertyAccessor->setValue($problem, $key, $value); |
324 |
| - } catch (Exception $e) { |
325 |
| - $messages['danger'][] = sprintf('Error: problem.%s: %s', $key, $e->getMessage()); |
326 |
| - return null; |
327 |
| - } |
328 |
| - } |
329 |
| - } |
| 265 | + $validationMode = 'default'; |
| 266 | + if (!$this->parseYaml($problemYaml, $messages, $validationMode, $propertyAccessor, $problem)) { |
| 267 | + return null; |
| 268 | + } |
| 269 | + if ($validationMode != 'default' && !$this->searchAndAddValidator($zip, $messages, $externalId, $validationMode, $problem)) { |
| 270 | + return null; |
330 | 271 | }
|
331 | 272 |
|
332 | 273 | // Add problem statement, also look in obsolete location.
|
@@ -1047,4 +988,82 @@ private function searchAndAddValidator(ZipArchive $zip, ?array &$messages, strin
|
1047 | 988 | }
|
1048 | 989 | return true;
|
1049 | 990 | }
|
| 991 | + |
| 992 | + // Returns true iff the yaml could be parsed correctly. |
| 993 | + public static function parseYaml(bool|string $problemYaml, array &$messages, string &$validationMode, PropertyAccessor $propertyAccessor, Problem $problem): bool |
| 994 | + { |
| 995 | + if ($problemYaml === false) { |
| 996 | + // While there was no problem.yaml, there was also no error in parsing. |
| 997 | + return true; |
| 998 | + } |
| 999 | + |
| 1000 | + $yamlData = Yaml::parse($problemYaml); |
| 1001 | + if (empty($yamlData)) { |
| 1002 | + // Empty yaml is OK. |
| 1003 | + return true; |
| 1004 | + } |
| 1005 | + |
| 1006 | + $yamlProblemProperties = []; |
| 1007 | + if (isset($yamlData['name'])) { |
| 1008 | + if (is_array($yamlData['name'])) { |
| 1009 | + foreach ($yamlData['name'] as $name) { |
| 1010 | + // TODO: select a specific instead of the first language. |
| 1011 | + $yamlProblemProperties['name'] = $name; |
| 1012 | + break; |
| 1013 | + } |
| 1014 | + } else { |
| 1015 | + $yamlProblemProperties['name'] = $yamlData['name']; |
| 1016 | + } |
| 1017 | + } |
| 1018 | + |
| 1019 | + if (isset($yamlData['type'])) { |
| 1020 | + $types = explode(' ', $yamlData['type']); |
| 1021 | + // Validation happens later when we set the properties. |
| 1022 | + $yamlProblemProperties['typesAsString'] = $types; |
| 1023 | + } else { |
| 1024 | + $yamlProblemProperties['typesAsString'] = ['pass-fail']; |
| 1025 | + } |
| 1026 | + |
| 1027 | + if (isset($yamlData['validator_flags'])) { |
| 1028 | + $yamlProblemProperties['special_compare_args'] = $yamlData['validator_flags']; |
| 1029 | + } |
| 1030 | + |
| 1031 | + $validationMode = 'default'; |
| 1032 | + if (isset($yamlData['validation']) |
| 1033 | + && ($yamlData['validation'] == 'custom' || |
| 1034 | + $yamlData['validation'] == 'custom interactive' || |
| 1035 | + $yamlData['validation'] == 'custom multi-pass')) { |
| 1036 | + $validationMode = $yamlData['validation']; |
| 1037 | + |
| 1038 | + if ($yamlData['validation'] == 'custom multi-pass') { |
| 1039 | + $yamlProblemProperties['typesAsString'][] = 'multi-pass'; |
| 1040 | + } |
| 1041 | + if ($yamlData['validation'] == 'custom interactive') { |
| 1042 | + $yamlProblemProperties['typesAsString'][] = 'interactive'; |
| 1043 | + } |
| 1044 | + } |
| 1045 | + |
| 1046 | + if (isset($yamlData['limits'])) { |
| 1047 | + if (isset($yamlData['limits']['memory'])) { |
| 1048 | + $yamlProblemProperties['memlimit'] = 1024 * $yamlData['limits']['memory']; |
| 1049 | + } |
| 1050 | + if (isset($yamlData['limits']['output'])) { |
| 1051 | + $yamlProblemProperties['outputlimit'] = 1024 * $yamlData['limits']['output']; |
| 1052 | + } |
| 1053 | + if (isset($yamlData['limits']['validation_passes'])) { |
| 1054 | + $yamlProblemProperties['multipassLimit'] = $yamlData['limits']['validation_passes']; |
| 1055 | + } |
| 1056 | + } |
| 1057 | + |
| 1058 | + foreach ($yamlProblemProperties as $key => $value) { |
| 1059 | + try { |
| 1060 | + $propertyAccessor->setValue($problem, $key, $value); |
| 1061 | + } catch (Exception $e) { |
| 1062 | + $messages['danger'][] = sprintf('Error: problem.%s: %s', $key, $e->getMessage()); |
| 1063 | + return false; |
| 1064 | + } |
| 1065 | + } |
| 1066 | + |
| 1067 | + return true; |
| 1068 | + } |
1050 | 1069 | }
|
0 commit comments