diff --git a/enrol/meta/locallib.php b/enrol/meta/locallib.php index a23f9b5dc5b..3a3c26bda1f 100644 --- a/enrol/meta/locallib.php +++ b/enrol/meta/locallib.php @@ -90,12 +90,6 @@ class enrol_meta_handler { $context = context_course::instance($instance->courseid); - if (!$parentcontext = context_course::instance($instance->customint1, IGNORE_MISSING)) { - // linking to missing course is not possible - role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta')); - return; - } - // list of enrolments in parent course (we ignore meta enrols in parents completely) list($enabled, $params) = $DB->get_in_or_equal(explode(',', $CFG->enrol_plugins_enabled), SQL_PARAMS_NAMED, 'e'); $params['userid'] = $userid; @@ -114,10 +108,8 @@ class enrol_meta_handler { return; } - if (!enrol_is_enabled('meta')) { - if ($ue) { - role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta')); - } + if (!$parentcontext = context_course::instance($instance->customint1, IGNORE_MISSING)) { + // Weird, we should not get here. return; } @@ -172,9 +164,13 @@ class enrol_meta_handler { $ue->status = $parentstatus; } + $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES); + // only active users in enabled instances are supposed to have roles (we can reassign the roles any time later) if ($ue->status != ENROL_USER_ACTIVE or $instance->status != ENROL_INSTANCE_ENABLED) { - if ($roles) { + if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND) { + // Always keep the roles. + } else if ($roles) { role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); } return; @@ -187,6 +183,11 @@ class enrol_meta_handler { } } + if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND) { + // Always keep the roles. + return; + } + // remove roles foreach ($roles as $rid) { if (!isset($parentroles[$rid])) { @@ -206,25 +207,30 @@ class enrol_meta_handler { */ protected static function user_not_supposed_to_be_here($instance, $ue, context_course $context, $plugin) { if (!$ue) { - // not enrolled yet - simple! + // Not enrolled yet - simple! return; } $userid = $ue->userid; - $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL); + $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES); if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) { - // purges grades, group membership, preferences, etc. - admins were warned! + // Purges grades, group membership, preferences, etc. - admins were warned! $plugin->unenrol_user($instance, $userid); - return; - } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES - // just suspend users and remove all roles (we can reassign the roles any time later) + } else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND) { if ($ue->status != ENROL_USER_SUSPENDED) { $plugin->update_user_enrol($instance, $userid, ENROL_USER_SUSPENDED); - role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); } - return; + + } else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) { + if ($ue->status != ENROL_USER_SUSPENDED) { + $plugin->update_user_enrol($instance, $userid, ENROL_USER_SUSPENDED); + } + role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); + + } else { + debugging('Unknown unenrol action '.$unenrolaction); } } @@ -316,8 +322,10 @@ class enrol_meta_handler { * @return bool success */ public static function user_unenrolled($ue) { - - // keep unenrolling even if plugin disabled + if (!enrol_is_enabled('meta')) { + // This is slow, let enrol_meta_sync() deal with disabled plugin. + return true; + } if ($ue->enrol === 'meta') { // prevent circular dependencies - we can not sync meta enrolments recursively @@ -360,7 +368,10 @@ class enrol_meta_handler { public static function course_deleted($course) { global $DB; - // NOTE: do not test if plugin enabled, we want to keep disabling instances with invalid course links + if (!enrol_is_enabled('meta')) { + // This is slow, let enrol_meta_sync() deal with disabled plugin. + return true; + } // does anything want to sync with this parent? if (!$enrols = $DB->get_records('enrol', array('customint1'=>$course->id, 'enrol'=>'meta'), 'courseid ASC, id ASC')) { @@ -368,19 +379,29 @@ class enrol_meta_handler { } $plugin = enrol_get_plugin('meta'); + $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES); - // hack the DB info for all courses first - foreach ($enrols as $enrol) { - $enrol->customint1 = 0; - $enrol->status = ENROL_INSTANCE_DISABLED; - $DB->update_record('enrol', $enrol); - $context = context_course::instance($enrol->courseid); - role_unassign_all(array('contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$enrol->id)); + if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) { + // Simple, just delete this instance which purges all enrolments, + // admins were warned that this is risky setting! + foreach ($enrols as $enrol) { + $plugin->delete_instance($enrol); + } + return true; } - // now trigger sync for each instance and purge caches foreach ($enrols as $enrol) { - $plugin->update_status($enrol, ENROL_INSTANCE_DISABLED); + $enrol->customint = 0; + $DB->update_record('enrol', $enrol); + + if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND or $unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) { + // This makes all enrolments suspended very quickly. + $plugin->update_status($enrol, ENROL_INSTANCE_DISABLED); + } + if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) { + $context = context_course::instance($enrol->courseid); + role_unassign_all(array('contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$enrol->id)); + } } return true; @@ -419,7 +440,7 @@ function enrol_meta_sync($courseid = NULL, $verbose = false) { $meta = enrol_get_plugin('meta'); - $unenrolaction = $meta->get_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL); + $unenrolaction = $meta->get_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES); $skiproles = $meta->get_config('nosyncroleids', ''); $skiproles = empty($skiproles) ? array() : explode(',', $skiproles); $syncall = $meta->get_config('syncall', 1); @@ -493,19 +514,24 @@ function enrol_meta_sync($courseid = NULL, $verbose = false) { if ($verbose) { mtrace(" unenrolling: $ue->userid ==> $instance->courseid"); } - continue; - } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES - // just disable and ignore any changes + } else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND) { + if ($ue->status != ENROL_USER_SUSPENDED) { + $meta->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED); + if ($verbose) { + mtrace(" suspending: $ue->userid ==> $instance->courseid"); + } + } + + } else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) { if ($ue->status != ENROL_USER_SUSPENDED) { $meta->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED); $context = context_course::instance($instance->courseid); - role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$context->id, 'component'=>'enrol_meta')); + role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id)); if ($verbose) { mtrace(" suspending and removing all roles: $ue->userid ==> $instance->courseid"); } } - continue; } } $rs->close(); @@ -617,6 +643,7 @@ function enrol_meta_sync($courseid = NULL, $verbose = false) { } else { $notignored = ""; } + $sql = "SELECT ra.roleid, ra.userid, ra.contextid, ra.itemid, e.courseid FROM {role_assignments} ra JOIN {enrol} e ON (e.id = ra.itemid AND ra.component = 'enrol_meta' AND e.enrol = 'meta' $onecourse) @@ -625,14 +652,16 @@ function enrol_meta_sync($courseid = NULL, $verbose = false) { LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = ra.userid AND ue.status = :activeuser) WHERE pra.id IS NULL OR ue.id IS NULL OR e.status <> :enabledinstance"; - $rs = $DB->get_recordset_sql($sql, $params); - foreach($rs as $ra) { - role_unassign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_meta', $ra->itemid); - if ($verbose) { - mtrace(" unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname); + if ($unenrolaction != ENROL_EXT_REMOVED_SUSPEND) { + $rs = $DB->get_recordset_sql($sql, $params); + foreach($rs as $ra) { + role_unassign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_meta', $ra->itemid); + if ($verbose) { + mtrace(" unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname); + } } + $rs->close(); } - $rs->close(); // kick out or suspend users without synced roles if syncall disabled diff --git a/enrol/meta/settings.php b/enrol/meta/settings.php index d2f5d935510..3cbc4e12dc0 100644 --- a/enrol/meta/settings.php +++ b/enrol/meta/settings.php @@ -36,8 +36,10 @@ if ($ADMIN->fulltree) { $settings->add(new admin_setting_configcheckbox('enrol_meta/syncall', get_string('syncall', 'enrol_meta'), get_string('syncall_desc', 'enrol_meta'), 1)); $options = array( - ENROL_EXT_REMOVED_UNENROL => get_string('extremovedunenrol', 'enrol'), - ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'enrol')); + ENROL_EXT_REMOVED_UNENROL => get_string('extremovedunenrol', 'core_enrol'), + ENROL_EXT_REMOVED_SUSPEND => get_string('extremovedsuspend', 'core_enrol'), + ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'core_enrol'), + ); $settings->add(new admin_setting_configselect('enrol_meta/unenrolaction', get_string('extremovedaction', 'enrol'), get_string('extremovedaction_help', 'enrol'), ENROL_EXT_REMOVED_SUSPENDNOROLES, $options)); } } diff --git a/enrol/meta/tests/plugin_test.php b/enrol/meta/tests/plugin_test.php new file mode 100644 index 00000000000..b4f00b338b1 --- /dev/null +++ b/enrol/meta/tests/plugin_test.php @@ -0,0 +1,443 @@ +. + +/** + * Meta enrolment sync functional test. + * + * @package enrol_meta + * @category phpunit + * @copyright 2013 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +class enrol_meta_plugin_testcase extends advanced_testcase { + + protected function enable_plugin() { + $enabled = enrol_get_plugins(true); + $enabled['meta'] = true; + $enabled = array_keys($enabled); + set_config('enrol_plugins_enabled', implode(',', $enabled)); + } + + protected function disable_plugin() { + $enabled = enrol_get_plugins(true); + unset($enabled['meta']); + $enabled = array_keys($enabled); + set_config('enrol_plugins_enabled', implode(',', $enabled)); + } + + protected function is_meta_enrolled($user, $enrol, $role = null) { + global $DB; + + if (!$DB->record_exists('user_enrolments', array('enrolid'=>$enrol->id, 'userid'=>$user->id))) { + return false; + } + + if ($role === null) { + return true; + } + + return $this->has_role($user, $enrol, $role); + } + + protected function has_role($user, $enrol, $role) { + global $DB; + + $context = context_course::instance($enrol->courseid); + + if ($role === false) { + if ($DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$user->id, 'component'=>'enrol_meta', 'itemid'=>$enrol->id))) { + return false; + } + } else if (!$DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$user->id, 'roleid'=>$role->id, 'component'=>'enrol_meta', 'itemid'=>$enrol->id))) { + return false; + } + + return true; + } + + public function test_sync() { + global $CFG, $DB; + + $this->resetAfterTest(true); + + $metalplugin = enrol_get_plugin('meta'); + $manplugin = enrol_get_plugin('manual'); + + + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + $user4 = $this->getDataGenerator()->create_user(); + $user5 = $this->getDataGenerator()->create_user(); + + $course1 = $this->getDataGenerator()->create_course(); + $course2 = $this->getDataGenerator()->create_course(); + $course3 = $this->getDataGenerator()->create_course(); + $course4 = $this->getDataGenerator()->create_course(); + $manual1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $manual2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $manual3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $manual4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST); + + $student = $DB->get_record('role', array('shortname'=>'student')); + $teacher = $DB->get_record('role', array('shortname'=>'teacher')); + $manager = $DB->get_record('role', array('shortname'=>'manager')); + + $this->disable_plugin(); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->getDataGenerator()->enrol_user($user2->id, $course1->id, $student->id); + $this->getDataGenerator()->enrol_user($user3->id, $course1->id, 0); + $this->getDataGenerator()->enrol_user($user4->id, $course1->id, $teacher->id); + $this->getDataGenerator()->enrol_user($user5->id, $course1->id, $manager->id); + + $this->getDataGenerator()->enrol_user($user1->id, $course2->id, $student->id); + $this->getDataGenerator()->enrol_user($user2->id, $course2->id, $teacher->id); + + $this->assertEquals(7, $DB->count_records('user_enrolments')); + $this->assertEquals(6, $DB->count_records('role_assignments')); + + set_config('syncall', 0, 'enrol_meta'); + set_config('nosyncroleids', $manager->id, 'enrol_meta'); + + require_once($CFG->dirroot.'/enrol/meta/locallib.php'); + + enrol_meta_sync(null, false); + $this->assertEquals(7, $DB->count_records('user_enrolments')); + $this->assertEquals(6, $DB->count_records('role_assignments')); + + $this->enable_plugin(); + enrol_meta_sync(null, false); + $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)); + $e3 = $metalplugin->add_instance($course4, array('customint1'=>$course2->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)); + + enrol_meta_sync($course4->id, false); + $this->assertEquals(9, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol3, $student)); + $this->assertTrue($this->is_meta_enrolled($user2, $enrol3, $teacher)); + + enrol_meta_sync(null, false); + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(13, $DB->count_records('role_assignments')); + + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + $this->assertTrue($this->is_meta_enrolled($user2, $enrol1, $student)); + $this->assertFalse($this->is_meta_enrolled($user3, $enrol1)); + $this->assertTrue($this->is_meta_enrolled($user4, $enrol1, $teacher)); + $this->assertFalse($this->is_meta_enrolled($user5, $enrol1)); + + $this->assertTrue($this->is_meta_enrolled($user1, $enrol2, $student)); + $this->assertTrue($this->is_meta_enrolled($user2, $enrol2, $teacher)); + + $this->assertTrue($this->is_meta_enrolled($user1, $enrol3, $student)); + $this->assertTrue($this->is_meta_enrolled($user2, $enrol3, $teacher)); + + set_config('syncall', 1, 'enrol_meta'); + enrol_meta_sync(null, false); + $this->assertEquals(16, $DB->count_records('user_enrolments')); + $this->assertEquals(13, $DB->count_records('role_assignments')); + + $this->assertTrue($this->is_meta_enrolled($user3, $enrol1, false)); + $this->assertTrue($this->is_meta_enrolled($user5, $enrol1, false)); + + $this->assertEquals(16, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->disable_plugin(); + $manplugin->unenrol_user($manual1, $user1->id); + $manplugin->unenrol_user($manual2, $user1->id); + + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(11, $DB->count_records('role_assignments')); + $this->assertEquals(14, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + $this->enable_plugin(); + + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND, 'enrol_meta'); + enrol_meta_sync($course4->id, false); + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(11, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol3, $student)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol3->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + + enrol_meta_sync(null, false); + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(11, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol1->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol2, $student)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol2->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES, 'enrol_meta'); + enrol_meta_sync($course4->id, false); + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol3, false)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol3->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + + enrol_meta_sync(null, false); + $this->assertEquals(14, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, false)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol1->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol2, false)); + $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$enrol2->id, 'status'=>ENROL_USER_SUSPENDED, 'userid'=>$user1->id))); + + set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL, 'enrol_meta'); + enrol_meta_sync($course4->id, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol3)); + + enrol_meta_sync(null, false); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol2)); + + + // Now try sync triggered by events. + + set_config('syncall', 1, 'enrol_meta'); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + $manplugin->unenrol_user($manual1, $user1->id); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + enrol_meta_sync(null, false); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 0); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, false)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, false)); + + $manplugin->unenrol_user($manual1, $user1->id); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + enrol_meta_sync(null, false); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + + set_config('syncall', 0, 'enrol_meta'); + enrol_meta_sync(null, false); + $this->assertEquals(9, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(9, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 0); + $this->assertEquals(10, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(10, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(10, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(10, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1, $student)); + + role_assign($teacher->id, $user1->id, context_course::instance($course1->id)->id); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $teacher)); + enrol_meta_sync(null, false); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $teacher)); + + role_unassign($teacher->id, $user1->id, context_course::instance($course1->id)->id); + $this->assertEquals(10, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(10, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(10, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(10, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1, $student)); + + $manplugin->unenrol_user($manual1, $user1->id); + $this->assertEquals(9, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(9, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertFalse($this->is_meta_enrolled($user1, $enrol1)); + + set_config('syncall', 1, 'enrol_meta'); + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND, 'enrol_meta'); + enrol_meta_sync(null, false); + $this->assertEquals(11, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + $manplugin->update_user_enrol($manual1, $user1->id, ENROL_USER_SUSPENDED); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + $manplugin->unenrol_user($manual1, $user1->id); + $this->assertEquals(12, $DB->count_records('user_enrolments')); + $this->assertEquals(9, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(12, $DB->count_records('user_enrolments')); + $this->assertEquals(9, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + set_config('syncall', 1, 'enrol_meta'); + set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES, 'enrol_meta'); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + $manplugin->unenrol_user($manual1, $user1->id); + $this->assertEquals(12, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, false)); + enrol_meta_sync(null, false); + $this->assertEquals(12, $DB->count_records('user_enrolments')); + $this->assertEquals(8, $DB->count_records('role_assignments')); + $this->assertEquals(11, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, false)); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $student->id); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + $this->assertTrue($this->is_meta_enrolled($user1, $enrol1, $student)); + + + set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL, 'enrol_meta'); + enrol_meta_sync(null, false); + $this->assertEquals(13, $DB->count_records('user_enrolments')); + $this->assertEquals(10, $DB->count_records('role_assignments')); + $this->assertEquals(13, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + delete_course($course1, false); + $this->assertEquals(3, $DB->count_records('user_enrolments')); + $this->assertEquals(3, $DB->count_records('role_assignments')); + $this->assertEquals(3, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + enrol_meta_sync(null, false); + $this->assertEquals(3, $DB->count_records('user_enrolments')); + $this->assertEquals(3, $DB->count_records('role_assignments')); + $this->assertEquals(3, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + delete_course($course2, false); + $this->assertEquals(0, $DB->count_records('user_enrolments')); + $this->assertEquals(0, $DB->count_records('role_assignments')); + $this->assertEquals(0, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + enrol_meta_sync(null, false); + $this->assertEquals(0, $DB->count_records('user_enrolments')); + $this->assertEquals(0, $DB->count_records('role_assignments')); + $this->assertEquals(0, $DB->count_records('user_enrolments', array('status'=>ENROL_USER_ACTIVE))); + + delete_course($course3, false); + delete_course($course4, false); + + } +}