Browse Source

Feature: Allow warnings to send multiple emails.

MOODLE_34_STABLE
Dan Marsden 8 years ago
parent
commit
7a76d7ff83
  1. 4
      backup/moodle2/backup_attendance_stepslib.php
  2. 5
      classes/add_warning_form.php
  3. 16
      classes/structure.php
  4. 36
      classes/task/notify.php
  5. 3
      db/install.xml
  6. 26
      db/upgrade.php
  7. 2
      lang/en/attendance.php
  8. 26
      locallib.php
  9. 3
      renderer.php
  10. 3
      resetcalendar.php
  11. 3
      settings.php
  12. 4
      version.php
  13. 2
      warnings.php

4
backup/moodle2/backup_attendance_stepslib.php

@ -51,8 +51,8 @@ class backup_attendance_activity_structure_step extends backup_activity_structur
'acronym', 'description', 'grade', 'studentavailability', 'setunmarked', 'visible', 'deleted', 'setnumber'));
$warnings = new backup_nested_element('warnings');
$warning = new backup_nested_element('warning', array('id'), array(
'warningpercent', 'warnafter', 'emailuser', 'emailsubject', 'emailcontent', 'emailcontentformat', 'thirdpartyemails'));
$warning = new backup_nested_element('warning', array('id'), array('warningpercent', 'warnafter',
'maxwarn', 'emailuser', 'emailsubject', 'emailcontent', 'emailcontentformat', 'thirdpartyemails'));
$sessions = new backup_nested_element('sessions');
$session = new backup_nested_element('session', array('id'), array(

5
classes/add_warning_form.php

@ -60,6 +60,11 @@ class mod_attendance_add_warning_form extends moodleform {
$mform->setType('warnafter', PARAM_INT);
$mform->setDefault('warnafter', $config->warnafter);
$mform->addElement('select', 'maxwarn', get_string('maxwarn', 'mod_attendance'), $options);
$mform->addHelpButton('maxwarn', 'maxwarn', 'mod_attendance');
$mform->setType('maxwarn', PARAM_INT);
$mform->setDefault('maxwarn', $config->maxwarn);
$mform->addElement('checkbox', 'emailuser', get_string('emailuser', 'mod_attendance'));
$mform->addHelpButton('emailuser', 'emailuser', 'mod_attendance');
$mform->setDefault('emailuser', $config->emailuser);

16
classes/structure.php

@ -647,14 +647,21 @@ class mod_attendance_structure {
$sesslog[$sid]->takenby = $USER->id;
}
}
// Get existing session log.
$dbsesslog = $this->get_session_log($this->pageparams->sessionid);
foreach ($sesslog as $log) {
// Don't save a record if no statusid or remark.
if (!empty($log->statusid) || !empty($log->remarks)) {
if (array_key_exists($log->studentid, $dbsesslog)) {
$log->id = $dbsesslog[$log->studentid]->id;
$DB->update_record('attendance_log', $log);
// Check if anything important has changed before updating record.
// Don't update timetaken/takenby records if nothing has changed.
if ($dbsesslog[$log->studentid]->remarks <> $log->remarks ||
$dbsesslog[$log->studentid]->statusid <> $log->statusid ||
$dbsesslog[$log->studentid]->statusset <> $log->statusset) {
$log->id = $dbsesslog[$log->studentid]->id;
$DB->update_record('attendance_log', $log);
}
} else {
$DB->insert_record('attendance_log', $log, false);
}
@ -664,6 +671,7 @@ class mod_attendance_structure {
$session = $this->get_session_info($this->pageparams->sessionid);
$session->lasttaken = $now;
$session->lasttakenby = $USER->id;
$DB->update_record('attendance_sessions', $session);
if ($this->grade != 0) {
@ -967,7 +975,7 @@ class mod_attendance_structure {
public function get_session_log($sessionid) {
global $DB;
return $DB->get_records('attendance_log', array('sessionid' => $sessionid), '', 'studentid,statusid,remarks,id');
return $DB->get_records('attendance_log', array('sessionid' => $sessionid), '', 'studentid,statusid,remarks,id,statusset');
}
/**

36
classes/task/notify.php

@ -44,16 +44,14 @@ class notify extends \core\task\scheduled_task {
return; // Warnings not enabled.
}
$now = time(); // Store current time to use in queries so they all match nicely.
$lastrun = get_config('mod_attendance', 'notifylastrun');
if (empty($lastrun)) {
$lastrun = 0;
}
if (!empty($lastrun)) {
mtrace("Get warnings to send for sessions that have ended since: ".userdate($lastrun));
}
$orderby = 'ORDER BY cm.id, atl.studentid, n.warningpercent ASC';
$records = attendance_get_users_to_notify(array(), $orderby, $lastrun, true);
// Get records for attendance sessions that have been updated since last time this task ran.
// Note: this returns all users for these sessions - even if the users attendance wasn't changed
// since last time we ran, before sending a notification we check to see if the users have
// updated attendance logs since last time they were notified.
$records = attendance_get_users_to_notify(array(), $orderby, true);
$sentnotifications = array();
$thirdpartynotifications = array();
$numsentusers = 0;
@ -64,8 +62,22 @@ class notify extends \core\task\scheduled_task {
}
if (!empty($record->emailuser)) {
// Only send one warning to this user from each attendance in this run. - flag any higher percent notifications as sent.
// Only send one warning to this user from each attendance in this run.
// Flag any higher percent notifications as sent.
if (empty($sentnotifications[$record->userid]) || !in_array($record->aid, $sentnotifications[$record->userid])) {
// If has previously been sent a warning, check to see if this user has
// attendance updated since the last time the notification was sent.
if (!empty($record->timesent)) {
$sql = "SELECT *
FROM {attendance_log} l
JOIN {attendance_sessions} s ON s.id = l.sessionid
WHERE s.attendanceid = ? AND studentid = ? AND timetaken > ?";
if (!$DB->record_exists_sql($sql, array($record->aid, $record->userid, $record->timesent))) {
continue; // Skip this record and move to the next user.
}
}
// Convert variables in emailcontent.
$record = attendance_template_variables($record);
$user = $DB->get_record('user', array('id' => $record->userid));
@ -91,14 +103,14 @@ class notify extends \core\task\scheduled_task {
$thirdpartynotifications[$senduser] = array();
}
if (!isset($thirdpartynotifications[$senduser][$record->aid . '_' . $record->userid])) {
$thirdpartynotifications[$senduser][$record->aid . '_' . $record->userid] = get_string('thirdpartyemailtext', 'attendance', $record);
$thirdpartynotifications[$senduser][$record->aid . '_' . $record->userid]
= get_string('thirdpartyemailtext', 'attendance', $record);
}
} else {
mtrace("user".$senduser. "does not have capablity in cm".$record->cmid);
}
}
}
$notify = new \stdClass();
$notify->userid = $record->userid;
$notify->notifyid = $record->notifyid;
@ -125,7 +137,5 @@ class notify extends \core\task\scheduled_task {
mtrace($numsentthird ." thirdparty emails sent");
}
}
set_config('notifylastrun', $now, 'mod_attendance');
}
}

3
db/install.xml

@ -119,6 +119,7 @@
<FIELD NAME="idnumber" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="attendance id or other id relating to this warning."/>
<FIELD NAME="warningpercent" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Percentage that triggers this warning."/>
<FIELD NAME="warnafter" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Start warning after this number of taken sessions."/>
<FIELD NAME="maxwarn" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Maximum number of warnings to send."/>
<FIELD NAME="emailuser" TYPE="int" LENGTH="4" NOTNULL="true" SEQUENCE="false" COMMENT="Should the user be notified at this level."/>
<FIELD NAME="emailsubject" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="Email subject line for emails going to user"/>
<FIELD NAME="emailcontent" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="The html-formatted text that should be sent to the user"/>
@ -141,7 +142,7 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="notifyid_userid" UNIQUE="true" FIELDS="notifyid, userid"/>
<INDEX NAME="notifyid_userid" UNIQUE="false" FIELDS="notifyid, userid"/>
</INDEXES>
</TABLE>
</TABLES>

26
db/upgrade.php

@ -408,5 +408,31 @@ function xmldb_attendance_upgrade($oldversion=0) {
upgrade_mod_savepoint(true, 2017071305, 'attendance');
}
if ($oldversion < 2017071800) {
// Define field setunmarked to be added to attendance_statuses.
$table = new xmldb_table('attendance_warning');
$field = new xmldb_field('maxwarn', XMLDB_TYPE_INTEGER, '10', null, true, null, '1', 'warnafter');
// Conditionally launch add field automark.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Attendance savepoint reached.
upgrade_mod_savepoint(true, 2017071800, 'attendance');
}
if ($oldversion < 2017071802) {
// Define field setunmarked to be added to attendance_statuses.
$table = new xmldb_table('attendance_warning_done');
$index = new xmldb_index('notifyid_userid', XMLDB_INDEX_UNIQUE, array('notifyid', 'userid'));
$dbman->drop_index($table, $index);
$index = new xmldb_index('notifyid', XMLDB_INDEX_NOTUNIQUE, array('notifyid', 'userid'));
$dbman->add_index($table, $index);
// Attendance savepoint reached.
upgrade_mod_savepoint(true, 2017071802, 'attendance');
}
return $result;
}

2
lang/en/attendance.php

@ -227,6 +227,8 @@ $string['maxpossible_help'] = 'Shows the score each user can reach if they recei
</ul>';
$string['maxpossiblepercentage'] = 'Maximum possible percentage';
$string['maxpossiblepoints'] = 'Maximum possible points';
$string['maxwarn'] = 'Maximum number of e-mail warnings';
$string['maxwarn_help'] = 'The maximum number of times a warning should be sent (only one warning per session is sent)';
$string['mergeuser'] = 'Merge user';
$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.

26
locallib.php

@ -716,15 +716,15 @@ SELECT a.id, a.course as courseid, c.fullname as coursename, atl.studentid AS us
* Generates a list of users flagged at-risk.
*
* @param array $courseids optional list of courses to return
* @param array $sincetime optional allows a list to be calculated for cron processing.
* @param bool $allfornotify get notification list for scheduled task.
* @return stdClass
*/
function attendance_get_users_to_notify($courseids = array(), $orderby = '', $sincetime = 0, $allfornotify = false) {
function attendance_get_users_to_notify($courseids = array(), $orderby = '', $allfornotify = false) {
global $DB;
$joingroup = 'LEFT JOIN {groups_members} gm ON (gm.userid = atl.studentid AND gm.groupid = ats.groupid)';
$where = ' AND (ats.groupid = 0 or gm.id is NOT NULL)';
$having = '';
$params = array();
if (!empty($courseids)) {
@ -733,8 +733,8 @@ function attendance_get_users_to_notify($courseids = array(), $orderby = '', $si
$params = array_merge($params, $inparams);
}
if ($allfornotify) {
// Exclude warnings that have already been sent.
$where .= ' AND ns.id IS NULL ';
// Exclude warnings that have already sent the max num.
$having .= ' AND n.maxwarn > COUNT(DISTINCT ns.id) ';
}
$unames = get_all_user_name_fields(true);
@ -743,8 +743,9 @@ function attendance_get_users_to_notify($courseids = array(), $orderby = '', $si
$idfield = $DB->sql_concat('cm.id', 'atl.studentid', 'n.id');
$sql = "SELECT {$idfield} as uniqueid, a.id as aid, {$unames2}, a.name as aname, cm.id as cmid, c.id as courseid,
c.fullname as coursename, atl.studentid AS userid, n.id as notifyid, n.warningpercent, n.emailsubject,
n.emailcontent, n.emailcontentformat, n.emailuser, n.thirdpartyemails, ns.timesent, n.warnafter,
n.emailcontent, n.emailcontentformat, n.emailuser, n.thirdpartyemails, n.warnafter, n.maxwarn,
COUNT(DISTINCT ats.id) AS numtakensessions, SUM(stg.grade) AS points, SUM(stm.maxgrade) AS maxpoints,
COUNT(DISTINCT ns.id) as nscount, MAX(ns.timesent) as timesent,
SUM(stg.grade) / SUM(stm.maxgrade) AS percent
FROM {attendance_sessions} ats
JOIN {attendance} a ON a.id = ats.attendanceid
@ -763,21 +764,22 @@ function attendance_get_users_to_notify($courseids = array(), $orderby = '', $si
GROUP BY attendanceid, setnumber) stm
ON (stm.setnumber = ats.statusset AND stm.attendanceid = ats.attendanceid)
{$joingroup}
WHERE ats.lasttaken >= {$sincetime} {$where}
WHERE 1 = 1 {$where}
GROUP BY uniqueid, a.id, a.name, a.course, c.fullname, atl.studentid, n.id, n.warningpercent,
n.emailsubject, n.emailcontent, n.emailcontentformat, n.warnafter,
n.emailuser, n.thirdpartyemails, ns.timesent, cm.id, c.id, {$unames2}
n.emailsubject, n.emailcontent, n.emailcontentformat, n.warnafter, n.maxwarn,
n.emailuser, n.thirdpartyemails, cm.id, c.id, {$unames2}, ns.userid
HAVING n.warnafter <= COUNT(DISTINCT ats.id) AND n.warningpercent > ((SUM(stg.grade) / SUM(stm.maxgrade)) * 100)
{$having}
{$orderby}";
if (!$allfornotify) {
$idfield = $DB->sql_concat('cmid', 'userid');
// Only show one record per attendance for teacher reports.
$sql = "SELECT {$idfield} as id, {$unames}, aid, cmid, courseid, aname, coursename, userid, MIN(warningpercent),
numtakensessions, points, maxpoints, percent, timesent
$sql = "SELECT DISTINCT {$idfield} as id, {$unames}, aid, cmid, courseid, aname, coursename, userid,
numtakensessions, percent, MAX(timesent) as timesent
FROM ({$sql}) as m
GROUP BY id, aid, cmid, courseid, aname, userid, numtakensessions, points, maxpoints,
percent, coursename, timesent, {$unames} {$orderby}";
GROUP BY id, aid, cmid, courseid, aname, userid, numtakensessions,
percent, coursename, {$unames} {$orderby}";
}
return $DB->get_records_sql($sql, $params);

3
renderer.php

@ -949,7 +949,8 @@ class mod_attendance_renderer extends plugin_renderer_base {
get_string('pointssessionscompleted', 'attendance'),
get_string('percentagesessionscompleted', 'attendance'));
$table->align = array('left', 'left', 'center', 'center', 'center');
$table->colclasses = array('colcourse', 'colatt', 'colsessionscompleted', 'colpointssessionscompleted', 'colpercentagesessionscompleted');
$table->colclasses = array('colcourse', 'colatt', 'colsessionscompleted',
'colpointssessionscompleted', 'colpercentagesessionscompleted');
$totalattendance = 0;
$totalpercentage = 0;
foreach ($userdata->coursesatts as $ca) {

3
resetcalendar.php

@ -70,7 +70,8 @@ if (get_config('attendance', 'enablecalendar')) {
}
} else {
if ($action == 'delete' && confirm_sesskey()) {
$caleventids = $DB->get_records_select_menu('attendance_sessions', 'caleventid > 0', array(), '', 'caleventid, caleventid as id2');
$caleventids = $DB->get_records_select_menu('attendance_sessions', 'caleventid > 0', array(),
'', 'caleventid, caleventid as id2');
$DB->delete_records_list('event', 'id', $caleventids);
$DB->execute("UPDATE {attendance_sessions} set caleventid = 0");
echo $OUTPUT->notification(get_string('eventsdeleted', 'mod_attendance'), 'notifysuccess');

3
settings.php

@ -125,6 +125,9 @@ if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configselect('attendance/warnafter',
get_string('warnafter', 'attendance'), get_string('warnafter_help', 'attendance'), 5, $options));
$settings->add(new admin_setting_configselect('attendance/maxwarn',
get_string('maxwarn', 'attendance'), get_string('maxwarn_help', 'attendance'), 1, $options));
$settings->add(new admin_setting_configcheckbox('attendance/emailuser',
get_string('emailuser', 'attendance'), get_string('emailuser_help', 'attendance'), 1));

4
version.php

@ -23,9 +23,9 @@
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017071305;
$plugin->version = 2017071802;
$plugin->requires = 2017042100;
$plugin->release = '3.3.9';
$plugin->release = '3.3.10';
$plugin->maturity = MATURITY_ALPHA;
$plugin->cron = 0;
$plugin->component = 'mod_attendance';

2
warnings.php

@ -84,6 +84,7 @@ if ($data = $mform->get_data()) {
$notify->warningpercent = $data->warningpercent;
$notify->warnafter = $data->warnafter;
$notify->maxwarn = $data->maxwarn;
$notify->emailuser = empty($data->emailuser) ? 0 : $data->emailuser;
$notify->emailsubject = $data->emailsubject;
$notify->emailcontent = $data->emailcontent['text'];
@ -113,6 +114,7 @@ if ($data = $mform->get_data()) {
$notify->idnumber = $data->idnumber;
$notify->warningpercent = $data->warningpercent;
$notify->warnafter = $data->warnafter;
$notify->maxwarn = $data->maxwarn;
$notify->emailuser = empty($data->emailuser) ? 0 : $data->emailuser;
$notify->emailsubject = $data->emailsubject;
$notify->emailcontentformat = $data->emailcontent['format'];

Loading…
Cancel
Save