Overview
The assignment_controller handles all operations related to assignments including CRUD operations, submission downloads, scoreboard management, and assignment duplication.
Constructor
public function __construct()
Applies the following middleware:
auth - Requires user authentication
ip_white_listing - IP whitelist validation
read_only_archive - Makes controller read-only when app is in archived mode
CRUD Methods
index()
Displays a listing of all assignments accessible to the authenticated user.
Access Control:
- Admin: Can view all assignments
- Head Instructor/Instructor: Can view assignments they created or assignments in their classes
- Student: Can only view open assignments they’re enrolled in
Returns: View with assignments list including:
- Assignment coefficient
- Finish status
- Number of problems
- Associated classes (lops)
Example from controller:
// For non-admin users, filter by lops and user ownership
$assignments = Assignment::where(function($query) use ($lops_id){
$query->whereHas('lops', function($q) use ($lops_id){
$q->whereIn('lops.id', $lops_id);
})->orWhere('user_id', Auth::user()->id);
});
create()
Shows the form for creating a new assignment.
Access Control:
- Admin and head_instructor only
- Aborts with 403 for other roles
Returns: View with:
- All available problems
- All classes (lops) accessible to user
- All languages
- Empty problem array with dummy problem
store()
public function store(Request $request)
Stores a newly created assignment in the database.
Assignment name (max 150 characters)
Assignment PDF file (must be PDF format)
Extra time formula (e.g., “06060” for hours)
Whether assignment is open (1 or 0)
Whether to show scoreboard (1 or 0)
Array of problem IDs to attach
Array of problem names for each problem
Array of scores for each problem
Array of class (lop) IDs to attach
Array of allowed language IDs
Validation Rules:
name: required, max 150 characters
pdf_file: must be PDF format
Returns: Redirect to assignments index
Example from controller:
$assignment = new Assignment;
$assignment->fill($input);
$assignment->user_id = Auth::user()->id;
$assignment->save();
// Attach problems with pivot data
foreach ($request->problem_id as $i => $id) {
if ($id == -1) continue;
$assignment->problems()->attach([
$id => ['problem_name' => $request->problem_name[$i],
'score' => $request->problem_score[$i],
'ordering' => $i]
]);
}
show()
public function show(Assignment $assignment, $problem_id)
Displays the specified problem within an assignment context.
Assignment model instance
ID of the problem to display
Access Control:
- Checks if assignment has started (for students)
- Checks if assignment is open (for students)
- Checks if user is participant
Returns: View with:
- Problem description and metadata
- Available languages
- Submission capability status
- Problem status for all problems in assignment
Route: /assignment/{assignment}/{problem_id}/
edit()
public function edit(Assignment $assignment)
Shows the form for editing an existing assignment.
Assignment model instance to edit
Access Control:
- Calls
cannot_edit() method to verify permissions
- Aborts with 403 if user cannot edit
Returns: View with:
- Assignment data
- All problems (ordered by ordering field)
- All classes (lops) accessible to user
- Selected problems and classes
- All languages
update()
public function update(Request $request, Assignment $assignment)
Updates the specified assignment in storage.
Assignment model instance to update
Assignment name (max 150 characters)
Updated assignment PDF file
Validation Rules:
name: required, max 150 characters
pdf: must be PDF format
Side Effects:
- Detaches and reattaches all problems
- Detaches and reattaches all classes
- Updates submission coefficients
- Updates scoreboard
Returns: Redirect to assignments index
Example from controller:
$assignment->fill($input);
$assignment->save();
// Update problems
$assignment->problems()->detach();
foreach ($request->problem_id as $i => $id) {
if ($id == -1) continue;
$assignment->problems()->attach([
$id => ['problem_name' => $request->problem_name[$i],
'score' => $request->problem_score[$i],
'ordering' => $i]
]);
}
$assignment->update_submissions_coefficient();
Scoreboard::update_scoreboard($assignment->id);
destroy()
public function destroy($id)
Removes the specified assignment from storage.
Access Control:
- Calls
cannot_edit() to verify permissions
Deletion includes:
- All submissions for this assignment
- Queue items for pending submissions
- Assignment-lop relationships
- Assignment-problem relationships
- PDF files in storage
Returns: JSON response:
{
"done": 1,
"message": "Optional error message"
}
Note: Assignment with ID 0 (practice) cannot be deleted
Download Methods
download_submissions()
public function download_submissions($type, $assignment_id)
Downloads final submissions organized by user or problem.
Organization type: “by_user” or “by_problem”
Access Control:
- Admin, head_instructor, and instructor only
File Structure:
by_user: {username}/problem_{problem_id}.{ext}
by_problem: problem_{problem_id}/{username}.{ext}
Returns: ZIP file download with automatic deletion after send
Route: /assignment/download_submissions/{type}/{assignment_id}/
Example from controller:
$final_subs = Submission::get_final_submissions($assignment_id);
$zip = new ZipArchive;
$zip_name = $assignments_root . "/assignment" . $assignment_id . "_submissions_by_user_" . date('Y-m-d_H-i') . ".zip";
$zip->open($zip_name, ZipArchive::CREATE | ZipArchive::OVERWRITE);
foreach ($final_subs as $final_sub) {
$file_path = Submission::get_path($final_sub->username, $assignment_id, $final_sub->problem_id)
. "/" . $final_sub->file_name . "." . Language::find($final_sub->language_id)->extension;
$file = file_get_contents($file_path);
$zip->addFromString("{$final_sub->username}/problem_{$final_sub->problem_id}.{$ext}", $file);
}
download_all_submissions()
public function download_all_submissions($assignment_id)
Downloads all submission files for an assignment (not just final submissions).
Access Control:
- Admin, head_instructor, and instructor only
Returns: ZIP file containing entire assignment directory
Route: /assignment/download_all_submissions/{assignment_id}/
Scoreboard Methods
reload_scoreboard()
public function reload_scoreboard($assignment_id)
Resets all final submission choices to best score and regenerates scoreboard.
Access Control:
- Admin, head_instructor, and instructor only
Process:
- Resets all final submission choices using
reset_final_submission_choices()
- Updates scoreboard using
Scoreboard::update_scoreboard()
Returns: Redirect back with success message
Route: /assignment/reload_scoreboard/{assignment_id}/
score_accepted()
public function score_accepted()
Displays view for accepted score calculation mode.
Access Control:
- Admin, head_instructor, and instructor only
Returns: View assignments.score_accepted
Route: /assignment/scores/accepted/
score_sum()
public function score_sum()
Displays view for sum score calculation mode.
Access Control:
- Admin, head_instructor, and instructor only
Returns: View assignments.score_sum
Route: /assignment/scores/sum/
Utility Methods
duplicate()
public function duplicate(Assignment $assignment)
Creates a copy of an existing assignment.
Assignment model instance to duplicate
Process:
- Replicates assignment model
- Sets current user as owner
- Resets total_submits to 0
- Copies all problem relationships with pivot data
Returns: Redirect to assignments index
Route: /assignment/duplicate/{assignment}
Example from controller:
$new = $assignment->replicate();
$new->user_id = Auth::user()->id;
$new->total_submits = 0;
$new->save();
foreach ($assignment->problems as $p) {
$new->problems()->attach($p->id, [
'score' => $p->pivot->score,
'problem_name' => $p->pivot->problem_name,
'ordering' => $p->pivot->ordering
]);
}
check_open()
public function check_open(Request $request)
Toggles the open/closed status of an assignment.
Access Control:
- Calls
cannot_edit() to verify permissions
Returns: Plain text response:
"success" - Toggle successful
"error, {message}" - Permission denied
"error" - Assignment not found
Route: /assignment/check_open/ (POST)
Example from controller:
$assignment = Assignment::find($assignment_id);
if (($t = $assignment->cannot_edit(Auth::user())) !== false) {
echo "error, " . $t;
return;
}
$assignment->open = !$assignment->open;
$assignment->save();
echo "success";
- Assignment: Main model for assignments
- Problem: Problems attached to assignments
- Submission: Student submissions for problems
- Lop: Classes/groups enrolled in assignments
- Language: Programming languages allowed
- Scoreboard: Assignment scoreboard data