/** * Create a new problem * * @throws ApiException * @throws DuplicatedEntryInDatabaseException * @throws InvalidDatabaseOperationException */ public static function apiCreate(Request $r) { self::authenticateRequest($r); // Validates request self::validateCreateOrUpdate($r); // Populate a new Problem object $problem = new Problems(); $problem->setPublic($r['public']); /* private by default */ $problem->setTitle($r['title']); $problem->setValidator($r['validator']); $problem->setTimeLimit($r['time_limit']); $problem->setValidatorTimeLimit($r['validator_time_limit']); $problem->setOverallWallTimeLimit($r['overall_wall_time_limit']); $problem->setExtraWallTime($r['extra_wall_time']); $problem->setMemoryLimit($r['memory_limit']); $problem->setOutputLimit($r['output_limit']); $problem->setVisits(0); $problem->setSubmissions(0); $problem->setAccepted(0); $problem->setDifficulty(0); $problem->setSource($r['source']); $problem->setOrder('normal'); /* defaulting to normal */ $problem->setAuthorId($r['current_user_id']); $problem->setAlias($r['alias']); $problem->setLanguages($r['languages']); $problem->setStackLimit($r['stack_limit']); $problem->setEmailClarifications($r['email_clarifications']); if (file_exists(PROBLEMS_PATH . DIRECTORY_SEPARATOR . $r['alias'])) { throw new DuplicatedEntryInDatabaseException('problemExists'); } $problemDeployer = new ProblemDeployer($r['alias'], ProblemDeployer::CREATE); // Insert new problem try { ProblemsDAO::transBegin(); // Create file after we know that alias is unique $problemDeployer->deploy(); if ($problemDeployer->hasValidator) { $problem->validator = 'custom'; } elseif ($problem->validator == 'custom') { throw new ProblemDeploymentFailedException('problemDeployerValidatorRequired'); } $problem->slow = $problemDeployer->isSlow($problem); // Calculate output limit. $output_limit = $problemDeployer->getOutputLimit(); if ($output_limit != -1) { $problem->setOutputLimit($output_limit); } // Save the contest object with data sent by user to the database ProblemsDAO::save($problem); ProblemsDAO::transEnd(); // Commit at the very end $problemDeployer->commit('Initial commit', $r['current_user']); } catch (ApiException $e) { // Operation failed in something we know it could fail, rollback transaction ProblemsDAO::transRollback(); throw $e; } catch (Exception $e) { self::$log->error('Failed to upload problem'); self::$log->error($e); // Operation failed unexpectedly, rollback transaction ProblemsDAO::transRollback(); // Alias may be duplicated, 1062 error indicates that if (strpos($e->getMessage(), '1062') !== false) { throw new DuplicatedEntryInDatabaseException('problemTitleExists'); } else { throw new InvalidDatabaseOperationException($e); } } finally { $problemDeployer->cleanup(); } // Adding unzipped files to response $result['uploaded_files'] = $problemDeployer->filesToUnzip; $result['status'] = 'ok'; $result['alias'] = $r['alias']; return $result; }