Skip to main content

Overview

The Submission model represents a single code submission by a user to a problem in an assignment. It stores the submission metadata, judging results, and final score calculations.

Traits

use Prunable, HasFactory;
  • Prunable: Automatically removes submissions for deleted users
  • HasFactory: Enables factory pattern for testing

Fillable Fields

id
integer
Unique identifier for the submission
user_id
integer
required
ID of the user who made the submission
assignment_id
integer
required
ID of the assignment (0 for practice submissions)
problem_id
integer
required
ID of the problem being solved
is_final
boolean
default:"false"
Whether this submission is counted for final scoringOnly one submission per user-problem pair should have is_final = 1
time
float
Execution time in seconds (maximum across all test cases)
status
string
Submission status: ‘Pending’, ‘Judging’, ‘Done’, ‘Failed’
pre_score
integer
default:"0"
Raw score before applying coefficient (0-10000, where 10000 = 100%)Calculated based on test cases passed
coefficient
string|float
Late submission penalty coefficient (0-100) or “error” if calculation failedFinal score = (pre_score * problem_score / 10000) * (coefficient / 100)
file_name
string
required
Name of the submitted source code file
language_id
integer
required
ID of the programming language used
judgement
object
Detailed judging results parsed from result HTMLCast: objectStructure:
{
  "times": [0.01, 0.02, 0.01],
  "mems": [1024, 1536, 1280],
  "verdicts": {
    "Correct": 3,
    "Wrong Answer": 1
  }
}

Casts

protected $casts = [
    'judgement' => 'object'
];

Relationships

user()

user
BelongsTo<User>
The user who made this submission
$submission->user // Returns User model

assignment()

assignment
BelongsTo<Assignment>
The assignment this submission belongs to
$submission->assignment // Returns Assignment model

problem()

problem
BelongsTo<Problem>
The problem being solved
$submission->problem // Returns Problem model

language()

language
BelongsTo<Language>
The programming language used for this submission
$submission->language // Returns Language model

Public Methods

get_path()

Static method to get the filesystem path for a user’s submissions.
public static function get_path($username, $assignment_id, $problem_id)
Parameters:
  • $username (string) - Username
  • $assignment_id (integer) - Assignment ID
  • $problem_id (integer) - Problem ID
Returns: string - Absolute path to submission directory Example:
$path = Submission::get_path('john_doe', 5, 10);
// Returns: '/var/www/assignments/assignment_5/problem_10/john_doe'

get_relative_path()

Static method to get the relative path for a user’s submissions.
public static function get_relative_path($username, $assignment_id, $problem_id)
Parameters:
  • $username (string) - Username
  • $assignment_id (integer) - Assignment ID
  • $problem_id (integer) - Problem ID
Returns: string - Relative path from assignments root Example:
$path = Submission::get_relative_path('john_doe', 5, 10);
// Returns: '/assignment_5/problem_10/john_doe'

directory()

Gets the filesystem directory for this submission.
public function directory()
Returns: string - Absolute path to submission directory Example:
$dir = $submission->directory();
// Returns: '/var/www/assignments/assignment_5/problem_10/john_doe'
Directory contents:
assignment_{id}/problem_{id}/{username}/
  ├── {file_name}              # Submitted source code
  ├── result-{submission_id}.html  # Judging results
  ├── compile-{submission_id}.txt  # Compilation output
  └── exec/                    # Execution files (temporary)

get_judgement_from_result_html()

Parses the result HTML file to extract judging details.
public function get_judgement_from_result_html()
Returns: array with keys:
  • times (array) - Execution time for each test case (seconds)
  • mems (array) - Memory usage for each test case (KiB)
  • verdicts (array) - Count of each verdict type
Example:
$judgement = $submission->get_judgement_from_result_html();

