diff --git a/enrol/database/enrol.php b/enrol/database/enrol.php
index 3957a33..66f5066 100644
--- a/enrol/database/enrol.php
+++ b/enrol/database/enrol.php
@@ -160,9 +160,55 @@ function setup_enrolments(&$user) {
}
}
} else {
- error_log('[ENROL_DB] Couldn\'t get rows from external db: '.$enroldb->ErrorMsg());
+ error_log('[ENROL_DB] Couldn\'t get rows from external db for course roles: '.$enroldb->ErrorMsg());
}
}
+ // SYSTEM ROLES START HERE
+ if (!empty($CFG->enrol_dbsystemtable) && !empty($CFG->enrol_db_remoterolefield)) { // not sensible to do this with no role settings
+ $sql = "SELECT *
+ FROM {$CFG->enrol_dbsystemtable}
+ WHERE {$CFG->enrol_remoteuserfield} = $useridfield
+ ";
+ if ($rs = $enroldb->Execute($sql)) {
+
+ $systemcontext = get_system_context();
+ // get the existing system role assignments
+ if (!$existing = get_records_sql("SELECT r.{$CFG->enrol_db_localrolefield},ra.*
+ FROM {$CFG->prefix}role r JOIN {$CFG->prefix}role_assignments ra ON ra.roleid = r.id
+ WHERE ra.userid = {$user->id} AND ra.contextid = {$systemcontext->id}")) {
+ $existing = array();
+ }
+ if (!$rs->EOF) { // we found some results for this user
+ // need to go fetch the local roles too so we can match role.{$CFG->enrol_remoterolefield} -> local role id
+ if (!$roles = get_records('role', '','','',$CFG->enrol_db_localrolefield . ',*')) {
+ // we can't assign any roles if there aren't any.
+ } else {
+ while ($fields_obj = rs_fetch_next_record($rs)) {
+ if (array_key_exists($fields_obj->{$CFG->enrol_db_remoterolefield}, $existing)) {
+ // user already has this role in system context. skip.
+ unset($existing[$fields_obj->{$CFG->enrol_db_remoterolefield}]);
+ continue;
+ }
+ if (!array_key_exists($fields_obj->{$CFG->enrol_db_remoterolefield}, $roles)) { // can't assign it if it doesn't exist
+ continue; // TODO perhaps we should raise a warning here
+ }
+ role_assign($roles[$fields_obj->{$CFG->enrol_db_remoterolefield}]->id, $user->id, '', $systemcontext->id, 0, 0, 0, 'database');
+ }
+ }
+ }
+
+ if (!$CFG->enrol_db_disableunenrol) {
+ foreach ($existing as $role_assignment) {
+ if ($role_assignment->enrol == 'database') {
+ role_unassign($role_assignment->roleid, $user->id, '', $systemcontext->id);
+ }
+ }
+ }
+ } else {
+ error_log('[ENROL_DB] Couldn\'t get rows from external db for system roles: '.$enroldb->ErrorMsg());
+ }
+ }
+ // END SYSTEM ROLES
$this->enrol_disconnect($enroldb);
}
@@ -673,6 +719,85 @@ function role_fields($enroldb, $role) {
return array($have_role, $remote_role_name, $remote_role_value);
}
+
+function sync_system_roles() {
+ global $CFG, $db;
+ if (empty($CFG->enrol_dbsystemtable) || empty($CFG->enrol_db_remoterolefield)) {
+ return;
+ }
+
+ $enroldb = $this->enrol_connect();
+ echo "=== Syncing system enrolments ===\n";
+
+ $sql = "SELECT * FROM {$CFG->enrol_dbsystemtable}";
+ if ($rs = $enroldb->Execute($sql)) {
+
+ $systemcontext = get_system_context();
+ // get the existing system role assignments
+ if (!$existing = get_records_sql("SELECT "
+ . sql_concat('r.' . $CFG->enrol_db_localrolefield, "'|'", 'u.' . $CFG->enrol_localuserfield)
+ . " AS unique, r.{$CFG->enrol_db_localrolefield}, u.{$CFG->enrol_localuserfield}, ra.*
+ FROM {$CFG->prefix}role r
+ JOIN {$CFG->prefix}role_assignments ra ON ra.roleid = r.id
+ JOIN {$CFG->prefix}user u ON ra.userid = u.id
+ WHERE ra.contextid = {$systemcontext->id}")) {
+ $existing = array();
+ }
+
+ begin_sql();
+
+ if (!$rs->EOF) { // we found some roles in the external db
+ $usercache = array(); // put the moodle user in there
+ $notfoundusercache = array(); // so we don't keep looking up again and again
+ if (!$roles = get_records('role', '', '', '', $CFG->enrol_db_localrolefield . ', *')) {
+ // we can't assign any roles if tehre aren't any
+ } else {
+ while ($fields_obj = rs_fetch_next_record($rs)) {
+ $key = $fields_obj->{$CFG->enrol_db_remoterolefield} . '|' . $fields_obj->{$CFG->enrol_remoteuserfield};
+ if (array_key_exists($key, $existing)) {
+ unset($existing[$key]);
+ }
+ if (!array_key_exists($fields_obj->{$CFG->enrol_db_remoterolefield}, $roles)) {
+ continue; // TODO maybe raise a warning here
+ }
+ if (array_key_exists($fields_obj->{$CFG->enrol_remoteuserfield}, $notfoundusercache)) {
+ continue; // TODO maybe raise a warning here
+ }
+ // find the moodle user
+ if (!array_key_exists($fields_obj->{$CFG->enrol_remoteuserfield}, $usercache)) {
+ if ($u = get_record('user', $CFG->enrol_localuserfield, $fields_obj->{$CFG->enrol_remoteuserfield}, '','','','','id,id')) {
+ $usercache[$fields_obj->{$CFG->enrol_remoteuserfield}] = $u;
+ } else {
+ $notfoundusercache[$fields_obj->{$CFG->enrol_remoteuserfield}] = 1;
+ continue;
+ }
+ }
+ if (role_assign($roles[$fields_obj->{$CFG->enrol_db_remoterolefield}]->id, $usercache[$fields_obj->{$CFG->enrol_remoteuserfield}]->id, '', $systemcontext->id, 0, 0, 0, 'database')) {
+ error_log("assigned role " . $fields_obj->{$CFG->enrol_db_remoterolefield} . " to user " . $fields_obj->{$CFG->enrol_remoteuserfield} . " at system context");
+ } else {
+ error_log("failed to assign role " . $fields_obj->{$CFG->enrol_db_remoterolefield} . " to user " . $fields_obj->{$CFG->enrol_remoteuserfield} . " at system context");
+ }
+ }
+ }
+ if (!$CFG->enrol_db_disableunenrol) {
+
+ foreach ($existing as $role_assignment) {
+ if ($role_assignment->enrol == 'database') {
+ error_log("unassigning role");
+ role_unassign($role_assignment->roleid, $user->id, '', $systemcontext->id);
+ }
+ }
+ }
+ } else {
+ error_log('[ENROL_DB] (sync) Couldn\'t get rows from external db for system roles: '.$enroldb->ErrorMsg());
+ }
+ commit_sql();
+ }
+ $this->enrol_disconnect($enroldb);
+}
+
+
+
} // end of class
?>
diff --git a/enrol/database/enrol_database_sync.php b/enrol/database/enrol_database_sync.php
index 322b1b2..cf27c70 100644
--- a/enrol/database/enrol_database_sync.php
+++ b/enrol/database/enrol_database_sync.php
@@ -34,6 +34,9 @@
$enrol->sync_enrolments($role);
}
+ // sync system roles
+ $enrol->sync_system_roles();
+
// sync metacourses
if (function_exists('sync_metacourses')) {
sync_metacourses();