Skip to main content

Overview

The Problem model represents a programming problem with test cases, judging configuration, and metadata. Problems can be attached to assignments or used for practice.

Fillable Fields

id
integer
Unique identifier for the problem
name
string
required
Display name of the problem
diff_cmd
string
default:"diff"
Command used to compare output (e.g., ‘diff’, ‘diff -w’, custom script)
diff_arg
string
Additional arguments passed to the diff command
allow_practice
boolean
default:"false"
Whether students can practice this problem outside of assignmentsCast: boolean
admin_note
text
Internal notes visible only to administrators and problem owner
difficult
string
Difficulty level (e.g., ‘easy’, ‘medium’, ‘hard’)
user_id
integer
required
ID of the user who created/owns this problem
sharable
boolean
default:"false"
Whether other instructors can use this problem in their assignmentsCast: boolean
author
string
Original author or source of the problem
editorial
text
Editorial/solution explanation (HTML supported)
allow_input_download
boolean
default:"false"
Whether students can download test case input filesCast: boolean
allow_output_download
boolean
default:"false"
Whether students can download test case output filesCast: boolean

Casts

protected $casts = [
    'allow_practice' => 'boolean',
    'sharable' => 'boolean',
    'allow_input_download' => 'boolean',
    'allow_output_download' => 'boolean',
];

Relationships

user() / owner()

user
BelongsTo<User>
The user who created this problem (both user() and owner() return the same relationship)
$problem->user // Returns User model
$problem->owner // Same as user()

languages()

languages
BelongsToMany<Language>
Programming languages allowed for this problemPivot fields:
  • time_limit - Execution time limit in seconds for this language
  • memory_limit - Memory limit in KB for this language
Timestamps: Yes
$problem->languages()->withPivot('time_limit', 'memory_limit')

assignments()

assignments
BelongsToMany<Assignment>
Assignments that include this problem
$problem->assignments // Returns collection of Assignment models

submissions()

submissions
HasMany<Submission>
All submissions made to this problem

tags()

tags
BelongsToMany<Tag>
Tags for categorizing this problem (e.g., ‘dynamic-programming’, ‘graphs’)
$problem->tags // Returns collection of Tag models

Public Methods

get_directory_path()

Returns the filesystem path where problem files are stored.
public function get_directory_path()
Returns: string - Absolute path to problem directory Example:
$path = $problem->get_directory_path();
// Returns: '/var/www/assignments/problems/123/'
Directory structure:
problems/{id}/
  ├── desc.html          # Problem description
  ├── problem.pdf        # Optional PDF version
  ├── template.cpp       # Code template (private)
  ├── template.public.cpp # Public code template
  ├── in/                # Test input files
  │   ├── input1.txt
  │   └── input2.txt
  └── out/               # Test output files
      ├── output1.txt
      └── output2.txt

can_practice()

Checks if a user has permission to practice this problem.
public function can_practice(User $user)
Parameters:
  • $user (User) - User requesting access
Returns: boolean Permission logic:
  1. Admin users: Always true
  2. Problem owner: Always true
  3. If allow_practice is true: Returns true
  4. If sharable is true AND user is head_instructor/instructor: Returns true
  5. Otherwise: Returns false
Example:
if ($problem->can_practice($user)) {
    // Show practice interface
} else {
    abort(403, 'You don\'t have permission to practice this problem');
}

can_edit()

Checks if a user has permission to edit this problem.
public function can_edit(User $user)
Parameters:
  • $user (User) - User requesting edit access
Returns: boolean Permission logic:
  • Admin users: Can edit any problem
  • Problem owner: Can edit their own problems
  • Others: Cannot edit

delete()

Deletes the problem and all associated data.
public function delete()
Actions performed:
  1. Starts database transaction
  2. Deletes all submissions for this problem
  3. Detaches all languages
  4. Detaches from all assignments
  5. Detaches all tags
  6. Deletes the model
  7. Commits transaction
  8. Deletes problem directory from filesystem using rm -rf
Example:
$problem->delete();
// Deletes database records and /var/www/assignments/problems/123/
The delete operation is destructive and removes all test cases and submissions. Use with caution.

pdf()

Serves the problem’s PDF file for download.
public function pdf()
Returns: File response with PDF Throws: 404 if PDF not found Example:
Route::get('/problems/{problem}/pdf', function(Problem $problem) {
    return $problem->pdf();
});

template_path()

Returns the path to the code template file for a specific language.
public function template_path($language_extension = 'cpp')
Parameters:
  • $language_extension (string) - File extension (e.g., ‘cpp’, ‘java’, ‘py’)
Returns: array - Array of matching file paths (or empty array) Priority:
  1. Checks for template.public.{extension} first
  2. Falls back to template.{extension}
Example:
$template_path = $problem->template_path('cpp');
// Returns: ['/var/www/assignments/problems/123/template.public.cpp']

template_content()

Returns the content of the code template for a specific language.
public function template_content($language_id)
Parameters:
  • $language_id (integer) - Language ID
Returns: string|null - Template file content or null if not found Example:
$template = $problem->template_content(1);
echo $template;
// Outputs: #include <iostream>...

description()

Returns the problem description and metadata.
public function description()
Returns: array with keys:
  • description (string) - HTML description or default message
  • has_pdf (boolean) - Whether PDF file exists
  • has_template (boolean) - Whether C++ template exists
Example:
$desc = $problem->description();
if ($desc['has_pdf']) {
    echo '<a href="/problems/{$problem->id}/pdf">Download PDF</a>';
}
echo $desc['description'];

available()

Static query scope for problems available to a user.
public static function available($user_id)
Parameters:
  • $user_id (integer) - User ID
Returns: Builder - Query builder instance Query logic: Returns problems where:
  • user_id matches the given user, OR
  • sharable is true
Example:
$problems = Problem::available(auth()->id())->get();
// Returns all problems owned by user or marked as sharable

Example Usage

// Create a new problem
$problem = Problem::create([
    'name' => 'Two Sum',
    'diff_cmd' => 'diff',
    'diff_arg' => '-w -B',
    'allow_practice' => true,
    'difficult' => 'easy',
    'user_id' => auth()->id(),
    'sharable' => true,
    'author' => 'LeetCode',
    'allow_input_download' => false,
    'allow_output_download' => false,
]);

// Attach languages with limits
$problem->languages()->attach(1, [
    'time_limit' => 1.0,    // 1 second
    'memory_limit' => 65536 // 64 MB
]);

// Add tags
$problem->tags()->attach([1, 5, 8]); // array, hash-table, two-pointers

// Check permissions
if ($problem->can_edit($user)) {
    // Show edit button
}

// Get template for user's selected language
$template = $problem->template_content($languageId);

// Use in query
$myProblems = Problem::available(auth()->id())
    ->where('difficult', 'medium')
    ->with('tags')
    ->get();

File System Integration

Problems require a specific directory structure in the filesystem:
# Problem directory
assignments_root=/var/www/assignments
problem_id=123

# Structure
/var/www/assignments/problems/123/
  desc.html               # Problem description (HTML)
  problem.pdf             # Optional PDF version
  template.cpp            # Private template (for reference solutions)
  template.public.cpp     # Public template (shown to students)
  template.java
  template.public.java
  in/                     # Test inputs
    01.txt
    02.txt
  out/                    # Expected outputs
    01.txt
    02.txt

Build docs developers (and LLMs) love