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. 4
      password_ajax.php
  10. 6
      settings.php
  11. 2
      student_attendance_form.php
  12. 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->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance');
$mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked');
if (isset($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.
$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);
$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;
$att = new mod_attendance_structure($attendance, $cm, $course, $PAGE->context, $pageparams);
// Require that a session key is passed to this page.
// require_sesskey();
if (empty($attforsession->includeqrcode)) {
$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.
if ($attforsession->autoassignstatus && empty($attforsession->studentpassword)) {
@ -79,22 +85,20 @@ if ($attforsession->autoassignstatus && empty($attforsession->studentpassword))
}
}
// Create the form.
$mform = new mod_attendance_student_attendance_form(null,
array('course' => $course, 'cm' => $cm, 'modcontext' => $PAGE->context, 'session' => $attforsession, 'attendance' => $att));
if ($password !== '') {
$fromform = $mform->get_data();
// Check to see if autoassignstatus is in use and if qrcode is being used.
if (!empty($qrpass) && !empty($attforsession->autoassignstatus)) {
$fromform = new stdClass();
// Check if password required and if set correctly.
if (!empty($attforsession->studentpassword) &&
$attforsession->studentpassword !== $password) {
$attforsession->studentpassword !== $qrpass) {
$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);
}
// 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->status = attendance_session_get_highest_status($att, $attforsession);
@ -114,52 +118,57 @@ if ($password !== '') {
print_error('attendance_already_submitted', 'mod_attendance', $url);
}
}
} else {
$PAGE->set_url($att->url_sessions());
}
if ($mform->is_cancelled()) {
// 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));
print_error('attendance_no_status', 'mod_attendance', $url);
}
}
$PAGE->set_url($att->url_sessions());
// Create the form.
$mform = new mod_attendance_student_attendance_form(null,
array('course' => $course, 'cm' => $cm, 'modcontext' => $PAGE->context, 'session' => $attforsession,
'attendance' => $att, 'password' => $qrpass));
if (!empty($fromform->status)) {
$success = $att->take_from_student($fromform);
if ($mform->is_cancelled()) {
// 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));
if ($success) {
// Redirect back to the view page.
redirect($url, get_string('studentmarked', 'attendance'));
} else {
print_error('attendance_already_submitted', 'mod_attendance', $url);
}
print_error('attendance_no_status', '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);
if (!empty($fromform->status)) {
$success = $att->take_from_student($fromform);
$output = $PAGE->get_renderer('mod_attendance');
echo $output->header();
$mform->display();
echo $output->footer();
$url = new moodle_url('/mod/attendance/view.php', array('id' => $cm->id));
if ($success) {
// 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);
$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',
'description', 'descriptionformat', 'studentscanmark', 'studentpassword', 'autoassignstatus',
'subnet', 'automark', 'automarkcompleted', 'statusset', 'absenteereport', 'preventsharedip',
'preventsharediptime', 'caleventid'));
'preventsharediptime', 'caleventid', 'calendarevent', 'includeqrcode'));
// XML nodes declaration - user data.
$logs = new backup_nested_element('logs');

15
classes/import/sessions.php

@ -110,7 +110,8 @@ class sessions {
get_string('absenteereport', 'attendance'),
get_string('preventsharedip', '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,
'preventsharedip' => $data->header16,
'preventsharediptime' => $data->header17,
'calendarevent' => $data->header18
'calendarevent' => $data->header18,
'includeqrcode' => $data->header19
);
} else {
return array(
@ -171,7 +173,8 @@ class sessions {
'absenteereport' => 15,
'preventsharedip' => 16,
'preventsharediptime' => 17,
'calendarevent' => 18
'calendarevent' => 18,
'includeqrcode' => 19
);
}
}
@ -337,6 +340,12 @@ class sessions {
$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;
$sessions[] = $session;

8
classes/structure.php

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

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['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['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['remark'] = 'Remark for: {$a}';
$string['remarks'] = 'Remarks';

12
password.php

@ -25,10 +25,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use Endroid\QrCode\QrCode;
require_once(dirname(__FILE__).'/../../config.php');
$session = required_param('session', PARAM_INT);
$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 html_writer::tag('h2', get_string('passwordgrp', 'attendance'));
echo html_writer::span($session->studentpassword, 'student-password');
echo html_writer::tag('h3', $plugininfos['qrlinks']);
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'));
// If the local_qrlinks plugin is installed, use it to create the QR code.
$plugininfos = core_plugin_manager::instance()->get_plugins_of_type('local');
if (isset($plugininfos['qrlinks'])) {
require_once(dirname(__FILE__).'/../../local/qrlinks/thirdparty/QrCode/src/QrCode.php');
$qrlinklib = dirname(__FILE__).'/../../local/qrlinks/thirdparty/QrCode/src/QrCode.php';
if (isset($plugininfos['qrlinks']) && file_exists($qrlinklib)) {
require_once($qrlinklib);
$code = new QrCode($qrcodeurl);
$code->setSize(500);
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) {
echo html_writer::tag('p', get_string('qrcodemissing', 'attendance'));
} 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'));
}
} catch (Exception $e) {

4
password_ajax.php

@ -47,8 +47,8 @@ $PAGE->set_context(context_system::instance());
$data->heading = get_string('passwordgrp', 'attendance');
if (isset($session->includeqrcode) && $session->includeqrcode == 1) {
$studentattendancepage = '/mod/attendance/password.php?session=' . $session->id;
$data->text = html_writer::tag('p', html_writer::span($session->studentpassword, 'student-password') .
html_writer::empty_tag('br') .
$data->text = html_writer::tag('p', html_writer::span($session->studentpassword, 'student-password') .
html_writer::empty_tag('br') .
html_writer::link($CFG->wwwroot . $studentattendancepage, get_string('showqrcode', 'attendance')));
} else {
$data->text = html_writer::span($session->studentpassword, 'student-password');

6
settings.php

@ -29,8 +29,14 @@ if ($ADMIN->fulltree) {
require_once(dirname(__FILE__).'/locallib.php');
$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));
$plugininfos = core_plugin_manager::instance()->get_plugins_of_type('local');
// Paging options.
$options = array(
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'];
$attblock = $this->_customdata['attendance'];
$password = $this->_customdata['password'];
$statuses = $attblock->get_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->setType('studentpassword', PARAM_TEXT);
$mform->addRule('studentpassword', get_string('passwordrequired', 'attendance'), 'required');
$mform->setDefault('studentpassword', $password);
}
if (!$attforsession->autoassignstatus) {

5
update_form.php

@ -76,7 +76,8 @@ class mod_attendance_update_form extends moodleform {
'absenteereport' => $sess->absenteereport,
'automarkcompleted' => 0,
'preventsharedip' => $sess->preventsharedip,
'preventsharediptime' => $sess->preventsharediptime
'preventsharediptime' => $sess->preventsharediptime,
'includeqrcode' => $sess->includeqrcode
);
if ($sess->subnet == $attendancesubnet) {
$data['usedefaultsubnet'] = 1;
@ -147,6 +148,8 @@ class mod_attendance_update_form extends moodleform {
$mform->hideif('studentpassword', 'studentscanmark', 'notchecked');
$mform->hideif('studentpassword', '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->addHelpButton('autoassignstatus', 'autoassignstatus', 'attendance');
$mform->hideif('autoassignstatus', 'studentscanmark', 'notchecked');

Loading…
Cancel
Save