public function testProblemArenaAndSubmbit() { // Login $contestant = $this->createUserAndLogin(); // Create a problem $problemData = ProblemsFactory::createProblem(); // Click in Problems $this->clickAndWait('link=Problemas'); // Click in Problem $problemData $this->waitForElementPresent('//*[@id="problems_list"]/table/tbody/tr[2]/td/a'); $this->clickAndWait('link=' . $problemData['request']['title']); // Check that arena contains the title $this->waitForElementPresent('//*[@id="problem"]/h1'); $this->assertElementContainsText('//*[@id="problem"]/h1', $problemData['request']['title']); // Click in New run $this->click('link=Nuevo envío'); $this->waitForElementPresent('//*[@id="lang-select"]'); // Write some code and submit $this->select('name=language', 'label=C++'); $this->type('code', 'Code lol'); $this->click('//*[@id="submit"]/input'); // Get run ID sleep(1); $runs = ProblemController::apiRuns(new Request(array('problem_alias' => $problemData['request']['alias'], 'auth_token' => OmegaupTestCase::login($contestant)))); // Wait for submit history to show $this->waitForElementPresent('//*[@id="run_' . $runs['runs'][0]['guid'] . '"]/td[2]'); }
/** * Test apiBestScore for submits in a problem for other user */ public function testBestScoreInProblemOtherUser() { // Create problem $problemData = ProblemsFactory::createProblem(); // Create contestant $contestant = UserFactory::createUser(); // Create user who will use the API $user = UserFactory::createUser(); // Create 2 runs, 100 and 50. $runData = RunsFactory::createRunToProblem($problemData, $contestant); $runDataPA = RunsFactory::createRunToProblem($problemData, $contestant); RunsFactory::gradeRun($runData); RunsFactory::gradeRun($runDataPA, 0.5, 'PA'); // Call API $response = ProblemController::apiBestScore(new Request(array('auth_token' => $this->login($user), 'problem_alias' => $problemData['request']['alias'], 'username' => $contestant->getUsername()))); $this->assertEquals(100.0, $response['score']); }
/** * Test apiBestScore for submits in a problem for other user */ public function testBestScoreInProblemOtherUser() { // Create problem $problemData = ProblemsFactory::createProblem(); // Create contestant $contestant = UserFactory::createUser(); // Create user who will use the API $user = UserFactory::createUser(); // Create 2 runs, 100 and 50. $runData = RunsFactory::createRunToProblem($problemData, $contestant); $runDataPA = RunsFactory::createRunToProblem($problemData, $contestant); RunsFactory::gradeRun($runData); RunsFactory::gradeRun($runDataPA, 0.5, "PA"); // Call API $response = ProblemController::apiBestScore(new Request(array("auth_token" => $this->login($user), "problem_alias" => $problemData["request"]["alias"], "username" => $contestant->getUsername()))); $this->assertEquals(100.0, $response["score"]); }
/** * Check stats are ok for WA, AC, PA and total counts * Also validates the max wait time guid */ public function testGetStats() { // Get a problem $problemData = ProblemsFactory::createProblem(); // Get a contest $contestData = ContestsFactory::createContest(); // Add the problem to the contest ContestsFactory::addProblemToContest($problemData, $contestData); // Create our contestant $contestant = UserFactory::createUser(); // Create some runs to be pending $pendingRunsCount = 5; $pendingRunsData = array(); for ($i = 0; $i < $pendingRunsCount; $i++) { $pendingRunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant); } $ACRunsCount = 2; $ACRunsData = array(); for ($i = 0; $i < $ACRunsCount; $i++) { $ACRunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant); // Grade the run RunsFactory::gradeRun($ACRunsData[$i]); } $WARunsCount = 1; $WARunsData = array(); for ($i = 0; $i < $WARunsCount; $i++) { $WARunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant); // Grade the run with WA RunsFactory::gradeRun($WARunsData[$i], 0, "WA"); } // Create request $r = new Request(); $r["problem_alias"] = $problemData["request"]["alias"]; $r["auth_token"] = $this->login($problemData["author"]); // Call API $response = ProblemController::apiStats($r); // Check number of pending runs $this->assertEquals(count($pendingRunsData), count($response["pending_runs"])); $this->assertEquals(count($ACRunsData), $response["verdict_counts"]["AC"]); $this->assertEquals(count($WARunsData), $response["verdict_counts"]["WA"]); $this->assertEquals($pendingRunsCount + $ACRunsCount + $WARunsCount, $response["total_runs"]); }
/** * Best score is returned, problem inside a contest */ public function testScoreInDetailsInsideContest() { // Create problem and contest $problemData = ProblemsFactory::createProblem(); $contestData = ContestsFactory::createContest(); ContestsFactory::addProblemToContest($problemData, $contestData); // Create contestant $contestant = UserFactory::createUser(); // Create 2 runs, 100 and 50. $runDataOutsideContest = RunsFactory::createRunToProblem($problemData, $contestant); $runDataInsideContest = RunsFactory::createRun($problemData, $contestData, $contestant); RunsFactory::gradeRun($runDataOutsideContest); RunsFactory::gradeRun($runDataInsideContest, 0.5, "PA"); // Call API $response = ProblemController::apiDetails(new Request(array("auth_token" => $this->login($contestant), "problem_alias" => $problemData["request"]["alias"], "contest_alias" => $contestData["request"]["alias"]))); $this->assertEquals(50.0, $response["score"]); }
<?php require_once '../../server/bootstrap.php'; $r = new Request($_REQUEST); $session = SessionController::apiCurrentSession($r); $r['statement_type'] = 'html'; $r['show_solvers'] = true; try { $result = ProblemController::apiDetails($r); $problem = ProblemsDAO::GetByAlias($result['alias']); } catch (ApiException $e) { header('HTTP/1.1 404 Not Found'); die(file_get_contents('../404.html')); } $smarty->assign('problem_statement', $result['problem_statement']); $smarty->assign('problem_statement_language', $result['problem_statement_language']); $smarty->assign('problem_alias', $result['alias']); $smarty->assign('public', $result['public']); $smarty->assign('source', $result['source']); $smarty->assign('title', $result['title']); $smarty->assign('points', $result['points']); $smarty->assign('validator', $result['validator']); $smarty->assign('time_limit', $result['time_limit'] / 1000 . 's'); $smarty->assign('validator_time_limit', $result['validator_time_limit'] / 1000 . 's'); $smarty->assign('overall_wall_time_limit', $result['overall_wall_time_limit'] / 1000 . 's'); $smarty->assign('memory_limit', $result['memory_limit'] / 1024 . 'MB'); $smarty->assign('solvers', $result['solvers']); $smarty->assign('karel_problem', count(array_intersect(explode(',', $result['languages']), array('kp', 'kj'))) == 2); if (isset($result['sample_input'])) { $smarty->assign('sample_input', $result['sample_input']); }
/** * Generates a CSV for contest report * * @param Request $r * @return array */ public static function apiCsvReport(Request $r) { self::authenticateRequest($r); self::validateStats($r); // Get full Report API of the contest $reportRequest = new Request(array("contest_alias" => $r["contest_alias"], "auth_token" => $r["auth_token"])); $contestReport = self::apiReport($reportRequest); // Get problem stats for each contest problem so we can // have the full list of cases $problemStats = array(); $i = 0; foreach ($contestReport["problems"] as $entry) { $problem_alias = $entry["alias"]; $problemStatsRequest = new Request(array("problem_alias" => $problem_alias, "auth_token" => $r["auth_token"])); $problemStats[$i] = ProblemController::apiStats($problemStatsRequest); $problemStats[$problem_alias] = $problemStats[$i]; $i++; } // Build a csv $csvData = array(); // Build titles $csvRow = array(); $csvRow[] = "username"; foreach ($contestReport["problems"] as $entry) { foreach ($problemStats[$entry["alias"]]["cases_stats"] as $caseName => $counts) { $csvRow[] = $caseName; } $csvRow[] = $entry["alias"] . " total"; } $csvRow[] = "total"; $csvData[] = $csvRow; foreach ($contestReport["ranking"] as $userData) { if ($userData === "ok") { continue; } $csvRow = array(); $csvRow[] = $userData["username"]; foreach ($userData["problems"] as $key => $problemData) { // If the user don't have these details then he didn't submit, // we need to fill the report with 0s for completeness if (!isset($problemData["run_details"]["cases"]) || count($problemData["run_details"]["cases"]) === 0) { for ($i = 0; $i < count($problemStats[$key]["cases_stats"]); $i++) { $csvRow[] = '0'; } // And adding the total for this problem $csvRow[] = '0'; } else { // for each case foreach ($problemData["run_details"]["cases"] as $caseData) { // If case is correct if (strcmp($caseData["meta"]["status"], "OK") === 0 && strcmp($caseData["out_diff"], "") === 0) { $csvRow[] = '1'; } else { $csvRow[] = '0'; } } $csvRow[] = $problemData["points"]; } } $csvRow[] = $userData["total"]["points"]; $csvData[] = $csvRow; } // Set headers to auto-download file header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); header("Content-Disposition: attachment;filename=" . $r["contest_alias"] . "_report.csv"); header("Content-Transfer-Encoding: binary"); // Write contents to a csv raw string // TODO(https://github.com/omegaup/omegaup/issues/628): Escape = to prevent applications from inadvertently executing code // http://contextis.co.uk/blog/comma-separated-vulnerabilities/ $out = fopen('php://output', 'w'); foreach ($csvData as $csvRow) { fputcsv($out, ContestController::escapeCsv($csvRow)); } fclose($out); // X_X die; }
<?php require_once "../server/bootstrap.php"; $r = new Request(); $mode = isset($_GET['mode']) ? $_GET['mode'] : 'asc'; $page = isset($_GET['page']) ? intval($_GET['page']) : 1; $order_by = isset($_GET['order_by']) ? $_GET['order_by'] : 'title'; $r['page'] = $page; $r['order_by'] = $order_by; $r['mode'] = $mode; if (!empty($_GET['tag'])) { $r['tag'] = $_GET['tag']; } $keyword = ''; if (!empty($_GET['query']) && strlen($_GET['query']) > 0) { $keyword = substr($_GET['query'], 0, 256); $r['query'] = $keyword; } $response = ProblemController::apiList($r); $params = array('query' => $keyword, 'order_by' => $order_by, 'mode' => $mode); if (!empty($_GET['tag'])) { $params['tag'] = $_GET['tag']; } $pager_items = Pager::paginate($response['total'], $page, '/problem/list/', 5, $params); $smarty->assign('KEYWORD', $keyword); $smarty->assign('MODE', $mode); $smarty->assign('ORDER_BY', $order_by); $smarty->assign('problems', $response['results']); $smarty->assign('pager_items', $pager_items); $smarty->display('../templates/problems.tpl');
/** * Basic test for uploadin problem missing outputs * * @expectedException InvalidParameterException */ public function testCreateProblemMissingOutput() { // Get the problem data $problemData = ProblemsFactory::getRequest(OMEGAUP_RESOURCES_ROOT . 'missingout.zip'); $r = $problemData['request']; $problemAuthor = $problemData['author']; // Login user $r['auth_token'] = $this->login($problemAuthor); // Get File Uploader Mock and tell Omegaup API to use it FileHandler::SetFileUploader($this->createFileUploaderMock()); // Call the API $response = ProblemController::apiCreate($r); }
/** * Check that user in private list can view private contest */ public function testNoPrivilegeEscalationOccurs() { // Get a contest $contestData = ContestsFactory::createContest(null, 0); // Get some problems into the contest $numOfProblems = 3; $problems = $this->insertProblemsInContest($contestData, $numOfProblems); // Get a user for our scenario $contestant = UserFactory::createUser(); // Prepare our request $r = new Request(array('auth_token' => $this->login($contestant), 'contest_alias' => $contestData['request']['alias'])); // Call api. This should fail. try { ContestController::apiDetails($r); $this->assertTrue(false, 'User with no access could see the contest'); } catch (ForbiddenAccessException $e) { // Pass } // Get details from a problem in that contest. This should also fail. try { $problem_request = new Request(array('auth_token' => $this->login($contestant), 'contest_alias' => $contestData['request']['alias'], 'problem_alias' => $problems[0]['request']['alias'])); ProblemController::apiDetails($problem_request); $this->assertTrue(false, 'User with no access could see the problem'); } catch (ForbiddenAccessException $e) { // Pass } // Call api again. This should (still) fail. try { $response = ContestController::apiDetails($r); $this->assertTrue(false, 'User with no access could see the contest'); } catch (ForbiddenAccessException $e) { // Pass } }
/** * Tests problem admins list API */ public function testProblemAdmins() { // Get a problem $problemData = ProblemsFactory::createProblem(); // Create our new admin $problemAdmin = UserFactory::createUser(); // Add admin to the problem $response = ProblemController::apiAddAdmin(new Request(array('usernameOrEmail' => $problemAdmin->username, 'problem_alias' => $problemData['request']['alias'], 'auth_token' => $this->login($problemData['author'])))); $this->assertEquals('ok', $response['status']); // Get the list of admins $response = ProblemController::apiAdmins(new Request(array('problem_alias' => $problemData['request']['alias'], 'auth_token' => $this->login($problemData['author'])))); $adminFound = false; $authorFound = false; foreach ($response['admins'] as $adminEntry) { if ($adminEntry['username'] == $problemAdmin->username) { $adminFound = true; } if ($adminEntry['username'] == $problemData['author']->username) { $authorFound = true; } } $this->assertTrue($adminFound); $this->assertTrue($authorFound); }
/** * Tests problem admins list API */ public function testProblemAdmins() { // Get a problem $problemData = ProblemsFactory::createProblem(); // Create our new admin $problemAdmin = UserFactory::createUser(); // Add admin to the problem $response = ProblemController::apiAddAdmin(new Request(array("usernameOrEmail" => $problemAdmin->username, "problem_alias" => $problemData["request"]["alias"], "auth_token" => $this->login($problemData["author"])))); $this->assertEquals("ok", $response["status"]); // Get the list of admins $response = ProblemController::apiAdmins(new Request(array("problem_alias" => $problemData["request"]["alias"], "auth_token" => $this->login($problemData["author"])))); $adminFound = false; $authorFound = false; foreach ($response["admins"] as $adminEntry) { if ($adminEntry["username"] == $problemAdmin->username) { $adminFound = true; } if ($adminEntry["username"] == $problemData["author"]->username) { $authorFound = true; } } $this->assertTrue($adminFound); $this->assertTrue($authorFound); }
$app->post('/dashboard/permissions', function () { fAuthorization::requireLoggedIn(); $controller = new DashboardController(); $controller->managePermission(fRequest::get('action', 'string')); }); $app->post('/set/variable', function () { fAuthorization::requireLoggedIn(); $controller = new DashboardController(); $controller->setVariable(); }); $app->get('/problem', function () { $controller = new ProblemController(); $controller->show(fRequest::get('id', 'integer')); }); $app->get('/problem/:id', function ($id) { $controller = new ProblemController(); $controller->show($id); }); $app->get('/record', function () { fAuthorization::requireLoggedIn(); User::requireEmailVerified(); $controller = new RecordController(); $controller->show(fRequest::get('id', 'integer')); }); $app->get('/record/:id', function ($id) { fAuthorization::requireLoggedIn(); User::requireEmailVerified(); $controller = new RecordController(); $controller->show($id); }); $app->get('/report', function () {
/** * Test 'page', 'order_by' and 'mode' parametes of the apiList() method, and search by title. */ public function testProblemListPager() { // Create a user and some problems with submissions for the tests. $contestant = UserFactory::createUser(); for ($i = 0; $i < 6; $i++) { $problemData[$i] = ProblemsFactory::createProblem(null, null, 1); $runs = $i / 2; for ($r = 0; $r < $runs; $r++) { $runData = RunsFactory::createRunToProblem($problemData[$i], $contestant); $points = rand(0, 100); $verdict = 'WA'; if ($points > 0) { $verdict = $points == 100 ? 'AC' : 'PA'; } RunsFactory::gradeRun($runData, $points / 100, $verdict); } } $request = new Request(); $request['auth_token'] = $this->login($contestant); $response = ProblemController::apiList($request); // Test search by title $titles = array(); foreach ($response['results'] as $problem) { array_push($titles, $problem['title']); } foreach ($titles as $title) { $request['query'] = $title; $response = ProblemController::apiList($request); $this->assertTrue(count($response['results']) == 1); $this->assertTrue($title === $response['results'][0]['title']); } $request['query'] = null; $response = ProblemController::apiList($request); $total = $response['total']; $pages = intval(($total + PROBLEMS_PER_PAGE - 1) / PROBLEMS_PER_PAGE); // The following tests will try the different scenarios that can occur // with the additions of the three features to apiList(), that is, paging, // order by column and order mode: Call apiList() with and without // pagination, for each allowed ordering and each possible order mode. $modes = array('asc', 'desc'); $columns = array('title', 'submissions', 'accepted', 'ratio', 'points', 'score'); $counter = 0; for ($paging = 0; $paging <= 1; $paging++) { foreach ($columns as $col) { foreach ($modes as $mode) { $first = null; $last = null; $request['mode'] = $mode; $request['order_by'] = $col; if ($paging == 1) { // Clear offset and rowcount if set. if (isset($request['offset'])) { unset($request['offset']); } if (isset($request['rowcount'])) { unset($request['rowcount']); } $request['page'] = 1; $response = ProblemController::apiList($request); $first = $response['results']; $request['page'] = $pages; $response = ProblemController::apiList($request); $last = $response['results']; // Test number of problems per page $this->assertEquals(PROBLEMS_PER_PAGE, count($first)); } else { $request['page'] = null; $response = ProblemController::apiList($request); $first = $response['results']; $last = $first; } $i = 0; $j = count($last) - 1; if ($col === 'title') { $comp = strcmp($first[$i]['title'], $last[$j]['title']); if ($mode === 'asc') { $this->assertTrue($comp <= 0); } else { $this->assertTrue($comp >= 0); } } else { if ($mode === 'asc') { $this->assertTrue($first[$i][$col] <= $last[$j][$col]); } else { $this->assertTrue($first[$i][$col] >= $last[$j][$col]); } } } } } }
/** * */ public static function createProblem($zipName = null, $title = null, $public = 1, Users $author = null, $languages = null) { if (is_null($zipName)) { $zipName = OMEGAUP_RESOURCES_ROOT . 'testproblem.zip'; } // Get a user $problemData = self::getRequest($zipName, $title, $public, $author, $languages); $r = $problemData["request"]; $problemAuthor = $problemData["author"]; // Login user $r["auth_token"] = OmegaupTestCase::login($problemAuthor); // Get File Uploader Mock and tell Omegaup API to use it FileHandler::SetFileUploader(new FileUploaderMock()); // Call the API ProblemController::apiCreate($r); // Clean up our mess unset($_REQUEST); return array("request" => $r, "author" => $problemAuthor); }
/** * Detours the Grader calls. * Problem: Submiting a new run invokes the Grader::grade() function which makes * a HTTP call to official grader using CURL. This call will fail if grader is * not turned on. We are not testing the Grader functionallity itself, we are * only validating that we populate the DB correctly and that we make a call * to the function Grader::grade(), without executing the contents. * * Solution: We create a phpunit mock of the Grader class. We create a fake * object Grader with the function grade() which will always return true * and expects to be excecuted once. * */ public function detourGraderCalls($times = null) { if (is_null($times)) { $times = $this->once(); } // Create a fake Grader object which will always return true (see // next line) $graderMock = $this->getMock('Grader', array('Grade')); // Set expectations: $graderMock->expects($times)->method('Grade')->will($this->returnValue(true)); // Detour all Grader::grade() calls to our mock RunController::$grader = $graderMock; ProblemController::$grader = $graderMock; }
/** * Entry point for Problem Details API * * @param Request $r * @throws InvalidFilesystemOperationException * @throws InvalidDatabaseOperationException */ public static function apiDetails(Request $r) { // Get user. // Allow unauthenticated requests if we are not openning a problem // inside a contest. try { self::authenticateRequest($r); } catch (UnauthorizedException $e) { if (!is_null($r['contest_alias'])) { throw $e; } } // Validate request self::validateDetails($r); $response = array(); // Create array of relevant columns $relevant_columns = array('title', 'alias', 'validator', 'time_limit', 'validator_time_limit', 'overall_wall_time_limit', 'extra_wall_time', 'memory_limit', 'output_limit', 'visits', 'submissions', 'accepted', 'difficulty', 'creation_date', 'source', 'order', 'points', 'public', 'languages', 'slow', 'stack_limit', 'email_clarifications'); // Read the file that contains the source if (!ProblemController::isLanguageSupportedForProblem($r)) { // If there is no language file for the problem, return the spanish version. $r['lang'] = 'es'; } $statement_type = ProblemController::getStatementType($r); Cache::getFromCacheOrSet(Cache::PROBLEM_STATEMENT, $r['problem']->getAlias() . '-' . $r['lang'] . '-' . $statement_type, $r, 'ProblemController::getProblemStatement', $file_content, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); // Add problem statement to source $response['problem_statement'] = $file_content; $response['problem_statement_language'] = $r['lang']; // Add the example input. $sample_input = null; Cache::getFromCacheOrSet(Cache::PROBLEM_SAMPLE, $r['problem']->getAlias() . '-sample.in', $r, 'ProblemController::getSampleInput', $sample_input, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); if (!empty($sample_input)) { $response['sample_input'] = $sample_input; } // Add the problem the response $response = array_merge($response, $r['problem']->asFilteredArray($relevant_columns)); // If the problem is public or if the user has admin privileges, show the // problem source and alias of owner. if ($r['problem']->public || Authorization::IsProblemAdmin($r['current_user_id'], $r['problem'])) { $problemsetter = UsersDAO::getByPK($r['problem']->author_id); if (!is_null($problemsetter)) { $response['problemsetter'] = array('username' => $problemsetter->username, 'name' => is_null($problemsetter->name) ? $problemsetter->username : $problemsetter->name); } } else { unset($response['source']); } if (!is_null($r['current_user_id'])) { // Create array of relevant columns for list of runs $relevant_columns = array('guid', 'language', 'status', 'verdict', 'runtime', 'penalty', 'memory', 'score', 'contest_score', 'time', 'submit_delay'); // Search the relevant runs from the DB $contest = ContestsDAO::getByAlias($r['contest_alias']); $keyrun = new Runs(array('user_id' => $r['current_user_id'], 'problem_id' => $r['problem']->getProblemId(), 'contest_id' => is_null($r['contest']) ? null : $r['contest']->getContestId())); // Get all the available runs done by the current_user try { $runs_array = RunsDAO::search($keyrun); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // Add each filtered run to an array if (count($runs_array) >= 0) { $runs_filtered_array = array(); foreach ($runs_array as $run) { $filtered = $run->asFilteredArray($relevant_columns); $filtered['alias'] = $r['problem']->alias; $filtered['username'] = $r['current_user']->username; $filtered['time'] = strtotime($filtered['time']); array_push($runs_filtered_array, $filtered); } } $response['runs'] = $runs_filtered_array; } if (!is_null($r['contest'])) { // At this point, contestant_user relationship should be established. try { ContestsUsersDAO::CheckAndSaveFirstTimeAccess($r['current_user_id'], $r['contest']->contest_id); } catch (ApiException $e) { throw $e; } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // As last step, register the problem as opened if (!ContestProblemOpenedDAO::getByPK($r['contest']->getContestId(), $r['problem']->getProblemId(), $r['current_user_id'])) { //Create temp object $keyContestProblemOpened = new ContestProblemOpened(array('contest_id' => $r['contest']->getContestId(), 'problem_id' => $r['problem']->getProblemId(), 'user_id' => $r['current_user_id'])); try { // Save object in the DB ContestProblemOpenedDAO::save($keyContestProblemOpened); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } } } elseif (isset($r['show_solvers']) && $r['show_solvers']) { $response['solvers'] = RunsDAO::GetBestSolvingRunsForProblem($r['problem']->problem_id); } if (!is_null($r['current_user_id'])) { ProblemViewedDAO::MarkProblemViewed($r['current_user_id'], $r['problem']->problem_id); } $response['score'] = self::bestScore($r); $response['status'] = 'ok'; return $response; }
public static function openProblemInContest($contestData, $problemData, $user) { // Prepare our request $r = new Request(); $r['contest_alias'] = $contestData['request']['alias']; $r['problem_alias'] = $problemData['request']['alias']; // Log in the user $r['auth_token'] = OmegaupTestCase::login($user); // Call api ProblemController::apiDetails($r); unset($_REQUEST); }
/** * Entry point for Problem Details API * * @param Request $r * @throws InvalidFilesystemOperationException * @throws InvalidDatabaseOperationException */ public static function apiDetails(Request $r) { // Get user. // Allow unauthenticated requests if we are not openning a problem // inside a contest. try { self::authenticateRequest($r); } catch (ForbiddenAccessException $e) { if (!is_null($r["contest_alias"])) { throw $e; } } // Validate request self::validateDetails($r); $response = array(); // Create array of relevant columns $relevant_columns = array("title", "author_id", "alias", "validator", "time_limit", "validator_time_limit", "overall_wall_time_limit", "extra_wall_time", "memory_limit", "output_limit", "visits", "submissions", "accepted", "difficulty", "creation_date", "source", "order", "points", "public", "languages", "slow", "stack_limit", "email_clarifications"); // Read the file that contains the source if (!ProblemController::isLanguageSupportedForProblem($r)) { // If there is no language file for the problem, return the spanish version. $r['lang'] = 'es'; } $statement_type = ProblemController::getStatementType($r); Cache::getFromCacheOrSet(Cache::PROBLEM_STATEMENT, $r["problem"]->getAlias() . "-" . $r["lang"] . "-" . $statement_type, $r, 'ProblemController::getProblemStatement', $file_content, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); // Add problem statement to source $response["problem_statement"] = $file_content; $response["problem_statement_language"] = $r['lang']; // Add the example input. $sample_input = null; Cache::getFromCacheOrSet(Cache::PROBLEM_SAMPLE, $r["problem"]->getAlias() . "-sample.in", $r, 'ProblemController::getSampleInput', $sample_input, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); if (!empty($sample_input)) { $response['sample_input'] = $sample_input; } // Add the problem the response $response = array_merge($response, $r["problem"]->asFilteredArray($relevant_columns)); if (!is_null($r['current_user_id'])) { // Create array of relevant columns for list of runs $relevant_columns = array("guid", "language", "status", "verdict", "runtime", "penalty", "memory", "score", "contest_score", "time", "submit_delay"); // Search the relevant runs from the DB $contest = ContestsDAO::getByAlias($r["contest_alias"]); $keyrun = new Runs(array("user_id" => $r["current_user_id"], "problem_id" => $r["problem"]->getProblemId(), "contest_id" => is_null($r["contest"]) ? null : $r["contest"]->getContestId())); // Get all the available runs done by the current_user try { $runs_array = RunsDAO::search($keyrun); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // Add each filtered run to an array if (count($runs_array) >= 0) { $runs_filtered_array = array(); foreach ($runs_array as $run) { $filtered = $run->asFilteredArray($relevant_columns); $filtered['time'] = strtotime($filtered['time']); array_push($runs_filtered_array, $filtered); } } $response["runs"] = $runs_filtered_array; } if (!is_null($r["contest"])) { // At this point, contestant_user relationship should be established. try { $contest_user = ContestsUsersDAO::CheckAndSaveFirstTimeAccess($r["current_user_id"], $r["contest"]->getContestId()); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // As last step, register the problem as opened if (!ContestProblemOpenedDAO::getByPK($r["contest"]->getContestId(), $r["problem"]->getProblemId(), $r["current_user_id"])) { //Create temp object $keyContestProblemOpened = new ContestProblemOpened(array("contest_id" => $r["contest"]->getContestId(), "problem_id" => $r["problem"]->getProblemId(), "user_id" => $r["current_user_id"])); try { // Save object in the DB ContestProblemOpenedDAO::save($keyContestProblemOpened); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } } } else { if (isset($r['show_solvers']) && $r['show_solvers']) { $response['solvers'] = RunsDAO::GetBestSolvingRunsForProblem($r['problem']->problem_id); } } if (!is_null($r['current_user_id'])) { ProblemViewedDAO::MarkProblemViewed($r['current_user_id'], $r['problem']->problem_id); } $response["score"] = self::bestScore($r); $response["status"] = "ok"; return $response; }