diff --git a/export.php b/export.php
index 76de1b4..d6a5253 100644
--- a/export.php
+++ b/export.php
@@ -50,8 +50,7 @@ $PAGE->navbar->add(get_string('export', 'attendance'));
$formparams = array('course' => $course, 'cm' => $cm, 'modcontext' => $PAGE->context);
$mform = new mod_attendance_export_form($att->url_export(), $formparams);
-if ($mform->is_submitted()) {
- $formdata = $mform->get_data();
+if ($formdata = $mform->get_data()) {
$pageparams = new att_page_with_filter_controls();
$pageparams->init($cm);
@@ -70,6 +69,9 @@ if ($mform->is_submitted()) {
$pageparams->startdate = $formdata->sessionstartdate;
$pageparams->enddate = $formdata->sessionenddate;
}
+ if ($formdata->selectedusers) {
+ $pageparams->userids = $formdata->users;
+ }
$att->pageparams = $pageparams;
$reportdata = new attendance_report_data($att);
diff --git a/export_form.php b/export_form.php
index 8d6990c..b07b8ad 100644
--- a/export_form.php
+++ b/export_form.php
@@ -39,7 +39,7 @@ class mod_attendance_export_form extends moodleform {
*/
public function definition() {
- global $USER;
+ global $USER, $DB, $PAGE;
$mform =& $this->_form;
$course = $this->_customdata['course'];
@@ -60,6 +60,43 @@ class mod_attendance_export_form extends moodleform {
}
$mform->addElement('select', 'group', get_string('group'), $grouplist);
+
+ // Restrict the export to the selected users.
+ $namefields = get_all_user_name_fields(true, 'u');
+ $allusers = get_enrolled_users($modcontext, 'mod/attendance:canbelisted', 0, 'u.id,'.$namefields);
+ $userlist = array();
+ foreach ($allusers as $user) {
+ $userlist[$user->id] = fullname($user);
+ }
+ unset($allusers);
+ $tempusers = $DB->get_records('attendance_tempusers', array('courseid' => $course->id), 'studentid, fullname');
+ foreach ($tempusers as $user) {
+ $userlist[$user->studentid] = $user->fullname;
+ }
+ list($gsql, $gparams) = $DB->get_in_or_equal(array_keys($grouplist), SQL_PARAMS_NAMED);
+ list($usql, $uparams) = $DB->get_in_or_equal(array_keys($userlist), SQL_PARAMS_NAMED);
+ $params = array_merge($gparams, $uparams);
+ $groupmembers = $DB->get_recordset_select('groups_members', "groupid {$gsql} AND userid {$usql}", $params,
+ '', 'groupid, userid');
+ $groupmappings = array();
+ foreach ($groupmembers as $groupmember) {
+ if (!isset($groupmappings[$groupmember->groupid])) {
+ $groupmappings[$groupmember->groupid] = array();
+ }
+ $groupmappings[$groupmember->groupid][$groupmember->userid] = $userlist[$groupmember->userid];
+ }
+ if (isset($grouplist[0])) {
+ $groupmappings[0] = $userlist;
+ }
+
+ $mform->addElement('selectyesno', 'selectedusers', get_string('onlyselectedusers', 'mod_attendance'));
+ $sel = $mform->addElement('select', 'users', get_string('users', 'mod_attendance'), $userlist, array('size' => 12));
+ $sel->setMultiple(true);
+ $mform->disabledIf('users', 'selectedusers', 'eq', 0);
+
+ $opts = array('groupmappings' => $groupmappings);
+ $PAGE->requires->yui_module('moodle-mod_attendance-groupfilter', 'M.mod_attendance.groupfilter.init', array($opts));
+
$ident = array();
$ident[] =& $mform->createElement('checkbox', 'id', '', get_string('studentid', 'attendance'));
$ident[] =& $mform->createElement('checkbox', 'uname', '', get_string('username'));
@@ -96,5 +133,16 @@ class mod_attendance_export_form extends moodleform {
$mform->addElement('hidden', 'id', $cm->id);
}
+
+ function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+
+ // Validate the 'users' field.
+ if ($data['selectedusers'] && empty($data['users'])) {
+ $errors['users'] = get_string('mustselectusers', 'mod_attendance');
+ }
+
+ return $errors;
+ }
}
diff --git a/lang/en/attendance.php b/lang/en/attendance.php
index 6bf3481..540760d 100644
--- a/lang/en/attendance.php
+++ b/lang/en/attendance.php
@@ -140,6 +140,7 @@ Reports are available for the entire class or individual students.';
$string['modulenameplural'] = 'Attendances';
$string['months'] = 'Months';
$string['moreattendance'] = 'Attendance has been successfully taken for this page';
+$string['mustselectusers'] = 'Must select users to export';
$string['myvariables'] = 'My Variables';
$string['newdate'] = 'New date';
$string['newduration'] = 'New duration';
@@ -158,7 +159,9 @@ $string['nosessionsselected'] = 'No sessions selected';
$string['notfound'] = 'Attendance activity not found in this course!';
$string['noupgradefromthisversion'] = 'The Attendance module cannot upgrade from the version of attforblock you have installed. - please delete attforblock or upgrade it to the latest version before isntalling the new attendance module';
$string['olddate'] = 'Old date';
+$string['onlyselectedusers'] = 'Export specific users';
$string['participant'] = 'Participant';
+$string['percentage'] = 'Percentage';
$string['period'] = 'Frequency';
$string['pluginname'] = 'Attendance';
$string['pluginadministration'] = 'Attendance administration';
@@ -267,6 +270,7 @@ $string['tusername'] = 'Full name';
$string['update'] = 'Update';
$string['usestatusset'] = 'Use status set';
$string['userexists'] = 'There is already a real user with this email address';
+$string['users'] = 'Users to export';
$string['variable'] = 'variable';
$string['variablesupdated'] = 'Variables successfully updated';
$string['versionforprinting'] = 'version for printing';
diff --git a/renderables.php b/renderables.php
index 047a461..8b04082 100644
--- a/renderables.php
+++ b/renderables.php
@@ -478,6 +478,14 @@ class attendance_report_data implements renderable {
$this->users = $att->get_users($att->pageparams->group, $att->pageparams->page);
+ if (isset($att->pageparams->userids)) {
+ foreach ($this->users as $key => $user) {
+ if (!in_array($user->id, $att->pageparams->userids)) {
+ unset($this->users[$key]);
+ }
+ }
+ }
+
$this->groups = groups_get_all_groups($att->course->id);
$this->sessions = $att->get_filtered_sessions();
diff --git a/tests/behat/extra_features.feature b/tests/behat/extra_features.feature
index ffab425..991bdfa 100644
--- a/tests/behat/extra_features.feature
+++ b/tests/behat/extra_features.feature
@@ -111,6 +111,40 @@ Feature: Test the various new features in the attendance module
And "A" "text" should exist in the "Student 3" "table_row"
And I should not see "Temporary user 2"
+ Scenario: A teacher can select a subset of users for export
+ Given the following "groups" exist:
+ | course | name | idnumber |
+ | C1 | Group1 | Group1 |
+ | C1 | Group2 | Group2 |
+ And the following "group members" exist:
+ | group | user |
+ | Group1 | student1 |
+ | Group1 | student2 |
+ | Group2 | student2 |
+ | Group2 | student3 |
+
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Test attendance"
+ And I follow "Add"
+ And I set the following fields to these values:
+ | Create multiple sessions | 0 |
+ And I click on "submitbutton" "button"
+
+ And I follow "Export"
+
+ When I set the field "Export specific users" to "Yes"
+ And I set the field "Group" to "Group1"
+ Then the "Users to export" select box should contain "Student 1"
+ And the "Users to export" select box should contain "Student 2"
+ And the "Users to export" select box should not contain "Student 3"
+
+ When I set the field "Group" to "Group2"
+ Then the "Users to export" select box should contain "Student 2"
+ And the "Users to export" select box should contain "Student 3"
+ And the "Users to export" select box should not contain "Student 1"
+ # Ideally the download would be tested here, but that is difficult to configure.
+
Scenario: A teacher can create and use multiple status lists
Given I log in as "teacher1"
And I follow "Course 1"
diff --git a/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-debug.js b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-debug.js
new file mode 100644
index 0000000..8cc126f
--- /dev/null
+++ b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-debug.js
@@ -0,0 +1,45 @@
+YUI.add('moodle-mod_attendance-groupfilter', function (Y, NAME) {
+
+/*global M*/
+M.mod_attendance = M.mod_attendance || {};
+M.mod_attendance.groupfilter = {
+ groupmappings: null,
+
+ init: function(opts) {
+ "use strict";
+
+ this.groupmappings = opts.groupmappings;
+ Y.one('#id_group').after('change', this.update_user_list, this);
+ },
+
+ /**
+ * Update the user list with those found in the selected group.
+ */
+ update_user_list: function() {
+ "use strict";
+ var groupid, userlist, users, userid, opt;
+
+ // Get the list of users in the current group.
+ groupid = Y.one('#id_group').get('value');
+ users = this.groupmappings[groupid];
+
+ // Remove the options from the users select.
+ userlist = Y.one('#id_users');
+ userlist.get('options').remove();
+
+ // Repopulate the users select with those users in the selected group (if any).
+ if (users !== undefined) {
+ for (userid in users) {
+ if (users.hasOwnProperty(userid)) {
+ opt = Y.Node.create('');
+ opt.set('value', userid);
+ opt.set('text', users[userid]);
+ userlist.appendChild(opt);
+ }
+ }
+ }
+ }
+};
+
+
+}, '@VERSION@', {"requires": ["base", "node"]});
diff --git a/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-min.js b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-min.js
new file mode 100644
index 0000000..6e5da57
--- /dev/null
+++ b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter-min.js
@@ -0,0 +1 @@
+YUI.add("moodle-mod_attendance-groupfilter",function(e,t){M.mod_attendance=M.mod_attendance||{},M.mod_attendance.groupfilter={groupmappings:null,init:function(t){"use strict";this.groupmappings=t.groupmappings,e.one("#id_group").after("change",this.update_user_list,this)},update_user_list:function(){"use strict";var t,n,r,i,s;t=e.one("#id_group").get("value"),r=this.groupmappings[t],n=e.one("#id_users"),n.get("options").remove();if(r!==undefined)for(i in r)r.hasOwnProperty(i)&&(s=e.Node.create(""),s.set("value",i),s.set("text",r[i]),n.appendChild(s))}}},"@VERSION@",{requires:["base","node"]});
diff --git a/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter.js b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter.js
new file mode 100644
index 0000000..8cc126f
--- /dev/null
+++ b/yui/build/moodle-mod_attendance-groupfilter/moodle-mod_attendance-groupfilter.js
@@ -0,0 +1,45 @@
+YUI.add('moodle-mod_attendance-groupfilter', function (Y, NAME) {
+
+/*global M*/
+M.mod_attendance = M.mod_attendance || {};
+M.mod_attendance.groupfilter = {
+ groupmappings: null,
+
+ init: function(opts) {
+ "use strict";
+
+ this.groupmappings = opts.groupmappings;
+ Y.one('#id_group').after('change', this.update_user_list, this);
+ },
+
+ /**
+ * Update the user list with those found in the selected group.
+ */
+ update_user_list: function() {
+ "use strict";
+ var groupid, userlist, users, userid, opt;
+
+ // Get the list of users in the current group.
+ groupid = Y.one('#id_group').get('value');
+ users = this.groupmappings[groupid];
+
+ // Remove the options from the users select.
+ userlist = Y.one('#id_users');
+ userlist.get('options').remove();
+
+ // Repopulate the users select with those users in the selected group (if any).
+ if (users !== undefined) {
+ for (userid in users) {
+ if (users.hasOwnProperty(userid)) {
+ opt = Y.Node.create('');
+ opt.set('value', userid);
+ opt.set('text', users[userid]);
+ userlist.appendChild(opt);
+ }
+ }
+ }
+ }
+};
+
+
+}, '@VERSION@', {"requires": ["base", "node"]});
diff --git a/yui/src/groupfilter/build.json b/yui/src/groupfilter/build.json
new file mode 100644
index 0000000..9545400
--- /dev/null
+++ b/yui/src/groupfilter/build.json
@@ -0,0 +1,10 @@
+{
+ "name": "moodle-mod_attendance-groupfilter",
+ "builds": {
+ "moodle-mod_attendance-groupfilter": {
+ "jsfiles": [
+ "groupfilter.js"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/yui/src/groupfilter/js/groupfilter.js b/yui/src/groupfilter/js/groupfilter.js
new file mode 100644
index 0000000..5bda295
--- /dev/null
+++ b/yui/src/groupfilter/js/groupfilter.js
@@ -0,0 +1,40 @@
+/*global M*/
+M.mod_attendance = M.mod_attendance || {};
+M.mod_attendance.groupfilter = {
+ groupmappings: null,
+
+ init: function(opts) {
+ "use strict";
+
+ this.groupmappings = opts.groupmappings;
+ Y.one('#id_group').after('change', this.update_user_list, this);
+ },
+
+ /**
+ * Update the user list with those found in the selected group.
+ */
+ update_user_list: function() {
+ "use strict";
+ var groupid, userlist, users, userid, opt;
+
+ // Get the list of users in the current group.
+ groupid = Y.one('#id_group').get('value');
+ users = this.groupmappings[groupid];
+
+ // Remove the options from the users select.
+ userlist = Y.one('#id_users');
+ userlist.get('options').remove();
+
+ // Repopulate the users select with those users in the selected group (if any).
+ if (users !== undefined) {
+ for (userid in users) {
+ if (users.hasOwnProperty(userid)) {
+ opt = Y.Node.create('');
+ opt.set('value', userid);
+ opt.set('text', users[userid]);
+ userlist.appendChild(opt);
+ }
+ }
+ }
+ }
+};
diff --git a/yui/src/groupfilter/meta/groupfilter.json b/yui/src/groupfilter/meta/groupfilter.json
new file mode 100644
index 0000000..5308751
--- /dev/null
+++ b/yui/src/groupfilter/meta/groupfilter.json
@@ -0,0 +1,8 @@
+{
+ "moodle-mod_attendance-groupfilter": {
+ "requires": [
+ "base",
+ "node"
+ ]
+ }
+}
\ No newline at end of file