@ -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) {
@ -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
@ -1295,7 +1395,7 @@ class attendance {
$sess->timemodified = $now;
$sess->timemodified = $now;
$DB->update_record('attendance_sessions', $sess);
$DB->update_record('attendance_sessions', $sess);
}
}
$sessions->close();
$sessions->close();
add_to_log($this->course->id, 'attendance', 'sessions duration updated', $this->url_manage(),
add_to_log($this->course->id, 'attendance', 'sessions duration updated', $this->url_manage(),
get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
}
}
@ -1353,9 +1453,9 @@ 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;