Scenario-Based Questions

System Design and Problem Solving for Senior Developers

Scenario 1: The "Slow Report" Problem

Question: A client complains that a custom report plugin you built times out when run for the entire university (50,000 students). It works fine for small courses. How do you fix it?

Analysis: The script is likely hitting PHP's max_execution_time or memory limit due to loading all records at once.

Solution:

  1. Use RecordSets: Replace $DB->get_records() with $DB->get_recordset() to iterate row-by-row instead of loading everything into RAM.
  2. Ad-hoc Task: Move the generation to a background Ad-hoc task. The user clicks "Generate", and receives a notification when it's ready.
  3. Pagination: If it must be on-screen, implement pagination using Moodle's table_sql class.
  4. Read Replica: If the query is complex, direct it to the read-only database replica.

Scenario 2: External System Integration

Question: The university wants to automatically enrol students into Moodle courses based on data from their SIS (Student Information System). The SIS exposes a REST API. How do you design this?

Design:

  1. Plugin Type: Create an enrol plugin (e.g., enrol_sis) or a local plugin with a scheduled task.
  2. Synchronization: Use a Scheduled Task running nightly.
  3. Logic:
    • Fetch data from SIS API.
    • Check if the user exists (create if not).
    • Check if the course exists (create if not).
    • Call enrol_try_internal_enrol() or use the manual enrolment plugin instance to enrol the user.
  4. Optimization: Use the "Delta" approach—only fetch changes since the last run, rather than the full dataset every night.

Scenario 3: The "Hacked" Site

Question: You inherit a Moodle site that has been compromised. Spam forum posts are appearing. What are your immediate steps?

  1. Maintenance Mode: Immediately put the site in maintenance mode via CLI.
  2. Check Accounts: Look for new admin accounts or modified permissions in mdl_role_assignments.
  3. Code Integrity: Use git status to check for modified core files. If not using git, compare against a fresh Moodle download.
  4. Uploads: Check moodledata and /pix folders for executable PHP files (webshells).
  5. Logs: Analyze web server access logs for suspicious POST requests.
  6. Patch: Update Moodle to the latest security release.

Scenario 4: Custom Dashboard

Question: A client wants a completely custom dashboard for students, different from the standard Moodle Dashboard. It needs to show progress bars, upcoming deadlines, and a custom "Gamification" score.

Approach:

  1. Theme vs. Plugin: Do not hack the core dashboard. Create a local plugin or a custom block.
  2. Page Override: In the theme config, you can override the layout for the dashboard page, or redirect the user to a custom page in your local plugin upon login.
  3. Data Aggregation:
    • Progress: Use \core_completion\progress API.
    • Deadlines: Query the mdl_event table (Calendar API).
    • Gamification: Store points in a custom table in your plugin.
  4. Frontend: Use a Mustache template and an AMD module to render the charts (e.g., ChartJS) asynchronously.

Scenario 5: High Availability Session Issue

Question: You deployed Moodle on two web servers behind a load balancer. Users report being logged out randomly as they navigate pages. What is wrong?

Diagnosis: Sessions are likely stored on the local file system of each server (default behavior). When a user hits Server A, they get a session. If the next request goes to Server B, that server doesn't know the session.

Fix:

  1. Shared Storage: Configure $CFG->session_handler_class to use Redis, Memcached, or the Database.
  2. Sticky Sessions: Alternatively, configure the Load Balancer for "Sticky Sessions" (Session Affinity), though shared storage is the more robust cloud-native solution.

Scenario 6: The Disappearing File

Question: You built a form with a file manager element. The user uploads a file, saves the form, and sees the success message. But when they reload the page, the file is gone. What step did you miss?

Diagnosis: The file is likely still in the "draft" area. Moodle file uploads go to a temporary draft area first.

Fix: You must process the files upon form submission.

  1. Draft Area: When the form loads, prepare the draft area using file_prepare_standard_filemanager().
  2. Save: On submit, use file_save_draft_area_files() to move the file from the draft area to the permanent file area (e.g., mod_myplugin, attachment, $id).
  3. Database: Update the database record to reference the new item ID if necessary (though usually the item ID is constant).