diff --git a/enrol/meta/addinstance.php b/enrol/meta/addinstance.php index 3ded0407915..235af96539a 100644 --- a/enrol/meta/addinstance.php +++ b/enrol/meta/addinstance.php @@ -51,7 +51,8 @@ if ($mform->is_cancelled()) { redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); } else if ($data = $mform->get_data()) { - $eid = $enrol->add_instance($course, array('customint1'=>$data->link)); + $eid = $enrol->add_instance($course, array('customint1' => $data->link, + 'customint2' => $data->customint2)); enrol_meta_sync($course->id); if (!empty($data->submitbuttonnext)) { redirect(new moodle_url('/enrol/meta/addinstance.php', diff --git a/enrol/meta/addinstance_form.php b/enrol/meta/addinstance_form.php index fb4b7489559..ed892e3b817 100644 --- a/enrol/meta/addinstance_form.php +++ b/enrol/meta/addinstance_form.php @@ -64,11 +64,18 @@ class enrol_meta_addinstance_form extends moodleform { } $rs->close(); + $groups = array(0 => get_string('none')); + foreach (groups_get_all_groups($course->id) as $group) { + $groups[$group->id] = format_string($group->name, true, array('context' => course_context::instance($course->id))); + } + $mform->addElement('header','general', get_string('pluginname', 'enrol_meta')); $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_meta'), $courses); $mform->addRule('link', get_string('required'), 'required', null, 'client'); + $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups); + $mform->addElement('hidden', 'id', null); $mform->setType('id', PARAM_INT); diff --git a/enrol/meta/lang/en/enrol_meta.php b/enrol/meta/lang/en/enrol_meta.php index b47f526f954..18f73c15e3a 100644 --- a/enrol/meta/lang/en/enrol_meta.php +++ b/enrol/meta/lang/en/enrol_meta.php @@ -22,6 +22,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['addgroup'] = 'Add to group'; $string['coursesort'] = 'Sort course list'; $string['coursesort_help'] = 'This determines whether the list of courses that can be linked are sorted by sort order (i.e. the order set in Site administration > Courses > Manage courses and categories) or alphabetically by course setting.'; $string['linkedcourse'] = 'Link course'; @@ -33,4 +34,4 @@ $string['nosyncroleids_desc'] = 'By default all course level role assignments ar $string['pluginname'] = 'Course meta link'; $string['pluginname_desc'] = 'Course meta link enrolment plugin synchronises enrolments and roles in two different courses.'; $string['syncall'] = 'Synchronise all enrolled users'; -$string['syncall_desc'] = 'If enabled all enrolled users are synchronised even if they have no role in parent course, if disabled only users that have at least one synchronised role are enrolled in child course.'; \ No newline at end of file +$string['syncall_desc'] = 'If enabled all enrolled users are synchronised even if they have no role in parent course, if disabled only users that have at least one synchronised role are enrolled in child course.'; diff --git a/enrol/meta/locallib.php b/enrol/meta/locallib.php index 84b61075c9c..6c4c0ce3422 100644 --- a/enrol/meta/locallib.php +++ b/enrol/meta/locallib.php @@ -150,11 +150,13 @@ class enrol_meta_handler { } } + // enrol user if not enrolled yet or fix status if ($ue) { if ($parentstatus != $ue->status) { $plugin->update_user_enrol($instance, $userid, $parentstatus); $ue->status = $parentstatus; + groups_add_member($instance->customint2, $userid, 'enrol_meta', $instance->courseid); } } else { $plugin->enrol_user($instance, $userid, NULL, 0, 0, $parentstatus); @@ -162,6 +164,7 @@ class enrol_meta_handler { $ue->userid = $userid; $ue->enrolid = $instance->id; $ue->status = $parentstatus; + groups_add_member($instance->customint2, $userid, 'enrol_meta', $instance->courseid); } $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES); @@ -171,6 +174,7 @@ class enrol_meta_handler { if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND) { // Always keep the roles. } else if ($roles) { + groups_remove_member($instance->customint2, $userid); role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); } return; @@ -180,6 +184,7 @@ class enrol_meta_handler { foreach ($parentroles as $rid) { if (!isset($roles[$rid])) { role_assign($rid, $userid, $context->id, 'enrol_meta', $instance->id); + groups_add_member($instance->customint2, $userid, 'enrol_meta', $instance->courseid); } } @@ -227,6 +232,8 @@ class enrol_meta_handler { if ($ue->status != ENROL_USER_SUSPENDED) { $plugin->update_user_enrol($instance, $userid, ENROL_USER_SUSPENDED); } + // Remove from metagroup. + groups_remove_member($instance->customint2, $userid); role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); } else { @@ -244,6 +251,7 @@ class enrol_meta_handler { */ function enrol_meta_sync($courseid = NULL, $verbose = false) { global $CFG, $DB; + require_once("{$CFG->dirroot}/group/lib.php"); // purge all roles if meta sync disabled, those can be recreated later here in cron if (!enrol_is_enabled('meta')) { @@ -544,6 +552,44 @@ function enrol_meta_sync($courseid = NULL, $verbose = false) { } } + // Finally sync groups. + $onecourse = $courseid ? "AND e.courseid = :courseid" : ""; + + // Remove invalid. + $sql = "SELECT gm.*, e.courseid, g.name AS groupname + FROM {groups_members} gm + JOIN {groups} g ON (g.id = gm.groupid) + JOIN {enrol} e ON (e.enrol = 'meta' AND e.courseid = g.courseid $onecourse) + JOIN {user_enrolments} ue ON (ue.userid = gm.userid AND ue.enrolid = e.id) + WHERE gm.component='enrol_meta' AND gm.itemid = e.id AND g.id <> e.customint2"; + $params = array(); + $params['courseid'] = $courseid; + + $rs = $DB->get_recordset_sql($sql, $params); + foreach ($rs as $gm) { + groups_remove_member($gm->groupid, $gm->userid); + mtrace("removing user from group: $gm->userid ==> $gm->courseid - $gm->groupname", 1); + } + $rs->close(); + + // Add missing. + $sql = "SELECT ue.*, g.id AS groupid, e.courseid, g.name AS groupname + FROM {user_enrolments} ue + JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'meta' $onecourse) + JOIN {groups} g ON (g.courseid = e.courseid AND g.id = e.customint2) + JOIN {user} u ON (u.id = ue.userid AND u.deleted = 0) + LEFT JOIN {groups_members} gm ON (gm.groupid = g.id AND gm.userid = ue.userid) + WHERE gm.id IS NULL"; + $params = array(); + $params['courseid'] = $courseid; + + $rs = $DB->get_recordset_sql($sql, $params); + foreach ($rs as $ue) { + groups_add_member($ue->groupid, $ue->userid, 'enrol_meta', $ue->enrolid); + mtrace("adding user to group: $ue->userid ==> $ue->courseid - $ue->groupname", 1); + } + $rs->close(); + if ($verbose) { mtrace('...user enrolment synchronisation finished.'); } diff --git a/enrol/meta/tests/plugin_test.php b/enrol/meta/tests/plugin_test.php index 63f182410f2..e4a0f2cb33f 100644 --- a/enrol/meta/tests/plugin_test.php +++ b/enrol/meta/tests/plugin_test.php @@ -100,6 +100,13 @@ class enrol_meta_plugin_testcase extends advanced_testcase { $teacher = $DB->get_record('role', array('shortname'=>'teacher')); $manager = $DB->get_record('role', array('shortname'=>'manager')); + $id = groups_create_group((object)array('name'=>'Group 1', 'courseid'=>$course1->id)); + $group1 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST); + $id = groups_create_group((object)array('name'=>'Group 2', 'courseid'=>$course1->id)); + $group2 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST); + $id = groups_create_group((object)array('name'=>'Group 3', 'courseid'=>$course2->id)); + $group3 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST); + $this->disable_plugin(); $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); @@ -128,12 +135,14 @@ class enrol_meta_plugin_testcase extends advanced_testcase { $this->assertEquals(7, $DB->count_records('user_enrolments')); $this->assertEquals(6, $DB->count_records('role_assignments')); - $e1 = $metalplugin->add_instance($course3, array('customint1'=>$course1->id)); - $e2 = $metalplugin->add_instance($course3, array('customint1'=>$course2->id)); + $e1 = $metalplugin->add_instance($course3, array('customint1'=>$course1->id, 'customint2'=>$group1->id)); + $e2 = $metalplugin->add_instance($course3, array('customint1'=>$course2->id, 'customint2'=>$group2->id)); $e3 = $metalplugin->add_instance($course4, array('customint1'=>$course2->id)); + $e4 = $metalplugin->add_instance($course4, array('customint1'=>$course2->id, 'customint2'=>$group3->id)); $enrol1 = $DB->get_record('enrol', array('id'=>$e1)); $enrol2 = $DB->get_record('enrol', array('id'=>$e2)); $enrol3 = $DB->get_record('enrol', array('id'=>$e3)); + $enrol4 = $DB->get_record('enrol', array('id'=>$e3)); enrol_meta_sync($course4->id, false); $this->assertEquals(9, $DB->count_records('user_enrolments')); @@ -176,6 +185,34 @@ class enrol_meta_plugin_testcase extends advanced_testcase { $this->enable_plugin(); + $this->assertTrue(is_enrolled(context_course::instance($course1->id), $user4)); + $this->assertTrue(groups_add_member($group1, $user4)); + $this->assertTrue(groups_add_member($group2, $user4)); + + $this->assertFalse(groups_is_member($group1->id, $user1->id)); + groups_add_member($group1->id, $user1->id); + $this->assertTrue(groups_is_member($group1->id, $user1->id)); + $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id))); + + groups_add_member($group1->id, $user4->id); + $this->assertTrue(groups_is_member($group1->id, $user4->id)); + $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id))); + + set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL, 'enrol_meta'); + + groups_remove_member($group1->id, $user1->id); + $this->assertFalse(groups_is_member($group1->id, $user1->id)); + + groups_remove_member($group1->id, $user4->id); + $this->assertTrue(groups_is_member($group1->id, $user4->id)); + $this->assertTrue(groups_is_member($group2->id, $user4->id)); + + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES, 'enrol_meta'); + groups_add_member($group1->id, $user1->id); + + groups_remove_member($group1->id, $user1->id); + $this->assertTrue(groups_is_member($group1->id, $user1->id)); + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND, 'enrol_meta'); enrol_meta_sync($course4->id, false); $this->assertEquals(14, $DB->count_records('user_enrolments'));