print_r($judgement);
// Output:
// [
//   'times' => [0.01, 0.02, 0.015, 0.012],
//   'mems' => [1024, 1536, 1280, 1152],
//   'verdicts' => [
//     'Correct' => 3,
//     'Wrong Answer' => 1
//   ]
// ]
Verdict types:
  • Correct - Output matches expected
  • Wrong Answer - Output doesn’t match
  • Time Limit Exceeded - Execution took too long
  • Runtime Error - Program crashed
  • Compilation Error - Code didn’t compile
  • Memory Limit Exceeded - Used too much memory

get_final_submissions()

Static method to retrieve final submissions for an assignment.
public static function get_final_submissions($assignment_id)
Parameters:
  • $assignment_id (integer) - Assignment ID
Returns: Collection - Submissions with user information Access control:
  • Admin/instructors: See all final submissions
  • Students: See only their own final submissions
Example:
$finals = Submission::get_final_submissions(5);

foreach ($finals as $sub) {
    echo "{$sub->username}: Problem {$sub->problem_id} - Score {$sub->pre_score}\n";
}
Columns returned:
  • All submissions table columns
  • username from joined users table
Ordering:
  • First by username (ascending)
  • Then by problem_id (ascending)

prunable()

Defines the query for pruning orphaned submissions.
public function prunable()
Returns: Builder - Query for submissions without associated users Usage:
// Run automatically or via command
php artisan model:prune

Scoring Calculation

Submission scores are calculated in multiple steps:

1. Pre-Score (0-10000)

// Based on test cases passed
$pre_score = (passed_tests / total_tests) * 10000;

2. Problem Score

// Get problem's score from assignment pivot
$problem_score = $assignment->problems()->find($problem_id)->pivot->score;

// Calculate points earned
$points = ceil(($pre_score * $problem_score) / 10000);

3. Apply Coefficient (Late Penalty)

if ($submission->coefficient === 'error') {
    $final_score = 0;
} else {
    $final_score = ceil($points * ($submission->coefficient / 100));
}

Example

// Submission passed 8 out of 10 test cases
$pre_score = 8000; // (8/10) * 10000

// Problem worth 100 points in assignment
$problem_score = 100;
$points = ceil((8000 * 100) / 10000); // 80 points

// Submitted 1 hour late, coefficient = 80%
$coefficient = 80;
$final_score = ceil(80 * (80 / 100)); // 64 points

File Structure

Each submission creates files in the filesystem:
# Submission directory
/var/www/assignments/assignment_5/problem_10/john_doe/

# Files created:
submission_123.cpp              # Source code
result-123.html                 # Formatted judge results
compile-123.txt                 # Compiler output
exec-123                        # Compiled executable (temp)

Example Usage

// Create a submission
$submission = Submission::create([
    'user_id' => auth()->id(),
    'assignment_id' => 5,
    'problem_id' => 10,
    'is_final' => 0,
    'status' => 'Pending',
    'pre_score' => 0,
    'coefficient' => $assignment->eval_coefficient(),
    'file_name' => 'solution.cpp',
    'language_id' => 1,
]);

// After judging, update results
$judgement = $submission->get_judgement_from_result_html();
$submission->update([
    'status' => 'Done',
    'pre_score' => 8500, // 85% test cases passed
    'judgement' => $judgement,
    'time' => max($judgement['times']),
]);

// Get final submissions for scoreboard
$finals = Submission::get_final_submissions($assignmentId);

// Check if this is the best submission
$assignment->reset_final_submission_choices();

// Access submission details
echo "User: {$submission->user->username}\n";
echo "Problem: {$submission->problem->name}\n";
echo "Language: {$submission->language->name}\n";
echo "Score: {$submission->pre_score}/10000\n";
echo "Coefficient: {$submission->coefficient}%\n";

if ($submission->judgement) {
    echo "Verdicts: " . json_encode($submission->judgement->verdicts);
}

Status Workflow

  1. Pending: Submission created, waiting in queue
  2. Judging: Being evaluated against test cases
  3. Done: All test cases evaluated, results available
  4. Failed: System error during judging (e.g., timeout, disk full)

Build docs developers (and LLMs) love