Merge branch 'MDL-59369-master' of git://github.com/junpataleta/moodle
This commit is contained in:
@@ -236,7 +236,9 @@ class enrol_cohort_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability('enrol/cohort:unenrol', $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,9 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability('enrol/database:unenrol', $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ $instance = $DB->get_record('enrol', array('id'=>$ue->enrolid), '*', MUST_EXIST)
|
||||
$course = $DB->get_record('course', array('id'=>$instance->courseid), '*', MUST_EXIST);
|
||||
|
||||
// The URL of the enrolled users page for the course.
|
||||
$usersurl = new moodle_url('/enrol/users.php', array('id' => $course->id));
|
||||
$usersurl = new moodle_url('/user/index.php', array('id' => $course->id));
|
||||
|
||||
// Do not allow any changes if plugin disabled, not available or not suitable.
|
||||
if (!$plugin = enrol_get_plugin($instance->enrol)) {
|
||||
|
||||
@@ -28,15 +28,10 @@ require_once("$CFG->libdir/formslib.php");
|
||||
|
||||
class enrol_user_enrolment_form extends moodleform {
|
||||
function definition() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$user = $this->_customdata['user'];
|
||||
$course = $this->_customdata['course'];
|
||||
$ue = $this->_customdata['ue'];
|
||||
|
||||
$mform->addElement('header','general', '');
|
||||
$ue = $this->_customdata['ue'];
|
||||
$modal = !empty($this->_customdata['modal']);
|
||||
|
||||
$options = array(ENROL_USER_ACTIVE => get_string('participationactive', 'enrol'),
|
||||
ENROL_USER_SUSPENDED => get_string('participationsuspended', 'enrol'));
|
||||
@@ -56,7 +51,10 @@ class enrol_user_enrolment_form extends moodleform {
|
||||
$mform->addElement('hidden', 'ifilter');
|
||||
$mform->setType('ifilter', PARAM_ALPHA);
|
||||
|
||||
$this->add_action_buttons();
|
||||
// Show action buttons if this is not being rendered as a fragment.
|
||||
if (!$modal) {
|
||||
$this->add_action_buttons();
|
||||
}
|
||||
|
||||
$this->set_data(array(
|
||||
'ue' => $ue->id,
|
||||
@@ -71,8 +69,7 @@ class enrol_user_enrolment_form extends moodleform {
|
||||
|
||||
if (!empty($data['timestart']) and !empty($data['timeend'])) {
|
||||
if ($data['timestart'] >= $data['timeend']) {
|
||||
$errors['timestart'] = get_string('error');
|
||||
$errors['timeend'] = get_string('error');
|
||||
$errors['timeend'] = get_string('enroltimeendinvalid', 'enrol');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -805,6 +805,107 @@ class core_enrol_external extends external_api {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of edit_user_enrolment() parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function edit_user_enrolment_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'courseid' => new external_value(PARAM_INT, 'User enrolment ID'),
|
||||
'ueid' => new external_value(PARAM_INT, 'User enrolment ID'),
|
||||
'status' => new external_value(PARAM_INT, 'Enrolment status'),
|
||||
'timestart' => new external_value(PARAM_INT, 'Enrolment start timestamp', VALUE_DEFAULT, 0),
|
||||
'timeend' => new external_value(PARAM_INT, 'Enrolment end timestamp', VALUE_DEFAULT, 0),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* External function that updates a given user enrolment.
|
||||
*
|
||||
* @param int $courseid The course ID.
|
||||
* @param int $ueid The user enrolment ID.
|
||||
* @param int $status The enrolment status.
|
||||
* @param int $timestart Enrolment start timestamp.
|
||||
* @param int $timeend Enrolment end timestamp.
|
||||
* @return array An array consisting of the processing result, errors and form output, if available.
|
||||
*/
|
||||
public static function edit_user_enrolment($courseid, $ueid, $status, $timestart = 0, $timeend = 0) {
|
||||
global $CFG, $DB, $PAGE;
|
||||
|
||||
$params = self::validate_parameters(self::edit_user_enrolment_parameters(), [
|
||||
'courseid' => $courseid,
|
||||
'ueid' => $ueid,
|
||||
'status' => $status,
|
||||
'timestart' => $timestart,
|
||||
'timeend' => $timeend,
|
||||
]);
|
||||
|
||||
$course = get_course($courseid);
|
||||
$context = context_course::instance($course->id);
|
||||
self::validate_context($context);
|
||||
|
||||
$userenrolment = $DB->get_record('user_enrolments', ['id' => $params['ueid']], '*', MUST_EXIST);
|
||||
$userenroldata = [
|
||||
'status' => $params['status'],
|
||||
'timestart' => $params['timestart'],
|
||||
'timeend' => $params['timeend'],
|
||||
];
|
||||
|
||||
$result = false;
|
||||
$errors = [];
|
||||
|
||||
// Validate data against the edit user enrolment form.
|
||||
require_once("$CFG->dirroot/enrol/editenrolment_form.php");
|
||||
$customformdata = [
|
||||
'ue' => $userenrolment,
|
||||
'modal' => true,
|
||||
];
|
||||
$mform = new \enrol_user_enrolment_form(null, $customformdata, 'post', '', null, true, $userenroldata);
|
||||
$mform->set_data($userenroldata);
|
||||
$validationerrors = $mform->validation($userenroldata, null);
|
||||
if (empty($validationerrors)) {
|
||||
require_once($CFG->dirroot . '/enrol/locallib.php');
|
||||
$manager = new course_enrolment_manager($PAGE, $course);
|
||||
$result = $manager->edit_enrolment($userenrolment, (object)$userenroldata);
|
||||
} else {
|
||||
foreach ($validationerrors as $key => $errormessage) {
|
||||
$errors[] = (object)[
|
||||
'key' => $key,
|
||||
'message' => $errormessage
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'result' => $result,
|
||||
'errors' => $errors,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of edit_user_enrolment() result value
|
||||
*
|
||||
* @return external_description
|
||||
*/
|
||||
public static function edit_user_enrolment_returns() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'result' => new external_value(PARAM_BOOL, 'True if the user\'s enrolment was successfully updated'),
|
||||
'errors' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
array(
|
||||
'key' => new external_value(PARAM_TEXT, 'The data that failed the validation'),
|
||||
'message' => new external_value(PARAM_TEXT, 'The error message'),
|
||||
)
|
||||
), 'List of validation errors'
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -132,11 +132,14 @@ class enrol_flatfile_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability("enrol/flatfile:unenrol", $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
if ($this->allow_manage($instance) && has_capability("enrol/flatfile:manage", $context)) {
|
||||
$url = new moodle_url('/enrol/editenrolment.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, array('class'=>'editenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'editenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_EDIT);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, $actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
+4
-3
@@ -392,13 +392,14 @@ class enrol_lti_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability("enrol/lti:unenrol", $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
array('class' => 'unenrollink', 'rel' => $ue->id));
|
||||
$actionparams);
|
||||
}
|
||||
if ($this->allow_manage($instance) && has_capability("enrol/lti:manage", $context)) {
|
||||
$url = new moodle_url('/enrol/editenrolment.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url,
|
||||
array('class' => 'editenrollink', 'rel' => $ue->id));
|
||||
$actionparams = array('class' => 'editenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_EDIT);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, $actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -376,11 +376,14 @@ class enrol_manual_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability("enrol/manual:unenrol", $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
if ($this->allow_manage($instance) && has_capability("enrol/manual:manage", $context)) {
|
||||
$url = new moodle_url('/enrol/editenrolment.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, array('class'=>'editenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'editenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_EDIT);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, $actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
+3
-1
@@ -110,7 +110,9 @@ class enrol_meta_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol_user($instance, $ue) && has_capability('enrol/meta:unenrol', $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -16,18 +16,21 @@ Feature: Enrolments are synchronised with meta courses
|
||||
| Course 1 | C1C1 |
|
||||
| Course 2 | C2C2 |
|
||||
| Course 3 | C3C3 |
|
||||
| Course 4 | C4C4 |
|
||||
And the following "groups" exist:
|
||||
| name | course | idnumber |
|
||||
| Groupcourse 1 | C3C3 | G1 |
|
||||
| Groupcourse 2 | C3C3 | G2 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1C1 | student |
|
||||
| student2 | C1C1 | student |
|
||||
| student3 | C1C1 | student |
|
||||
| student4 | C1C1 | student |
|
||||
| student1 | C2C2 | student |
|
||||
| student2 | C2C2 | student |
|
||||
| user | course | role | status |
|
||||
| student1 | C1C1 | student | 0 |
|
||||
| student2 | C1C1 | student | 0 |
|
||||
| student3 | C1C1 | student | 0 |
|
||||
| student4 | C1C1 | student | 0 |
|
||||
| student1 | C2C2 | student | 0 |
|
||||
| student2 | C2C2 | student | 0 |
|
||||
| student1 | C4C4 | student | 0 |
|
||||
| student2 | C4C4 | student | 1 |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Manage enrol plugins" node in "Site administration > Plugins > Enrolments"
|
||||
And I click on "Enable" "link" in the "Course meta link" "table_row"
|
||||
@@ -105,3 +108,13 @@ Feature: Enrolments are synchronised with meta courses
|
||||
And I should see "Groupcourse 1" in the "Student 4" "table_row"
|
||||
And I should see "Course 2" in the "Student 1" "table_row"
|
||||
And I should not see "Course 2" in the "Student 3" "table_row"
|
||||
|
||||
Scenario: Unenrol a user from the course participants page that was enrolled via course meta link.
|
||||
Given I am on "Course 3" course homepage
|
||||
And I add "Course meta link" enrolment method with:
|
||||
| Link course | C4C4 |
|
||||
And I navigate to course participants
|
||||
# Suspended users can be unenrolled.
|
||||
When I click on "//a[@data-action='unenrol']" "xpath_element" in the "student2" "table_row"
|
||||
And I click on "Yes" "button"
|
||||
Then I should not see "Student 2" in the "participants" "table"
|
||||
|
||||
@@ -291,11 +291,14 @@ class enrol_paypal_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol($instance) && has_capability("enrol/paypal:unenrol", $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
if ($this->allow_manage($instance) && has_capability("enrol/paypal:manage", $context)) {
|
||||
$url = new moodle_url('/enrol/editenrolment.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, array('class'=>'editenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'editenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_EDIT);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, $actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
+5
-2
@@ -536,11 +536,14 @@ class enrol_self_plugin extends enrol_plugin {
|
||||
$params['ue'] = $ue->id;
|
||||
if ($this->allow_unenrol($instance) && has_capability("enrol/self:unenrol", $context)) {
|
||||
$url = new moodle_url('/enrol/unenroluser.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'unenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_UNENROL);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url,
|
||||
$actionparams);
|
||||
}
|
||||
if ($this->allow_manage($instance) && has_capability("enrol/self:manage", $context)) {
|
||||
$url = new moodle_url('/enrol/editenrolment.php', $params);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, array('class'=>'editenrollink', 'rel'=>$ue->id));
|
||||
$actionparams = array('class' => 'editenrollink', 'rel' => $ue->id, 'data-action' => ENROL_ACTION_EDIT);
|
||||
$actions[] = new user_enrolment_action(new pix_icon('t/edit', ''), get_string('edit'), $url, $actionparams);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -87,3 +87,41 @@ Feature: Users can auto-enrol themself in courses where self enrolment is allowe
|
||||
Then I should see "Topic 1"
|
||||
And I should not see "Enrolment options"
|
||||
And I should not see "Enrol me in this course"
|
||||
|
||||
@javascript
|
||||
Scenario: Edit a self-enrolled user's enrolment from the course participants page
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I add "Self enrolment" enrolment method with:
|
||||
| Custom instance name | Test student enrolment |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I press "Enrol me"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='editenrolment']" "xpath_element" in the "student1" "table_row"
|
||||
And I should see "Edit Student 1's enrolment"
|
||||
And I set the field "Status" to "Suspended"
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Suspended" in the "student1" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Unenrol a self-enrolled student from the course participants page
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I add "Self enrolment" enrolment method with:
|
||||
| Custom instance name | Test student enrolment |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I press "Enrol me"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='unenrol']" "xpath_element" in the "student1" "table_row"
|
||||
And I click on "Yes" "button"
|
||||
Then I should not see "Student 1" in the "participants" "table"
|
||||
|
||||
@@ -682,4 +682,86 @@ class core_enrol_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($data->student1->id, $expecteduser['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for core_enrol_external::edit_user_enrolment().
|
||||
*/
|
||||
public function test_edit_user_enrolment() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$datagen = $this->getDataGenerator();
|
||||
|
||||
/** @var enrol_manual_plugin $manualplugin */
|
||||
$manualplugin = enrol_get_plugin('manual');
|
||||
$this->assertNotNull($manualplugin);
|
||||
|
||||
$studentroleid = $DB->get_field('role', 'id', ['shortname' => 'student'], MUST_EXIST);
|
||||
$teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher'], MUST_EXIST);
|
||||
$course = $datagen->create_course();
|
||||
$user = $datagen->create_user();
|
||||
$teacher = $datagen->create_user();
|
||||
|
||||
$instanceid = null;
|
||||
$instances = enrol_get_instances($course->id, true);
|
||||
foreach ($instances as $inst) {
|
||||
if ($inst->enrol == 'manual') {
|
||||
$instanceid = (int)$inst->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (empty($instanceid)) {
|
||||
$instanceid = $manualplugin->add_default_instance($course);
|
||||
if (empty($instanceid)) {
|
||||
$instanceid = $manualplugin->add_instance($course);
|
||||
}
|
||||
}
|
||||
$this->assertNotNull($instanceid);
|
||||
|
||||
$instance = $DB->get_record('enrol', ['id' => $instanceid], '*', MUST_EXIST);
|
||||
$manualplugin->enrol_user($instance, $user->id, $studentroleid, 0, 0, ENROL_USER_ACTIVE);
|
||||
$manualplugin->enrol_user($instance, $teacher->id, $teacherroleid, 0, 0, ENROL_USER_ACTIVE);
|
||||
$ueid = (int)$DB->get_field(
|
||||
'user_enrolments',
|
||||
'id',
|
||||
['enrolid' => $instance->id, 'userid' => $user->id],
|
||||
MUST_EXIST
|
||||
);
|
||||
|
||||
// Login as teacher.
|
||||
$this->setUser($teacher);
|
||||
|
||||
$now = new DateTime();
|
||||
$nowtime = $now->getTimestamp();
|
||||
|
||||
// Invalid data.
|
||||
$data = core_enrol_external::edit_user_enrolment($course->id, $ueid, ENROL_USER_ACTIVE, $nowtime, $nowtime);
|
||||
$data = external_api::clean_returnvalue(core_enrol_external::edit_user_enrolment_returns(), $data);
|
||||
$this->assertFalse($data['result']);
|
||||
$this->assertNotEmpty($data['errors']);
|
||||
|
||||
// Valid data.
|
||||
$nextmonth = clone($now);
|
||||
$nextmonth->add(new DateInterval('P1M'));
|
||||
$nextmonthtime = $nextmonth->getTimestamp();
|
||||
$data = core_enrol_external::edit_user_enrolment($course->id, $ueid, ENROL_USER_ACTIVE, $nowtime, $nextmonthtime);
|
||||
$data = external_api::clean_returnvalue(core_enrol_external::edit_user_enrolment_returns(), $data);
|
||||
$this->assertTrue($data['result']);
|
||||
$this->assertEmpty($data['errors']);
|
||||
|
||||
// Check updated user enrolment.
|
||||
$ue = $DB->get_record('user_enrolments', ['id' => $ueid], '*', MUST_EXIST);
|
||||
$this->assertEquals(ENROL_USER_ACTIVE, $ue->status);
|
||||
$this->assertEquals($nowtime, $ue->timestart);
|
||||
$this->assertEquals($nextmonthtime, $ue->timeend);
|
||||
|
||||
// Suspend user.
|
||||
$data = core_enrol_external::edit_user_enrolment($course->id, $ueid, ENROL_USER_SUSPENDED);
|
||||
$data = external_api::clean_returnvalue(core_enrol_external::edit_user_enrolment_returns(), $data);
|
||||
$this->assertTrue($data['result']);
|
||||
$this->assertEmpty($data['errors']);
|
||||
|
||||
// Check updated user enrolment.
|
||||
$ue = $DB->get_record('user_enrolments', ['id' => $ueid], '*', MUST_EXIST);
|
||||
$this->assertEquals(ENROL_USER_SUSPENDED, $ue->status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,7 @@ if (!$plugin->allow_unenrol_user($instance, $ue) or !has_capability("enrol/$inst
|
||||
$manager = new course_enrolment_manager($PAGE, $course, $filter);
|
||||
$table = new course_enrolment_users_table($manager, $PAGE);
|
||||
|
||||
$returnurl = new moodle_url('/enrol/users.php', array('id' => $course->id)+$manager->get_url_params()+$table->get_url_params());
|
||||
$usersurl = new moodle_url('/enrol/users.php', array('id' => $course->id));
|
||||
$usersurl = new moodle_url('/user/index.php', array('id' => $course->id));
|
||||
|
||||
$PAGE->set_pagelayout('admin');
|
||||
navigation_node::override_active_url($usersurl);
|
||||
@@ -67,7 +66,7 @@ navigation_node::override_active_url($usersurl);
|
||||
// If the unenrolment has been confirmed and the sesskey is valid unenrol the user.
|
||||
if ($confirm && confirm_sesskey()) {
|
||||
$plugin->unenrol_user($instance, $ue->userid);
|
||||
redirect($returnurl);
|
||||
redirect($usersurl);
|
||||
}
|
||||
|
||||
$yesurl = new moodle_url($PAGE->url, array('confirm'=>1, 'sesskey'=>sesskey()));
|
||||
@@ -82,5 +81,5 @@ $PAGE->navbar->add($fullname);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading($fullname);
|
||||
echo $OUTPUT->confirm($message, $yesurl, $returnurl);
|
||||
echo $OUTPUT->confirm($message, $yesurl, $usersurl);
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -43,11 +43,13 @@ $string['deleteinstancenousersconfirm'] = 'You are about to delete the enrolment
|
||||
$string['disableinstanceconfirmself'] = 'Are you really sure you want to disable instance "{$a->name}" that gives you access to this course? It is possible that you will not be able to access this course if you continue.';
|
||||
$string['durationdays'] = '{$a} days';
|
||||
$string['editenrolment'] = 'Edit enrolment';
|
||||
$string['edituserenrolment'] = 'Edit {$a}\'s enrolment';
|
||||
$string['enrol'] = 'Enrol';
|
||||
$string['enrolcandidates'] = 'Not enrolled users';
|
||||
$string['enrolcandidatesmatching'] = 'Matching not enrolled users';
|
||||
$string['enrolcohort'] = 'Enrol cohort';
|
||||
$string['enrolcohortusers'] = 'Enrol users';
|
||||
$string['enroldetails'] = 'Enrolment details';
|
||||
$string['eventenrolinstancecreated'] = 'Enrolment instance created';
|
||||
$string['eventenrolinstancedeleted'] = 'Enrolment instance deleted';
|
||||
$string['eventenrolinstanceupdated'] = 'Enrolment instance updated';
|
||||
@@ -58,6 +60,7 @@ $string['enrolme'] = 'Enrol me in this course';
|
||||
$string['enrolmentinstances'] = 'Enrolment methods';
|
||||
$string['enrolmentnew'] = 'New enrolment in {$a}';
|
||||
$string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"';
|
||||
$string['enrolmentmethod'] = 'Enrolment method';
|
||||
$string['enrolments'] = 'Enrolments';
|
||||
$string['enrolmentoptions'] = 'Enrolment options';
|
||||
$string['enrolnotpermitted'] = 'You do not have permission or are not allowed to enrol someone in this course';
|
||||
@@ -67,6 +70,7 @@ $string['enrolusers'] = 'Enrol users';
|
||||
$string['enrolxusers'] = 'Enrol {$a} users';
|
||||
$string['enroltimecreated'] = 'Enrolment created';
|
||||
$string['enroltimeend'] = 'Enrolment ends';
|
||||
$string['enroltimeendinvalid'] = 'Enrolment end date must be after the enrolment start date';
|
||||
$string['enroltimestart'] = 'Enrolment starts';
|
||||
$string['errajaxfailedenrol'] = 'Failed to enrol user';
|
||||
$string['errajaxsearch'] = 'Error when searching users';
|
||||
@@ -104,6 +108,7 @@ $string['notenrollable'] = 'You can not enrol yourself in this course.';
|
||||
$string['notenrolledusers'] = 'Other users';
|
||||
$string['otheruserdesc'] = 'The following users are not enrolled in this course but do have roles, inherited or assigned within it.';
|
||||
$string['participationactive'] = 'Active';
|
||||
$string['participationnotcurrent'] = 'Not current';
|
||||
$string['participationstatus'] = 'Status';
|
||||
$string['participationsuspended'] = 'Suspended';
|
||||
$string['periodend'] = 'until {$a}';
|
||||
|
||||
@@ -482,6 +482,14 @@ $functions = array(
|
||||
'capabilities' => 'moodle/course:viewparticipants',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
'core_enrol_edit_user_enrolment' => array(
|
||||
'classname' => 'core_enrol_external',
|
||||
'methodname' => 'edit_user_enrolment',
|
||||
'classpath' => 'enrol/externallib.php',
|
||||
'description' => 'External function that updates a given user enrolment',
|
||||
'type' => 'write',
|
||||
'ajax' => true,
|
||||
),
|
||||
'core_fetch_notifications' => array(
|
||||
'classname' => 'core_external',
|
||||
'methodname' => 'fetch_notifications',
|
||||
|
||||
@@ -87,6 +87,12 @@ define('ENROL_SEND_EMAIL_FROM_KEY_HOLDER', 2);
|
||||
*/
|
||||
define('ENROL_SEND_EMAIL_FROM_NOREPLY', 3);
|
||||
|
||||
/** Edit enrolment action. */
|
||||
define('ENROL_ACTION_EDIT', 'editenrolment');
|
||||
|
||||
/** Unenrol action. */
|
||||
define('ENROL_ACTION_UNENROL', 'unenrol');
|
||||
|
||||
/**
|
||||
* Returns instances of enrol plugins
|
||||
* @param bool $enabled return enabled only
|
||||
@@ -1414,6 +1420,44 @@ function enrol_send_welcome_email_options() {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve the user enrolment form as a fragment.
|
||||
*
|
||||
* @param array $args List of named arguments for the fragment loader.
|
||||
* @return string
|
||||
*/
|
||||
function enrol_output_fragment_user_enrolment_form($args) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$args = (object) $args;
|
||||
$context = $args->context;
|
||||
require_capability('moodle/course:enrolreview', $context);
|
||||
|
||||
$ueid = $args->ueid;
|
||||
$userenrolment = $DB->get_record('user_enrolments', ['id' => $ueid], '*', MUST_EXIST);
|
||||
$customdata = [
|
||||
'ue' => $userenrolment,
|
||||
'modal' => true,
|
||||
];
|
||||
|
||||
// Set the data if applicable.
|
||||
$data = [];
|
||||
if (isset($args->formdata)) {
|
||||
$serialiseddata = json_decode($args->formdata);
|
||||
parse_str($serialiseddata, $data);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/enrol/editenrolment_form.php");
|
||||
$mform = new \enrol_user_enrolment_form(null, $customdata, 'post', '', null, true, $data);
|
||||
|
||||
if (!empty($data)) {
|
||||
$mform->set_data($data);
|
||||
$mform->is_validated();
|
||||
}
|
||||
|
||||
return $mform->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the course where a user enrolment belong to.
|
||||
*
|
||||
|
||||
@@ -25,6 +25,13 @@ information provided here is intended especially for developers.
|
||||
every form. The method should accept a single parameter with the submitted value. It should return a string with the
|
||||
eventual validation error, or an empty value if the validation passes.
|
||||
* New user_picture attribute $includefullname to determine whether to include the user's full name with the user's picture.
|
||||
* Enrol plugins which provide enrolment actions can now declare the following "data-action" attributes in their implementation of
|
||||
enrol_plugin::get_user_enrolment_actions() whenever applicable:
|
||||
* "editenrolment" - For editing a user'e enrolment details. Defined by constant ENROL_ACTION_EDIT.
|
||||
* "unenrol" - For unenrolling a student. Defined by constant ENROL_ACTION_UNENROL.
|
||||
These attributes enable enrol actions to be rendered via modals. If not added, clicking on the enrolment action buttons will still
|
||||
redirect the user to the appropriate enrolment action page. Though optional, it is recommended to add these attributes for a
|
||||
better user experience when performing enrol actions.
|
||||
|
||||
=== 3.3.1 ===
|
||||
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
define(["core/templates","jquery","core/str","core/config","core/notification","core/modal_factory","core/modal_events","core/fragment","core/ajax"],function(a,b,c,d,e,f,g,h,i){var j={EDIT_ENROLMENT:'[data-action="editenrolment"]',SHOW_DETAILS:'[data-action="showdetails"]',UNENROL:'[data-action="unenrol"]'},k=function(a){this.contextid=a.contextid,this.courseid=a.courseid,this.bindEditEnrol(),this.bindUnenrol(),this.bindStatusDetails()};return k.prototype.courseid=0,k.prototype.bindEditEnrol=function(){var a=this;b(j.EDIT_ENROLMENT).click(function(d){d.preventDefault();var h=b(this),i=h.parent(),j=i.data("fullname"),k=h.attr("rel");b.when(c.get_string("edituserenrolment","enrol",j)).then(function(a){return f.create({large:!0,title:a,type:f.types.SAVE_CANCEL})}).done(function(b){b.getRoot().on(g.save,function(c){c.preventDefault(),a.submitEditFormAjax(b)}),b.getRoot().on(g.hidden,function(){b.destroy()}),b.setBody(a.getBody(k)),b.show()}).fail(e.exception)})},k.prototype.bindUnenrol=function(){b(j.UNENROL).click(function(a){a.preventDefault();var h=b(this),i=h.parent(),j=[{key:"unenrol",component:"enrol"},{key:"unenrolconfirm",component:"enrol",param:{user:i.data("fullname"),course:i.data("coursename")}}];b.when(c.get_strings(j)).then(function(a){var b=a[0],c=a[1];return f.create({body:c,large:!0,title:b,type:f.types.CONFIRM})}).done(function(a){a.getRoot().on(g.yes,function(){var a={confirm:1,sesskey:d.sesskey,ue:b(h).attr("rel")};window.location.href=d.wwwroot+"/enrol/unenroluser.php?"+b.param(a)}),a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)})},k.prototype.bindStatusDetails=function(){b(j.SHOW_DETAILS).click(function(d){d.preventDefault();var h=b(this),i=h.parent(),j={fullname:i.data("fullname"),coursename:i.data("coursename"),enrolinstancename:i.data("enrolinstancename"),status:i.data("status"),statusclass:i.find("span").attr("class"),timestart:i.data("timestart"),timeend:i.data("timeend")},k=c.get_string("enroldetails","enrol"),l=f.create({large:!0,type:f.types.CANCEL});b.when(k,l).done(function(b,c){var d=a.render("core_user/status_details",j);c.setTitle(b),c.setBody(d),c.show(),c.getRoot().on(g.hidden,function(){c.destroy()})}).fail(e.exception)})},k.prototype.submitEditFormAjax=function(a){var c=this,d=a.getRoot().find("form"),f=b(d).find('[name="ue"]').val(),g=b(d).find('[name="status"]').val(),h={courseid:this.courseid,ueid:f,status:g},j=b(d).find('[name="timestart[enabled]"]');if(j.is(":checked")){var k=b(d).find('[name="timestart[year]"]').val(),l=b(d).find('[name="timestart[month]"]').val()-1,m=b(d).find('[name="timestart[day]"]').val(),n=b(d).find('[name="timestart[hour]"]').val(),o=b(d).find('[name="timestart[minute]"]').val(),p=new Date(k,l,m,n,o);h.timestart=p.getTime()/1e3}var q=b(d).find('[name="timeend[enabled]"]');if(q.is(":checked")){var r=b(d).find('[name="timeend[year]"]').val(),s=b(d).find('[name="timeend[month]"]').val()-1,t=b(d).find('[name="timeend[day]"]').val(),u=b(d).find('[name="timeend[hour]"]').val(),v=b(d).find('[name="timeend[minute]"]').val(),w=new Date(r,s,t,u,v);h.timeend=w.getTime()/1e3}var x={methodname:"core_enrol_edit_user_enrolment",args:h};i.call([x])[0].done(function(b){if(b.result)a.hide(),"undefined"!=typeof window.M.core_formchangechecker&&window.M.core_formchangechecker.reset_form_dirty_state(),window.location.reload();else{var e=JSON.stringify(d.serialize());a.setBody(c.getBody(f,e))}}).fail(e.exception)},k.prototype.getBody=function(a,b){var c={ueid:a};return"undefined"!=typeof b&&(c.formdata=b),h.loadFragment("enrol","user_enrolment_form",this.contextid,c).fail(e.exception)},{init:function(a){new k(a)}}});
|
||||
@@ -0,0 +1,323 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* AMD module for the user enrolment status field in the course participants page.
|
||||
*
|
||||
* @module core_user/status_field
|
||||
* @copyright 2017 Jun Pataleta
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['core/templates',
|
||||
'jquery',
|
||||
'core/str',
|
||||
'core/config',
|
||||
'core/notification',
|
||||
'core/modal_factory',
|
||||
'core/modal_events',
|
||||
'core/fragment',
|
||||
'core/ajax'
|
||||
],
|
||||
function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Ajax) {
|
||||
|
||||
/**
|
||||
* Action selectors.
|
||||
*
|
||||
* @access private
|
||||
* @type {{EDIT_ENROLMENT: string, SHOW_DETAILS: string, UNENROL: string}}
|
||||
*/
|
||||
var SELECTORS = {
|
||||
EDIT_ENROLMENT: '[data-action="editenrolment"]',
|
||||
SHOW_DETAILS: '[data-action="showdetails"]',
|
||||
UNENROL: '[data-action="unenrol"]'
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Object} options Object containing options. The only valid option at this time is contextid.
|
||||
* Each call to templates.render gets it's own instance of this class.
|
||||
*/
|
||||
var StatusFieldActions = function(options) {
|
||||
this.contextid = options.contextid;
|
||||
this.courseid = options.courseid;
|
||||
|
||||
// Bind click event to editenrol buttons.
|
||||
this.bindEditEnrol();
|
||||
|
||||
// Bind click event to unenrol buttons.
|
||||
this.bindUnenrol();
|
||||
|
||||
// Bind click event to status details buttons.
|
||||
this.bindStatusDetails();
|
||||
};
|
||||
// Class variables and functions.
|
||||
|
||||
/** @var {number} courseid The course ID. */
|
||||
StatusFieldActions.prototype.courseid = 0;
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method initModal
|
||||
* @private
|
||||
*/
|
||||
StatusFieldActions.prototype.bindEditEnrol = function() {
|
||||
var statusFieldInstsance = this;
|
||||
|
||||
$(SELECTORS.EDIT_ENROLMENT).click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// The particular edit button that was clicked.
|
||||
var clickedEditTrigger = $(this);
|
||||
// Get the parent container (it contains the data attributes associated with the status field).
|
||||
var parentContainer = clickedEditTrigger.parent();
|
||||
// Get the name of the user whose enrolment status is being edited.
|
||||
var fullname = parentContainer.data('fullname');
|
||||
// Get the user enrolment ID.
|
||||
var ueid = clickedEditTrigger.attr('rel');
|
||||
|
||||
$.when(Str.get_string('edituserenrolment', 'enrol', fullname)).then(function(modalTitle) {
|
||||
return ModalFactory.create({
|
||||
large: true,
|
||||
title: modalTitle,
|
||||
type: ModalFactory.types.SAVE_CANCEL
|
||||
});
|
||||
}).done(function(modal) {
|
||||
// Handle save event.
|
||||
modal.getRoot().on(ModalEvents.save, function(e) {
|
||||
// Don't close the modal yet.
|
||||
e.preventDefault();
|
||||
// Submit form data.
|
||||
statusFieldInstsance.submitEditFormAjax(modal);
|
||||
});
|
||||
|
||||
// Handle hidden event.
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
// Destroy when hidden.
|
||||
modal.destroy();
|
||||
});
|
||||
|
||||
// Set the modal body.
|
||||
modal.setBody(statusFieldInstsance.getBody(ueid));
|
||||
|
||||
// Show the modal!
|
||||
modal.show();
|
||||
}).fail(Notification.exception);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method bindUnenrol
|
||||
* @private
|
||||
*/
|
||||
StatusFieldActions.prototype.bindUnenrol = function() {
|
||||
$(SELECTORS.UNENROL).click(function(e) {
|
||||
e.preventDefault();
|
||||
var unenrolLink = $(this);
|
||||
var parentContainer = unenrolLink.parent();
|
||||
var strings = [
|
||||
{
|
||||
key: 'unenrol',
|
||||
component: 'enrol'
|
||||
},
|
||||
{
|
||||
key: 'unenrolconfirm',
|
||||
component: 'enrol',
|
||||
param: {
|
||||
user: parentContainer.data('fullname'),
|
||||
course: parentContainer.data('coursename')
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$.when(Str.get_strings(strings)).then(function(results) {
|
||||
var title = results[0];
|
||||
var confirmMessage = results[1];
|
||||
return ModalFactory.create({
|
||||
body: confirmMessage,
|
||||
large: true,
|
||||
title: title,
|
||||
type: ModalFactory.types.CONFIRM
|
||||
});
|
||||
}).done(function(modal) {
|
||||
// Handle confirm event.
|
||||
modal.getRoot().on(ModalEvents.yes, function() {
|
||||
// Build params.
|
||||
var unenrolParams = {
|
||||
confirm: 1,
|
||||
sesskey: Config.sesskey,
|
||||
ue: $(unenrolLink).attr('rel')
|
||||
};
|
||||
// Send data to unenrol page (which will redirect back to the participants page after unenrol).
|
||||
window.location.href = Config.wwwroot + '/enrol/unenroluser.php?' + $.param(unenrolParams);
|
||||
});
|
||||
|
||||
// Handle hidden event.
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
// Destroy when hidden.
|
||||
modal.destroy();
|
||||
});
|
||||
|
||||
// Display the delete confirmation modal.
|
||||
modal.show();
|
||||
}).fail(Notification.exception);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method bindStatusDetails
|
||||
* @private
|
||||
*/
|
||||
StatusFieldActions.prototype.bindStatusDetails = function() {
|
||||
$(SELECTORS.SHOW_DETAILS).click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var detailsButton = $(this);
|
||||
var parentContainer = detailsButton.parent();
|
||||
var context = {
|
||||
"fullname": parentContainer.data('fullname'),
|
||||
"coursename": parentContainer.data('coursename'),
|
||||
"enrolinstancename": parentContainer.data('enrolinstancename'),
|
||||
"status": parentContainer.data('status'),
|
||||
"statusclass": parentContainer.find('span').attr('class'),
|
||||
"timestart": parentContainer.data('timestart'),
|
||||
"timeend": parentContainer.data('timeend')
|
||||
};
|
||||
|
||||
var modalTitlePromise = Str.get_string('enroldetails', 'enrol');
|
||||
var modalPromise = ModalFactory.create({large: true, type: ModalFactory.types.CANCEL});
|
||||
$.when(modalTitlePromise, modalPromise).done(function(modalTitle, modal) {
|
||||
var modalBodyPromise = Template.render('core_user/status_details', context);
|
||||
modal.setTitle(modalTitle);
|
||||
modal.setBody(modalBodyPromise);
|
||||
modal.show();
|
||||
|
||||
// Handle hidden event.
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
// Destroy when hidden.
|
||||
modal.destroy();
|
||||
});
|
||||
}).fail(Notification.exception);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method submitEditFormAjax
|
||||
* @param {Object} modal The the AMD modal object containing the form.
|
||||
* @private
|
||||
*/
|
||||
StatusFieldActions.prototype.submitEditFormAjax = function(modal) {
|
||||
var statusFieldInstsance = this;
|
||||
var form = modal.getRoot().find('form');
|
||||
|
||||
// User enrolment ID.
|
||||
var ueid = $(form).find('[name="ue"]').val();
|
||||
// Status.
|
||||
var status = $(form).find('[name="status"]').val();
|
||||
|
||||
var params = {
|
||||
'courseid': this.courseid,
|
||||
'ueid': ueid,
|
||||
'status': status
|
||||
};
|
||||
|
||||
// Enrol time start.
|
||||
var timeStartEnabled = $(form).find('[name="timestart[enabled]"]');
|
||||
if (timeStartEnabled.is(':checked')) {
|
||||
var timeStartYear = $(form).find('[name="timestart[year]"]').val();
|
||||
var timeStartMonth = $(form).find('[name="timestart[month]"]').val() - 1;
|
||||
var timeStartDay = $(form).find('[name="timestart[day]"]').val();
|
||||
var timeStartHour = $(form).find('[name="timestart[hour]"]').val();
|
||||
var timeStartMinute = $(form).find('[name="timestart[minute]"]').val();
|
||||
var timeStart = new Date(timeStartYear, timeStartMonth, timeStartDay, timeStartHour, timeStartMinute);
|
||||
params.timestart = timeStart.getTime() / 1000;
|
||||
}
|
||||
|
||||
// Enrol time end.
|
||||
var timeEndEnabled = $(form).find('[name="timeend[enabled]"]');
|
||||
if (timeEndEnabled.is(':checked')) {
|
||||
var timeEndYear = $(form).find('[name="timeend[year]"]').val();
|
||||
var timeEndMonth = $(form).find('[name="timeend[month]"]').val() - 1;
|
||||
var timeEndDay = $(form).find('[name="timeend[day]"]').val();
|
||||
var timeEndHour = $(form).find('[name="timeend[hour]"]').val();
|
||||
var timeEndMinute = $(form).find('[name="timeend[minute]"]').val();
|
||||
var timeEnd = new Date(timeEndYear, timeEndMonth, timeEndDay, timeEndHour, timeEndMinute);
|
||||
params.timeend = timeEnd.getTime() / 1000;
|
||||
}
|
||||
|
||||
var request = {
|
||||
methodname: 'core_enrol_edit_user_enrolment',
|
||||
args: params
|
||||
};
|
||||
|
||||
Ajax.call([request])[0].done(function(data) {
|
||||
if (data.result) {
|
||||
// Dismiss the modal.
|
||||
modal.hide();
|
||||
|
||||
// Reload the page, don't show changed data warnings.
|
||||
if (typeof window.M.core_formchangechecker !== "undefined") {
|
||||
window.M.core_formchangechecker.reset_form_dirty_state();
|
||||
}
|
||||
window.location.reload();
|
||||
|
||||
} else {
|
||||
// Serialise the form data and reload the form fragment to show validation errors.
|
||||
var formData = JSON.stringify(form.serialize());
|
||||
modal.setBody(statusFieldInstsance.getBody(ueid, formData));
|
||||
}
|
||||
}).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method getBody
|
||||
* @private
|
||||
* @param {Number} ueid The user enrolment ID associated with the user.
|
||||
* @param {string} formData Serialized string of the edit enrolment form data.
|
||||
* @return {Promise}
|
||||
*/
|
||||
StatusFieldActions.prototype.getBody = function(ueid, formData) {
|
||||
var params = {
|
||||
'ueid': ueid
|
||||
};
|
||||
if (typeof formData !== 'undefined') {
|
||||
params.formdata = formData;
|
||||
}
|
||||
return Fragment.loadFragment('enrol', 'user_enrolment_form', this.contextid, params).fail(Notification.exception);
|
||||
};
|
||||
|
||||
return /** @alias module:core_user/editenrolment */ {
|
||||
// Public variables and functions.
|
||||
/**
|
||||
* Every call to init creates a new instance of the class with it's own event listeners etc.
|
||||
*
|
||||
* @method init
|
||||
* @public
|
||||
* @param {object} config - config variables for the module.
|
||||
*/
|
||||
init: function(config) {
|
||||
(new StatusFieldActions(config));
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Class containing the data necessary for rendering the status field in the course participants page.
|
||||
*
|
||||
* @package core_user
|
||||
* @copyright 2017 Jun Pataleta
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_user\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
use templatable;
|
||||
use user_enrolment_action;
|
||||
|
||||
/**
|
||||
* Class containing the data for the status field.
|
||||
*
|
||||
* @package core_user
|
||||
* @copyright 2017 Jun Pataleta
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class status_field implements renderable, templatable {
|
||||
|
||||
/** Active user enrolment status constant. */
|
||||
const STATUS_ACTIVE = 0;
|
||||
|
||||
/** Suspended user enrolment status constant. */
|
||||
const STATUS_SUSPENDED = 1;
|
||||
|
||||
/** Not current user enrolment status constant. */
|
||||
const STATUS_NOT_CURRENT = 2;
|
||||
|
||||
/** @var string $enrolinstancename The enrolment instance name. */
|
||||
protected $enrolinstancename;
|
||||
|
||||
/** @var string $coursename The course's full name. */
|
||||
protected $coursename;
|
||||
|
||||
/** @var string $fullname The user's full name. */
|
||||
protected $fullname;
|
||||
|
||||
/** @var string $status The user enrolment status. */
|
||||
protected $status;
|
||||
|
||||
/** @var int $timestart The timestamp when the user's enrolment starts. */
|
||||
protected $timestart;
|
||||
|
||||
/** @var int $timeend The timestamp when the user's enrolment ends. */
|
||||
protected $timeend;
|
||||
|
||||
/** @var user_enrolment_action[] $enrolactions Array of enrol action objects for the given enrolment method. */
|
||||
protected $enrolactions;
|
||||
|
||||
/** @var bool $statusactive Indicates whether a user enrolment status should be rendered as active. */
|
||||
protected $statusactive = false;
|
||||
|
||||
/** @var bool $statusactive Indicates whether a user enrolment status should be rendered as suspended. */
|
||||
protected $statussuspended = false;
|
||||
|
||||
/** @var bool $statusactive Indicates whether a user enrolment status should be rendered as not current. */
|
||||
protected $statusnotcurrent = false;
|
||||
|
||||
/**
|
||||
* status_field constructor.
|
||||
*
|
||||
* @param string $enrolinstancename The enrolment instance name.
|
||||
* @param string $coursename The course's full name.
|
||||
* @param string $fullname The user's full name.
|
||||
* @param string $status The user enrolment status.
|
||||
* @param int|null $timestart The timestamp when the user's enrolment starts.
|
||||
* @param int|null $timeend The timestamp when the user's enrolment ends.
|
||||
* @param user_enrolment_action[] $enrolactions Array of enrol action objects for the given enrolment method.
|
||||
*/
|
||||
public function __construct($enrolinstancename, $coursename, $fullname, $status, $timestart = null, $timeend = null,
|
||||
$enrolactions = []) {
|
||||
$this->enrolinstancename = $enrolinstancename;
|
||||
$this->coursename = $coursename;
|
||||
$this->fullname = $fullname;
|
||||
$this->status = $status;
|
||||
$this->timestart = $timestart;
|
||||
$this->timeend = $timeend;
|
||||
$this->enrolactions = $enrolactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to export the renderer data in a format that is suitable for a
|
||||
* mustache template. This means:
|
||||
* 1. No complex types - only stdClass, array, int, string, float, bool
|
||||
* 2. Any additional info that is required for the template is pre-calculated (e.g. capability checks).
|
||||
*
|
||||
* @param renderer_base $output Used to do a final render of any components that need to be rendered for export.
|
||||
* @return stdClass|array
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
$data = new stdClass();
|
||||
$data->enrolinstancename = $this->enrolinstancename;
|
||||
$data->coursename = $this->coursename;
|
||||
$data->fullname = $this->fullname;
|
||||
$data->status = $this->status;
|
||||
$data->active = $this->statusactive;
|
||||
$data->suspended = $this->statussuspended;
|
||||
$data->notcurrent = $this->statusnotcurrent;
|
||||
|
||||
if ($this->timestart) {
|
||||
$data->timestart = userdate($this->timestart);
|
||||
}
|
||||
if ($this->timeend) {
|
||||
$data->timeend = userdate($this->timeend);
|
||||
}
|
||||
$data->enrolactions = [];
|
||||
|
||||
foreach ($this->enrolactions as $enrolaction) {
|
||||
$action = new stdClass();
|
||||
$action->url = $enrolaction->get_url()->out(false);
|
||||
$action->icon = $output->render($enrolaction->get_icon());
|
||||
$action->attributes = [];
|
||||
foreach ($enrolaction->get_attributes() as $name => $value) {
|
||||
$attribute = (object) [
|
||||
'name' => $name,
|
||||
'value' => $value
|
||||
];
|
||||
$action->attributes[] = $attribute;
|
||||
}
|
||||
$data->enrolactions[] = $action;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status setter.
|
||||
*
|
||||
* @param int $status The user enrolment status representing one of this class' STATUS_* constants.
|
||||
* @return status_field This class' instance. Useful for chaining.
|
||||
*/
|
||||
public function set_status($status = self::STATUS_ACTIVE) {
|
||||
$this->statusactive = $status == static::STATUS_ACTIVE;
|
||||
$this->statussuspended = $status == static::STATUS_SUSPENDED;
|
||||
$this->statusnotcurrent = $status == static::STATUS_NOT_CURRENT;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
namespace core_user;
|
||||
|
||||
use context;
|
||||
use core_user\output\status_field;
|
||||
use DateTime;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
global $CFG;
|
||||
@@ -86,12 +90,12 @@ class participants_table extends \table_sql {
|
||||
protected $extrafields;
|
||||
|
||||
/**
|
||||
* @var \stdClass The course details.
|
||||
* @var \stdClass $course The course details.
|
||||
*/
|
||||
protected $course;
|
||||
|
||||
/**
|
||||
* @var \context The course context.
|
||||
* @var context $context The course context.
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
@@ -125,6 +129,7 @@ class participants_table extends \table_sql {
|
||||
// Get the context.
|
||||
$this->course = get_course($courseid);
|
||||
$context = \context_course::instance($courseid, MUST_EXIST);
|
||||
$this->context = $context;
|
||||
|
||||
// Define the headers and columns.
|
||||
$headers = [];
|
||||
@@ -168,6 +173,13 @@ class participants_table extends \table_sql {
|
||||
$columns[] = 'lastaccess';
|
||||
}
|
||||
|
||||
$canreviewenrol = has_capability('moodle/course:enrolreview', $context);
|
||||
if ($canreviewenrol) {
|
||||
$columns[] = 'status';
|
||||
$headers[] = get_string('participationstatus', 'enrol');
|
||||
$this->no_sorting('status');
|
||||
};
|
||||
|
||||
$this->define_columns($columns);
|
||||
$this->define_headers($headers);
|
||||
|
||||
@@ -192,6 +204,24 @@ class participants_table extends \table_sql {
|
||||
$this->assignableroles = get_assignable_roles($this->context, ROLENAME_ALIAS, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the participants table.
|
||||
*
|
||||
* @param int $pagesize Size of page for paginated displayed table.
|
||||
* @param bool $useinitialsbar Whether to use the initials bar which will only be used if there is a fullname column defined.
|
||||
* @param string $downloadhelpbutton
|
||||
*/
|
||||
public function out($pagesize, $useinitialsbar, $downloadhelpbutton = '') {
|
||||
global $PAGE;
|
||||
|
||||
parent::out($pagesize, $useinitialsbar, $downloadhelpbutton);
|
||||
|
||||
if (has_capability('moodle/course:enrolreview', $this->context)) {
|
||||
$params = ['contextid' => $this->context->id, 'courseid' => $this->course->id];
|
||||
$PAGE->requires->js_call_amd('core_user/status_field', 'init', [$params]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the select column.
|
||||
*
|
||||
@@ -290,6 +320,56 @@ class participants_table extends \table_sql {
|
||||
return get_string('never');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the status column.
|
||||
*
|
||||
* @param \stdClass $data The data object.
|
||||
* @return string
|
||||
*/
|
||||
public function col_status($data) {
|
||||
global $CFG, $OUTPUT, $PAGE;
|
||||
|
||||
$enrolstatusoutput = '';
|
||||
$canreviewenrol = has_capability('moodle/course:enrolreview', $this->context);
|
||||
if ($canreviewenrol) {
|
||||
$fullname = fullname($data);
|
||||
$coursename = $this->course->fullname;
|
||||
require_once($CFG->dirroot . '/enrol/locallib.php');
|
||||
$manager = new \course_enrolment_manager($PAGE, $this->course);
|
||||
$userenrolments = $manager->get_user_enrolments($data->id);
|
||||
foreach ($userenrolments as $ue) {
|
||||
$timestart = $ue->timestart;
|
||||
$timeend = $ue->timeend;
|
||||
$actions = $ue->enrolmentplugin->get_user_enrolment_actions($manager, $ue);
|
||||
$instancename = $ue->enrolmentinstancename;
|
||||
|
||||
// Default status field label and value.
|
||||
$status = get_string('participationactive', 'enrol');
|
||||
$statusval = status_field::STATUS_ACTIVE;
|
||||
switch ($ue->status) {
|
||||
case ENROL_USER_ACTIVE:
|
||||
$currentdate = new DateTime();
|
||||
$now = $currentdate->getTimestamp();
|
||||
// If user enrolment status has not yet started/already ended.
|
||||
if ($timestart > $now || ($timeend > 0 && $timeend < $now)) {
|
||||
$status = get_string('participationnotcurrent', 'enrol');
|
||||
$statusval = status_field::STATUS_NOT_CURRENT;
|
||||
}
|
||||
break;
|
||||
case ENROL_USER_SUSPENDED:
|
||||
$status = get_string('participationsuspended', 'enrol');
|
||||
$statusval = status_field::STATUS_SUSPENDED;
|
||||
break;
|
||||
}
|
||||
|
||||
$statusfield = new status_field($instancename, $coursename, $fullname, $status, $timestart, $timeend, $actions);
|
||||
$statusfielddata = $statusfield->set_status($statusval)->export_for_template($OUTPUT);
|
||||
$enrolstatusoutput .= $OUTPUT->render_from_template('core_user/status_field', $statusfielddata);
|
||||
}
|
||||
}
|
||||
return $enrolstatusoutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used for the extra user fields.
|
||||
*
|
||||
|
||||
+3
-1
@@ -1234,7 +1234,9 @@ function user_get_participants_sql($courseid, $groupid = 0, $accesssince = 0, $r
|
||||
|
||||
$isfrontpage = ($courseid == SITEID);
|
||||
|
||||
list($esql, $params) = get_enrolled_sql($context, null, $groupid, true);
|
||||
// Show active users only if the user doesn't have the 'moodle/course:enrolreview' capability.
|
||||
$onlyactive = !has_capability('moodle/course:enrolreview', $context);
|
||||
list($esql, $params) = get_enrolled_sql($context, null, $groupid, $onlyactive);
|
||||
|
||||
$joins = array('FROM {user} u');
|
||||
$wheres = array();
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_user/status_details
|
||||
|
||||
Template for the user enrolment status details.
|
||||
|
||||
Context variables required for this template:
|
||||
* fullname string - The user's full name.
|
||||
* coursename string - The course name.
|
||||
* enrolinstancename string - The enrolment instance name.
|
||||
* status string - The enrolment status.
|
||||
* statusclass string - The CSS class for the enrolment status.
|
||||
* timestart string - Optional. The enrolment time start.
|
||||
* timeend string - Optional. The enrolment time end.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"fullname": "Student John",
|
||||
"coursename": "TC 1",
|
||||
"enrolinstancename": "Manual enrolment",
|
||||
"status": "Active",
|
||||
"statusclass": "label label-success",
|
||||
"timestart": "1 January 2017",
|
||||
"timeend": "31 January 2018"
|
||||
}
|
||||
}}
|
||||
<table class="table user-enrol-details">
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}fullname{{/str}}
|
||||
</th>
|
||||
<td class="user-fullname">
|
||||
{{fullname}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}course{{/str}}
|
||||
</th>
|
||||
<td class="user-course">
|
||||
{{coursename}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}enrolmentmethod, enrol{{/str}}
|
||||
</th>
|
||||
<td class="user-enrol-instance">
|
||||
{{enrolinstancename}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}participationstatus, enrol{{/str}}
|
||||
</th>
|
||||
<td class="user-enrol-status">
|
||||
<span class="{{statusclass}}">
|
||||
{{status}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{{#timestart}}
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}enroltimestart, enrol{{/str}}
|
||||
</th>
|
||||
<td class="user-enrol-timestart">
|
||||
{{timestart}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/timestart}}
|
||||
{{#timeend}}
|
||||
<tr>
|
||||
<th>
|
||||
{{#str}}enroltimeend, enrol{{/str}}
|
||||
</th>
|
||||
<td class="user-enrol-timeend">
|
||||
{{timeend}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/timeend}}
|
||||
</table>
|
||||
@@ -0,0 +1,71 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_user/status_field
|
||||
|
||||
Template for the enrolment status field.
|
||||
|
||||
Context variables required for this template:
|
||||
* fullname string - The user's full name.
|
||||
* coursename string - The course name.
|
||||
* enrolinstancename string - The enrolment instance name.
|
||||
* status string - The enrolment status.
|
||||
* active boolean - Flag to indicate whether the user has an active enrolment.
|
||||
* suspended boolean - Flag to indicate whether the user is suspended.
|
||||
* notcurrent boolean - Flag to indicate whether the user's enrolment is active, but not current.
|
||||
* timestart string - Optional. The enrolment time start.
|
||||
* timeend string - Optional. The enrolment time end.
|
||||
* enrolactions array - Optional. Array of enrol actions consisting of:
|
||||
* url string - The URL of the enrol action link.
|
||||
* attributes array - The array of attributes for the enrol action link.
|
||||
* icon string - The HTML output for the enrol action icon.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"fullname": "Student John",
|
||||
"coursename": "TC 1",
|
||||
"enrolinstancename": "Manual enrolment",
|
||||
"status": "Active",
|
||||
"active": true,
|
||||
"timestart": "1 January 2017",
|
||||
"timeend": "31 January 2018",
|
||||
"enrolactions": [
|
||||
{
|
||||
"url": "#",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "class",
|
||||
"value": "action-class"
|
||||
}
|
||||
],
|
||||
"icon": "<i class=\"icon fa fa-cog fa-fw\" aria-hidden=\"true\" title=\"Edit enrolment\" aria-label=\"\"></i>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div data-fullname="{{fullname}}" data-coursename="{{coursename}}" data-enrolinstancename="{{enrolinstancename}}"
|
||||
data-status="{{status}}" data-timestart="{{timestart}}" data-timeend="{{timeend}}">
|
||||
<span class="label {{#active}}label-success{{/active}}{{#suspended}}label-warning{{/suspended}}{{#notcurrent}}label-default{{/notcurrent}}">{{status}}</span>
|
||||
<a data-action="showdetails" role="button" tabindex="0">
|
||||
{{#pix}}docs, core, {{#str}}enroldetails, enrol{{/str}}{{/pix}}
|
||||
</a>
|
||||
{{#enrolactions}}
|
||||
<a href="{{url}}" role="button" {{#attributes}}{{name}}="{{value}}" {{/attributes}}>
|
||||
{{{icon}}}
|
||||
</a>
|
||||
{{/enrolactions}}
|
||||
</div>
|
||||
@@ -0,0 +1,93 @@
|
||||
@core @core_user
|
||||
Feature: Edit user enrolment
|
||||
In order to manage students' enrolments
|
||||
As a teacher
|
||||
I need to be able to view enrolment details and edit student enrolments in the course participants page
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| student2 | Student | 2 | student2@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role | status |
|
||||
| teacher1 | C1 | editingteacher | 0 |
|
||||
| student1 | C1 | student | 0 |
|
||||
| student2 | C1 | student | 1 |
|
||||
|
||||
@javascript
|
||||
Scenario: Edit a user's enrolment
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='editenrolment']" "xpath_element" in the "student1" "table_row"
|
||||
And I should see "Edit Student 1's enrolment"
|
||||
And I set the field "Status" to "Suspended"
|
||||
And I click on "Save changes" "button"
|
||||
And I click on "//a[@data-action='editenrolment']" "xpath_element" in the "student2" "table_row"
|
||||
And I should see "Edit Student 2's enrolment"
|
||||
And I set the field "timeend[enabled]" to "1"
|
||||
And I set the field "timeend[day]" to "1"
|
||||
And I set the field "timeend[month]" to "January"
|
||||
And I set the field "timeend[year]" to "2017"
|
||||
And I set the field "Status" to "Active"
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Suspended" in the "student1" "table_row"
|
||||
And I should see "Not current" in the "student2" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Unenrol a student
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='unenrol']" "xpath_element" in the "student1" "table_row"
|
||||
And I click on "Yes" "button"
|
||||
Then I should not see "Student 1" in the "participants" "table"
|
||||
|
||||
@javascript
|
||||
Scenario: View a student's enrolment details
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='showdetails']" "xpath_element" in the "student1" "table_row"
|
||||
Then I should see "Enrolment details"
|
||||
And I should see "Student 1" in the "Full name" "table_row"
|
||||
And I should see "Active" in the "//td[@class='user-enrol-status']" "xpath_element"
|
||||
And I press "Cancel"
|
||||
And I click on "//a[@data-action='showdetails']" "xpath_element" in the "student2" "table_row"
|
||||
And I should see "Enrolment details"
|
||||
And I should see "Student 2" in the "Full name" "table_row"
|
||||
And I should see "Suspended" in the "//td[@class='user-enrol-status']" "xpath_element"
|
||||
|
||||
# Without JS, the user should be redirected to the original edit enrolment form.
|
||||
Scenario: Edit a user's enrolment without JavaScript
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='editenrolment']" "xpath_element" in the "student1" "table_row"
|
||||
And I should see "Student 1"
|
||||
And I set the field "Status" to "Suspended"
|
||||
And I click on "Save changes" "button"
|
||||
And I click on "//a[@data-action='editenrolment']" "xpath_element" in the "student2" "table_row"
|
||||
And I should see "Student 2"
|
||||
And I set the field "timeend[enabled]" to "1"
|
||||
And I set the field "timeend[day]" to "1"
|
||||
And I set the field "timeend[month]" to "January"
|
||||
And I set the field "timeend[year]" to "2017"
|
||||
And I set the field "Status" to "Active"
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Suspended" in the "student1" "table_row"
|
||||
And I should see "Not current" in the "student2" "table_row"
|
||||
|
||||
# Without JS, the user should be redirected to the original unenrol confirmation page.
|
||||
Scenario: Unenrol a student
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to course participants
|
||||
When I click on "//a[@data-action='unenrol']" "xpath_element" in the "student1" "table_row"
|
||||
And I click on "Continue" "button"
|
||||
Then I should not see "Student 1" in the "participants" "table"
|
||||
@@ -32,27 +32,27 @@ Feature: View course participants
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
| student3 | C1 | student |
|
||||
| student4 | C1 | student |
|
||||
| student5 | C1 | student |
|
||||
| student6 | C1 | student |
|
||||
| student7 | C1 | student |
|
||||
| student8 | C1 | student |
|
||||
| student9 | C1 | student |
|
||||
| student10 | C1 | student |
|
||||
| student11 | C1 | student |
|
||||
| student12 | C1 | student |
|
||||
| student13 | C1 | student |
|
||||
| student14 | C1 | student |
|
||||
| student15 | C1 | student |
|
||||
| student16 | C1 | student |
|
||||
| student17 | C1 | student |
|
||||
| student18 | C1 | student |
|
||||
| student19 | C1 | student |
|
||||
| user | course | role | status | timeend |
|
||||
| teacher1 | C1 | editingteacher | 0 | 0 |
|
||||
| student1 | C1 | student | 0 | 0 |
|
||||
| student2 | C1 | student | 0 | 0 |
|
||||
| student3 | C1 | student | 0 | 0 |
|
||||
| student4 | C1 | student | 0 | 0 |
|
||||
| student5 | C1 | student | 0 | 0 |
|
||||
| student6 | C1 | student | 0 | 0 |
|
||||
| student7 | C1 | student | 0 | 0 |
|
||||
| student8 | C1 | student | 0 | 0 |
|
||||
| student9 | C1 | student | 0 | 0 |
|
||||
| student10 | C1 | student | 1 | 0 |
|
||||
| student11 | C1 | student | 0 | 100 |
|
||||
| student12 | C1 | student | 0 | 0 |
|
||||
| student13 | C1 | student | 0 | 0 |
|
||||
| student14 | C1 | student | 0 | 0 |
|
||||
| student15 | C1 | student | 0 | 0 |
|
||||
| student16 | C1 | student | 0 | 0 |
|
||||
| student17 | C1 | student | 0 | 0 |
|
||||
| student18 | C1 | student | 0 | 0 |
|
||||
| student19 | C1 | student | 0 | 0 |
|
||||
|
||||
@javascript
|
||||
Scenario: Use select and deselect all buttons
|
||||
@@ -222,3 +222,46 @@ Feature: View course participants
|
||||
And the field with xpath "//tbody//tr[19]//input[@class='usercheckbox']" matches value "0"
|
||||
And the field with xpath "//tbody//tr[20]//input[@class='usercheckbox']" matches value "0"
|
||||
And the field with xpath "//tbody//tr[21]//input[@class='usercheckbox']" matches value "0"
|
||||
|
||||
Scenario: View the participants page as a teacher
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I navigate to course participants
|
||||
Then I should see "Active" in the "student1" "table_row"
|
||||
And I should see "Active" in the "student2" "table_row"
|
||||
And I should see "Active" in the "student3" "table_row"
|
||||
And I should see "Active" in the "student4" "table_row"
|
||||
And I should see "Active" in the "student5" "table_row"
|
||||
And I should see "Active" in the "student6" "table_row"
|
||||
And I should see "Active" in the "student7" "table_row"
|
||||
And I should see "Active" in the "student8" "table_row"
|
||||
And I should see "Active" in the "student9" "table_row"
|
||||
And I should see "Suspended" in the "student10" "table_row"
|
||||
And I should see "Not current" in the "student11" "table_row"
|
||||
And I should see "Active" in the "student12" "table_row"
|
||||
And I should see "Active" in the "student13" "table_row"
|
||||
And I should see "Active" in the "student14" "table_row"
|
||||
And I should see "Active" in the "student15" "table_row"
|
||||
And I should see "Active" in the "student16" "table_row"
|
||||
And I should see "Active" in the "student17" "table_row"
|
||||
And I should see "Active" in the "student18" "table_row"
|
||||
And I should see "Active" in the "student19" "table_row"
|
||||
|
||||
Scenario: View the participants page as a student
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I navigate to course participants
|
||||
# Student should not see the status column.
|
||||
Then I should not see "Status" in the "participants" "table"
|
||||
# Student should be able to see the other actively-enrolled students.
|
||||
And I should see "Student 1" in the "participants" "table"
|
||||
And I should see "Student 2" in the "participants" "table"
|
||||
And I should see "Student 3" in the "participants" "table"
|
||||
And I should see "Student 4" in the "participants" "table"
|
||||
And I should see "Student 5" in the "participants" "table"
|
||||
And I should see "Student 6" in the "participants" "table"
|
||||
And I should see "Student 7" in the "participants" "table"
|
||||
And I should see "Student 8" in the "participants" "table"
|
||||
# Suspended and non-current students should not be rendered.
|
||||
And I should not see "Student 10" in the "participants" "table"
|
||||
And I should not see "Student 11" in the "participants" "table"
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2017072500.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2017072600.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user