diff --git a/add_form.php b/add_form.php
index 9877980..a9550a3 100644
--- a/add_form.php
+++ b/add_form.php
@@ -78,9 +78,9 @@ class mod_attendance_add_form extends moodleform {
}
if ($groupmode == SEPARATEGROUPS or $groupmode == VISIBLEGROUPS) {
if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $modcontext)) {
- $groups = groups_get_all_groups ($course->id, $USER->id);
+ $groups = groups_get_all_groups ($course->id, $USER->id, $cm->groupingid);
} else {
- $groups = groups_get_all_groups($course->id);
+ $groups = groups_get_all_groups($course->id, 0, $cm->groupingid);
}
if ($groups) {
$selectgroups = array();
@@ -162,9 +162,19 @@ class mod_attendance_add_form extends moodleform {
public function validation($data, $files) {
$errors = parent::validation($data, $files);
+ if (!empty($data['addmultiply']) && $data['sessiondate'] != 0 && $data['sessionenddate'] != 0 && $data['sessionenddate'] < $data['sessiondate']) {
+ $errors['sessionenddate'] = get_string('invalidsessionenddate', 'attendance');
+ }
+
if ($data['sessiontype'] == attendance::SESSION_GROUP and empty($data['groups'])) {
$errors['groups'] = get_string('errorgroupsnotselected', 'attendance');
}
+
+ $addmulti = isset($data['addmultiply'])? (int)$data['addmultiply'] : 0;
+ if (($addmulti != 0) && (!array_key_exists('sdays',$data) || empty($data['sdays']))) {
+ $data['sdays']= array();
+ $errors['sdays'] = get_string('required', 'attendance');
+ }
return $errors;
}
diff --git a/db/upgrade.php b/db/upgrade.php
index 2642874..579f80f 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -32,6 +32,8 @@ function xmldb_attendance_upgrade($oldversion=0) {
global $CFG, $THEME, $DB;
$dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
+ $result = true;
+
if ($oldversion < 2013082901) {
$table = new xmldb_table('attendance_sessions');
@@ -41,9 +43,47 @@ function xmldb_attendance_upgrade($oldversion=0) {
$dbman->add_field($table, $field);
}
- upgrade_mod_savepoint(true, 2013082901, 'attendance');
+ upgrade_mod_savepoint($result, 2013082901, 'attendance');
+ }
+
+ if ($oldversion < 2013082902) {
+ // Replace values that reference old module "attforblock" to "attendance".
+ $sql = "UPDATE {grade_items}
+ SET itemmodule = 'attendance'
+ WHERE itemmodule = 'attforblock'";
+
+ $DB->execute($sql);
+
+ $sql = "UPDATE {grade_items_history}
+ SET itemmodule = 'attendance'
+ WHERE itemmodule = 'attforblock'";
+
+ $DB->execute($sql);
+
+ /*
+ * The user's custom capabilities need to be preserved due to the module renaming.
+ * Capabilities with a modifierid = 0 value are installed by default.
+ * Only update the user's custom capabilities where modifierid is not zero.
+ */
+ $sql = $DB->sql_like('capability', '?').' AND modifierid <> 0';
+ $rs = $DB->get_recordset_select('role_capabilities', $sql, array('%mod/attforblock%'));
+ foreach ($rs as $cap) {
+ $renamedcapability = str_replace('mod/attforblock', 'mod/attendance', $cap->capability);
+ $exists = $DB->record_exists('role_capabilities', array('roleid' => $cap->roleid, 'capability' => $renamedcapability));
+ if (!$exists) {
+ $DB->update_record('role_capabilities', array('id' => $cap->id, 'capability' => $renamedcapability));
+ }
+ }
+
+ // Delete old role capabilities.
+ $sql = $DB->sql_like('capability', '?');
+ $DB->delete_records_select('role_capabilities', $sql, array('%mod/attforblock%'));
+
+ // Delete old capabilities.
+ $DB->delete_records_select('capabilities', 'component = ?', array('mod_attforblock'));
+
+ upgrade_plugin_savepoint($result, 2013082902, 'mod', 'attendance');
}
- // UPGRADES from attforblock are only supported for sites that are running attforblock version 2012120700.
return $result;
}
diff --git a/export.php b/export.php
index 995e937..9b6fb99 100644
--- a/export.php
+++ b/export.php
@@ -55,6 +55,7 @@ if ($mform->is_submitted()) {
$pageparams = new att_page_with_filter_controls();
$pageparams->init($cm);
+ $pageparams->page = 0;
$pageparams->group = $formdata->group;
$pageparams->set_current_sesstype($formdata->group ? $formdata->group : att_page_with_filter_controls::SESSTYPE_ALL);
if (isset($formdata->includeallsessions)) {
@@ -97,6 +98,10 @@ if ($mform->is_submitted()) {
$data->tabhead[] = get_string('lastname');
$data->tabhead[] = get_string('firstname');
+ $groupmode = groups_get_activity_groupmode($cm, $course);
+ if (!empty($groupmode)) {
+ $data->tabhead[] = get_string('groups');
+ }
if (count($reportdata->sessions) > 0) {
foreach ($reportdata->sessions as $sess) {
@@ -104,6 +109,9 @@ if ($mform->is_submitted()) {
$text .= ' ';
$text .= $sess->groupid ? $reportdata->groups[$sess->groupid]->name : get_string('commonsession', 'attendance');
$data->tabhead[] = $text;
+ if (isset($formdata->includeremarks)) {
+ $data->tabhead[] = get_string('remark', 'attendance', $text);
+ }
}
} else {
print_error('sessionsnotfound', 'attendance', $att->url_manage());
@@ -131,8 +139,17 @@ if ($mform->is_submitted()) {
$data->table[$i][] = $user->lastname;
$data->table[$i][] = $user->firstname;
+ if (!empty($groupmode)) {
+ $grouptext = '';
+ $groupsraw = groups_get_all_groups($course->id, $user->id, 0, 'g.name');
+ $groups = array();
+ foreach ($groupsraw as $group) {
+ $groups[] = $group->name;;
+ }
+ $data->table[$i][] = implode(', ', $groups);
+ }
$cellsgenerator = new user_sessions_cells_text_generator($reportdata, $user);
- $data->table[$i] = array_merge($data->table[$i], $cellsgenerator->get_cells());
+ $data->table[$i] = array_merge($data->table[$i], $cellsgenerator->get_cells(isset($formdata->includeremarks)));
if ($reportdata->gradable) {
$data->table[$i][] = $reportdata->grades[$user->id].' / '.$reportdata->maxgrades[$user->id];
}
diff --git a/export_form.php b/export_form.php
index ef33010..766e863 100644
--- a/export_form.php
+++ b/export_form.php
@@ -48,7 +48,7 @@ class mod_attendance_export_form extends moodleform {
$mform->addElement('header', 'general', get_string('export', 'quiz'));
- $groupmode=groups_get_activity_groupmode($cm);
+ $groupmode=groups_get_activity_groupmode($cm, $course);
$groups = groups_get_activity_allowed_groups($cm, $USER->id);
if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $modcontext)) {
$grouplist[0] = get_string('allparticipants');
@@ -78,6 +78,7 @@ class mod_attendance_export_form extends moodleform {
$mform->addElement('checkbox', 'includeallsessions', get_string('includeall', 'attendance'), get_string('yes'));
$mform->setDefault('includeallsessions', true);
$mform->addElement('checkbox', 'includenottaken', get_string('includenottaken', 'attendance'), get_string('yes'));
+ $mform->addElement('checkbox', 'includeremarks', get_string('includeremarks', 'attendance'), get_string('yes'));
$mform->addElement('date_selector', 'sessionstartdate', get_string('startofperiod', 'attendance'));
$mform->setDefault('sessionstartdate', $course->startdate);
$mform->disabledIf('sessionstartdate', 'includeallsessions', 'checked');
diff --git a/index.php b/index.php
index dcb421c..f699052 100644
--- a/index.php
+++ b/index.php
@@ -29,8 +29,11 @@ $id = required_param('id', PARAM_INT);
$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
require_login($course);
+$PAGE->set_url('/mod/attendance/index.php', array('id' => $id));
+
// TODO: check if this is correct behaviour - other modules list all the instances of the module in the course.
-if ($att = array_pop(get_all_instances_in_course('attendance', $course, null, true))) {
+if ($att = get_all_instances_in_course('attendance', $course, null, true)) {
+ $att = array_pop($att);
redirect("view.php?id=$att->coursemodule");
} else {
print_error('notfound', 'attendance');
diff --git a/lang/en/attendance.php b/lang/en/attendance.php
index 8138358..ee35575 100755
--- a/lang/en/attendance.php
+++ b/lang/en/attendance.php
@@ -96,6 +96,7 @@ $string['displaymode'] = 'Display mode';
$string['downloadexcel'] = 'Download in Excel format';
$string['downloadooo'] = 'Download in OpenOffice format';
$string['downloadtext'] = 'Download in text format';
+$string['donotusepaging'] = 'Do not use paging';
$string['duration'] = 'Duration';
$string['editsession'] = 'Edit Session';
$string['endtime'] = 'Session end time';
@@ -120,7 +121,9 @@ You can use this feature to hide older sessions instead delete. Remember than on
$string['identifyby'] = 'Identify student by';
$string['includeall'] = 'Select all sessions';
$string['includenottaken'] = 'Include not taken sessions';
+$string['includeremarks'] = 'Include remarks';
$string['indetail'] = 'In detail...';
+$string['invalidsessionenddate'] = 'The session end date can not be earlier than the session start date';
$string['jumpto'] = 'Jump to';
$string['modulename'] = 'Attendance';
$string['modulename_help'] = 'The attendance activity module enables a teacher to take attendance during class and students to view their own attendance record.
@@ -130,6 +133,7 @@ The teacher can create multiple sessions and can mark the attendance status as "
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['myvariables'] = 'My Variables';
$string['newdate'] = 'New date';
$string['newduration'] = 'New duration';
@@ -150,11 +154,15 @@ $string['olddate'] = 'Old date';
$string['period'] = 'Frequency';
$string['pluginname'] = 'Attendance';
$string['pluginadministration'] = 'Attendance administration';
+$string['remark'] = 'Remark for: {a}';
$string['remarks'] = 'Remarks';
$string['report'] = 'Report';
+$string['required'] = 'Required*';
$string['resetdescription'] = 'Remember that deleting attendance data will erase information from database. You can just hide older sessions having changed start date of course!';
$string['resetstatuses'] = 'Reset statuses to default';
$string['restoredefaults'] = 'Restore defaults';
+$string['resultsperpage'] = 'Results per page';
+$string['resultsperpage_desc'] = 'Number of students displayed on a page';
$string['save'] = 'Save attendance';
$string['session'] = 'Session';
$string['session_help'] = 'Session';
diff --git a/lib.php b/lib.php
index 32d65e5..134288b 100644
--- a/lib.php
+++ b/lib.php
@@ -35,14 +35,10 @@ function attendance_supports($feature) {
return true;
case FEATURE_GROUPS:
return true;
- // Artem Andreev: AFAIK it's not tested
- // we need implement filtration of groups list by grouping.
case FEATURE_GROUPINGS:
- return false;
- // Artem Andreev: AFAIK it's not tested
- // harder "All courses" report.
+ return true;
case FEATURE_GROUPMEMBERSONLY:
- return false;
+ return true;
case FEATURE_MOD_INTRO:
return false;
case FEATURE_BACKUP_MOODLE2:
@@ -58,12 +54,13 @@ function attendance_supports($feature) {
function att_add_default_statuses($attid) {
global $DB;
- $statuses = $DB->get_records('attendance_statuses', array('attendanceid'=> 0), 'id');
+ $statuses = $DB->get_recordset('attendance_statuses', array('attendanceid'=> 0), 'id');
foreach ($statuses as $st) {
$rec = $st;
$rec->attendanceid = $attid;
$DB->insert_record('attendance_statuses', $rec);
}
+ $statuses->close();
}
function attendance_add_instance($attendance) {
@@ -217,7 +214,6 @@ function attendance_reset_userdata($data) {
*/
function attendance_user_outline($course, $user, $mod, $attendance) {
global $CFG;
-
require_once(dirname(__FILE__).'/locallib.php');
require_once($CFG->libdir.'/gradelib.php');
@@ -233,9 +229,9 @@ function attendance_user_outline($course, $user, $mod, $attendance) {
if (has_capability('mod/attendance:canbelisted', $mod->context, $user->id)) {
$statuses = att_get_statuses($attendance->id);
$grade = att_get_user_grade(att_get_user_statuses_stat($attendance->id, $course->startdate,
- $user->id), $statuses);
+ $user->id, $mod), $statuses);
$maxgrade = att_get_user_max_grade(att_get_user_taken_sessions_count($attendance->id, $course->startdate,
- $user->id), $statuses);
+ $user->id, $mod), $statuses);
$result->info = $grade.' / '.$maxgrade;
}
@@ -254,7 +250,7 @@ function attendance_user_complete($course, $user, $mod, $attendance) {
require_once($CFG->libdir.'/gradelib.php');
if (has_capability('mod/attendance:canbelisted', $mod->context, $user->id)) {
- echo construct_full_user_stat_html_table($attendance, $course, $user);
+ echo construct_full_user_stat_html_table($attendance, $course, $user, $mod);
}
}
function attendance_print_recent_activity($course, $isteacher, $timestart) {
diff --git a/locallib.php b/locallib.php
index c2b257c..f30c292 100644
--- a/locallib.php
+++ b/locallib.php
@@ -330,9 +330,8 @@ class att_page_with_filter_controls {
if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $PAGE->context)) {
$this->sessgroupslist[self::SESSTYPE_ALL] = get_string('all', 'attendance');
}
- if ($groupmode == VISIBLEGROUPS) {
- $this->sessgroupslist[self::SESSTYPE_COMMON] = get_string('commonsessions', 'attendance');
- }
+ // Show Common groups always
+ $this->sessgroupslist[self::SESSTYPE_COMMON] = get_string('commonsessions', 'attendance');
foreach ($allowedgroups as $group) {
$this->sessgroupslist[$group->id] = format_string($group->name);
}
@@ -601,7 +600,7 @@ class attendance {
public function get_group_mode() {
if (is_null($this->groupmode)) {
- $this->groupmode = groups_get_activity_groupmode($this->cm);
+ $this->groupmode = groups_get_activity_groupmode($this->cm, $this->course);
}
return $this->groupmode;
}
@@ -812,7 +811,8 @@ class attendance {
$i++;
}
- $this->log('sessions added', $this->url_manage(), implode(', ', $info_array));
+ add_to_log($this->course->id, 'attendance', 'sessions added', $this->url_manage(),
+ implode(',', $info_array), $this->cm->id);
}
public function update_session_from_form_data($formdata, $sessionid) {
@@ -834,7 +834,7 @@ class attendance {
$url = $this->url_sessions(array('sessionid' => $sessionid, 'action' => att_sessions_page_params::ACTION_UPDATE));
$info = construct_session_full_date_time($sess->sessdate, $sess->duration);
- $this->log('session updated', $url, $info);
+ add_to_log($this->course->id, 'attendance', 'session updated', $url, $info, $this->cm->id);
}
/**
@@ -888,10 +888,11 @@ class attendance {
'grouptype' => 0);
$url = $this->url_take($params);
-
+ $logurl = att_log_convert_url($url);
+
// Log the change.
- $this->log('taken by student', $url, $USER->firstname.' '.$USER->lastname);
-
+ add_to_log($this->course->id, 'attendance', 'taken by student', $logurl, '', $this->cm->id);
+
return true;
}
@@ -948,9 +949,30 @@ class attendance {
'grouptype' => $this->pageparams->grouptype);
$url = $this->url_take($params);
-
+ $logurl = att_log_convert_url($url);
+
// Log the change.
- $this->log('taken', $url, $USER->firstname.' '.$USER->lastname);
+ add_to_log($this->course->id, 'attendance', 'taken', $logurl, '', $this->cm->id);
+
+ $group = 0;
+ if ($this->pageparams->grouptype != attendance::SESSION_COMMON) {
+ $group = $this->pageparams->grouptype;
+ } else {
+ if ($this->pageparams->group) {
+ $group = $this->pageparams->group;
+ }
+ }
+
+ $totalusers = count_enrolled_users(context_module::instance($this->cm->id), 'mod/attendance:canbelisted', $group);
+ $usersperpage = $this->pageparams->perpage;
+
+ if (!empty($this->pageparams->page) && $this->pageparams->page && $totalusers && $usersperpage) {
+ $numberofpages = ceil($totalusers / $usersperpage);
+ if ($this->pageparams->page < $numberofpages) {
+ $params['page'] = $this->pageparams->page + 1;
+ redirect($this->url_take($params), get_string('moreattendance', 'attendance'));
+ }
+ }
redirect($this->url_manage(), get_string('attendancesuccess', 'attendance'));
}
@@ -958,11 +980,11 @@ class attendance {
/**
* MDL-27591 made this method obsolete.
*/
- public function get_users($groupid = 0) {
- global $DB;
+ public function get_users($groupid = 0, $page = 1) {
+ global $DB, $CFG;
// Fields we need from the user table.
- $userfields = user_picture::fields('u').',u.username,u.idnumber,u.institution,u.department';
+ $userfields = user_picture::fields('u', array('username' , 'idnumber' , 'institution' , 'department'));
if (isset($this->pageparams->sort) and ($this->pageparams->sort == ATT_SORT_FIRSTNAME)) {
$orderby = "u.firstname ASC, u.lastname ASC, u.idnumber ASC, u.institution ASC, u.department ASC";
@@ -970,27 +992,64 @@ class attendance {
$orderby = "u.lastname ASC, u.firstname ASC, u.idnumber ASC, u.institution ASC, u.department ASC";
}
- $users = get_enrolled_users($this->context, 'mod/attendance:canbelisted', $groupid, $userfields, $orderby);
+ if ($page) {
+ $usersperpage = $this->pageparams->perpage;
+ if (!empty($CFG->enablegroupmembersonly) and $this->cm->groupmembersonly) {
+ $startusers = ($page - 1) * $usersperpage;
+ if ($groupid == 0) {
+ $groups = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id'));
+ } else {
+ $groups = $groupid;
+ }
+ $users = get_users_by_capability($this->context, 'mod/attendance:canbelisted',
+ $userfields.',u.id, u.firstname, u.lastname, u.email',
+ $orderby, $startusers, $usersperpage, $groups,
+ '', false, true);
+ } else {
+ $startusers = ($page - 1) * $usersperpage;
+ $users = get_enrolled_users($this->context, 'mod/attendance:canbelisted', $groupid, $userfields, $orderby, $startusers, $usersperpage);
+ }
+ } else {
+ if (!empty($CFG->enablegroupmembersonly) and $this->cm->groupmembersonly) {
+ if ($groupid == 0) {
+ $groups = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id'));
+ } else {
+ $groups = $groupid;
+ }
+ $users = get_users_by_capability($this->context, 'mod/attendance:canbelisted',
+ $userfields.',u.id, u.firstname, u.lastname, u.email',
+ $orderby, '', '', $groups,
+ '', false, true);
+ } else {
+ $users = get_enrolled_users($this->context, 'mod/attendance:canbelisted', $groupid, $userfields, $orderby);
+ }
+ }
// Add a flag to each user indicating whether their enrolment is active.
if (!empty($users)) {
- list($usql, $uparams) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'usid0');
+ list($sql, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'usid0');
- // CONTRIB-3549.
- $sql = "SELECT ue.userid, ue.status, ue.timestart, ue.timeend
+ // CONTRIB-4868
+ $mintime = 'MIN(CASE WHEN (ue.timestart > :zerotime) THEN ue.timestart ELSE ue.timecreated END)';
+ $maxtime = 'MAX(ue.timeend)';
+
+ // CONTRIB-3549
+ $sql = "SELECT ue.userid, ue.status,
+ $mintime AS mintime,
+ $maxtime AS maxtime
FROM {user_enrolments} ue
JOIN {enrol} e ON e.id = ue.enrolid
- WHERE ue.userid $usql
+ WHERE ue.userid $sql
AND e.status = :estatus
AND e.courseid = :courseid
- GROUP BY ue.userid, ue.status, ue.timestart, ue.timeend";
- $params = array_merge($uparams, array('estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id));
- $enrolmentsparams = $DB->get_records_sql($sql, $params);
+ GROUP BY ue.userid, ue.status";
+ $params += array('zerotime'=>0, 'estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id);
+ $enrolments = $DB->get_records_sql($sql, $params);
foreach ($users as $user) {
- $users[$user->id]->enrolmentstatus = $enrolmentsparams[$user->id]->status;
- $users[$user->id]->enrolmentstart = $enrolmentsparams[$user->id]->timestart;
- $users[$user->id]->enrolmentend = $enrolmentsparams[$user->id]->timeend;
+ $users[$user->id]->enrolmentstatus = $enrolments[$user->id]->status;
+ $users[$user->id]->enrolmentstart = $enrolments[$user->id]->mintime;
+ $users[$user->id]->enrolmentend = $enrolments[$user->id]->maxtime;
}
}
@@ -1002,19 +1061,25 @@ class attendance {
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
- $sql = "SELECT ue.userid, ue.status, ue.timestart, ue.timeend
+ // CONTRIB-4868
+ $mintime = 'MIN(CASE WHEN (ue.timestart > :zerotime) THEN ue.timestart ELSE ue.timecreated END)';
+ $maxtime = 'MAX(ue.timeend)';
+
+ $sql = "SELECT ue.userid, ue.status,
+ $mintime AS mintime,
+ $maxtime AS maxtime
FROM {user_enrolments} ue
JOIN {enrol} e ON e.id = ue.enrolid
WHERE ue.userid = :uid
AND e.status = :estatus
AND e.courseid = :courseid
- GROUP BY ue.userid, ue.status, ue.timestart, ue.timeend";
- $params = array('uid' => $userid, 'estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id);
- $enrolmentsparams = $DB->get_record_sql($sql, $params);
+ GROUP BY ue.userid, ue.status";
+ $params = array('zerotime'=>0, 'uid'=>$userid, 'estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id);
+ $enrolments = $DB->get_record_sql($sql, $params);
- $user->enrolmentstatus = $enrolmentsparams->status;
- $user->enrolmentstart = $enrolmentsparams->timestart;
- $user->enrolmentend = $enrolmentsparams->timeend;
+ $user->enrolmentstatus = $enrolments->status;
+ $user->enrolmentstart = $enrolments->mintime;
+ $user->enrolmentend = $enrolments->maxtime;
return $user;
}
@@ -1076,7 +1141,11 @@ class attendance {
public function get_user_taken_sessions_count($userid) {
if (!array_key_exists($userid, $this->usertakensesscount)) {
- $this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid);
+ if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) {
+ $this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid, $this->cm, $this->pageparams->startdate, $this->pageparams->enddate);
+ } else {
+ $this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid, $this->cm);
+ }
}
return $this->usertakensesscount[$userid];
}
@@ -1090,14 +1159,13 @@ class attendance {
*/
public function get_user_statuses_stat($userid, array $filters = null) {
global $DB;
-
- // Need to start setting the parameters here for the filters to work.
$params = array(
- 'aid' => $this->id,
- 'cstartdate' => $this->course->startdate,
- 'uid' => $userid);
+ 'aid' => $this->id,
+ 'cstartdate' => $this->course->startdate,
+ 'uid' => $userid);
$processed_filters = array();
+
// We test for any valid filters sent.
if (isset($filters['enddate'])) {
$processed_filters[] = 'ats.sessdate <= :enddate';
@@ -1106,22 +1174,42 @@ class attendance {
// Make the filter array into a SQL string.
if (!empty($processed_filters)) {
- $processed_filters = 'AND '.implode(' AND ', $processed_filters);
+ $processed_filters = ' AND '.implode(' AND ', $processed_filters);
} else {
$processed_filters = '';
}
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats
- ON al.sessionid = ats.id
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid
- $processed_filters
- GROUP BY al.statusid";
-
- if ($filters !== null) { // We do not want to cache, or use a cached version of the results when a filter is set.
+
+ $period = '';
+ if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) {
+ $period = ' AND ats.sessdate >= :sdate AND ats.sessdate < :edate ';
+ $params['sdate'] = $this->pageparams->startdate;
+ $params['edate'] = $this->pageparams->enddate;
+ }
+
+ if ($this->get_group_mode()) {
+ $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
+ FROM {attendance_log} al
+ JOIN {attendance_sessions} ats ON al.sessionid = ats.id
+ LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
+ WHERE ats.attendanceid = :aid AND
+ ats.sessdate >= :cstartdate AND
+ al.studentid = :uid AND
+ (ats.groupid = 0 or gm.id is NOT NULL)".$period.$processed_filters."
+ GROUP BY al.statusid";
+ } else {
+ $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
+ FROM {attendance_log} al
+ JOIN {attendance_sessions} ats
+ ON al.sessionid = ats.id
+ WHERE ats.attendanceid = :aid AND
+ ats.sessdate >= :cstartdate AND
+ al.studentid = :uid".$period.$processed_filters."
+ GROUP BY al.statusid";
+ }
+
+ // We do not want to cache, or use a cached version of the results when a filter is set.
+ if ($filters !== null) {
return $DB->get_records_sql($qry, $params);
} else if (!array_key_exists($userid, $this->userstatusesstat)) {
// Not filtered so if we do not already have them do the query.
@@ -1176,20 +1264,36 @@ class attendance {
} else {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate";
}
+ if ($this->get_group_mode()) {
+ $sql = "SELECT ats.id, ats.sessdate, ats.groupid, al.statusid, al.remarks
+ FROM {attendance_sessions} ats
+ JOIN {attendance_log} al ON ats.id = al.sessionid AND al.studentid = :uid
+ LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
+ WHERE $where AND (ats.groupid = 0 or gm.id is NOT NULL)
+ ORDER BY ats.sessdate ASC";
- $sql = "SELECT ats.id, ats.sessdate, ats.groupid, al.statusid
+ $params = array(
+ 'uid' => $userid,
+ 'aid' => $this->id,
+ 'csdate' => $this->course->startdate,
+ 'sdate' => $this->pageparams->startdate,
+ 'edate' => $this->pageparams->enddate);
+
+ } else {
+ $sql = "SELECT ats.id, ats.sessdate, ats.groupid, al.statusid, al.remarks
FROM {attendance_sessions} ats
JOIN {attendance_log} al
ON ats.id = al.sessionid AND al.studentid = :uid
WHERE $where
ORDER BY ats.sessdate ASC";
- $params = array(
+ $params = array(
'uid' => $userid,
'aid' => $this->id,
'csdate' => $this->course->startdate,
'sdate' => $this->pageparams->startdate,
'edate' => $this->pageparams->enddate);
+ }
$sessions = $DB->get_records_sql($sql, $params);
return $sessions;
@@ -1197,35 +1301,35 @@ class attendance {
public function get_user_filtered_sessions_log_extended($userid) {
global $DB;
-
// All taked sessions (including previous groups).
- $groups = array_keys(groups_get_all_groups($this->course->id, $userid));
- $groups[] = 0;
- list($gsql, $gparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'gid0');
-
if ($this->pageparams->startdate && $this->pageparams->enddate) {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND
ats.sessdate >= :sdate AND ats.sessdate < :edate";
- $where2 = "ats.attendanceid = :aid2 AND ats.sessdate >= :csdate2 AND
- ats.sessdate >= :sdate2 AND ats.sessdate < :edate2 AND ats.groupid $gsql";
} else {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate";
- $where2 = "ats.attendanceid = :aid2 AND ats.sessdate >= :csdate2 AND ats.groupid $gsql";
}
- $sql = "SELECT ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark
+ // We need to add this concatination so that moodle will use it as the array index that is a string.
+ // If the array's index is a number it will not merge entries.
+ // It would be better as a UNION query butunfortunatly MS SQL does not seem to support doing a DISTINCT on a the description field.
+ $id = $DB->sql_concat(':value', 'ats.id');
+ if ($this->get_group_mode()) {
+ $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark
FROM {attendance_sessions} ats
- RIGHT JOIN {attendance_log} al
+ RIGHT JOIN {attendance_log} al
ON ats.id = al.sessionid AND al.studentid = :uid
- WHERE $where
- UNION
- SELECT ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark
+ LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
+ WHERE $where AND (ats.groupid = 0 or gm.id is NOT NULL)
+ ORDER BY ats.sessdate ASC";
+ } else {
+ $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark
FROM {attendance_sessions} ats
- LEFT JOIN {attendance_log} al
- ON ats.id = al.sessionid AND al.studentid = :uid2
- WHERE $where2
- ORDER BY sessdate ASC";
+ RIGHT JOIN {attendance_log} al
+ ON ats.id = al.sessionid AND al.studentid = :uid
+ WHERE $where
+ ORDER BY ats.sessdate ASC";
+ }
$params = array(
'uid' => $userid,
@@ -1233,14 +1337,32 @@ class attendance {
'csdate' => $this->course->startdate,
'sdate' => $this->pageparams->startdate,
'edate' => $this->pageparams->enddate,
- 'uid2' => $userid,
- 'aid2' => $this->id,
- 'csdate2' => $this->course->startdate,
- 'sdate2' => $this->pageparams->startdate,
- 'edate2' => $this->pageparams->enddate);
- $params = array_merge($params, $gparams);
+ 'value' => 'c');
$sessions = $DB->get_records_sql($sql, $params);
+ // All sessions for current groups.
+
+ $groups = array_keys(groups_get_all_groups($this->course->id, $userid));
+ $groups[] = 0;
+ list($gsql, $gparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'gid0');
+
+ if ($this->pageparams->startdate && $this->pageparams->enddate) {
+ $where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND
+ ats.sessdate >= :sdate AND ats.sessdate < :edate AND ats.groupid $gsql";
+ } else {
+ $where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND ats.groupid $gsql";
+ }
+
+ $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark
+ FROM {attendance_sessions} ats
+ LEFT JOIN {attendance_log} al
+ ON ats.id = al.sessionid AND al.studentid = :uid
+ WHERE $where
+ ORDER BY ats.sessdate ASC";
+
+ $params = array_merge($params, $gparams);
+ $sessions = array_merge($sessions, $DB->get_records_sql($sql, $params));
+
foreach ($sessions as $sess) {
if (empty($sess->description)) {
$sess->description = get_string('nodescription', 'attendance');
@@ -1259,21 +1381,23 @@ class attendance {
list($sql, $params) = $DB->get_in_or_equal($sessionsids);
$DB->delete_records_select('attendance_log', "sessionid $sql", $params);
$DB->delete_records_list('attendance_sessions', 'id', $sessionsids);
- $this->log('sessions deleted', null, get_string('sessionsids', 'attendance').implode(', ', $sessionsids));
+ add_to_log($this->course->id, 'attendance', 'sessions deleted', $this->url_manage(),
+ get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
}
public function update_sessions_duration($sessionsids, $duration) {
global $DB;
$now = time();
- $sessions = $DB->get_records_list('attendance_sessions', 'id', $sessionsids);
+ $sessions = $DB->get_recordset_list('attendance_sessions', 'id', $sessionsids);
foreach ($sessions as $sess) {
$sess->duration = $duration;
$sess->timemodified = $now;
$DB->update_record('attendance_sessions', $sess);
}
-
- $this->log('sessions duration updated', $this->url_manage(), get_string('sessionsids', 'attendance').implode(', ', $sessionsids));
+ $sessions->close();
+ add_to_log($this->course->id, 'attendance', 'sessions duration updated', $this->url_manage(),
+ get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
}
public function remove_status($statusid) {
@@ -1294,7 +1418,8 @@ class attendance {
$rec->grade = $grade;
$DB->insert_record('attendance_statuses', $rec);
- $this->log('status added', $this->url_preferences(), $acronym.': '.$description.' ('.$grade.')');
+ add_to_log($this->course->id, 'attendance', 'status added', $this->url_preferences(),
+ $acronym.': '.$description.' ('.$grade.')', $this->cm->id);
} else {
print_error('cantaddstatus', 'attendance', $this->url_preferences());
}
@@ -1325,11 +1450,12 @@ class attendance {
}
$DB->update_record('attendance_statuses', $status);
- $this->log('status updated', $this->url_preferences(), implode(' ', $updated));
+ add_to_log($this->course->id, 'attendance', 'status updated', $this->url_preferences(),
+ implode(' ', $updated), $this->cm->id);
}
+
}
-
function att_get_statuses($attid, $onlyvisible=true) {
global $DB;
@@ -1344,28 +1470,56 @@ function att_get_statuses($attid, $onlyvisible=true) {
return $statuses;
}
-function att_get_user_taken_sessions_count($attid, $coursestartdate, $userid) {
- global $DB;
-
- $qry = "SELECT count(*) as cnt
+function att_get_user_taken_sessions_count($attid, $coursestartdate, $userid, $coursemodule, $startdate = '', $enddate = '') {
+ global $DB, $COURSE;
+ $groupmode = groups_get_activity_groupmode($coursemodule, $COURSE);
+ if (!empty($groupmode)) {
+ $qry = "SELECT count(*) as cnt
+ FROM {attendance_log} al
+ JOIN {attendance_sessions} ats ON al.sessionid = ats.id
+ LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
+ WHERE ats.attendanceid = :aid AND
+ ats.sessdate >= :cstartdate AND
+ al.studentid = :uid AND
+ (ats.groupid = 0 or gm.id is NOT NULL)";
+ } else {
+ $qry = "SELECT count(*) as cnt
FROM {attendance_log} al
JOIN {attendance_sessions} ats
ON al.sessionid = ats.id
WHERE ats.attendanceid = :aid AND
ats.sessdate >= :cstartdate AND
al.studentid = :uid";
+ }
$params = array(
- 'aid' => $attid,
- 'cstartdate' => $coursestartdate,
- 'uid' => $userid);
+ 'aid' => $attid,
+ 'cstartdate' => $coursestartdate,
+ 'uid' => $userid);
+
+ if (!empty($startdate) && !empty($enddate)) {
+ $qry .= ' AND sessdate >= :sdate AND sessdate < :edate ';
+ $params['sdate'] = $startdate;
+ $params['edate'] = $enddate;
+ }
return $DB->count_records_sql($qry, $params);
}
-function att_get_user_statuses_stat($attid, $coursestartdate, $userid) {
- global $DB;
-
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
+function att_get_user_statuses_stat($attid, $coursestartdate, $userid, $coursemodule) {
+ global $DB, $COURSE;
+ $groupmode = groups_get_activity_groupmode($coursemodule, $COURSE);
+ if (!empty($groupmode)) {
+ $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
+ FROM {attendance_log} al
+ JOIN {attendance_sessions} ats ON al.sessionid = ats.id
+ LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
+ WHERE ats.attendanceid = :aid AND
+ ats.sessdate >= :cstartdate AND
+ al.studentid = :uid AND
+ (ats.groupid = 0 or gm.id is NOT NULL)
+ GROUP BY al.statusid";
+ } else {
+ $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
FROM {attendance_log} al
JOIN {attendance_sessions} ats
ON al.sessionid = ats.id
@@ -1373,6 +1527,7 @@ function att_get_user_statuses_stat($attid, $coursestartdate, $userid) {
ats.sessdate >= :cstartdate AND
al.studentid = :uid
GROUP BY al.statusid";
+ }
$params = array(
'aid' => $attid,
'cstartdate' => $coursestartdate,
@@ -1429,7 +1584,7 @@ function att_get_gradebook_maxgrade($attid) {
return $DB->get_field('attendance', 'grade', array('id' => $attid));
}
-function att_update_all_users_grades($attid, $course, $context) {
+function att_update_all_users_grades($attid, $course, $context, $coursemodule) {
$grades = array();
$userids = array_keys(get_enrolled_users($context, 'mod/attendance:canbelisted', 0, 'u.id'));
@@ -1439,8 +1594,8 @@ function att_update_all_users_grades($attid, $course, $context) {
foreach ($userids as $userid) {
$grade = new stdClass;
$grade->userid = $userid;
- $userstatusesstat = att_get_user_statuses_stat($attid, $course->startdate, $userid);
- $usertakensesscount = att_get_user_taken_sessions_count($attid, $course->startdate, $userid);
+ $userstatusesstat = att_get_user_statuses_stat($attid, $course->startdate, $userid, $coursemodule);
+ $usertakensesscount = att_get_user_taken_sessions_count($attid, $course->startdate, $userid, $coursemodule);
$usergrade = att_get_user_grade($userstatusesstat, $statuses);
$usermaxgrade = att_get_user_max_grade($usertakensesscount, $statuses);
$grade->rawgrade = att_calc_user_grade_fraction($usergrade, $usermaxgrade) * $gradebook_maxgrade;
@@ -1471,6 +1626,14 @@ function att_log_convert_url(moodle_url $fullurl) {
function attforblock_upgrade() {
global $DB, $CFG;
$module = $DB->get_record('modules', array('name' => 'attforblock'));
+
+ // Deal with Moodle versions above 2013092001.02, where version is in config
+ $versioninmodtable = true;
+ if (!isset($module->version)) {
+ $versioninmodtable = false;
+ $module->version = get_config('mod_attforblock', 'version');
+ }
+
if ($module->version <= '2011061800') {
print_error("noupgradefromthisversion", 'attendance');
}
@@ -1489,12 +1652,49 @@ function attforblock_upgrade() {
}
// Now convert module record.
$module->name = 'attendance';
+ if (!$versioninmodtable) {
+ set_config('version', $module->version, 'mod_attendance');
+ unset($module->version);
+ }
$DB->update_record('modules', $module);
+ // Now convert grade items to 'attendance'
+ $sql = "UPDATE {grade_items}
+ SET itemmodule = ?
+ WHERE itemmodule = ?";
+ $DB->execute($sql, array('attendance', 'attforblock'));
+
+ $sql = "UPDATE {grade_items_history}
+ SET itemmodule = 'attendance'
+ WHERE itemmodule = 'attforblock'";
+ $DB->execute($sql);
+
+ /*
+ * The user's custom capabilities need to be preserved due to the module renaming.
+ * Capabilities with a modifierid = 0 value are installed by default.
+ * Only update the user's custom capabilities where modifierid is not zero.
+ */
+ $sql = $DB->sql_like('capability', '?').' AND modifierid <> 0';
+ $rs = $DB->get_recordset_select('role_capabilities', $sql, array('%mod/attforblock%'));
+ foreach ($rs as $cap) {
+ $renamedcapability = str_replace('mod/attforblock', 'mod/attendance', $cap->capability);
+ $exists = $DB->record_exists('role_capabilities', array('roleid' => $cap->roleid, 'capability' => $renamedcapability));
+ if (!$exists) {
+ $DB->update_record('role_capabilities', array('id' => $cap->id, 'capability' => $renamedcapability));
+ }
+ }
+
+ // Delete old role capabilities.
+ $sql = $DB->sql_like('capability', '?');
+ $DB->delete_records_select('role_capabilities', $sql, array('%mod/attforblock%'));
+
+ // Delete old capabilities.
+ $DB->delete_records_select('capabilities', 'component = ?', array('mod_attforblock'));
+
// Clear cache for courses with attendances.
$attendances = $DB->get_recordset('attendance', array(), '', 'course');
foreach ($attendances as $attendance) {
rebuild_course_cache($attendance->course, true);
}
$attendances->close();
-}
\ No newline at end of file
+}
diff --git a/manage.php b/manage.php
index 03a394c..0099d5e 100644
--- a/manage.php
+++ b/manage.php
@@ -31,6 +31,7 @@ $id = required_param('id', PARAM_INT);
$from = optional_param('from', null, PARAM_ALPHANUMEXT);
$pageparams->view = optional_param('view', null, PARAM_INT);
$pageparams->curdate = optional_param('curdate', null, PARAM_INT);
+$pageparams->perpage = get_config('attendance', 'resultsperpage');
$cm = get_coursemodule_from_id('attendance', $id, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
diff --git a/preferences.php b/preferences.php
index b597958..8597fdd 100644
--- a/preferences.php
+++ b/preferences.php
@@ -93,7 +93,9 @@ switch ($att->pageparams->action) {
foreach ($acronym as $id => $v) {
$att->update_status($id, $acronym[$id], $description[$id], $grade[$id], null);
}
- att_update_all_users_grades($att->id, $att->course, $att->context);
+ if ($att->grade > 0) {
+ att_update_all_users_grades($att->id, $att->course, $att->context, $cm);
+ }
break;
}
diff --git a/renderables.php b/renderables.php
index d62ede4..75c5324 100644
--- a/renderables.php
+++ b/renderables.php
@@ -269,9 +269,9 @@ class attendance_take_data implements renderable {
public function __construct(attendance $att) {
if ($att->pageparams->grouptype) {
- $this->users = $att->get_users($att->pageparams->grouptype);
+ $this->users = $att->get_users($att->pageparams->grouptype, $att->pageparams->page);
} else {
- $this->users = $att->get_users($att->pageparams->group);
+ $this->users = $att->get_users($att->pageparams->group, $att->pageparams->page);
}
$this->pageparams = $att->pageparams;
@@ -389,8 +389,8 @@ class attendance_user_data implements renderable {
$this->maxgrade = array();
foreach ($this->coursesatts as $ca) {
$statuses = att_get_statuses($ca->attid);
- $user_taken_sessions_count = att_get_user_taken_sessions_count($ca->attid, $ca->coursestartdate, $userid);
- $user_statuses_stat = att_get_user_statuses_stat($ca->attid, $ca->coursestartdate, $userid);
+ $user_taken_sessions_count = att_get_user_taken_sessions_count($ca->attid, $ca->coursestartdate, $userid, $att->cm);
+ $user_statuses_stat = att_get_user_statuses_stat($ca->attid, $ca->coursestartdate, $userid, $att->cm);
$this->statuses[$ca->attid] = $statuses;
@@ -468,7 +468,7 @@ class attendance_report_data implements renderable {
$this->pageparams = $att->pageparams;
- $this->users = $att->get_users($att->pageparams->group);
+ $this->users = $att->get_users($att->pageparams->group, $att->pageparams->page);
$this->groups = groups_get_all_groups($att->course->id);
diff --git a/renderer.php b/renderer.php
index 7d06d88..9f43f0d 100644
--- a/renderer.php
+++ b/renderer.php
@@ -57,12 +57,14 @@ class mod_attendance_renderer extends plugin_renderer_base {
$filtertable = new html_table();
$filtertable->attributes['class'] = ' ';
$filtertable->width = '100%';
- $filtertable->align = array('left', 'center', 'right');
+ $filtertable->align = array('left', 'center', 'right', 'right');
$filtertable->data[0][] = $this->render_sess_group_selector($fcontrols);
$filtertable->data[0][] = $this->render_curdate_controls($fcontrols);
+ $filtertable->data[0][] = $this->render_paging_controls($fcontrols);
+
$filtertable->data[0][] = $this->render_view_controls($fcontrols);
$o = html_writer::table($filtertable);
@@ -91,6 +93,37 @@ class mod_attendance_renderer extends plugin_renderer_base {
return '';
}
+ protected function render_paging_controls(attendance_filter_controls $fcontrols) {
+ global $CFG;
+
+ $paging_controls = '';
+
+ $group = 0;
+ if (!empty($fcontrols->pageparams->group)) {
+ $group = $fcontrols->pageparams->group;
+ }
+
+ $totalusers = count_enrolled_users(context_module::instance($fcontrols->cm->id), 'mod/attendance:canbelisted', $group);
+
+ if (empty($fcontrols->pageparams->page) || !$fcontrols->pageparams->page || !$totalusers || empty($fcontrols->pageparams->perpage)) {
+ return $paging_controls;
+ }
+
+ $numberofpages = ceil($totalusers / $fcontrols->pageparams->perpage);
+
+ if ($fcontrols->pageparams->page > 1) {
+ $paging_controls .= html_writer::link($fcontrols->url(array('curdate' => $fcontrols->nextcur, 'page' => $fcontrols->pageparams->page - 1)),
+ $this->output->larrow());
+ }
+ $paging_controls .= html_writer::tag('span', "Page {$fcontrols->pageparams->page} of $numberofpages", array('class' => 'attbtn'));
+ if ($fcontrols->pageparams->page < $numberofpages) {
+ $paging_controls .= html_writer::link($fcontrols->url(array('curdate' => $fcontrols->nextcur, 'page' => $fcontrols->pageparams->page + 1)),
+ $this->output->rarrow());
+ }
+
+ return $paging_controls ;
+ }
+
protected function render_curdate_controls(attendance_filter_controls $fcontrols) {
global $CFG;
@@ -283,14 +316,30 @@ class mod_attendance_renderer extends plugin_renderer_base {
} else {
$table = $this->render_attendance_take_grid($takedata);
}
- $table .= html_writer::input_hidden_params($takedata->url(array('sesskey' => sesskey())));
+ $table .= html_writer::input_hidden_params($takedata->url(array('sesskey' => sesskey(), 'page' => $takedata->pageparams->page)));
$params = array(
'type' => 'submit',
'value' => get_string('save', 'attendance'));
$table .= html_writer::tag('center', html_writer::empty_tag('input', $params));
$table = html_writer::tag('form', $table, array('method' => 'post', 'action' => $takedata->url_path()));
- return $controls.$table;
+ foreach($takedata->statuses as $status) {
+ $sessionstats[$status->id] = 0;
+ }
+ // Calculate the sum of statuses for each user
+ $sessionstats[] = array();
+ foreach ($takedata->sessionlog as $userlog) {
+ foreach($takedata->statuses as $status) {
+ if ($userlog->statusid == $status->id) $sessionstats[$status->id]++;
+ }
+ }
+
+ $statsoutput = '
';
+ foreach($takedata->statuses as $status) {
+ $statsoutput .= "$status->description = ".$sessionstats[$status->id]."
";
+ }
+
+ return $controls.$table.$statsoutput;
}
protected function render_attendance_take_controls(attendance_take_data $takedata) {
@@ -318,7 +367,47 @@ class mod_attendance_renderer extends plugin_renderer_base {
}
private function construct_take_controls(attendance_take_data $takedata) {
+ GLOBAL $CFG;
+
$controls = '';
+
+ $group = 0;
+ if ($takedata->pageparams->grouptype != attendance::SESSION_COMMON) {
+ $group = $takedata->pageparams->grouptype;
+ } else {
+ if ($takedata->pageparams->group) {
+ $group = $takedata->pageparams->group;
+ }
+ }
+
+ if (!empty($CFG->enablegroupmembersonly) and $takedata->cm->groupmembersonly) {
+ if ($group == 0) {
+ $groups = array_keys(groups_get_all_groups($takedata->cm->course, 0, $takedata->cm->groupingid, 'g.id'));
+ } else {
+ $groups = $group;
+ }
+ $users = get_users_by_capability(context_module::instance($takedata->cm->id), 'mod/attendance:canbelisted',
+ 'u.id, u.firstname, u.lastname, u.email',
+ '', '', '', $groups,
+ '', false, true);
+ $totalusers = count($users);
+ } else {
+ $totalusers = count_enrolled_users(context_module::instance($takedata->cm->id), 'mod/attendance:canbelisted', $group);
+ }
+ $usersperpage = $takedata->pageparams->perpage;
+ if (!empty($takedata->pageparams->page) && $takedata->pageparams->page && $totalusers && $usersperpage) {
+ $controls .= html_writer::empty_tag('br');
+ $numberofpages = ceil($totalusers / $usersperpage);
+
+ if ($takedata->pageparams->page > 1) {
+ $controls .= html_writer::link($takedata->url(array('page' => $takedata->pageparams->page - 1)), $this->output->larrow());
+ }
+ $controls .= html_writer::tag('span', "Page {$takedata->pageparams->page} of $numberofpages", array('class' => 'attbtn'));
+ if ($takedata->pageparams->page < $numberofpages) {
+ $controls .= html_writer::link($takedata->url(array('page' => $takedata->pageparams->page + 1)), $this->output->rarrow());
+ }
+ }
+
if ($takedata->pageparams->grouptype == attendance::SESSION_COMMON and
($takedata->groupmode == VISIBLEGROUPS or
($takedata->groupmode and $takedata->perm->can_access_all_groups()))) {
@@ -530,7 +619,8 @@ class mod_attendance_renderer extends plugin_renderer_base {
}
$params = array(
'type' => 'text',
- 'name' => 'remarks'.$user->id);
+ 'name' => 'remarks'.$user->id,
+ 'maxlength' => 255);
if (array_key_exists($user->id, $takedata->sessionlog)) {
$params['value'] = $takedata->sessionlog[$user->id]->remarks;
}
@@ -619,8 +709,8 @@ class mod_attendance_renderer extends plugin_renderer_base {
get_string('status', 'attendance'),
get_string('remarks', 'attendance')
);
- $table->align = array('', '', '', 'left', 'left', 'center', 'left');
- $table->size = array('1px', '1px', '1px', '1px', '*', '1px', '1px');
+ $table->align = array('', '', '', 'left', 'left', 'center', 'left', 'center');
+ $table->size = array('1px', '1px', '1px', '1px', '*', '1px', '1px', '*');
$i = 0;
foreach ($userdata->sessionslog as $sess) {
@@ -693,6 +783,7 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->head[] = $this->construct_fullname_head($reportdata);
$table->align[] = 'left';
$table->size[] = '';
+ $sessionstats = array();
foreach ($reportdata->sessions as $sess) {
$sesstext = userdate($sess->sessdate, get_string('strftimedm', 'attendance'));
@@ -713,6 +804,7 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->head[] = $status->acronym;
$table->align[] = 'center';
$table->size[] = '1px';
+ $sessionstats[$status->id] = 0;
}
if ($reportdata->gradable) {
@@ -721,6 +813,12 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->size[] = '1px';
}
+ if ($reportdata->sessionslog) {
+ $table->head[] = get_string('remarks', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '200px';
+ }
+
if ($bulkmessagecapability) { // Display the table header for bulk messaging.
// The checkbox must have an id of cb_selector so that the JavaScript will pick it up.
$table->head[] = html_writer::checkbox('cb_selector', 0, false, '', array('id' => 'cb_selector'));
@@ -749,28 +847,59 @@ class mod_attendance_renderer extends plugin_renderer_base {
$row->cells[] = $reportdata->grades[$user->id].' / '.$reportdata->maxgrades[$user->id];
}
+ if ($reportdata->sessionslog) {
+ if (isset($sess) && isset($reportdata->sessionslog[$user->id][$sess->id]->remarks)) {
+ $row->cells[] = $reportdata->sessionslog[$user->id][$sess->id]->remarks;
+ } else {
+ $row->cells[] = '';
+ }
+ }
+
if ($bulkmessagecapability) { // Create the checkbox for bulk messaging.
$row->cells[] = html_writer::checkbox('user'.$user->id, 'on', false);
}
-
+
$table->data[] = $row;
}
+ // Calculate the sum of statuses for each user
+ $statrow = new html_table_row();
+ $statrow->cells[] = '';
+ $statrow->cells[] = get_string('summary');
+ foreach ($reportdata->sessions as $sess) {
+ foreach ($reportdata->users as $user) {
+ foreach($reportdata->statuses as $status) {
+ if (!empty($reportdata->sessionslog[$user->id][$sess->id])) {
+ if ($reportdata->sessionslog[$user->id][$sess->id]->statusid == $status->id) $sessionstats[$status->id]++;
+ }
+ }
+ }
+
+ $statsoutput = '
';
+ foreach($reportdata->statuses as $status) {
+ $statsoutput .= "$status->description:".$sessionstats[$status->id]."
";
+ }
+ $statrow->cells[] = $statsoutput;
+
+ }
+ $table->data[] = $statrow;
+
if ($bulkmessagecapability) { // Require that the user can bulk message users.
// Display check boxes that will allow the user to send a message to the students that have been checked.
$output = html_writer::empty_tag('input', array('name' => 'sesskey', 'type' => 'hidden', 'value' => sesskey()));
$output .= html_writer::empty_tag('input', array('name' => 'formaction', 'type' => 'hidden', 'value' => 'messageselect.php'));
$output .= html_writer::empty_tag('input', array('name' => 'id', 'type' => 'hidden', 'value' => $GLOBALS['COURSE']->id));
$output .= html_writer::empty_tag('input', array('name' => 'returnto', 'type' => 'hidden', 'value' => s(me())));
- $output .= html_writer::table($table);
+ $output .= html_writer::table($table).html_writer::tag('div', get_string('users').': '.count($reportdata->users));;
$output .= html_writer::tag('div',
html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('messageselectadd'))),
array('class' => 'buttons'));
$url = new moodle_url('/user/action_redir.php');
return html_writer::tag('form', $output, array('action' => $url->out(), 'method' => 'post'));
} else {
- return html_writer::table($table);
+ return html_writer::table($table).html_writer::tag('div', get_string('users').': '.count($reportdata->users));
}
+
}
protected function render_attendance_preferences_data(attendance_preferences_data $prefdata) {
diff --git a/renderhelpers.php b/renderhelpers.php
index e25bfb0..15ab178 100644
--- a/renderhelpers.php
+++ b/renderhelpers.php
@@ -43,7 +43,7 @@ class user_sessions_cells_generator {
$this->user = $user;
}
- public function get_cells() {
+ public function get_cells($remarks = false) {
$this->init_cells();
foreach ($this->reportdata->sessions as $sess) {
if (array_key_exists($sess->id, $this->reportdata->sessionslog[$this->user->id])) {
@@ -53,6 +53,9 @@ class user_sessions_cells_generator {
} else {
$this->construct_hidden_status_cell($this->reportdata->allstatuses[$statusid]->acronym);
}
+ if ($remarks) {
+ $this->construct_remarks_cell($this->reportdata->sessionslog[$this->user->id][$sess->id]->remarks);
+ }
} else {
if ($this->user->enrolmentstart > $sess->sessdate) {
$starttext = get_string('enrolmentstart', 'attendance', userdate($this->user->enrolmentstart, '%d.%m.%Y'));
@@ -71,6 +74,9 @@ class user_sessions_cells_generator {
$this->construct_not_existing_for_user_session_cell('');
}
}
+ if ($remarks) {
+ $this->construct_remarks_cell('');
+ }
}
}
$this->finalize_cells();
@@ -97,6 +103,10 @@ class user_sessions_cells_generator {
protected function construct_not_taken_cell($text) {
$this->cells[] = $text;
}
+
+ protected function construct_remarks_cell($text) {
+ $this->cells[] = $text;
+ }
protected function construct_not_existing_for_user_session_cell($text) {
$this->cells[] = $text;
@@ -150,6 +160,11 @@ class user_sessions_cells_html_generator extends user_sessions_cells_generator {
$this->close_open_cell_if_needed();
$this->cells[] = $text;
}
+
+ protected function construct_remarks_cell($text) {
+ $this->close_open_cell_if_needed();
+ $this->cells[] = $text;
+ }
protected function construct_not_existing_for_user_session_cell($text) {
$this->close_open_cell_if_needed();
@@ -239,17 +254,17 @@ function construct_user_data_stat($stat, $statuses, $gradable, $grade, $maxgrade
return html_writer::table($stattable);
}
-function construct_full_user_stat_html_table($attendance, $course, $user) {
+function construct_full_user_stat_html_table($attendance, $course, $user, $coursemodule) {
global $CFG;
$gradeable = $attendance->grade > 0;
$statuses = att_get_statuses($attendance->id);
- $userstatusesstat = att_get_user_statuses_stat($attendance->id, $course->startdate, $user->id);
- $stat['completed'] = att_get_user_taken_sessions_count($attendance->id, $course->startdate, $user->id);
+ $userstatusesstat = att_get_user_statuses_stat($attendance->id, $course->startdate, $user->id, $coursemodule);
+ $stat['completed'] = att_get_user_taken_sessions_count($attendance->id, $course->startdate, $user->id, $coursemodule);
$stat['statuses'] = $userstatusesstat;
if ($gradeable) {
$grade = att_get_user_grade($userstatusesstat, $statuses);
$maxgrade = att_get_user_max_grade(att_get_user_taken_sessions_count($attendance->id, $course->startdate,
- $user->id), $statuses);
+ $user->id, $coursemodule), $statuses);
if (!$decimalpoints = grade_get_setting($course->id, 'decimalpoints')) {
$decimalpoints = $CFG->grade_decimalpoints;
}
diff --git a/report.php b/report.php
index addb4f6..b9d37eb 100644
--- a/report.php
+++ b/report.php
@@ -33,6 +33,8 @@ $pageparams->view = optional_param('view', null, PARAM_INT);
$pageparams->curdate = optional_param('curdate', null, PARAM_INT);
$pageparams->group = optional_param('group', null, PARAM_INT);
$pageparams->sort = optional_param('sort', null, PARAM_INT);
+$pageparams->page = optional_param('page', 1, PARAM_INT);
+$pageparams->perpage = get_config('attendance', 'resultsperpage');
$cm = get_coursemodule_from_id('attendance', $id, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
diff --git a/sessions.php b/sessions.php
index ea44026..fda84fe 100644
--- a/sessions.php
+++ b/sessions.php
@@ -85,7 +85,9 @@ switch ($att->pageparams->action) {
if (isset($confirm) && confirm_sesskey()) {
$att->delete_sessions(array($sessionid));
- att_update_all_users_grades($att->id, $att->course, $att->context);
+ if ($att->grade > 0) {
+ att_update_all_users_grades($att->id, $att->course, $att->context, $cm);
+ }
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
@@ -112,7 +114,9 @@ switch ($att->pageparams->action) {
$sessionsids = explode('_', $sessionsids);
$att->delete_sessions($sessionsids);
- att_update_all_users_grades($att->id, $att->course, $att->context);
+ if ($att->grade > 0) {
+ att_update_all_users_grades($att->id, $att->course, $att->context, $cm);
+ }
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
$sessid = required_param('sessid', PARAM_SEQUENCE);
diff --git a/settings.php b/settings.php
new file mode 100644
index 0000000..66c5805
--- /dev/null
+++ b/settings.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * Attendance plugin settings
+ *
+ * @package mod_attendance
+ * @copyright 2013 Netspot, Tim Lock.
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+if ($ADMIN->fulltree) {
+ require_once(dirname(__FILE__).'/lib.php');
+
+ // Paging options.
+ $options = array(
+ 0 => get_string('donotusepaging', 'attendance'),
+ 25 => 25,
+ 50 => 50,
+ 75 => 75,
+ 100 => 100,
+ 250 => 250,
+ 500 => 500,
+ 1000 => 1000,
+ );
+
+ $settings->add(new admin_setting_configselect('attendance/resultsperpage',
+ get_string('resultsperpage', 'attendance'), get_string('resultsperpage_desc', 'attendance'), 25, $options));
+}
diff --git a/take.php b/take.php
index d7c7ac0..4452927 100644
--- a/take.php
+++ b/take.php
@@ -34,6 +34,8 @@ $pageparams->sort = optional_param('sort', null, PARAM_INT);
$pageparams->copyfrom = optional_param('copyfrom', null, PARAM_INT);
$pageparams->viewmode = optional_param('viewmode', null, PARAM_INT);
$pageparams->gridcols = optional_param('gridcols', null, PARAM_INT);
+$pageparams->page = optional_param('page', 1, PARAM_INT);
+$pageparams->perpage = get_config('attendance', 'resultsperpage');
$cm = get_coursemodule_from_id('attendance', $id, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
diff --git a/version.php b/version.php
index d36b123..ae31eea 100644
--- a/version.php
+++ b/version.php
@@ -22,12 +22,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-$module->version = 2013082901;
-$module->requires = 2013040500;
-$module->release = '2.5.1';
-$module->maturity = MATURITY_STABLE;
-$module->cron = 0;
-$module->component = 'mod_attendance';
+$plugin->version = 2014022801;
+$plugin->requires = 2013040500;
+$plugin->release = '2.6.1';
+$plugin->maturity = MATURITY_STABLE;
+$plugin->cron = 0;
+$plugin->component = 'mod_attendance';
// Nasty upgrade code to check if need to upgrade from attforblock.
// TODO: remove this asap.
diff --git a/view.php b/view.php
index 19e288d..51e7eb4 100644
--- a/view.php
+++ b/view.php
@@ -63,7 +63,15 @@ $PAGE->navbar->add(get_string('attendancereport', 'attendance'));
$output = $PAGE->get_renderer('mod_attendance');
-$userid = (isset($pageparams->studentid) && ($att->perm->can_manage() || $att->perm->can_take() || $att->perm->can_change())) ? $pageparams->studentid : $USER->id;
+if (isset($pageparams->studentid) && $USER->id != $pageparams->studentid) {
+ // Only users with proper permissions should be able to see any user's individual report.
+ require_capability('mod/attendance:viewreports', $PAGE->context);
+ $userid = $pageparams->studentid;
+} else {
+ // A valid request to see another users report has not been sent, show the user's own.
+ $userid = $USER->id;
+}
+
$userdata = new attendance_user_data($att, $userid);
echo $output->header();