|
@ -33,6 +33,7 @@ define('ATT_VIEW_WEEKS', 2); |
|
|
define('ATT_VIEW_MONTHS', 3); |
|
|
define('ATT_VIEW_MONTHS', 3); |
|
|
define('ATT_VIEW_ALLPAST', 4); |
|
|
define('ATT_VIEW_ALLPAST', 4); |
|
|
define('ATT_VIEW_ALL', 5); |
|
|
define('ATT_VIEW_ALL', 5); |
|
|
|
|
|
define('ATT_VIEW_NOTPRESENT', 6); |
|
|
|
|
|
|
|
|
define('ATT_SORT_LASTNAME', 1); |
|
|
define('ATT_SORT_LASTNAME', 1); |
|
|
define('ATT_SORT_FIRSTNAME', 2); |
|
|
define('ATT_SORT_FIRSTNAME', 2); |
|
@ -701,6 +702,8 @@ class attendance { |
|
|
|
|
|
|
|
|
if ($this->pageparams->startdate && $this->pageparams->enddate) { |
|
|
if ($this->pageparams->startdate && $this->pageparams->enddate) { |
|
|
$where = "attendanceid = :aid AND sessdate >= :csdate AND sessdate >= :sdate AND sessdate < :edate"; |
|
|
$where = "attendanceid = :aid AND sessdate >= :csdate AND sessdate >= :sdate AND sessdate < :edate"; |
|
|
|
|
|
} else if ($this->pageparams->enddate) { |
|
|
|
|
|
$where = "attendanceid = :aid AND sessdate >= :csdate AND sessdate < :edate"; |
|
|
} else { |
|
|
} else { |
|
|
$where = "attendanceid = :aid AND sessdate >= :csdate"; |
|
|
$where = "attendanceid = :aid AND sessdate >= :csdate"; |
|
|
} |
|
|
} |
|
@ -807,6 +810,7 @@ class attendance { |
|
|
} |
|
|
} |
|
|
$i++; |
|
|
$i++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
add_to_log($this->course->id, 'attendance', 'sessions added', $this->url_manage(), |
|
|
add_to_log($this->course->id, 'attendance', 'sessions added', $this->url_manage(), |
|
|
implode(',', $info_array), $this->cm->id); |
|
|
implode(',', $info_array), $this->cm->id); |
|
|
} |
|
|
} |
|
@ -833,6 +837,65 @@ class attendance { |
|
|
add_to_log($this->course->id, 'attendance', 'session updated', $url, $info, $this->cm->id); |
|
|
add_to_log($this->course->id, 'attendance', 'session updated', $url, $info, $this->cm->id); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Used to record attendance submitted by the student. |
|
|
|
|
|
* |
|
|
|
|
|
* @global type $DB |
|
|
|
|
|
* @global type $USER |
|
|
|
|
|
* @param type $mformdata |
|
|
|
|
|
* @return boolean |
|
|
|
|
|
*/ |
|
|
|
|
|
public function take_from_student($mformdata) { |
|
|
|
|
|
global $DB, $USER; |
|
|
|
|
|
|
|
|
|
|
|
$statuses = implode(',', array_keys( (array)$this->get_statuses() )); |
|
|
|
|
|
$now = time(); |
|
|
|
|
|
|
|
|
|
|
|
$record = new stdClass(); |
|
|
|
|
|
$record->studentid = $USER->id; |
|
|
|
|
|
$record->statusid = $mformdata->status; |
|
|
|
|
|
$record->statusset = $statuses; |
|
|
|
|
|
$record->remarks = get_string('set_by_student', 'mod_attendance'); |
|
|
|
|
|
$record->sessionid = $mformdata->sessid; |
|
|
|
|
|
$record->timetaken = $now; |
|
|
|
|
|
$record->takenby = $USER->id; |
|
|
|
|
|
|
|
|
|
|
|
$dbsesslog = $this->get_session_log($mformdata->sessid); |
|
|
|
|
|
if (array_key_exists($record->studentid, $dbsesslog)) { |
|
|
|
|
|
// Already recorded do not save. |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
$DB->insert_record('attendance_log', $record, false); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update the session to show that a register has been taken, or staff may overwrite records. |
|
|
|
|
|
$rec = new object(); |
|
|
|
|
|
$rec->id = $mformdata->sessid; |
|
|
|
|
|
$rec->lasttaken = $now; |
|
|
|
|
|
$rec->lasttakenby = $USER->id; |
|
|
|
|
|
$DB->update_record('attendance_sessions', $rec); |
|
|
|
|
|
|
|
|
|
|
|
// Update the users grade. |
|
|
|
|
|
$this->update_users_grade(array($USER->id)); |
|
|
|
|
|
|
|
|
|
|
|
/* create url for link in log screen |
|
|
|
|
|
* need to set grouptype to 0 to allow take attendance page to be called |
|
|
|
|
|
* from report/log page */ |
|
|
|
|
|
|
|
|
|
|
|
$params = array( |
|
|
|
|
|
'sessionid' => $this->pageparams->sessionid, |
|
|
|
|
|
'grouptype' => 0); |
|
|
|
|
|
|
|
|
|
|
|
$url = $this->url_take($params); |
|
|
|
|
|
$logurl = att_log_convert_url($url); |
|
|
|
|
|
|
|
|
|
|
|
// Log the change. |
|
|
|
|
|
add_to_log($this->course->id, 'attendance', 'taken by student', $logurl, '', $this->cm->id); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public function take_from_form_data($formdata) { |
|
|
public function take_from_form_data($formdata) { |
|
|
global $DB, $USER; |
|
|
global $DB, $USER; |
|
|
// TODO: WARNING - $formdata is unclean - comes from direct $_POST - ideally needs a rewrite but we do some cleaning below. |
|
|
// TODO: WARNING - $formdata is unclean - comes from direct $_POST - ideally needs a rewrite but we do some cleaning below. |
|
@ -880,11 +943,16 @@ class attendance { |
|
|
$this->update_users_grade(array_keys($sesslog)); |
|
|
$this->update_users_grade(array_keys($sesslog)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// create url for link in log screen |
|
|
$params = array( |
|
|
$params = array( |
|
|
'sessionid' => $this->pageparams->sessionid, |
|
|
'sessionid' => $this->pageparams->sessionid, |
|
|
'grouptype' => $this->pageparams->grouptype); |
|
|
'grouptype' => $this->pageparams->grouptype); |
|
|
|
|
|
|
|
|
$url = $this->url_take($params); |
|
|
$url = $this->url_take($params); |
|
|
add_to_log($this->course->id, 'attendance', 'taken', $url, '', $this->cm->id); |
|
|
$logurl = att_log_convert_url($url); |
|
|
|
|
|
|
|
|
|
|
|
// Log the change. |
|
|
|
|
|
add_to_log($this->course->id, 'attendance', 'taken', $logurl, '', $this->cm->id); |
|
|
|
|
|
|
|
|
$group = 0; |
|
|
$group = 0; |
|
|
if ($this->pageparams->grouptype != attendance::SESSION_COMMON) { |
|
|
if ($this->pageparams->grouptype != attendance::SESSION_COMMON) { |
|
@ -916,12 +984,12 @@ class attendance { |
|
|
global $DB, $CFG; |
|
|
global $DB, $CFG; |
|
|
|
|
|
|
|
|
// Fields we need from the user table. |
|
|
// Fields we need from the user table. |
|
|
$userfields = user_picture::fields('u', array('username')); |
|
|
$userfields = user_picture::fields('u', array('username' , 'idnumber' , 'institution' , 'department')); |
|
|
|
|
|
|
|
|
if (isset($this->pageparams->sort) and ($this->pageparams->sort == ATT_SORT_FIRSTNAME)) { |
|
|
if (isset($this->pageparams->sort) and ($this->pageparams->sort == ATT_SORT_FIRSTNAME)) { |
|
|
$orderby = "u.firstname ASC, u.lastname ASC"; |
|
|
$orderby = "u.firstname ASC, u.lastname ASC, u.idnumber ASC, u.institution ASC, u.department ASC"; |
|
|
} else { |
|
|
} else { |
|
|
$orderby = "u.lastname ASC, u.firstname ASC"; |
|
|
$orderby = "u.lastname ASC, u.firstname ASC, u.idnumber ASC, u.institution ASC, u.department ASC"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ($page) { |
|
|
if ($page) { |
|
@ -963,7 +1031,7 @@ class attendance { |
|
|
|
|
|
|
|
|
// CONTRIB-4868 |
|
|
// CONTRIB-4868 |
|
|
$mintime = 'MIN(CASE WHEN (ue.timestart > :zerotime) THEN ue.timestart ELSE ue.timecreated END)'; |
|
|
$mintime = 'MIN(CASE WHEN (ue.timestart > :zerotime) THEN ue.timestart ELSE ue.timecreated END)'; |
|
|
$maxtime = 'MAX(ue.timeend)'; |
|
|
$maxtime = 'CASE WHEN MIN(ue.timeend) = 0 THEN 0 ELSE MAX(ue.timeend) END'; |
|
|
|
|
|
|
|
|
// CONTRIB-3549 |
|
|
// CONTRIB-3549 |
|
|
$sql = "SELECT ue.userid, ue.status, |
|
|
$sql = "SELECT ue.userid, ue.status, |
|
@ -1073,7 +1141,7 @@ class attendance { |
|
|
|
|
|
|
|
|
public function get_user_taken_sessions_count($userid) { |
|
|
public function get_user_taken_sessions_count($userid) { |
|
|
if (!array_key_exists($userid, $this->usertakensesscount)) { |
|
|
if (!array_key_exists($userid, $this->usertakensesscount)) { |
|
|
if ($this->pageparams->startdate && $this->pageparams->enddate) { |
|
|
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); |
|
|
$this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid, $this->cm, $this->pageparams->startdate, $this->pageparams->enddate); |
|
|
} else { |
|
|
} else { |
|
|
$this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid, $this->cm); |
|
|
$this->usertakensesscount[$userid] = att_get_user_taken_sessions_count($this->id, $this->course->startdate, $userid, $this->cm); |
|
@ -1082,13 +1150,36 @@ class attendance { |
|
|
return $this->usertakensesscount[$userid]; |
|
|
return $this->usertakensesscount[$userid]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public function get_user_statuses_stat($userid) { |
|
|
/** |
|
|
|
|
|
* |
|
|
|
|
|
* @global type $DB |
|
|
|
|
|
* @param type $userid |
|
|
|
|
|
* @param type $filters - An array things to filter by. For now only enddate is valid. |
|
|
|
|
|
* @return type |
|
|
|
|
|
*/ |
|
|
|
|
|
public function get_user_statuses_stat($userid, array $filters = null) { |
|
|
global $DB; |
|
|
global $DB; |
|
|
$params = array( |
|
|
$params = array( |
|
|
'aid' => $this->id, |
|
|
'aid' => $this->id, |
|
|
'cstartdate' => $this->course->startdate, |
|
|
'cstartdate' => $this->course->startdate, |
|
|
'uid' => $userid); |
|
|
'uid' => $userid); |
|
|
|
|
|
|
|
|
|
|
|
$processed_filters = array(); |
|
|
|
|
|
|
|
|
|
|
|
// We test for any valid filters sent. |
|
|
|
|
|
if (isset($filters['enddate'])) { |
|
|
|
|
|
$processed_filters[] = 'ats.sessdate <= :enddate'; |
|
|
|
|
|
$params['enddate'] = $filters['enddate']; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Make the filter array into a SQL string. |
|
|
|
|
|
if (!empty($processed_filters)) { |
|
|
|
|
|
$processed_filters = ' AND '.implode(' AND ', $processed_filters); |
|
|
|
|
|
} else { |
|
|
|
|
|
$processed_filters = ''; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$period = ''; |
|
|
$period = ''; |
|
|
if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) { |
|
|
if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) { |
|
|
$period = ' AND ats.sessdate >= :sdate AND ats.sessdate < :edate '; |
|
|
$period = ' AND ats.sessdate >= :sdate AND ats.sessdate < :edate '; |
|
@ -1096,38 +1187,47 @@ class attendance { |
|
|
$params['edate'] = $this->pageparams->enddate; |
|
|
$params['edate'] = $this->pageparams->enddate; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!array_key_exists($userid, $this->userstatusesstat)) { |
|
|
if ($this->get_group_mode()) { |
|
|
if ($this->get_group_mode()) { |
|
|
$qry = "SELECT al.statusid, count(al.statusid) AS stcnt |
|
|
$qry = "SELECT al.statusid, count(al.statusid) AS stcnt |
|
|
FROM {attendance_log} al |
|
|
FROM {attendance_log} al |
|
|
JOIN {attendance_sessions} ats ON al.sessionid = ats.id |
|
|
JOIN {attendance_sessions} ats ON al.sessionid = ats.id |
|
|
LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid |
|
|
LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid |
|
|
WHERE ats.attendanceid = :aid AND |
|
|
WHERE ats.attendanceid = :aid AND |
|
|
ats.sessdate >= :cstartdate AND |
|
|
ats.sessdate >= :cstartdate AND |
|
|
al.studentid = :uid AND |
|
|
al.studentid = :uid AND |
|
|
(ats.groupid = 0 or gm.id is NOT NULL)".$period.$processed_filters." |
|
|
(ats.groupid = 0 or gm.id is NOT NULL)".$period." |
|
|
GROUP BY al.statusid"; |
|
|
GROUP BY al.statusid"; |
|
|
} else { |
|
|
} else { |
|
|
$qry = "SELECT al.statusid, count(al.statusid) AS stcnt |
|
|
$qry = "SELECT al.statusid, count(al.statusid) AS stcnt |
|
|
FROM {attendance_log} al |
|
|
FROM {attendance_log} al |
|
|
JOIN {attendance_sessions} ats |
|
|
JOIN {attendance_sessions} ats |
|
|
ON al.sessionid = ats.id |
|
|
ON al.sessionid = ats.id |
|
|
WHERE ats.attendanceid = :aid AND |
|
|
WHERE ats.attendanceid = :aid AND |
|
|
ats.sessdate >= :cstartdate AND |
|
|
ats.sessdate >= :cstartdate AND |
|
|
al.studentid = :uid".$period.$processed_filters." |
|
|
al.studentid = :uid".$period." |
|
|
GROUP BY al.statusid"; |
|
|
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. |
|
|
$this->userstatusesstat[$userid] = $DB->get_records_sql($qry, $params); |
|
|
$this->userstatusesstat[$userid] = $DB->get_records_sql($qry, $params); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Return the cached stats. |
|
|
return $this->userstatusesstat[$userid]; |
|
|
return $this->userstatusesstat[$userid]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public function get_user_grade($userid) { |
|
|
/** |
|
|
return att_get_user_grade($this->get_user_statuses_stat($userid), $this->get_statuses()); |
|
|
* |
|
|
|
|
|
* @param type $userid |
|
|
|
|
|
* @param type $filters - An array things to filter by. For now only enddate is valid. |
|
|
|
|
|
* @return type |
|
|
|
|
|
*/ |
|
|
|
|
|
public function get_user_grade($userid, array $filters = null) { |
|
|
|
|
|
return att_get_user_grade($this->get_user_statuses_stat($userid, $filters), $this->get_statuses()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// For getting sessions count implemented simplest method - taken sessions. |
|
|
// For getting sessions count implemented simplest method - taken sessions. |
|
@ -1215,7 +1315,7 @@ class attendance { |
|
|
// It would be better as a UNION query butunfortunatly MS SQL does not seem to support doing a DISTINCT on a the description field. |
|
|
// 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'); |
|
|
$id = $DB->sql_concat(':value', 'ats.id'); |
|
|
if ($this->get_group_mode()) { |
|
|
if ($this->get_group_mode()) { |
|
|
$sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks |
|
|
$sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark |
|
|
FROM {attendance_sessions} ats |
|
|
FROM {attendance_sessions} ats |
|
|
RIGHT JOIN {attendance_log} al |
|
|
RIGHT JOIN {attendance_log} al |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
@ -1223,7 +1323,7 @@ class attendance { |
|
|
WHERE $where AND (ats.groupid = 0 or gm.id is NOT NULL) |
|
|
WHERE $where AND (ats.groupid = 0 or gm.id is NOT NULL) |
|
|
ORDER BY ats.sessdate ASC"; |
|
|
ORDER BY ats.sessdate ASC"; |
|
|
} else { |
|
|
} else { |
|
|
$sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks |
|
|
$sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark |
|
|
FROM {attendance_sessions} ats |
|
|
FROM {attendance_sessions} ats |
|
|
RIGHT JOIN {attendance_log} al |
|
|
RIGHT JOIN {attendance_log} al |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
@ -1253,7 +1353,7 @@ class attendance { |
|
|
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND ats.groupid $gsql"; |
|
|
$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 |
|
|
$sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks, ats.studentscanmark |
|
|
FROM {attendance_sessions} ats |
|
|
FROM {attendance_sessions} ats |
|
|
LEFT JOIN {attendance_log} al |
|
|
LEFT JOIN {attendance_log} al |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
|
ON ats.id = al.sessionid AND al.studentid = :uid |
|
@ -1353,8 +1453,8 @@ class attendance { |
|
|
add_to_log($this->course->id, 'attendance', 'status updated', $this->url_preferences(), |
|
|
add_to_log($this->course->id, 'attendance', 'status updated', $this->url_preferences(), |
|
|
implode(' ', $updated), $this->cm->id); |
|
|
implode(' ', $updated), $this->cm->id); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function att_get_statuses($attid, $onlyvisible=true) { |
|
|
function att_get_statuses($attid, $onlyvisible=true) { |
|
|
global $DB; |
|
|
global $DB; |
|
|