Compare commits

...

19 Commits

Author SHA1 Message Date
Tim Gus 2a191a65c0 CONTRIB-4754 Added upgrade step to account for name change from 11 years ago
Dan Marsden 8d8046f8f5 use cross-db update of capabilities 11 years ago
Dan Marsden 0e80b0b0fa update grade_items and capability tables 11 years ago
Dan Marsden 1e8237f8d9 version bump for security release 11 years ago
NeillM feca3fd8a7 Security fix to prevent access to other students attendance 11 years ago
Dan Marsden 4bd418d71b bump version 11 years ago
NeillM bed2ee7d4b Fix for sessions with taken attendance show twice in student report. 12 years ago
Dan Marsden e1554f79a0 fix another typo 12 years ago
Dan Marsden 4d11297a17 fix typo 12 years ago
Dan Marsden b1a985a486 clear course cache during upgrade 12 years ago
Dan Marsden 96b7fff8af prevent duplication of template values 12 years ago
Dan Marsden c5eaf4279f lower number of entries used in log - to bring under 255 including utf8 12 years ago
Dan Marsden 0dc8d1f714 Prevent too much info in add_to_log - enter first 10 and last session into log 12 years ago
Dan Marsden 20587362fa check var exists before using 12 years ago
Dan Marsden 21afd6e0c4 remove abstracted add_to_log function 12 years ago
Dan Marsden e8890a6a33 slightly better check - there's probably a cfg var I could check here instead of using try/catch 12 years ago
Dan Marsden 36166f95d4 Prevent fatal error on fresh install 12 years ago
Dan Marsden 240be82c38 Tested code on 2.3.4 and use older style install.xml 12 years ago
Dan Marsden 51327b7a26 Revert "update xml based on new guidelines - using xmldb editor" 12 years ago
  1. 2
      db/install.php
  2. 86
      db/install.xml
  3. 40
      db/upgrade.php
  4. 139
      locallib.php
  5. 3
      report.php
  6. 2
      sessions.php
  7. 18
      version.php
  8. 9
      view.php

2
db/install.php

@ -38,8 +38,10 @@ function xmldb_attendance_install() {
$rec->grade = $v; $rec->grade = $v;
$rec->visible = 1; $rec->visible = 1;
$rec->deleted = 0; $rec->deleted = 0;
if (!$DB->record_exists('attendance_statuses', array('attendanceid' => 0, 'acronym' => $rec->acronym))) {
$result = $result && $DB->insert_record('attendance_statuses', $rec); $result = $result && $DB->insert_record('attendance_statuses', $rec);
} }
}
return $result; return $result;
} }

