Browse Source

Improve QRcode support.

MOODLE_35_STABLE
Dan Marsden 6 years ago
parent
commit
67c63bfb1b
  1. 1
      add_form.php
  2. 111
      attendance.php
  3. 2
      backup/moodle2/backup_attendance_stepslib.php
  4. 15
      classes/import/sessions.php
  5. 8
      classes/structure.php
  6. 3
      externallib.php
  7. 3
      lang/en/attendance.php
  8. 12
      password.php
  9. 6
      settings.php
  10. 2
      student_attendance_form.php
  11. 5
      update_form.php

1
add_form.php

@ -222,7 +222,6 @@ class mod_attendance_add_form extends moodleform {
$mform->addElement('checkbox', 'autoassignstatus', '', get_string('autoassignstatus', 'attendance')); $mform->addElement('checkbox', 'autoassignstatus', '', get_string('autoassignstatus', 'attendance'));
$mform->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance'); $mform->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance');
$mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked'); $mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked');
if (isset($pluginconfig->autoassignstatus)) { if (isset($pluginconfig->autoassignstatus)) {
$mform->setDefault('autoassignstatus', $pluginconfig->autoassignstatus); $mform->setDefault('autoassignstatus', $pluginconfig->autoassignstatus);
} }

111
attendance.php

