Overview
The submission_controller manages all operations related to code submissions including creating submissions, viewing submission code and results, rejudging, and selecting final submissions.
Constructor
public function __construct()
Applies the following middleware:
auth - Requires user authentication
read_only_archive - Makes controller read-only when app is in archived mode
ip_white_listing - IP whitelist validation
Storage: Uses assignment_root disk for file operations
Listing Methods
index()
public function index($assignment_id = NULL, $user_id = 'all', $problem_id = 'all', $choose = 'all')
Displays a paginated listing of submissions with filtering capabilities.
Assignment ID to filter submissions
User ID to filter, or “all” for all users
Problem ID to filter, or “all” for all problems
Filter type: “all” for all submissions, “final” for final submissions only
Access Control:
- Admin: Can view all submissions
- Head Instructor/Instructor: Can view submissions for their assignments and classes
- Student: Can only view their own submissions
- Practice submissions (assignment_id = 0): Instructors can view their own only
Returns: Paginated view with:
- Submission list with language and user data
- Submission delay relative to assignment finish time
- Submission status and score
- All problems in the assignment
Route: /submissions/assignment/{assignment_id}/user/{user_id}/problem/{problem_id}/view/{choose}
Example from controller:
$submissions = $assignment->submissions();
if (in_array(Auth::user()->role->name, ['student', 'guest'])
|| ($assignment->id == 0 && !in_array(Auth::user()->role->name, ['admin']))) {
$submissions = $submissions->where('user_id', Auth::user()->id);
} else if ($user_id != 'all') {
$submissions = $submissions->where('user_id', intval($user_id));
}
if ($choose == 'final') {
$submissions = $submissions->where('is_final', 1);
}
if ($problem_id != 'all') {
$submissions = $submissions->where('problem_id', intval($problem_id));
}
$submissions = $submissions->with(['language','user'])->latest()->paginate();
Submission Creation
create()
public function create($assignment_id, $problem_id, $old_sub = -1)
Shows the form for creating a new submission.
Optional previous submission ID to load code from
Access Control:
- Calls
_creation_guard_check() to verify:
- Assignment contains the problem
- User can submit to the assignment
- Assignment has started and is open (for students)
- User is a participant
Returns: View with:
- Assignment and problem data
- Last submission code (if exists)
Route: /submissions/create/assignment/{assignment}/problem/{problem}/{oldsub?}
Example from controller:
$last = Submission::where([
'assignment_id' => $assignment_id,
'problem_id' => $problem_id,
'user_id' => Auth::user()->id
]);
if ($old_sub != -1) $last = $last->where(['id'=> $old_sub]);
$last = $last->get()->last();
if ($last != null) {
$submit_path = Submission::get_path($last->user->username, $last->assignment_id, $last->problem_id);
$file_extension = $last->language->extension;
$file_path = $submit_path . "/{$last->file_name}." . $file_extension;
$last_code = file_exists($file_path) ? file_get_contents($file_path) : null;
}
store()
public function store(Request $request)
Stores a newly created submission and adds it to the judging queue.
Assignment ID (must be >= 0)
Language ID to use for submission
Source code text (if submitting via text editor)
Source code file (if submitting via file upload)
Validation Rules:
assignment: integer, greater than -1
problem: integer, greater than 0
Validation Checks:
- File/code size must be under
file_size_limit setting
- User cannot have another submission in queue for same problem
- Language must be enabled for the problem
- User must be able to submit to the assignment
Process:
- Creates submission record with PENDING status
- Saves code to file system
- Increments assignment’s
total_submits counter
- Adds submission to queue for judging
- Triggers queue processing
Returns: Redirect to submissions index for the assignment
Route: /submissions/store/ (POST)
Example from controller:
$submission = new Submission([
'assignment_id' => $assignment->id,
'problem_id' => $problem->id,
'user_id' => Auth::user()->id,
'is_final' => 0,
'status' => 'pending',
'pre_score' => 0,
'coefficient' => $coefficient,
'file_name' => null,
'language_id' => $language->id,
]);
$user_dir = Submission::get_relative_path(Auth::user()->username, $assignment->id, $problem->id);
$this->storage->makeDirectory($user_dir);
if ($code != NULL)
return $this->upload_post_code($code, $user_dir, $submission);
else if ($request->hasFile('userfile'))
return $this->upload_file_code($request, $user_dir, $submission);
Rejudging Methods
rejudge()
public function rejudge(Request $request)
Rejudges a single submission.
Access Control:
- Not available to students and guests
Validation Rules:
Process:
- Checks if submission already in queue
- Sets submission status to PENDING
- Adds to queue with type ‘rejudge’
- Triggers queue processing
Returns: JSON response:
{
"done": 1,
"message": "Optional error message"
}
Route: /submissions/rejudge/ (POST)
rejudge_all_problems_assignment()
public function rejudge_all_problems_assignment(Request $request)
Rejudges all submissions for an assignment or specific problem in an assignment.
Problem ID to rejudge, or “all” for all problems
Access Control:
- Admin, head_instructor, and instructor only
Process:
- Fetches all matching submissions
- Sets all submissions to PENDING status
- Adds all to queue with type ‘rejudge’
- Starts concurrent queue processing
Returns: Redirect back with status message
Route: /submissions/rejudge_all_problems_assignment/ (POST)
Example from controller:
if ($request->problem_id == 'all')
$submissions = Submission::where('assignment_id', $assignment->id)->get();
else
$submissions = Submission::where('assignment_id', $assignment->id)
->where('problem_id', $request->problem_id)->get();
foreach ($submissions as $submission) {
Queue_item::add_not_process($submission->id, 'rejudge');
$submission->status = 'PENDING';
$submission->save();
}
for ($i = 0; $i < Setting::get('concurent_queue_process', 2); $i++) {
Queue_item::work();
}
Viewing Methods
view_code()
public function view_code()
Returns the source code, log, or result file for a submission.
Type of file to view: “code”, “log”, or “result” (via POST)
Access Control:
- Students/guests can only view their own submissions
- Assignment must be open for students
File Types:
code: Source code file with language extension
log: Judge log file (log-)
result: HTML result file (result-.html)
Returns: JSON response:
{
"file_name": "solution.cpp",
"text": "source code content",
"lang": "cpp"
}
Route: /submissions/view_code/ (POST)
Example from controller:
$submit_id = $_POST['submit_id'];
$type = $_POST['type'];
$submission = Submission::with('assignment')->find($submit_id);
$this->_do_access_check($submission);
$submit_path = Submission::get_relative_path($submission->user->username,
$submission->assignment_id, $submission->problem_id);
$file_extension = $submission->language->extension;
if ($type == "code")
$file_path = $submit_path . "/{$submission->file_name}." . $file_extension;
elseif ($type == "log")
$file_path = $submit_path . "/log-{$submission->id}";
elseif ($type == "result")
$file_path = $submit_path . "/result-{$submission->id}.html";
$file_content = $this->storage->exists($file_path)
? $this->storage->get($file_path)
: "File not found";
view_status()
public function view_status()
Returns the current status and score of a submission.
Access Control:
- Students/guests can only view their own submissions
- Assignment must be open for students
Returns: JSON response with submission data including:
- Status and verdict
- Pre-score and final score
- Coefficient applied
- Rendered verdict component
Route: /submissions/view_status/ (POST)
Example from controller:
$submit_id = $_POST['submit_id'];
$submission = Submission::with('assignment')->find($submit_id);
$this->_do_access_check($submission);
$score = ($submission->pre_score *
($all_problems[$submission->problem_id]->pivot->score ?? 100) / 10000);
if ($submission->coefficient == 'error')
$submission->final_score = $score;
else
$submission->final_score = round($score * $submission->coefficient / 100, 0);
$a = new verdict($submission);
$submission->rendered_verdict = $a->resolveView()->with($a->data())->render();
echo json_encode($submission);
Selection Methods
select_final()
public function select_final(Request $request)
Marks a submission as the final submission for scoring.
Submission ID to mark as final
Access Control:
- Students/guests can only select their own submissions
- Assignment must be open for students
Process:
- Unmarks any existing final submission for the same user/assignment/problem
- Marks selected submission as final
- Updates assignment scoreboard
Returns: JSON response:
Route: /submissions/select/ (POST)
Example from controller:
$submission_curr = Submission::find($request->submission);
$this->_do_access_check($submission_curr);
$submission_final = Submission::where([
'user_id' => $submission_curr->user_id,
'assignment_id' => $submission_curr->assignment_id,
'problem_id' => $submission_curr->problem_id,
'is_final' => 1
])->update(['is_final' => 0]);
$submission_curr->is_final = 1;
$submission_curr->save();
Scoreboard::update_scoreboard($submission_curr->assignment_id);
Template Methods
get_template()
public function get_template(Request $request)
Returns the code template for a problem and language.
Validation Rules:
assignment_id: integer
problem_id: integer
language_id: integer
Template Format:
Templates are parsed for three sections:
- Banned keywords - Between
/*###Begin banned and ###End banned keyword*/
- Before code - Between banned section and
//###INSERT CODE HERE
- After code - After
//###INSERT CODE HERE
Returns: JSON response:
{
"banned": "banned keywords text",
"before": "code before insertion point",
"after": "code after insertion point",
"full": "full template"
}
If no template exists, all fields return empty strings.
Route: /submissions/get_template/ (POST)
Example from controller:
$problem = $this->_creation_guard_check($request->input('assignment_id'),
$request->input('problem_id'));
$template = $problem->template_content($request->input('language_id'));
if ($template === NULL) {
$result = array('banned' => '', 'before' => '', 'after' => '', 'full' => '');
} else {
preg_match(
"/(\/\*###Begin banned.*\n)((.*\n)*)(###End banned keyword\*\/)/",
$template, $matches
);
$banned = $matches[2] ?? "";
preg_match(
"/(###End banned keyword\*\/\n)((.*\n)*)\/\/###INSERT CODE HERE -\n?((.*\n?)*)/",
$template, $matches
);
$before = $matches[2] ?? "";
$after = $matches[4] ?? "";
$result = array(
'banned' => $banned,
'before' => $before,
'after' => $after,
'full' => $template
);
}
File Storage
Submission Path Structure
assignments_root/
└── assignment_{assignment_id}/
└── problem_{problem_id}/
└── {username}/
├── solution-upload-count{N}.{ext}
├── solution-editcode-count{N}.{ext}
├── log-{submission_id}
└── result-{submission_id}.html
File Naming
- Upload submissions:
solution-upload-count{N}.{ext} where N is assignment’s total_submits
- Code editor submissions:
solution-editcode-count{N}.{ext}
- Log files:
log-{submission_id}
- Result files:
result-{submission_id}.html
Submission Lifecycle
- Creation - User submits code via file or text editor
- Validation - System checks permissions, size limits, queue status
- Storage - Code saved to filesystem with unique filename
- Queuing - Submission added to queue with type ‘judge’
- Processing - Queue worker picks up submission and runs tests
- Scoring - Results written to log and result files, score calculated
- Selection - User can select which submission counts as final
Score Calculation
$score = ($submission->pre_score * $problem->pivot->score) / 10000;
$submission->final_score = round($score * $submission->coefficient / 100, 0);
Where:
pre_score: Raw score from judge (0-10000 scale)
pivot->score: Problem’s weight in assignment
coefficient: Time-based penalty coefficient (0-100)
final_score: Final score for scoreboard
- Submission: Main model for submissions
- Assignment: Assignment being submitted to
- Problem: Problem being solved
- Language: Programming language used
- Queue_item: Queue management for judging
- Scoreboard: Assignment scoreboard data
- User: Submission author