86
db/install.xml

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/attendance/db" VERSION="20130704" COMMENT="XMLDB file for Moodle mod/attendance" <XMLDB PATH="mod/attendance/db" VERSION="20090112" COMMENT="XMLDB file for Moodle mod/attendance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd" xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
> >
<TABLES> <TABLES>
<TABLE NAME="attendance" COMMENT="Attendance module table"> <TABLE NAME="attendance" COMMENT="Module for support Attendances" NEXT="attendance_sessions">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" COMMENT="id of the table, please edit me"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" COMMENT="id of the table, please edit me" NEXT="course"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/> <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="course" NEXT="grade"/>
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="100" SEQUENCE="false" COMMENT="This is maximum grade for instance"/> <FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="100" SEQUENCE="false" COMMENT="This is maximum grade for instance" PREVIOUS="name"/>
</FIELDS> </FIELDS>
<KEYS> <KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance"/> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance"/>
@ -18,65 +18,65 @@
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/> <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
</INDEXES> </INDEXES>
</TABLE> </TABLE>
<TABLE NAME="attendance_sessions" COMMENT="attendance_sessions table retrofitted from MySQL"> <TABLE NAME="attendance_sessions" COMMENT="attendance_sessions table retrofitted from MySQL" PREVIOUS="attendance" NEXT="attendance_log">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="attendanceid"/>
<FIELD NAME="attendanceid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="attendanceid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="attendanceid" NEXT="sessdate"/>
<FIELD NAME="sessdate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="sessdate" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="groupid" NEXT="duration"/>
<FIELD NAME="duration" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="duration" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="sessdate" NEXT="lasttaken"/>
<FIELD NAME="lasttaken" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/> <FIELD NAME="lasttaken" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" PREVIOUS="duration" NEXT="lasttakenby"/>
<FIELD NAME="lasttakenby" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="lasttakenby" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="lasttaken" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/> <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" PREVIOUS="lasttakenby" NEXT="description"/>
<FIELD NAME="description" TYPE="text" NOTNULL="true" SEQUENCE="false"/> <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" PREVIOUS="timemodified" NEXT="descriptionformat"/>
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="descriptionformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="description"/>
</FIELDS> </FIELDS>
<KEYS> <KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_sessions"/> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_sessions"/>
</KEYS> </KEYS>
<INDEXES> <INDEXES>
<INDEX NAME="attendanceid" UNIQUE="false" FIELDS="attendanceid"/> <INDEX NAME="attendanceid" UNIQUE="false" FIELDS="attendanceid" NEXT="groupid"/>
<INDEX NAME="groupid" UNIQUE="false" FIELDS="groupid"/> <INDEX NAME="groupid" UNIQUE="false" FIELDS="groupid" PREVIOUS="attendanceid" NEXT="sessdate"/>
<INDEX NAME="sessdate" UNIQUE="false" FIELDS="sessdate"/> <INDEX NAME="sessdate" UNIQUE="false" FIELDS="sessdate" PREVIOUS="groupid"/>
</INDEXES> </INDEXES>
</TABLE> </TABLE>
<TABLE NAME="attendance_log" COMMENT="attendance_log table retrofitted from MySQL"> <TABLE NAME="attendance_log" COMMENT="attendance_log table retrofitted from MySQL" PREVIOUS="attendance_sessions" NEXT="attendance_statuses">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="sessionid"/>
<FIELD NAME="sessionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="sessionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="studentid"/>
<FIELD NAME="studentid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="studentid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="sessionid" NEXT="statusid"/>
<FIELD NAME="statusid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="link with attendance_status table"/> <FIELD NAME="statusid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="link with attendance_status table" PREVIOUS="studentid" NEXT="statusset"/>
<FIELD NAME="statusset" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/> <FIELD NAME="statusset" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false" PREVIOUS="statusid" NEXT="timetaken"/>
<FIELD NAME="timetaken" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="When attendance of this student was taken"/> <FIELD NAME="timetaken" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="When attendance of this student was taken" PREVIOUS="statusset" NEXT="takenby"/>
<FIELD NAME="takenby" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="takenby" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timetaken" NEXT="remarks"/>
<FIELD NAME="remarks" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/> <FIELD NAME="remarks" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="takenby"/>
</FIELDS> </FIELDS>
<KEYS> <KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_log"/> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_log"/>
</KEYS> </KEYS>
<INDEXES> <INDEXES>
<INDEX NAME="sessionid" UNIQUE="false" FIELDS="sessionid"/> <INDEX NAME="sessionid" UNIQUE="false" FIELDS="sessionid" NEXT="studentid"/>
<INDEX NAME="studentid" UNIQUE="false" FIELDS="studentid"/> <INDEX NAME="studentid" UNIQUE="false" FIELDS="studentid" PREVIOUS="sessionid" NEXT="statusid"/>
<INDEX NAME="statusid" UNIQUE="false" FIELDS="statusid"/> <INDEX NAME="statusid" UNIQUE="false" FIELDS="statusid" PREVIOUS="studentid"/>
</INDEXES> </INDEXES>
</TABLE> </TABLE>
<TABLE NAME="attendance_statuses" COMMENT="attendance_statuses table retrofitted from MySQL"> <TABLE NAME="attendance_statuses" COMMENT="attendance_statuses table retrofitted from MySQL" PREVIOUS="attendance_log">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="attendanceid"/>
<FIELD NAME="attendanceid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="attendanceid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="acronym"/>
<FIELD NAME="acronym" TYPE="char" LENGTH="2" NOTNULL="true" SEQUENCE="false"/> <FIELD NAME="acronym" TYPE="char" LENGTH="2" NOTNULL="true" SEQUENCE="false" PREVIOUS="attendanceid" NEXT="description"/>
<FIELD NAME="description" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false"/> <FIELD NAME="description" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" PREVIOUS="acronym" NEXT="grade"/>
<FIELD NAME="grade" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="grade" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="description" NEXT="visible"/>
<FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/> <FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="grade" NEXT="deleted"/>
<FIELD NAME="deleted" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/> <FIELD NAME="deleted" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="visible"/>
</FIELDS> </FIELDS>
<KEYS> <KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_settings"/> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for attendance_settings"/>
</KEYS> </KEYS>
<INDEXES> <INDEXES>
<INDEX NAME="attendanceid" UNIQUE="false" FIELDS="attendanceid"/> <INDEX NAME="attendanceid" UNIQUE="false" FIELDS="attendanceid" NEXT="visible"/>
<INDEX NAME="visible" UNIQUE="false" FIELDS="visible"/> <INDEX NAME="visible" UNIQUE="false" FIELDS="visible" PREVIOUS="attendanceid" NEXT="deleted"/>
<INDEX NAME="deleted" UNIQUE="false" FIELDS="deleted"/> <INDEX NAME="deleted" UNIQUE="false" FIELDS="deleted" PREVIOUS="visible"/>
</INDEXES> </INDEXES>
</TABLE> </TABLE>
</TABLES> </TABLES>

