/** * 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; }
/** * 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; }