mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
MDL-22780 sync ext db enrol when user logs in - except admins in case something goes really wrong in plugins
This commit is contained in:
parent
5f8354eb06
commit
e384d2dc7b
@ -50,15 +50,180 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces synchronisation of user enrolments with external database.
|
||||
* Forces synchronisation of user enrolments with external database,
|
||||
* does not create new courses.
|
||||
*
|
||||
* @param object $user user record
|
||||
* @return void
|
||||
*/
|
||||
public function sync_user_enrolments($user = NULL) {
|
||||
public function sync_user_enrolments($user) {
|
||||
global $CFG, $DB;
|
||||
|
||||
//TODO: full sync with external system is very expensive, it could cause big perf problems if we did that during each log-in,
|
||||
// so do the sync only once in a while or rely on cron
|
||||
// we do not create courses here intentionally because it requires full sync and is slow
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$table = $this->get_config('remoteenroltable');
|
||||
$coursefield = strtolower($this->get_config('remotecoursefield'));
|
||||
$userfield = strtolower($this->get_config('remoteuserfield'));
|
||||
$rolefield = strtolower($this->get_config('remoterolefield'));
|
||||
|
||||
$localrolefield = $this->get_config('localrolefield');
|
||||
$localuserfield = $this->get_config('localuserfield');
|
||||
$localcoursefiled = $this->get_config('localcoursefield');
|
||||
|
||||
$unenrolaction = $this->get_config('unenrolaction');
|
||||
$defaultrole = $this->get_config('defaultrole');
|
||||
|
||||
$ignorehidden = $this->get_config('ignorehiddencourses');
|
||||
|
||||
// create roles mapping
|
||||
$allroles = get_all_roles();
|
||||
if (!isset($allroles[$defaultrole])) {
|
||||
$defaultrole = 0;
|
||||
}
|
||||
$roles = array();
|
||||
foreach ($allroles as $role) {
|
||||
$roles[$role->$localrolefield] = $role->id;
|
||||
}
|
||||
|
||||
$enrols = array();
|
||||
$instances = array();
|
||||
|
||||
$extdb = $this->db_init();
|
||||
|
||||
// read remote enrols and create instances
|
||||
$sql = $this->db_get_sql($table, array($userfield=>$user->$localuserfield), array(), false);
|
||||
|
||||
if ($rs = $extdb->Execute($sql)) {
|
||||
if (!$rs->EOF) {
|
||||
while ($fields = $rs->FetchRow()) {
|
||||
$fields = $this->db_decode($fields);
|
||||
|
||||
if (empty($fields[$coursefield])) {
|
||||
// missing course info
|
||||
continue;
|
||||
}
|
||||
if (!$course = $DB->get_record('course', array($localcoursefiled=>$fields[$coursefield]), 'id,visible')) {
|
||||
continue;
|
||||
}
|
||||
if (!$course->visible and $ignorehidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($fields[$rolefield]) or !isset($roles[$fields[$rolefield]])) {
|
||||
if (!$defaultrole) {
|
||||
// role is mandatory
|
||||
continue;
|
||||
}
|
||||
$roleid = $defaultrole;
|
||||
} else {
|
||||
$roleid = $roles[$fields[$rolefield]];
|
||||
}
|
||||
|
||||
if (empty($enrols[$course->id])) {
|
||||
$enrols[$course->id] = array();
|
||||
}
|
||||
$enrols[$course->id][] = $roleid;
|
||||
|
||||
if ($instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'database'), '*', IGNORE_MULTIPLE)) {
|
||||
$instances[$course->id] = $instance;
|
||||
continue;
|
||||
}
|
||||
|
||||
$enrolid = $this->add_instance($course);
|
||||
$instances[$course->id] = $DB->get_record('enrol', array('id'=>$enrolid));
|
||||
}
|
||||
}
|
||||
$rs->Close();
|
||||
$extdb->Close();
|
||||
} else {
|
||||
// bad luck, something is wrong with the db connection
|
||||
$extdb->Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// enrol user into courses and sync roles
|
||||
foreach ($enrols as $courseid => $roles) {
|
||||
if (!isset($instances[$courseid])) {
|
||||
// ignored
|
||||
continue;
|
||||
}
|
||||
$instance = $instances[$courseid];
|
||||
|
||||
if ($e = $DB->get_record('user_enrolments', array('userid'=>$user->id, 'enrolid'=>$instance->id))) {
|
||||
// reenable enrolment when previously disable enrolment refreshed
|
||||
if ($e->status == ENROL_USER_SUSPENDED) {
|
||||
$DB->set_field('user_enrolments', 'status', ENROL_USER_ACTIVE, array('enrolid'=>$instance->id, 'userid'=>$user->id));
|
||||
}
|
||||
} else {
|
||||
$roleid = reset($roles);
|
||||
$this->enrol_user($instance, $user->id, $roleid);
|
||||
}
|
||||
|
||||
if (!$context = get_context_instance(CONTEXT_COURSE, $instance->courseid)) {
|
||||
//weird
|
||||
continue;
|
||||
}
|
||||
$current = $DB->get_records('role_assignments', array('contextid'=>$context->id, 'userid'=>$user->id, 'component'=>'enrol_database', 'itemid'=>$instance->id), '', 'id, roleid');
|
||||
|
||||
$existing = array();
|
||||
foreach ($current as $r) {
|
||||
if (in_array($r->id, $roles)) {
|
||||
$existing[$r->roleid] = $r->roleid;
|
||||
} else {
|
||||
role_unassign($r->roleid, $user->id, $context->id, 'enrol_database', $instance->id);
|
||||
}
|
||||
}
|
||||
foreach ($roles as $rid) {
|
||||
if (!isset($existing[$rid])) {
|
||||
role_assign($rid, $user->id, $context->id, 'enrol_database', $instance->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unenrol as necessary
|
||||
$sql = "SELECT e.*, c.visible AS cvisible, ue.status AS ustatus
|
||||
FROM {enrol} e
|
||||
JOIN {user_enrolments} ue ON ue.enrolid = e.id
|
||||
JOIN {course} c ON c.id = e.courseid
|
||||
WHERE ue.userid = :userid AND e.enrol = 'database'";
|
||||
$rs = $DB->get_recordset_sql($sql, array('userid'=>$user->id));
|
||||
foreach ($rs as $instance) {
|
||||
if (!$instance->cvisible and $ignorehidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$context = get_context_instance(CONTEXT_COURSE, $instance->courseid)) {
|
||||
//weird
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($enrols[$instance->courseid])) {
|
||||
// we want this user enrolled
|
||||
continue;
|
||||
}
|
||||
|
||||
// deal with enrolments removed from external table
|
||||
if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
|
||||
// unenrol
|
||||
$this->unenrol_user($instance, $user->id);
|
||||
|
||||
} else if ($unenrolaction == ENROL_EXT_REMOVED_KEEP) {
|
||||
// keep - only adding enrolments
|
||||
|
||||
} else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND or $unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
|
||||
// disable
|
||||
if ($instance->ustatus != ENROL_USER_SUSPENDED) {
|
||||
$DB->set_field('user_enrolments', 'status', ENROL_USER_SUSPENDED, array('enrolid'=>$instance->id, 'userid'=>$user->id));
|
||||
}
|
||||
if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
|
||||
role_unassign_all(array('contextid'=>$context->id, 'userid'=>$user->id, 'component'=>'enrol_database', 'itemid'=>$instance->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,17 +246,20 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
$extdb = $this->db_init();
|
||||
|
||||
// second step is to sync instances and users
|
||||
$table = $this->get_config('remoteenroltable');
|
||||
$coursefield = strtolower($this->get_config('remotecoursefield'));
|
||||
$userfield = strtolower($this->get_config('remoteuserfield'));
|
||||
$rolefield = strtolower($this->get_config('remoterolefield'));
|
||||
$localrolefield = $this->get_config('localrolefield');
|
||||
$localuserfield = $this->get_config('localuserfield');
|
||||
$unenrolaction = $this->get_config('unenrolaction');
|
||||
$table = $this->get_config('remoteenroltable');
|
||||
$coursefield = strtolower($this->get_config('remotecoursefield'));
|
||||
$userfield = strtolower($this->get_config('remoteuserfield'));
|
||||
$rolefield = strtolower($this->get_config('remoterolefield'));
|
||||
|
||||
$localrolefield = $this->get_config('localrolefield');
|
||||
$localuserfield = $this->get_config('localuserfield');
|
||||
$localcoursefiled = $this->get_config('localcoursefield');
|
||||
|
||||
$unenrolaction = $this->get_config('unenrolaction');
|
||||
$defaultrole = $this->get_config('defaultrole');
|
||||
|
||||
// create roles mapping
|
||||
$allroles = get_all_roles();
|
||||
$defaultrole = $this->get_config('defaultrole');
|
||||
if (!isset($allroles[$defaultrole])) {
|
||||
$defaultrole = 0;
|
||||
}
|
||||
@ -101,7 +269,6 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
}
|
||||
|
||||
// first find all existing courses with enrol instance
|
||||
$localcoursefiled = $this->get_config('localcoursefield');
|
||||
$sql = "SELECT c.id, c.visible, c.$localcoursefiled AS mapping, e.id AS enrolid
|
||||
FROM {course} c
|
||||
JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'database')";
|
||||
|
@ -186,6 +186,12 @@ function enrol_check_plugins($user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_siteadmin()) {
|
||||
// no sync for admin user, please use admin accounts only for admin tasks like the unix root user!
|
||||
// if plugin fails on sync admins need to be able to log in
|
||||
return;
|
||||
}
|
||||
|
||||
static $inprogress = array(); // To prevent this function being called more than once in an invocation
|
||||
|
||||
if (!empty($inprogress[$user->id])) {
|
||||
@ -943,6 +949,7 @@ abstract class enrol_plugin {
|
||||
|
||||
if (!$ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) {
|
||||
// weird, user not enrolled
|
||||
echo "grrrr";
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user