@ -30,7 +30,7 @@ $pageparams = new mod_attendance_sessions_page_params();
// Check that the required parameters are present. // Check that the required parameters are present.
$id = required_param('sessid', PARAM_INT); $id = required_param('sessid', PARAM_INT);
$password = optional_param('studentpassword', '', PARAM_TEXT); $qrpass = optional_param('qrpass', '', PARAM_TEXT);
$attforsession = $DB->get_record('attendance_sessions', array('id' => $id), '*', MUST_EXIST); $attforsession = $DB->get_record('attendance_sessions', array('id' => $id), '*', MUST_EXIST);
$attendance = $DB->get_record('attendance', array('id' => $attforsession->attendanceid), '*', MUST_EXIST); $attendance = $DB->get_record('attendance', array('id' => $attforsession->attendanceid), '*', MUST_EXIST);
@ -56,8 +56,14 @@ if (!empty($attforsession->subnet) && !address_in_subnet(getremoteaddr(), $attfo
$pageparams->sessionid = $id; $pageparams->sessionid = $id;
$att = new mod_attendance_structure($attendance, $cm, $course, $PAGE->context, $pageparams); $att = new mod_attendance_structure($attendance, $cm, $course, $PAGE->context, $pageparams);
// Require that a session key is passed to this page. if (empty($attforsession->includeqrcode)) {
// require_sesskey(); $qrpass = ''; // Override qrpass if set, as it is not allowed.
}
if (empty($qrpass)) {
// Sesskey is required on this page when QR code not in use.
require_sesskey();
}
// Check to see if autoassignstatus is in use and no password required. // Check to see if autoassignstatus is in use and no password required.
if ($attforsession->autoassignstatus && empty($attforsession->studentpassword)) { if ($attforsession->autoassignstatus && empty($attforsession->studentpassword)) {
@ -79,22 +85,20 @@ if ($attforsession->autoassignstatus && empty($attforsession->studentpassword))
} }
} }
// Create the form. // Check to see if autoassignstatus is in use and if qrcode is being used.
$mform = new mod_attendance_student_attendance_form(null, if (!empty($qrpass) && !empty($attforsession->autoassignstatus)) {
array('course' => $course, 'cm' => $cm, 'modcontext' => $PAGE->context, 'session' => $attforsession, 'attendance' => $att)); $fromform = new stdClass();
if ($password !== '') {
$fromform = $mform->get_data();
// Check if password required and if set correctly. // Check if password required and if set correctly.
if (!empty($attforsession->studentpassword) && if (!empty($attforsession->studentpassword) &&
$attforsession->studentpassword !== $password) { $attforsession->studentpassword !== $qrpass) {
$url = new moodle_url('/mod/attendance/attendance.php', array('sessid' => $id, 'sesskey' => sesskey())); $url = new moodle_url('/mod/attendance/attendance.php', array('sessid' => $id, 'sesskey' => sesskey()));
redirect($url, get_string('incorrectpassword', 'mod_attendance'), null, \core\output\notification::NOTIFY_ERROR); redirect($url, get_string('incorrectpassword', 'mod_attendance'), null, \core\output\notification::NOTIFY_ERROR);
} }
// Set the password and session id in the form, because they are saved in the attendance log. // Set the password and session id in the form, because they are saved in the attendance log.
$fromform->studentpassword = $password; $fromform->studentpassword = $qrpass;
$fromform->sessid = $attforsession->id; $fromform->sessid = $attforsession->id;
$fromform->status = attendance_session_get_highest_status($att, $attforsession); $fromform->status = attendance_session_get_highest_status($att, $attforsession);
@ -114,52 +118,57 @@ if ($password !== '') {
print_error('attendance_already_submitted', 'mod_attendance', $url); print_error('attendance_already_submitted', 'mod_attendance', $url);
} }
} }
} else { }
$PAGE->set_url($att->url_sessions());
if ($mform->is_cancelled()) { $PAGE->set_url($att->url_sessions());
// The user cancelled the form, so redirect them to the view page.
$url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id)); // Create the form.
redirect($url); $mform = new mod_attendance_student_attendance_form(null,
} else if ($fromform = $mform->get_data()) { array('course' => $course, 'cm' => $cm, 'modcontext' => $PAGE->context, 'session' => $attforsession,
// Check if password required and if set correctly. 'attendance' => $att, 'password' => $qrpass));
if (!empty($attforsession->studentpassword) &&
$attforsession->studentpassword !== $fromform->studentpassword) {
$url = new moodle_url('/mod/attendance/attendance.php', array('sessid' => $id, 'sesskey' => sesskey()));
redirect($url, get_string('incorrectpassword', 'mod_attendance'), null, \core\output\notification::NOTIFY_ERROR);
}
if ($attforsession->autoassignstatus) {
$fromform->status = attendance_session_get_highest_status($att, $attforsession);
if (empty($fromform->status)) {
$url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id));
print_error('attendance_no_status', 'mod_attendance', $url);
}
}
if (!empty($fromform->status)) { if ($mform->is_cancelled()) {
$success = $att->take_from_student($fromform); // The user cancelled the form, so redirect them to the view page.
$url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id));
redirect($url);
} else if ($fromform = $mform->get_data()) {
// Check if password required and if set correctly.
if (!empty($attforsession->studentpassword) &&
$attforsession->studentpassword !== $fromform->studentpassword) {
$url = new moodle_url('/mod/attendance/attendance.php', array('sessid' => $id, 'sesskey' => sesskey()));
redirect($url, get_string('incorrectpassword', 'mod_attendance'), null, \core\output\notification::NOTIFY_ERROR);
}
if ($attforsession->autoassignstatus) {
$fromform->status = attendance_session_get_highest_status($att, $attforsession);
if (empty($fromform->status)) {
$url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id)); $url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id));
if ($success) { print_error('attendance_no_status', 'mod_attendance', $url);
// Redirect back to the view page.
redirect($url, get_string('studentmarked', 'attendance'));
} else {
print_error('attendance_already_submitted', 'mod_attendance', $url);
}
} }
// The form did not validate correctly so we will set it to display the data they submitted.
$mform->set_data($fromform);
} }
$PAGE->set_title($course->shortname. ": ".$att->name); if (!empty($fromform->status)) {
$PAGE->set_heading($course->fullname); $success = $att->take_from_student($fromform);
$PAGE->set_cacheable(true);
$PAGE->navbar->add($att->name);
$output = $PAGE->get_renderer('mod_attendance'); $url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id));
echo $output->header(); if ($success) {
$mform->display(); // Redirect back to the view page.
echo $output->footer(); redirect($url, get_string('studentmarked', 'attendance'));
} else {
print_error('attendance_already_submitted', 'mod_attendance', $url);
}
}
// The form did not validate correctly so we will set it to display the data they submitted.
$mform->set_data($fromform);
} }
$PAGE->set_title($course->shortname. ": ".$att->name);
$PAGE->set_heading($course->fullname);
$PAGE->set_cacheable(true);
$PAGE->navbar->add($att->name);
$output = $PAGE->get_renderer('mod_attendance');
echo $output->header();
$mform->display();
echo $output->footer();

2
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', 'groupid', 'sessdate', 'duration', 'lasttaken', 'lasttakenby', 'timemodified',
'description', 'descriptionformat', 'studentscanmark', 'studentpassword', 'autoassignstatus', 'description', 'descriptionformat', 'studentscanmark', 'studentpassword', 'autoassignstatus',
'subnet', 'automark', 'automarkcompleted', 'statusset', 'absenteereport', 'preventsharedip', 'subnet', 'automark', 'automarkcompleted', 'statusset', 'absenteereport', 'preventsharedip',
'preventsharediptime', 'caleventid')); 'preventsharediptime', 'caleventid', 'calendarevent', 'includeqrcode'));
// XML nodes declaration - user data. // XML nodes declaration - user data.
$logs = new backup_nested_element('logs'); $logs = new backup_nested_element('logs');

