diff --git a/backup/moodle2/backup_attendance_stepslib.php b/backup/moodle2/backup_attendance_stepslib.php
index 67e90f4..a98e79b 100644
--- a/backup/moodle2/backup_attendance_stepslib.php
+++ b/backup/moodle2/backup_attendance_stepslib.php
@@ -59,7 +59,7 @@ class backup_attendance_activity_structure_step extends backup_activity_structur
'groupid', 'sessdate', 'duration', 'lasttaken', 'lasttakenby', 'timemodified',
'description', 'descriptionformat', 'studentscanmark', 'studentpassword', 'autoassignstatus',
'subnet', 'automark', 'automarkcompleted', 'statusset', 'absenteereport', 'preventsharedip',
- 'preventsharediptime', 'caleventid', 'calendarevent', 'includeqrcode'));
+ 'preventsharediptime', 'caleventid', 'calendarevent', 'includeqrcode', 'automarkcmid'));
// XML nodes declaration - user data.
$logs = new backup_nested_element('logs');
diff --git a/classes/form/addsession.php b/classes/form/addsession.php
index 4bf381c..ece7d8b 100644
--- a/classes/form/addsession.php
+++ b/classes/form/addsession.php
@@ -46,7 +46,7 @@ class addsession extends moodleform {
*/
public function definition() {
- global $CFG, $USER;
+ global $CFG, $USER, $DB;
$mform =& $this->_form;
$course = $this->_customdata['course'];
@@ -215,6 +215,12 @@ class addsession extends moodleform {
$mform->addHelpButton('automark', 'automark', 'attendance');
$mform->setDefault('automark', $this->_customdata['att']->automark);
+ $automarkcmoptions = attendance_get_coursemodulenames($course->id);
+
+ $mform->addElement('select', 'automarkcmid', get_string('selectactivity', 'attendance'), $automarkcmoptions);
+ $mform->setType('automarkcmid', PARAM_INT);
+ $mform->hideif('automarkcmid', 'automark', 'neq', '3');
+
if (!empty($studentscanmark)) {
$mgroup = array();
@@ -240,6 +246,7 @@ class addsession extends moodleform {
$mform->addElement('checkbox', 'autoassignstatus', '', get_string('autoassignstatus', 'attendance'));
$mform->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance');
$mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked');
+
if (isset($pluginconfig->autoassignstatus)) {
$mform->setDefault('autoassignstatus', $pluginconfig->autoassignstatus);
}
diff --git a/classes/form/updatesession.php b/classes/form/updatesession.php
index 0dcaf11..c4ce7da 100644
--- a/classes/form/updatesession.php
+++ b/classes/form/updatesession.php
@@ -41,7 +41,7 @@ class updatesession extends \moodleform {
*/
public function definition() {
- global $DB;
+ global $DB, $COURSE;
$mform =& $this->_form;
$modcontext = $this->_customdata['modcontext'];
@@ -148,6 +148,12 @@ class updatesession extends \moodleform {
$mform->setType('automark', PARAM_INT);
$mform->addHelpButton('automark', 'automark', 'attendance');
+ $automarkcmoptions2 = attendance_get_coursemodulenames($COURSE->id);
+
+ $mform->addElement('select', 'automarkcmid', get_string('selectactivity', 'attendance'), $automarkcmoptions2);
+ $mform->setType('automarkcmid', PARAM_INT);
+ $mform->hideif('automarkcmid', 'automark', 'neq', '3');
+
if (!empty($studentscanmark)) {
$mform->addElement('text', 'studentpassword', get_string('studentpassword', 'attendance'));
$mform->setType('studentpassword', PARAM_TEXT);
diff --git a/classes/structure.php b/classes/structure.php
index d70347f..bd03cee 100644
--- a/classes/structure.php
+++ b/classes/structure.php
@@ -534,6 +534,9 @@ class mod_attendance_structure {
$sess->rotateqrcode = 0;
$sess->rotateqrcodesecret = '';
}
+ if (!isset($sess->automarkcmid)) {
+ $sess->automarkcmid = null;
+ }
$event->add_record_snapshot('attendance_sessions', $sess);
$event->trigger();
diff --git a/classes/task/auto_mark.php b/classes/task/auto_mark.php
index c30b258..7d7876c 100644
--- a/classes/task/auto_mark.php
+++ b/classes/task/auto_mark.php
@@ -34,6 +34,7 @@ require_once($CFG->dirroot . '/mod/attendance/locallib.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class auto_mark extends \core\task\scheduled_task {
+
/**
* Returns localised general event name.
*
@@ -76,10 +77,12 @@ class auto_mark extends \core\task\scheduled_task {
$setunmarked = $DB->get_field('attendance_statuses', 'id',
array('attendanceid' => $session->attendanceid, 'setnumber' => $session->statusset,
'setunmarked' => 1, 'deleted' => 0));
+
if (empty($setunmarked)) {
mtrace("No unmarked status configured for session id: ".$session->id);
continue;
}
+
if (empty($cacheatt[$session->attendanceid])) {
$cacheatt[$session->attendanceid] = $DB->get_record('attendance', array('id' => $session->attendanceid));
}
@@ -102,6 +105,9 @@ class auto_mark extends \core\task\scheduled_task {
}
$pageparams->sessionid = $session->id;
+ $att = new \mod_attendance_structure($cacheatt[$session->attendanceid],
+ $cachecm[$session->attendanceid], $cachecourse[$courseid], $context, $pageparams);
+
if ($session->automark == 1) {
$userfirstacess = array();
// If set to do full automarking, get all users that have accessed course during session open.
@@ -136,12 +142,39 @@ class auto_mark extends \core\task\scheduled_task {
}
}
$logusers->close();
+
+ } else if ($session->automark == 3) {
+
+ $completedusers = array();
+ $newlog = new \stdClass();
+ $newlog->timetaken = $now;
+ $newlog->takenby = 0;
+ $newlog->sessionid = $session->id;
+ $newlog->remarks = get_string('autorecorded', 'attendance');
+ $newlog->statusset = implode(',', array_keys( (array)$att->get_statuses()));
+
+ // Get users who have completed the course in this session.
+ $completedusers[] = $DB->get_record('course_modules_completion', array(
+ 'coursemoduleid' => $session->automarkcmid,
+ 'completionstate' => 1
+ ));
+
+ if (!empty($completedusers)) {
+
+ // Get automark status the users and update the attendance log.
+ foreach ($completedusers as $completionuser) {
+
+ $newlog->statusid = $att->get_automark_status($completionuser->timemodified, $session->id);
+
+ if (!empty($newlog->statusid)) {
+ $newlog->studentid = $completionuser->userid;
+ $DB->insert_record('attendance_log', $newlog);
+ }
+ }
+ }
}
// Get all unmarked students.
- $att = new \mod_attendance_structure($cacheatt[$session->attendanceid],
- $cachecm[$session->attendanceid], $cachecourse[$courseid], $context, $pageparams);
-
$users = $att->get_users($session->groupid, 0);
$existinglog = $DB->get_recordset('attendance_log', array('sessionid' => $session->id));
diff --git a/db/install.xml b/db/install.xml
index ae0d375..7aba70a 100755
--- a/db/install.xml
+++ b/db/install.xml
@@ -52,6 +52,7 @@
+
diff --git a/db/upgrade.php b/db/upgrade.php
index d3f1c16..c8974b2 100755
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -650,5 +650,20 @@ function xmldb_attendance_upgrade($oldversion=0) {
upgrade_mod_savepoint(true, 2021050700, 'attendance');
}
+ if ($oldversion < 2021060700) {
+
+ // Changing precision of field statusset on table attendance_log to (1333).
+ $table = new xmldb_table('attendance_sessions');
+ $field = new xmldb_field('automarkcmid', XMLDB_TYPE_CHAR, '10', null, false, null, null, 'rotateqrcodesecret');
+
+ // Launch change of precision for field statusset.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Attendance savepoint reached.
+ upgrade_mod_savepoint(true, 2021060700, 'attendance');
+ }
+
return $result;
}
diff --git a/externallib.php b/externallib.php
index 50f65ef..163a880 100644
--- a/externallib.php
+++ b/externallib.php
@@ -255,6 +255,7 @@ class mod_attendance_external extends external_api {
$sess->subnet = $attendance->subnet;
$sess->statusset = 0;
$sess->groupid = $groupid;
+ $sess->automarkcmid = 0;
$sessionid = $attendance->add_session($sess);
return array('sessionid' => $sessionid);
diff --git a/lang/en/attendance.php b/lang/en/attendance.php
index df0b275..2f30a9f 100644
--- a/lang/en/attendance.php
+++ b/lang/en/attendance.php
@@ -76,11 +76,13 @@ $string['attrecords'] = 'Attendances records';
$string['autoassignstatus'] = 'Automatically select highest status available';
$string['autoassignstatus_help'] = 'If this is selected, students will automatically be assigned the highest available grade.';
$string['automark'] = 'Automatic marking';
+$string['selectactivity'] = 'Select activity';
$string['automark_help'] = 'Allows marking to be completed automatically.
If "Yes" students will be automatically marked depending on their first access to the course.
If "Set unmarked at end of session" any students who have not marked their attendance will be set to the unmarked status selected.';
$string['automarkall'] = 'Yes';
$string['automarkclose'] = 'Set unmarked at end of session';
+$string['onactivitycompletion'] = 'On activity completion';
$string['automarktask'] = 'Check for attendance sessions that require auto marking';
$string['autorecorded'] = 'system auto recorded';
$string['averageattendance'] = 'Average attendance';
diff --git a/locallib.php b/locallib.php
index fb7c65b..bc35188 100644
--- a/locallib.php
+++ b/locallib.php
@@ -42,6 +42,8 @@ define('ATT_SORT_FIRSTNAME', 2);
define('ATTENDANCE_AUTOMARK_DISABLED', 0);
define('ATTENDANCE_AUTOMARK_ALL', 1);
define('ATTENDANCE_AUTOMARK_CLOSE', 2);
+define('ATTENDANCE_AUTOMARK_ACTIVITYCOMPLETION', 3);
+
define('ATTENDANCE_SHAREDIP_DISABLED', 0);
define('ATTENDANCE_SHAREDIP_MINUTES', 1);
@@ -788,6 +790,12 @@ function attendance_construct_sessions_data_for_add($formdata, mod_attendance_st
}
$sess->automark = $formdata->automark;
$sess->automarkcompleted = 0;
+
+ if (!empty($formdata->automarkcmid)) {
+ $sess->automarkcmid = $formdata->automarkcmid;
+ } else {
+ $sess->automarkcmid = 0;
+ }
if (!empty($formdata->preventsharedip)) {
$sess->preventsharedip = $formdata->preventsharedip;
}
@@ -852,6 +860,13 @@ function attendance_construct_sessions_data_for_add($formdata, mod_attendance_st
$sess->studentpassword = '';
$sess->automark = 0;
$sess->automarkcompleted = 0;
+
+ if (!empty($formdata->automarkcmid)) {
+ $sess->automarkcmid = $formdata->automarkcmid;
+ } else {
+ $sess->automarkcmid = 0;
+ }
+
$sess->absenteereport = $absenteereport;
$sess->includeqrcode = 0;
$sess->rotateqrcode = 0;
@@ -1150,15 +1165,49 @@ function attendance_session_get_highest_status(mod_attendance_structure $att, $a
* @return array
*/
function attendance_get_automarkoptions() {
+
$options = array();
+
$options[ATTENDANCE_AUTOMARK_DISABLED] = get_string('noautomark', 'attendance');
if (strpos(get_config('tool_log', 'enabled_stores'), 'logstore_standard') !== false) {
$options[ATTENDANCE_AUTOMARK_ALL] = get_string('automarkall', 'attendance');
}
$options[ATTENDANCE_AUTOMARK_CLOSE] = get_string('automarkclose', 'attendance');
+ $options[ATTENDANCE_AUTOMARK_ACTIVITYCOMPLETION] = get_string('onactivitycompletion', 'attendance');
+
return $options;
}
+/**
+ * Get course module names associated to this course, if they're visible and complete.
+ * @param int $id - course id.
+ * @return array $automarkcmoptions - list of course module names associated to this course.
+ */
+function attendance_get_coursemodulenames($id) {
+
+ global $DB;
+ $automarkcmoptions = [];
+
+ $sql = "SELECT DISTINCT cm.id, cm.module, m.name
+ FROM {course_modules} cm
+ JOIN {modules} m ON m.id = cm.module
+ WHERE cm.course = :cmcourse
+ AND cm.visible = :cmvisible
+ AND cm.completion = :cmcompletion";
+
+ $coursemodulenames = $DB->get_records_sql($sql, array(
+ 'cmcourse' => $id,
+ 'cmvisible' => 1,
+ 'cmcompletion' => 1
+ ));
+ if ($coursemodulenames) {
+ foreach ($coursemodulenames as $coursemodulename) {
+ $automarkcmoptions[$coursemodulename->id] = format_string($coursemodulename->name);
+ }
+ }
+ return $automarkcmoptions;
+}
+
/**
* Get available sharedip options.
*
diff --git a/renderhelpers.php b/renderhelpers.php
index c5754e1..86783d1 100644
--- a/renderhelpers.php
+++ b/renderhelpers.php
@@ -68,7 +68,8 @@ class user_sessions_cells_generator {
$this->construct_existing_status_cell($this->reportdata->statuses[$statusid]->acronym .
" ({$points}/{$maxpoints})");
} else {
- if (!empty($this->reportdata->allstatuses[$statusid] && isset($this->reportdata->allstatuses[$statusid]->acronym))) {
+ if (!empty($this->reportdata->allstatuses[$statusid] &&
+ isset($this->reportdata->allstatuses[$statusid]->acronym))) {
$statusac = $this->reportdata->allstatuses[$statusid]->acronym;
} else {
$statusac = get_string('unknownstatus', 'mod_attendance', $statusid);