40
db/upgrade.php

@ -34,6 +34,44 @@ function xmldb_attendance_upgrade($oldversion=0) {
$result = true; $result = true;
// UPGRADES from attforblock are only supported for sites that are running attforblock version 2012120700. if ($oldversion < 2013070405) {
// 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, 2013070405, 'mod', 'attendance');
}
return $result; return $result;
} }

139
locallib.php

@ -795,11 +795,21 @@ class attendance {
} }
$info_array = array(); $info_array = array();
$maxlog = 7; // Only log first 10 sessions and last session in the log info. as we can only store 255 chars.
$i = 0;
foreach ($sessions as $sess) { foreach ($sessions as $sess) {
if ($i > $maxlog) {
$lastsession = end($sessions);
$info_array[] = '...';
$info_array[] = construct_session_full_date_time($lastsession->sessdate, $lastsession->duration);
break;
} else {
$info_array[] = construct_session_full_date_time($sess->sessdate, $sess->duration); $info_array[] = construct_session_full_date_time($sess->sessdate, $sess->duration);
} }
$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) { public function update_session_from_form_data($formdata, $sessionid) {
@ -821,7 +831,7 @@ class attendance {
$url = $this->url_sessions(array('sessionid' => $sessionid, 'action' => att_sessions_page_params::ACTION_UPDATE)); $url = $this->url_sessions(array('sessionid' => $sessionid, 'action' => att_sessions_page_params::ACTION_UPDATE));
$info = construct_session_full_date_time($sess->sessdate, $sess->duration); $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);
} }
public function take_from_form_data($formdata) { public function take_from_form_data($formdata) {
@ -875,7 +885,7 @@ class attendance {
'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);
$this->log('attendance taked', $url, $USER->firstname.' '.$USER->lastname); add_to_log($this->course->id, 'attendance', 'taken', $url, '', $this->cm->id);
redirect($this->url_manage(), get_string('attendancesuccess', 'attendance')); redirect($this->url_manage(), get_string('attendancesuccess', 'attendance'));
} }
@ -1091,11 +1101,18 @@ class attendance {
// All taked sessions (including previous groups). // 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) { if ($this->pageparams->startdate && $this->pageparams->enddate) {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND $where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND
ats.sessdate >= :sdate AND ats.sessdate < :edate"; 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 { } else {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate"; $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 $sql = "SELECT ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks
@ -1103,38 +1120,27 @@ class attendance {
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
WHERE $where WHERE $where
ORDER BY ats.sessdate ASC"; UNION
SELECT ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks
FROM {attendance_sessions} ats
LEFT JOIN {attendance_log} al
ON ats.id = al.sessionid AND al.studentid = :uid2
WHERE $where2
ORDER BY sessdate ASC";
$params = array( $params = array(
'uid' => $userid, 'uid' => $userid,
'aid' => $this->id, 'aid' => $this->id,
'csdate' => $this->course->startdate, 'csdate' => $this->course->startdate,
'sdate' => $this->pageparams->startdate, 'sdate' => $this->pageparams->startdate,
'edate' => $this->pageparams->enddate); 'edate' => $this->pageparams->enddate,
$sessions = $DB->get_records_sql($sql, $params); 'uid2' => $userid,
'aid2' => $this->id,
// All sessions for current groups. 'csdate2' => $this->course->startdate,
'sdate2' => $this->pageparams->startdate,
$groups = array_keys(groups_get_all_groups($this->course->id, $userid)); 'edate2' => $this->pageparams->enddate);
$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 ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks
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); $params = array_merge($params, $gparams);
$sessions = array_merge($sessions, $DB->get_records_sql($sql, $params)); $sessions = $DB->get_records_sql($sql, $params);
foreach ($sessions as $sess) { foreach ($sessions as $sess) {
if (empty($sess->description)) { if (empty($sess->description)) {
@ -1154,8 +1160,8 @@ class attendance {
list($sql, $params) = $DB->get_in_or_equal($sessionsids); list($sql, $params) = $DB->get_in_or_equal($sessionsids);
$DB->delete_records_select('attendance_log', "sessionid $sql", $params); $DB->delete_records_select('attendance_log', "sessionid $sql", $params);
$DB->delete_records_list('attendance_sessions', 'id', $sessionsids); $DB->delete_records_list('attendance_sessions', 'id', $sessionsids);
add_to_log($this->course->id, 'attendance', 'sessions deleted', $this->url_manage(),
$this->log('sessions deleted', null, get_string('sessionsids', 'attendance').implode(', ', $sessionsids)); get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
} }
public function update_sessions_duration($sessionsids, $duration) { public function update_sessions_duration($sessionsids, $duration) {
@ -1168,9 +1174,8 @@ class attendance {
$sess->timemodified = $now; $sess->timemodified = $now;
$DB->update_record('attendance_sessions', $sess); $DB->update_record('attendance_sessions', $sess);
} }
add_to_log($this->course->id, 'attendance', 'sessions duration updated', $this->url_manage(),
$this->log('sessions duration updated', $this->url_manage(), get_string('sessionsids', 'attendance').implode(', ', $sessionsids), $this->cm->id);
get_string('sessionsids', 'attendance').implode(', ', $sessionsids));
} }
public function remove_status($statusid) { public function remove_status($statusid) {
@ -1191,7 +1196,8 @@ class attendance {
$rec->grade = $grade; $rec->grade = $grade;
$DB->insert_record('attendance_statuses', $rec); $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 { } else {
print_error('cantaddstatus', 'attendance', $this->url_preferences()); print_error('cantaddstatus', 'attendance', $this->url_preferences());
} }
@ -1222,27 +1228,8 @@ class attendance {
} }
$DB->update_record('attendance_statuses', $status); $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);
/**
* wrapper around {@see add_to_log()}
*
* @param string $action to be logged
* @param moodle_url $url absolute url, if null will be used $this->url_manage()
* @param mixed $info additional info, usually id in a table
*/
public function log($action, moodle_url $url = null, $info = null) {
if (is_null($url)) {
$url = $this->url_manage();
}
if (is_null($info)) {
$info = $this->id;
}
$logurl = att_log_convert_url($url);
add_to_log($this->course->id, 'attendance', $action, $logurl, $info, $this->cm->id);
} }
} }
@ -1407,4 +1394,44 @@ function attforblock_upgrade() {
// Now convert module record. // Now convert module record.
$module->name = 'attendance'; $module->name = 'attendance';
$DB->update_record('modules', $module); $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();
} }

3
report.php

@ -58,8 +58,7 @@ $tabs = new attendance_tabs($att, attendance_tabs::TAB_REPORT);
$filtercontrols = new attendance_filter_controls($att); $filtercontrols = new attendance_filter_controls($att);
$reportdata = new attendance_report_data($att); $reportdata = new attendance_report_data($att);
global $USER; add_to_log($course->id, 'attendance', 'report viewed', '/mod/attendance/report.php?id='.$id, '', $cm->id);
$att->log('report viewed', null, $USER->firstname.' '.$USER->lastname);
// Output starts here. // Output starts here.

2
sessions.php

@ -208,7 +208,7 @@ function construct_sessions_data_for_add($formdata) {
while ($sdate < $enddate) { while ($sdate < $enddate) {
if ($sdate < $startweek + WEEKSECS) { if ($sdate < $startweek + WEEKSECS) {
$dinfo = usergetdate($sdate); $dinfo = usergetdate($sdate);
if (array_key_exists($wdaydesc[$dinfo['wday']], $formdata->sdays)) { if (isset($formdata->sdays) && array_key_exists($wdaydesc[$dinfo['wday']], $formdata->sdays)) {
$sess = new stdClass(); $sess = new stdClass();
$sess->sessdate = usergetmidnight($sdate) + $starttime; $sess->sessdate = usergetmidnight($sdate) + $starttime;
$sess->duration = $duration; $sess->duration = $duration;

18
version.php

@ -22,10 +22,10 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
$module->version = 2013070403; $module->version = 2013070405;
$module->requires = 2012120300; $module->requires = 2012062504;
$module->release = '2.4.1'; $module->release = '2.4.3';
$module->maturity = MATURITY_ALPHA; $module->maturity = MATURITY_STABLE;
$module->cron = 0; $module->cron = 0;
$module->component = 'mod_attendance'; $module->component = 'mod_attendance';
@ -33,8 +33,16 @@ $module->component = 'mod_attendance';
// TODO: remove this asap. // TODO: remove this asap.
if (defined('MOODLE_INTERNAL')) { // Only run if config.php has already been included. if (defined('MOODLE_INTERNAL')) { // Only run if config.php has already been included.
global $DB; global $DB;
if ($DB->record_exists('modules', array('name' =>'attforblock'))) { $moduleexists = false;
try {
$moduleexists = $DB->record_exists('modules', array('name' =>'attforblock'));
} catch (Exception $e) {
// Probably a fresh install - modules table doesn't exist
}
if ($moduleexists) {
require_once('locallib.php'); require_once('locallib.php');
attforblock_upgrade(); attforblock_upgrade();
} }
} }

9
view.php

@ -63,7 +63,14 @@ $PAGE->navbar->add(get_string('attendancereport', 'attendance'));
$output = $PAGE->get_renderer('mod_attendance'); $output = $PAGE->get_renderer('mod_attendance');
$userid = isset($pageparams->studentid) ? $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); $userdata = new attendance_user_data($att, $userid);
echo $output->header(); echo $output->header();

Loading…
Cancel
Save