15
classes/import/sessions.php

@ -110,7 +110,8 @@ class sessions {
get_string('absenteereport', 'attendance'), get_string('absenteereport', 'attendance'),
get_string('preventsharedip', 'attendance'), get_string('preventsharedip', 'attendance'),
get_string('preventsharediptime', 'attendance'), get_string('preventsharediptime', 'attendance'),
get_string('calendarevent', 'attendance') get_string('calendarevent', 'attendance'),
get_string('includeqrcode', 'attendance'),
); );
} }
@ -149,7 +150,8 @@ class sessions {
'absenteereport' => $data->header15, 'absenteereport' => $data->header15,
'preventsharedip' => $data->header16, 'preventsharedip' => $data->header16,
'preventsharediptime' => $data->header17, 'preventsharediptime' => $data->header17,
'calendarevent' => $data->header18 'calendarevent' => $data->header18,
'includeqrcode' => $data->header19
); );
} else { } else {
return array( return array(
@ -171,7 +173,8 @@ class sessions {
'absenteereport' => 15, 'absenteereport' => 15,
'preventsharedip' => 16, 'preventsharedip' => 16,
'preventsharediptime' => 17, 'preventsharediptime' => 17,
'calendarevent' => 18 'calendarevent' => 18,
'includeqrcode' => 19
); );
} }
} }
@ -337,6 +340,12 @@ class sessions {
$session->preventsharediptime = $this->get_column_data($row, $mapping['preventsharediptime']); $session->preventsharediptime = $this->get_column_data($row, $mapping['preventsharediptime']);
} }
if ($mapping['includeqrcode'] == -1) {
$session->includeqrcode = $pluginconfig->includeqrcode_default;
} else {
$session->includeqrcode = $this->get_column_data($row, $mapping['includeqrcode']);
}
$session->statusset = 0; $session->statusset = 0;
$sessions[] = $session; $sessions[] = $session;

8
classes/structure.php

@ -504,7 +504,9 @@ class mod_attendance_structure {
if (!isset($sess->preventsharediptime)) { if (!isset($sess->preventsharediptime)) {
$sess->preventsharediptime = ''; $sess->preventsharediptime = '';
} }
if (!isset($sess->includeqrcode)) {
$sess->includeqrcode = 0;
}
$event->add_record_snapshot('attendance_sessions', $sess); $event->add_record_snapshot('attendance_sessions', $sess);
$event->trigger(); $event->trigger();
} }
@ -544,6 +546,7 @@ class mod_attendance_structure {
$sess->automarkcompleted = 0; $sess->automarkcompleted = 0;
$sess->preventsharedip = 0; $sess->preventsharedip = 0;
$sess->preventsharediptime = ''; $sess->preventsharediptime = '';
$sess->includeqrcode = 0;
if (!empty(get_config('attendance', 'enablewarnings'))) { if (!empty(get_config('attendance', 'enablewarnings'))) {
$sess->absenteereport = empty($formdata->absenteereport) ? 0 : 1; $sess->absenteereport = empty($formdata->absenteereport) ? 0 : 1;
} }
@ -570,6 +573,9 @@ class mod_attendance_structure {
if (!empty($formdata->preventsharediptime)) { if (!empty($formdata->preventsharediptime)) {
$sess->preventsharediptime = $formdata->preventsharediptime; $sess->preventsharediptime = $formdata->preventsharediptime;
} }
if (!empty($formdata->includeqrcode)) {
$sess->includeqrcode = $formdata->includeqrcode;
}
} }

3
externallib.php

@ -72,7 +72,8 @@ class mod_wsattendance_external extends external_api {
'autoassignstatus' => new external_value(PARAM_INT, 'Automatically assign a status to students.'), 'autoassignstatus' => new external_value(PARAM_INT, 'Automatically assign a status to students.'),
'preventsharedip' => new external_value(PARAM_INT, 'Prevent students from sharing IP addresses.'), 'preventsharedip' => new external_value(PARAM_INT, 'Prevent students from sharing IP addresses.'),
'preventsharediptime' => new external_value(PARAM_INT, 'Time delay before IP address is allowed again.'), 'preventsharediptime' => new external_value(PARAM_INT, 'Time delay before IP address is allowed again.'),
'statusset' => new external_value(PARAM_INT, 'Session statusset.')); 'statusset' => new external_value(PARAM_INT, 'Session statusset.'),
'includeqrcode' => new external_value(PARAM_INT, 'Include QR code when displaying password'));
return $session; return $session;
} }

