'classpath' => 'enrol/self/externallib.php',
'description' => 'self enrolment instance information.',
'type' => 'read'
+ ),
+
+ 'enrol_self_enrol_user' => array(
+ 'classname' => 'enrol_self_external',
+ 'methodname' => 'enrol_user',
+ 'classpath' => 'enrol/self/externallib.php',
+ 'description' => 'Self enrol the current user in the given course.',
+ 'type' => 'write'
)
);
)
);
}
+
+ /**
+ * Returns description of method parameters
+ *
+ * @return external_function_parameters
+ * @since Moodle 3.0
+ */
+ public static function enrol_user_parameters() {
+ return new external_function_parameters(
+ array(
+ 'courseid' => new external_value(PARAM_INT, 'Id of the course'),
+ 'password' => new external_value(PARAM_RAW, 'Enrolment key', VALUE_DEFAULT, ''),
+ 'instanceid' => new external_value(PARAM_INT, 'Instance id of self enrolment plugin.', VALUE_DEFAULT, 0)
+ )
+ );
+ }
+
+ /**
+ * Self enrol the current user in the given course.
+ *
+ * @param int $courseid id of course
+ * @param string $password enrolment key
+ * @param int $instanceid instance id of self enrolment plugin
+ * @return array of warnings and status result
+ * @since Moodle 3.0
+ * @throws moodle_exception
+ */
+ public static function enrol_user($courseid, $password = '', $instanceid = 0) {
+ global $CFG;
+
+ require_once($CFG->libdir . '/enrollib.php');
+
+ $params = self::validate_parameters(self::enrol_user_parameters(),
+ array(
+ 'courseid' => $courseid,
+ 'password' => $password,
+ 'instanceid' => $instanceid
+ ));
+
+ $warnings = array();
+
+ $course = get_course($params['courseid']);
+ $context = context_course::instance($course->id);
+ // Note that we can't use validate_context because the user is not enrolled in the course.
+ require_login(null, false, null, false, true);
+
+ if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ throw new moodle_exception('coursehidden');
+ }
+
+ // Retrieve the self enrolment plugin.
+ $enrol = enrol_get_plugin('self');
+ if (empty($enrol)) {
+ throw new moodle_exception('canntenrol', 'enrol_self');
+ }
+
+ // We can expect multiple self-enrolment instances.
+ $instances = array();
+ $enrolinstances = enrol_get_instances($course->id, true);
+ foreach ($enrolinstances as $courseenrolinstance) {
+ if ($courseenrolinstance->enrol == "self") {
+ // Instance specified.
+ if (!empty($params['instanceid'])) {
+ if ($courseenrolinstance->id == $params['instanceid']) {
+ $instances[] = $courseenrolinstance;
+ break;
+ }
+ } else {
+ $instances[] = $courseenrolinstance;
+ }
+
+ }
+ }
+ if (empty($instances)) {
+ throw new moodle_exception('canntenrol', 'enrol_self');
+ }
+
+ // Try to enrol the user in the instance/s.
+ $enrolled = false;
+ foreach ($instances as $instance) {
+ $enrolstatus = $enrol->can_self_enrol($instance);
+ if ($enrolstatus === true) {
+ if ($instance->password and $params['password'] !== $instance->password) {
+
+ // Check if we are using group enrolment keys.
+ if ($instance->customint1) {
+ require_once($CFG->dirroot . "/enrol/self/locallib.php");
+
+ if (!enrol_self_check_group_enrolment_key($course->id, $params['password'])) {
+ $warnings[] = array(
+ 'item' => 'instance',
+ 'itemid' => $instance->id,
+ 'warningcode' => '2',
+ 'message' => get_string('passwordinvalid', 'enrol_self')
+ );
+ continue;
+ }
+ } else {
+ if ($enrol->get_config('showhint')) {
+ $hint = core_text::substr($instance->password, 0, 1);
+ $warnings[] = array(
+ 'item' => 'instance',
+ 'itemid' => $instance->id,
+ 'warningcode' => '3',
+ 'message' => s(get_string('passwordinvalidhint', 'enrol_self', $hint)) // message is PARAM_TEXT.
+ );
+ continue;
+ } else {
+ $warnings[] = array(
+ 'item' => 'instance',
+ 'itemid' => $instance->id,
+ 'warningcode' => '4',
+ 'message' => get_string('passwordinvalid', 'enrol_self')
+ );
+ continue;
+ }
+ }
+ }
+
+ // Do the enrolment.
+ $data = array('enrolpassword' => $params['password']);
+ $enrol->enrol_self($instance, (object) $data);
+ $enrolled = true;
+ break;
+ } else {
+ $warnings[] = array(
+ 'item' => 'instance',
+ 'itemid' => $instance->id,
+ 'warningcode' => '1',
+ 'message' => $enrolstatus
+ );
+ }
+ }
+
+ $result = array();
+ $result['status'] = $enrolled;
+ $result['warnings'] = $warnings;
+ return $result;
+ }
+
+ /**
+ * Returns description of method result value
+ *
+ * @return external_description
+ * @since Moodle 3.0
+ */
+ public static function enrol_user_returns() {
+ return new external_single_structure(
+ array(
+ 'status' => new external_value(PARAM_BOOL, 'status: true if the user is enrolled, false otherwise'),
+ 'warnings' => new external_warnings()
+ )
+ );
+ }
}
require_once("$CFG->libdir/formslib.php");
+/**
+ * Check if the given password match a group enrolment key in the specified course.
+ *
+ * @param int $courseid course id
+ * @param string $enrolpassword enrolment password
+ * @return bool True if match
+ * @since Moodle 3.0
+ */
+function enrol_self_check_group_enrolment_key($courseid, $enrolpassword) {
+ global $DB;
+
+ $found = false;
+ $groups = $DB->get_records('groups', array('courseid' => $courseid), 'id ASC', 'id, enrolmentkey');
+
+ foreach ($groups as $group) {
+ if (empty($group->enrolmentkey)) {
+ continue;
+ }
+ if ($group->enrolmentkey === $enrolpassword) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+}
+
class enrol_self_enrol_form extends moodleform {
protected $instance;
protected $toomany = false;
if ($instance->password) {
if ($data['enrolpassword'] !== $instance->password) {
if ($instance->customint1) {
- $groups = $DB->get_records('groups', array('courseid'=>$instance->courseid), 'id ASC', 'id, enrolmentkey');
- $found = false;
- foreach ($groups as $group) {
- if (empty($group->enrolmentkey)) {
- continue;
- }
- if ($group->enrolmentkey === $data['enrolpassword']) {
- $found = true;
- break;
- }
- }
- if (!$found) {
+ // Check group enrolment key.
+ if (!enrol_self_check_group_enrolment_key($instance->courseid, $data['enrolpassword'])) {
// We can not hint because there are probably multiple passwords.
$errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
}
$this->assertTrue($instanceinfo3['status']);
$this->assertEquals(get_string('password', 'enrol_self'), $instanceinfo3['enrolpassword']);
}
+
+ /**
+ * Test enrol_user
+ */
+ public function test_enrol_user() {
+ global $DB;
+
+ self::resetAfterTest(true);
+
+ $user = self::getDataGenerator()->create_user();
+ self::setUser($user);
+
+ $course1 = self::getDataGenerator()->create_course();
+ $course2 = self::getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1));
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+ $user4 = self::getDataGenerator()->create_user();
+
+ $context1 = context_course::instance($course1->id);
+ $context2 = context_course::instance($course2->id);
+
+ $selfplugin = enrol_get_plugin('self');
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+ $instance1id = $selfplugin->add_instance($course1, array('status' => ENROL_INSTANCE_ENABLED,
+ 'name' => 'Test instance 1',
+ 'customint6' => 1,
+ 'roleid' => $studentrole->id));
+ $instance2id = $selfplugin->add_instance($course2, array('status' => ENROL_INSTANCE_DISABLED,
+ 'customint6' => 1,
+ 'name' => 'Test instance 2',
+ 'roleid' => $studentrole->id));
+ $instance1 = $DB->get_record('enrol', array('id' => $instance1id), '*', MUST_EXIST);
+ $instance2 = $DB->get_record('enrol', array('id' => $instance2id), '*', MUST_EXIST);
+
+ self::setUser($user1);
+
+ // Self enrol me.
+ $result = enrol_self_external::enrol_user($course1->id);
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+
+ self::assertTrue($result['status']);
+ self::assertEquals(1, $DB->count_records('user_enrolments', array('enrolid' => $instance1->id)));
+ self::assertTrue(is_enrolled($context1, $user1));
+
+ // Add password.
+ $instance2->password = 'abcdef';
+ $DB->update_record('enrol', $instance2);
+
+ // Try instance not enabled.
+ try {
+ enrol_self_external::enrol_user($course2->id);
+ } catch (moodle_exception $e) {
+ self::assertEquals('canntenrol', $e->errorcode);
+ }
+
+ // Enable the instance.
+ $selfplugin->update_status($instance2, ENROL_INSTANCE_ENABLED);
+
+ // Try not passing a key.
+ $result = enrol_self_external::enrol_user($course2->id);
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertFalse($result['status']);
+ self::assertCount(1, $result['warnings']);
+ self::assertEquals('4', $result['warnings'][0]['warningcode']);
+
+ // Try passing an invalid key.
+ $result = enrol_self_external::enrol_user($course2->id, 'invalidkey');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertFalse($result['status']);
+ self::assertCount(1, $result['warnings']);
+ self::assertEquals('4', $result['warnings'][0]['warningcode']);
+
+ // Try passing an invalid key with hint.
+ $selfplugin->set_config('showhint', true);
+ $result = enrol_self_external::enrol_user($course2->id, 'invalidkey');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertFalse($result['status']);
+ self::assertCount(1, $result['warnings']);
+ self::assertEquals('3', $result['warnings'][0]['warningcode']);
+
+ // Everything correct, now.
+ $result = enrol_self_external::enrol_user($course2->id, 'abcdef');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+
+ self::assertTrue($result['status']);
+ self::assertEquals(1, $DB->count_records('user_enrolments', array('enrolid' => $instance2->id)));
+ self::assertTrue(is_enrolled($context2, $user1));
+
+ // Try group password now, other user.
+ $instance2->customint1 = 1;
+ $instance2->password = 'zyx';
+ $DB->update_record('enrol', $instance2);
+
+ $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
+ $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enrolmentkey' => 'zyx'));
+
+ self::setUser($user2);
+ // Try passing and invalid key for group.
+ $result = enrol_self_external::enrol_user($course2->id, 'invalidkey');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertFalse($result['status']);
+ self::assertCount(1, $result['warnings']);
+ self::assertEquals('2', $result['warnings'][0]['warningcode']);
+
+ // Now, everything ok.
+ $result = enrol_self_external::enrol_user($course2->id, 'zyx');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+
+ self::assertTrue($result['status']);
+ self::assertEquals(2, $DB->count_records('user_enrolments', array('enrolid' => $instance2->id)));
+ self::assertTrue(is_enrolled($context2, $user2));
+
+ // Try multiple instances now, multiple errors.
+ $instance3id = $selfplugin->add_instance($course2, array('status' => ENROL_INSTANCE_ENABLED,
+ 'customint6' => 1,
+ 'name' => 'Test instance 2',
+ 'roleid' => $studentrole->id));
+ $instance3 = $DB->get_record('enrol', array('id' => $instance3id), '*', MUST_EXIST);
+ $instance3->password = 'abcdef';
+ $DB->update_record('enrol', $instance3);
+
+ self::setUser($user3);
+ $result = enrol_self_external::enrol_user($course2->id, 'invalidkey');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertFalse($result['status']);
+ self::assertCount(2, $result['warnings']);
+
+ // Now, everything ok.
+ $result = enrol_self_external::enrol_user($course2->id, 'zyx');
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertTrue($result['status']);
+ self::assertTrue(is_enrolled($context2, $user3));
+
+ // Now test passing an instance id.
+ self::setUser($user4);
+ $result = enrol_self_external::enrol_user($course2->id, 'abcdef', $instance3id);
+ $result = external_api::clean_returnvalue(enrol_self_external::enrol_user_returns(), $result);
+ self::assertTrue($result['status']);
+ self::assertTrue(is_enrolled($context2, $user3));
+ self::assertCount(0, $result['warnings']);
+ self::assertEquals(1, $DB->count_records('user_enrolments', array('enrolid' => $instance3->id)));
+ }
}
$this->setUser($user1);
$this->assertSame($expectederrorstring, $selfplugin->can_self_enrol($instance1, true));
}
+
+ /**
+ * Test enrol_self_check_group_enrolment_key
+ */
+ public function test_enrol_self_check_group_enrolment_key() {
+ global $DB;
+ self::resetAfterTest(true);
+
+ // Test in course with groups.
+ $course = self::getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1));
+
+ $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
+ $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'enrolmentkey' => 'thepassword'));
+
+ $result = enrol_self_check_group_enrolment_key($course->id, 'invalidpassword');
+ $this->assertFalse($result);
+
+ $result = enrol_self_check_group_enrolment_key($course->id, 'thepassword');
+ $this->assertTrue($result);
+
+ // Test disabling group options.
+ $course->groupmode = NOGROUPS;
+ $course->groupmodeforce = 0;
+ $DB->update_record('course', $course);
+
+ $result = enrol_self_check_group_enrolment_key($course->id, 'invalidpassword');
+ $this->assertFalse($result);
+
+ $result = enrol_self_check_group_enrolment_key($course->id, 'thepassword');
+ $this->assertTrue($result);
+
+ // Test without groups.
+ $othercourse = self::getDataGenerator()->create_course();
+ $result = enrol_self_check_group_enrolment_key($othercourse->id, 'thepassword');
+ $this->assertFalse($result);
+
+ }
}
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2015051100; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2015051101; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2015050500; // Requires this Moodle version
$plugin->component = 'enrol_self'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 600;
'core_calendar_get_calendar_events',
'core_enrol_get_users_courses',
'core_enrol_get_enrolled_users',
+ 'enrol_self_enrol_user',
'core_user_get_users_by_id',
'core_webservice_get_site_info',
'core_notes_create_notes',
defined('MOODLE_INTERNAL') || die();
-$version = 2015100800.00; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2015100800.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.