Salvatore Salvatore
Lead maintainer
local_csv_user_sync)local_csv_user_sync is a Moodle local plugin that synchronizes users and manual course enrolments from a CSV source.
It supports user creation and updates, enrolment creation/update/removal, dry-run mode, detailed logging, and a secure onboarding email flow for new users.
UTF-8, ISO-8859-1, Windows-1252, auto).mtrace and plugin DB table (local_cus_log).4.5 branch or newer ($plugin->requires = 2024100700).local_csv_user_sync.local/csv_user_syncSite administration -> NotificationsPath:
Site administration -> Plugins -> Local plugins -> CSV User SyncConfigure only one source:
CSV file path (absolute path), orCSV file upload (stored file area csvsource)If both or neither are set, the task stops with a configuration error.
File encoding: UTF-8, ISO-8859-1, Windows-1252, autoDelimiter: single character (default ;)Default authentication method: used when CSV auth is empty or invalid.Send credentials email: for newly created users.Email template: supports placeholders:
{{firstname}}{{lastname}}{{username}}{{setpasswordurl}}{{sitename}}{{loginurl}}{{password}} is still accepted as an alias for {{setpasswordurl}}.Update only changed dataDetailed loggingDry-run modeHeaders are normalized before matching:
_[a-z0-9_] characters removedExample:
Course Shortname -> course_shortnameThese headers must exist:
usernamefirstnamelastnameemailEnrolment headers must be paired:
course_shortname and role_shortname must both be present if either is present.usernamefirstnamelastnameemailauthcitycountrylangidnumberinstitutiondepartmentphone1phone2addresscourse_shortnamerole_shortnameenrol_start_date (alias: start_date)enrol_end_date (alias: end_date)suspended (0 or 1, empty treated as 0)deleted (0 or 1, empty treated as 0)Two ways are accepted:
profile_field_<shortname><shortname> (if it is not a reserved/system header and matches an existing profile field)Y-m-d (example 2026-02-18)d.m.Y (example 18.02.2026)d/m/Y (example 18/02/2026)YYYYMMDD (example 20260218)0 (no date)For each row:
Enrolment logic highlights:
deleted = 1: remove existing manual enrolment.suspended = 1: set enrolment to suspended.If a manual enrolment instance is missing on a target course, the plugin creates one (unless dry-run).
sesskeymoodle/site:config capabilitymoodle/site:config.{{setpasswordurl}}) when supported by user auth.Logs are written to:
mtrace outputlocal_cus_log table (runid, level, rownum, userid, username, message, timecreated)Privacy support:
local_cus_log.Task class:
\local_csv_user_sync\task\sync_taskDefault schedule:
R R * * *)Manual execution example:
php admin/cli/scheduled_task.php --execute="\\local_csv_user_sync\\task\\sync_task"
When enabled:
Common checks:
course_shortname and role_shortname are both present for enrolment imports.