3
lang/en/attendance.php

@ -344,7 +344,8 @@ $string['priorto'] = 'The session date is prior to the course start date ({$a})
$string['processingfile'] = 'Processing file'; $string['processingfile'] = 'Processing file';
$string['qrcode'] = 'QR Code'; $string['qrcode'] = 'QR Code';
$string['qrcodemissing'] = 'QR Code not available. Please ask your administrator to install the <a href="https://moodle.org/plugins/local_qrlinks">QR Links</a> plugin.'; $string['qrcodemissing'] = 'QR Code not available. Please ask your administrator to install the <a href="https://moodle.org/plugins/local_qrlinks">QR Links</a> plugin.';
$string['qrcodewarning'] = 'Local QR code generator not available. Using web-based 3rd-party service <a href="https://goqr.me/">goQR.me</a> instead.'; $string['qrcodewarning'] = 'This QR code was generated using the 3rd-party service <a href="http://goqr.me/?refer=moodle-mod_attendance">goQR.me</a>.';
$string['qrcodeadminwarning'] = 'Warning: QR codes for student self-marking will be generated using the external service <a href="http://goqr.me/?refer=moodle-mod_attendance">goQR.me</a>. Install the <a href="https://moodle.org/plugins/local_qrlinks">QR Links</a> plugin to generate them locally.';
$string['randompassword'] = 'Random password'; $string['randompassword'] = 'Random password';
$string['remark'] = 'Remark for: {$a}'; $string['remark'] = 'Remark for: {$a}';
$string['remarks'] = 'Remarks'; $string['remarks'] = 'Remarks';

12
password.php

@ -25,10 +25,8 @@
* @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
*/ */
use Endroid\QrCode\QrCode;
require_once(dirname(__FILE__).'/../../config.php'); require_once(dirname(__FILE__).'/../../config.php');
$session = required_param('session', PARAM_INT); $session = required_param('session', PARAM_INT);
$session = $DB->get_record('attendance_sessions', array('id' => $session), '*', MUST_EXIST); $session = $DB->get_record('attendance_sessions', array('id' => $session), '*', MUST_EXIST);
@ -51,16 +49,16 @@ $PAGE->set_title(get_string('password', 'attendance'));
echo $OUTPUT->header(); echo $OUTPUT->header();
echo html_writer::tag('h2', get_string('passwordgrp', 'attendance')); echo html_writer::tag('h2', get_string('passwordgrp', 'attendance'));
echo html_writer::span($session->studentpassword, 'student-password'); echo html_writer::span($session->studentpassword, 'student-password');
echo html_writer::tag('h3', $plugininfos['qrlinks']);
if (isset($session->includeqrcode) && $session->includeqrcode == 1) { if (isset($session->includeqrcode) && $session->includeqrcode == 1) {
$qrcodeurl = $CFG->wwwroot . '/mod/attendance/attendance.php?studentpassword=' . $session->studentpassword . '&sessid=' . $session->id; $qrcodeurl = $CFG->wwwroot . '/mod/attendance/attendance.php?qrpass=' . $session->studentpassword . '&sessid=' . $session->id;
echo html_writer::tag('h3', get_string('qrcode', 'attendance')); echo html_writer::tag('h3', get_string('qrcode', 'attendance'));
// If the local_qrlinks plugin is installed, use it to create the QR code. // If the local_qrlinks plugin is installed, use it to create the QR code.
$plugininfos = core_plugin_manager::instance()->get_plugins_of_type('local'); $plugininfos = core_plugin_manager::instance()->get_plugins_of_type('local');
if (isset($plugininfos['qrlinks'])) { $qrlinklib = dirname(__FILE__).'/../../local/qrlinks/thirdparty/QrCode/src/QrCode.php';
require_once(dirname(__FILE__).'/../../local/qrlinks/thirdparty/QrCode/src/QrCode.php'); if (isset($plugininfos['qrlinks']) && file_exists($qrlinklib)) {
require_once($qrlinklib);
$code = new QrCode($qrcodeurl); $code = new QrCode($qrcodeurl);
$code->setSize(500); $code->setSize(500);
echo html_writer::img('data:image/png;base64,' . base64_encode($code->get())); echo html_writer::img('data:image/png;base64,' . base64_encode($code->get()));
@ -71,7 +69,7 @@ if (isset($session->includeqrcode) && $session->includeqrcode == 1) {
if ($qrcode === false) { if ($qrcode === false) {
echo html_writer::tag('p', get_string('qrcodemissing', 'attendance')); echo html_writer::tag('p', get_string('qrcodemissing', 'attendance'));
} else { } else {
echo html_writer::img('data:image/png;base64,' . base64_encode($qrcode)); echo html_writer::img('data:image/png;base64,' . base64_encode($qrcode), get_string('qrcode', 'attendance'));
echo html_writer::tag('p', get_string('qrcodewarning', 'attendance')); echo html_writer::tag('p', get_string('qrcodewarning', 'attendance'));
} }
} catch (Exception $e) { } catch (Exception $e) {

6
settings.php

@ -29,8 +29,14 @@ if ($ADMIN->fulltree) {
require_once(dirname(__FILE__).'/locallib.php'); require_once(dirname(__FILE__).'/locallib.php');
$tabmenu = attendance_print_settings_tabs(); $tabmenu = attendance_print_settings_tabs();
if (empty($plugininfos['qrlinks'])) {
$tabmenu = '<div class="alert alert-warning">'.get_string('qrcodeadminwarning', 'mod_attendance').'</div>'.$tabmenu;
}
$settings->add(new admin_setting_heading('attendance_header', '', $tabmenu)); $settings->add(new admin_setting_heading('attendance_header', '', $tabmenu));
$plugininfos = core_plugin_manager::instance()->get_plugins_of_type('local');
// Paging options. // Paging options.
$options = array( $options = array(
0 => get_string('donotusepaging', 'attendance'), 0 => get_string('donotusepaging', 'attendance'),

2
student_attendance_form.php

@ -44,6 +44,7 @@ class mod_attendance_student_attendance_form extends moodleform {
$attforsession = $this->_customdata['session']; $attforsession = $this->_customdata['session'];
$attblock = $this->_customdata['attendance']; $attblock = $this->_customdata['attendance'];
$password = $this->_customdata['password'];
$statuses = $attblock->get_statuses(); $statuses = $attblock->get_statuses();
// Check if user has access to all statuses. // Check if user has access to all statuses.
@ -81,6 +82,7 @@ class mod_attendance_student_attendance_form extends moodleform {
$mform->addElement('text', 'studentpassword', get_string('password', 'attendance')); $mform->addElement('text', 'studentpassword', get_string('password', 'attendance'));
$mform->setType('studentpassword', PARAM_TEXT); $mform->setType('studentpassword', PARAM_TEXT);
$mform->addRule('studentpassword', get_string('passwordrequired', 'attendance'), 'required'); $mform->addRule('studentpassword', get_string('passwordrequired', 'attendance'), 'required');
$mform->setDefault('studentpassword', $password);
} }
if (!$attforsession->autoassignstatus) { if (!$attforsession->autoassignstatus) {

5
update_form.php

@ -76,7 +76,8 @@ class mod_attendance_update_form extends moodleform {
'absenteereport' => $sess->absenteereport, 'absenteereport' => $sess->absenteereport,
'automarkcompleted' => 0, 'automarkcompleted' => 0,
'preventsharedip' => $sess->preventsharedip, 'preventsharedip' => $sess->preventsharedip,
'preventsharediptime' => $sess->preventsharediptime 'preventsharediptime' => $sess->preventsharediptime,
'includeqrcode' => $sess->includeqrcode
); );
if ($sess->subnet == $attendancesubnet) { if ($sess->subnet == $attendancesubnet) {
$data['usedefaultsubnet'] = 1; $data['usedefaultsubnet'] = 1;
@ -147,6 +148,8 @@ class mod_attendance_update_form extends moodleform {
$mform->hideif('studentpassword', 'studentscanmark', 'notchecked'); $mform->hideif('studentpassword', 'studentscanmark', 'notchecked');
$mform->hideif('studentpassword', 'automark', 'eq', ATTENDANCE_AUTOMARK_ALL); $mform->hideif('studentpassword', 'automark', 'eq', ATTENDANCE_AUTOMARK_ALL);
$mform->hideif('randompassword', 'automark', 'eq', ATTENDANCE_AUTOMARK_ALL); $mform->hideif('randompassword', 'automark', 'eq', ATTENDANCE_AUTOMARK_ALL);
$mform->addElement('checkbox', 'includeqrcode', '', get_string('includeqrcode', 'attendance'));
$mform->hideif('includeqrcode', 'studentscanmark', 'notchecked');
$mform->addElement('checkbox', 'autoassignstatus', '', get_string('autoassignstatus', 'attendance')); $mform->addElement('checkbox', 'autoassignstatus', '', get_string('autoassignstatus', 'attendance'));
$mform->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance'); $mform->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance');
$mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked'); $mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked');

Loading…
Cancel
Save