Compare commits
144 Commits
40-behatfi
...
MOODLE_33_
Author | SHA1 | Date |
---|---|---|
Morgan Harris | a9e4c798ed | 6 years ago |
Dan Marsden | 61b0455a4c | 6 years ago |
Dan Marsden | 65f82bd0cd | 6 years ago |
Dan Marsden | 537ed2a0e8 | 6 years ago |
Dan Marsden | 8d486b6b54 | 6 years ago |
Dan Marsden | d01649fa27 | 6 years ago |
Tõnis Tartes | dadf8426a4 | 6 years ago |
Dan Marsden | c3b9ad119d | 6 years ago |
Dan Marsden | ef75ac81b5 | 6 years ago |
Dan Marsden | 0d8509d814 | 7 years ago |
Dan Marsden | 8f34fbf32a | 7 years ago |
Dan Marsden | 67f83cfacf | 7 years ago |
Dan Marsden | 82b9c51139 | 7 years ago |
Dan Marsden | 0e1d1d5561 | 7 years ago |
Dan Marsden | a2ac42a34e | 7 years ago |
Dan Marsden | 4c81211d85 | 7 years ago |
Dan Marsden | b72c2c52f5 | 7 years ago |
Dan Marsden | 55d524f85f | 7 years ago |
Dan Marsden | 38dacd225e | 7 years ago |
Dan Marsden | d7a908707a | 7 years ago |
Dan Marsden | aa38db6fdc | 7 years ago |
Dan Marsden | 3b275d0d0a | 7 years ago |
Dan Marsden | 5754d1a8b5 | 7 years ago |
Dan Marsden | dae3ac525b | 7 years ago |
Dan Marsden | 60402e1d7d | 7 years ago |
Nick Phillips | 53c30ab658 | 7 years ago |
Nick Phillips | 9a727878ea | 7 years ago |
Dan Marsden | 3e41d3ebe6 | 7 years ago |
Nick Phillips | c9fc3c4c7b | 7 years ago |
Dan Marsden | 326509fe99 | 7 years ago |
Dan Marsden | ba479427f1 | 7 years ago |
Dan Marsden | 41f52a6c95 | 7 years ago |
Dan Marsden | 3d228b9d0e | 7 years ago |
Dan Marsden | 83fa2a9dae | 7 years ago |
Dan Marsden | 692a8368ed | 7 years ago |
Dan Marsden | 20f9e4b9e3 | 7 years ago |
Dan Marsden | b90eb366a4 | 7 years ago |
Dan Marsden | ae7dd6f8d4 | 7 years ago |
Dan Marsden | 79c40ad826 | 7 years ago |
Dan Marsden | 5dd2f785a0 | 7 years ago |
Dan Marsden | 63546aab95 | 7 years ago |
Dan Marsden | a2496ef8c8 | 7 years ago |
Dan Marsden | bd8538c3bb | 7 years ago |
Dan Marsden | 6d53ae24a6 | 7 years ago |
Dan Marsden | f78902e7eb | 7 years ago |
Dan Marsden | 541f46963f | 7 years ago |
Dan Marsden | 0b3d6bb3d2 | 7 years ago |
Dan Marsden | 3458c729bb | 7 years ago |
Dan Marsden | 0fdea972d1 | 7 years ago |
Dan Marsden | ba0e9281f8 | 7 years ago |
Dan Marsden | 1b9ea04ea3 | 7 years ago |
Dan Marsden | a7845a2b87 | 7 years ago |
Dan Marsden | ff0b2ae7d6 | 7 years ago |
Dan Marsden | 670f592217 | 7 years ago |
James Voong | 8982de60e4 | 7 years ago |
Dan Marsden | 92b3d5ca82 | 7 years ago |
Dan Marsden | 03cdde1a34 | 7 years ago |
Dan Marsden | b008844733 | 7 years ago |
Dan Marsden | e4b67ff880 | 7 years ago |
Dan Marsden | 5827cb6731 | 7 years ago |
Dan Marsden | d06e216f9c | 7 years ago |
Chris Wharton | 5647da0b7f | 7 years ago |
Dan Marsden | 89bdd37463 | 7 years ago |
Dan Marsden | bd2856558b | 7 years ago |
Dan Marsden | 06cfb316af | 7 years ago |
Dan Marsden | 40761ac65f | 7 years ago |
Dan Marsden | a0503e820c | 7 years ago |
Dan Marsden | 97232cdc8a | 7 years ago |
Dan Marsden | a1ed607526 | 7 years ago |
Dan Marsden | ae89d47148 | 7 years ago |
Dan Marsden | f67ebb0856 | 7 years ago |
Dan Marsden | a0a955c020 | 7 years ago |
Dan Marsden | a3ff39a7d3 | 7 years ago |
Dan Marsden | fd78759a0a | 7 years ago |
Dan Marsden | 5f1114072f | 7 years ago |
Dan Marsden | c7c319cba8 | 7 years ago |
Dan Marsden | c84c5d8959 | 7 years ago |
Dan Marsden | f1e9440b5b | 7 years ago |
Dan Marsden | 34c5125f1a | 8 years ago |
Dan Marsden | b90403cf97 | 8 years ago |
Dan Marsden | a90aa44e5a | 8 years ago |
Dan Marsden | c87e48a1ee | 8 years ago |
Dan Marsden | 35f83c0558 | 8 years ago |
Dan Marsden | 374d547a9a | 8 years ago |
Dan Marsden | 700c4b1bfb | 8 years ago |
Dan Marsden | d735461745 | 8 years ago |
Dan Marsden | 8d30f0d8b0 | 8 years ago |
Dan Marsden | 336545792c | 8 years ago |
Dan Marsden | 400776b52c | 8 years ago |
Dan Marsden | 8ccea71898 | 8 years ago |
Dan Marsden | 9b09681b02 | 8 years ago |
Dan Marsden | 2c0fef46a8 | 8 years ago |
Dan Marsden | bb09dd2ff4 | 8 years ago |
Dan Marsden | 441b343d17 | 8 years ago |
Dan Marsden | 3751e7fb44 | 8 years ago |
Dan Marsden | d277d10bb7 | 8 years ago |
Dan Marsden | ac697980a1 | 8 years ago |
Dan Marsden | 984ef55b0a | 8 years ago |
Dan Marsden | 36a10b9eb5 | 8 years ago |
Dan Marsden | a69bdf1d26 | 8 years ago |
Dan Marsden | a642cd8450 | 8 years ago |
Dan Marsden | ffff8251ba | 8 years ago |
Dan Marsden | ac586b83bc | 8 years ago |
Dan Marsden | 63aeaeba69 | 8 years ago |
Dan Marsden | c626c78eae | 8 years ago |
Dan Marsden | 36e2b32a92 | 8 years ago |
Dan Marsden | 664dfe0ca4 | 8 years ago |
Dan Marsden | b4ed81d27c | 8 years ago |
Dan Marsden | 83a9b87f6f | 8 years ago |
Dan Marsden | 6cfeef1b2c | 8 years ago |
Dan Marsden | 82912d8e0a | 8 years ago |
Dan Marsden | aa93cbb0a1 | 8 years ago |
Dan Marsden | 762153972f | 8 years ago |
Dan Marsden | 026b2ee06f | 8 years ago |
Dan Marsden | 26c5c6299f | 8 years ago |
Dan Marsden | 9ae22ff659 | 8 years ago |
Dan Marsden | 9404332ebc | 8 years ago |
Dan Marsden | 503a924386 | 8 years ago |
Dan Marsden | 24da43c6eb | 8 years ago |
Dan Marsden | 311b553543 | 8 years ago |
Dan Marsden | 968dc0e5b7 | 8 years ago |
Dan Marsden | 896d00c99a | 8 years ago |
Dan Marsden | 49650bbbac | 8 years ago |
Dan Marsden | f63b4a62cb | 8 years ago |
Dan Marsden | 8d2967f4c6 | 8 years ago |
Dan Marsden | 45386e0031 | 8 years ago |
Dan Marsden | 2b95e51c05 | 8 years ago |
Dan Marsden | fcb1b97670 | 8 years ago |
Dan Marsden | 9b1a853fff | 8 years ago |
Dan Marsden | 02840a9015 | 8 years ago |
Dan Marsden | 6445dbc3a1 | 8 years ago |
Dan Marsden | cca799d24e | 8 years ago |
Dan Marsden | 349d9f2dcf | 8 years ago |
Dan Marsden | a9960beab1 | 8 years ago |
Dan Marsden | 8c31246a5f | 8 years ago |
Dan Marsden | 4bafe58349 | 8 years ago |
Dan Marsden | bd3e960ded | 8 years ago |
Dan Marsden | 1a5478bc88 | 8 years ago |
Dan Marsden | 117ed9d90e | 8 years ago |
Dan Marsden | 29be4af8b9 | 8 years ago |
Dan Marsden | 148501bd89 | 8 years ago |
Dan Marsden | 5d2676d775 | 8 years ago |
Dan Marsden | f050d089df | 8 years ago |
Dan Marsden | 6f057052f2 | 8 years ago |
64 changed files with 4446 additions and 380 deletions
@ -0,0 +1,35 @@ |
|||||
|
### Date: 2017-June-22 |
||||
|
### Release: 3.3.9 |
||||
|
- New Feature: Allow automatic marking using site logs. |
||||
|
- New Feature: Warn users when attendance drops below threshold. |
||||
|
- Improvement: Allow default view for teachers to be set at admin level. |
||||
|
- Improvement: All courses user report now displays as table. |
||||
|
- Bug fix: Restored attendances do not create calendar events correctly. |
||||
|
|
||||
|
### Date: 2017-May-23 |
||||
|
### Release: 3.3.7 |
||||
|
- New Feature: New site Level/course category report with average course attendance. |
||||
|
- New Feature: Allow unmarked students to be automatically marked when session closes. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
### Date: 2017-May-11 |
||||
|
- New Feature: Allow subnet mask to be set at the attendance session level. |
||||
|
- New Feature: Allow certain statuses to be hidden from students when self-marking attendance. |
||||
|
- New Feature: Allow student password to be viewed on session list page. |
||||
|
- Improvement: Improve usablity by grouping settings on session add form. |
||||
|
- Bug fix - fix issue with displaying dates when site hosted on Windows server. |
||||
|
- Bug fix - improve compliance with Moodle coding guidelines. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
### Date: 2017-Apr-21 |
||||
|
- Feature: Allow a random self-marking password to be used when creating session. |
||||
|
- Improvement: #63 use core useridentity setting when showing list of users. |
||||
|
- Improvement: #258 Add link to attendance on student overview report. |
||||
|
- Improvement: allow student self-marking to be restricted to the session time. |
||||
|
- Improvement: allow admin to set default values when teachers creating new sessions. |
||||
|
- Bug fix - improve compliance with Moodle coding guidelines - phpdocs etc. |
||||
|
|
||||
|
--- |
||||
|
|
@ -0,0 +1,140 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Attendance course summary report. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
require_once('../../config.php'); |
||||
|
require_once($CFG->libdir.'/adminlib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/locallib.php'); |
||||
|
require_once($CFG->libdir.'/tablelib.php'); |
||||
|
require_once($CFG->libdir.'/coursecatlib.php'); |
||||
|
|
||||
|
$category = optional_param('category', 0, PARAM_INT); |
||||
|
$attendancecm = optional_param('id', 0, PARAM_INT); |
||||
|
$download = optional_param('download', '', PARAM_ALPHA); |
||||
|
$sort = optional_param('tsort', 'timesent', PARAM_ALPHA); |
||||
|
|
||||
|
if (!empty($category)) { |
||||
|
$context = context_coursecat::instance($category); |
||||
|
$coursecat = coursecat::get($category); |
||||
|
$courses = $coursecat->get_courses(array('recursive' => true, 'idonly' => true)); |
||||
|
$PAGE->set_category_by_id($category); |
||||
|
require_login(); |
||||
|
} else if (!empty($attendancecm)) { |
||||
|
$cm = get_coursemodule_from_id('attendance', $attendancecm, 0, false, MUST_EXIST); |
||||
|
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); |
||||
|
$att = $DB->get_record('attendance', array('id' => $cm->instance), '*', MUST_EXIST); |
||||
|
$courses = array($course->id); |
||||
|
$context = context_module::instance($cm->id); |
||||
|
require_login($course, false, $cm); |
||||
|
} else { |
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
$context = context_system::instance(); |
||||
|
$courses = array(); // Show all courses. |
||||
|
} |
||||
|
// Check permissions. |
||||
|
require_capability('mod/attendance:viewreports', $context); |
||||
|
|
||||
|
$exportfilename = 'attendance-absentee.csv'; |
||||
|
|
||||
|
$PAGE->set_url('/mod/attendance/absentee.php', array('category' => $category, 'id' => $attendancecm)); |
||||
|
|
||||
|
$PAGE->set_heading($SITE->fullname); |
||||
|
|
||||
|
$table = new flexible_table('attendanceabsentee'); |
||||
|
$table->define_baseurl($PAGE->url); |
||||
|
|
||||
|
if (!$table->is_downloading($download, $exportfilename)) { |
||||
|
if (!empty($attendancecm)) { |
||||
|
$pageparams = new mod_attendance_sessions_page_params(); |
||||
|
$att = new mod_attendance_structure($att, $cm, $course, $context, $pageparams); |
||||
|
$output = $PAGE->get_renderer('mod_attendance'); |
||||
|
$tabs = new attendance_tabs($att, attendance_tabs::TAB_ABSENTEE); |
||||
|
echo $output->header(); |
||||
|
echo $output->heading(get_string('attendanceforthecourse', 'attendance').' :: ' .format_string($course->fullname)); |
||||
|
echo $output->render($tabs); |
||||
|
} else { |
||||
|
echo $OUTPUT->header(); |
||||
|
echo $OUTPUT->heading(get_string('absenteereport', 'mod_attendance')); |
||||
|
if (empty($category)) { |
||||
|
// Only show tabs if displaying via the admin page. |
||||
|
$tabmenu = attendance_print_settings_tabs('absentee'); |
||||
|
echo $tabmenu; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
$table->define_columns(array('coursename', 'aname', 'userid', 'numtakensessions', 'percent', 'timesent')); |
||||
|
$table->define_headers(array(get_string('course'), |
||||
|
get_string('pluginname', 'attendance'), |
||||
|
get_string('user'), |
||||
|
get_string('takensessions', 'attendance'), |
||||
|
get_string('averageattendance', 'attendance'), |
||||
|
get_string('triggered', 'attendance'))); |
||||
|
$table->sortable(true); |
||||
|
$table->set_attribute('cellspacing', '0'); |
||||
|
$table->set_attribute('class', 'generaltable generalbox'); |
||||
|
$table->show_download_buttons_at(array(TABLE_P_BOTTOM)); |
||||
|
$table->setup(); |
||||
|
|
||||
|
// Work out direction of sort required. |
||||
|
$sortcolumns = $table->get_sort_columns(); |
||||
|
// Now do sorting if specified. |
||||
|
|
||||
|
$orderby = ' ORDER BY percent ASC'; |
||||
|
if (!empty($sort)) { |
||||
|
$direction = ' DESC'; |
||||
|
if (!empty($sortcolumns[$sort]) && $sortcolumns[$sort] == SORT_ASC) { |
||||
|
$direction = ' ASC'; |
||||
|
} |
||||
|
$orderby = " ORDER BY $sort $direction"; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
$records = attendance_get_users_to_notify($courses, $orderby); |
||||
|
foreach ($records as $record) { |
||||
|
if (!$table->is_downloading($download, $exportfilename)) { |
||||
|
$url = new moodle_url('/mod/attendance/index.php', array('id' => $record->courseid)); |
||||
|
$name = html_writer::link($url, $record->coursename); |
||||
|
} else { |
||||
|
$name = $record->coursename; |
||||
|
} |
||||
|
$url = new moodle_url('/mod/attendance/view.php', array('studentid' => $record->userid, |
||||
|
'id' => $record->cmid, 'view' => ATT_VIEW_ALL)); |
||||
|
$attendancename = html_writer::link($url, $record->aname); |
||||
|
|
||||
|
$username = html_writer::link($url, fullname($record)); |
||||
|
$percent = round($record->percent * 100)."%"; |
||||
|
$timesent = "-"; |
||||
|
if (!empty($record->timesent)) { |
||||
|
$timesent = userdate($record->timesent); |
||||
|
} |
||||
|
|
||||
|
$table->add_data(array($name, $attendancename, $username, $record->numtakensessions, $percent, $timesent)); |
||||
|
} |
||||
|
$table->finish_output(); |
||||
|
|
||||
|
if (!$table->is_downloading()) { |
||||
|
echo $OUTPUT->footer(); |
||||
|
} |
@ -0,0 +1,113 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Contains class mod_attendance_add_warning_form |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
/** |
||||
|
* Class mod_attendance_add_warning_form |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class mod_attendance_add_warning_form extends moodleform { |
||||
|
/** |
||||
|
* Form definition |
||||
|
*/ |
||||
|
public function definition() { |
||||
|
global $COURSE; |
||||
|
$mform = $this->_form; |
||||
|
|
||||
|
// Load global defaults. |
||||
|
$config = get_config('attendance'); |
||||
|
|
||||
|
$options = array(); |
||||
|
for ($i = 1; $i <= 100; $i++) { |
||||
|
$options[$i] = "$i%"; |
||||
|
} |
||||
|
$mform->addElement('select', 'warningpercent', get_string('warningpercent', 'mod_attendance'), $options); |
||||
|
$mform->addHelpButton('warningpercent', 'warningpercent', 'mod_attendance'); |
||||
|
$mform->setType('warningpercent', PARAM_INT); |
||||
|
$mform->setDefault('warningpercent', $config->warningpercent); |
||||
|
|
||||
|
$options = array(); |
||||
|
for ($i = 1; $i <= ATTENDANCE_MAXWARNAFTER; $i++) { |
||||
|
$options[$i] = "$i"; |
||||
|
} |
||||
|
$mform->addElement('select', 'warnafter', get_string('warnafter', 'mod_attendance'), $options); |
||||
|
$mform->addHelpButton('warnafter', 'warnafter', 'mod_attendance'); |
||||
|
$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); |
||||
|
|
||||
|
$mform->addElement('text', 'emailsubject', get_string('emailsubject', 'mod_attendance'), array('size' => '64')); |
||||
|
$mform->setType('emailsubject', PARAM_TEXT); |
||||
|
$mform->addRule('emailsubject', get_string('maximumchars', '', 255), 'maxlength', 255, 'client'); |
||||
|
$mform->addHelpButton('emailsubject', 'emailsubject', 'mod_attendance'); |
||||
|
$mform->setDefault('emailsubject', $config->emailsubject); |
||||
|
|
||||
|
$mform->addElement('editor', 'emailcontent', get_string('emailcontent', 'mod_attendance'), null, null); |
||||
|
$mform->setDefault('emailcontent', array('text' => format_text($config->emailcontent))); |
||||
|
$mform->setType('emailcontent', PARAM_RAW); |
||||
|
$mform->addHelpButton('emailcontent', 'emailcontent', 'mod_attendance'); |
||||
|
|
||||
|
$users = get_users_by_capability(context_course::instance($COURSE->id), 'mod/attendance:warningemails'); |
||||
|
$options = array(); |
||||
|
foreach ($users as $user) { |
||||
|
$options[$user->id] = fullname($user); |
||||
|
} |
||||
|
|
||||
|
$select = $mform->addElement('searchableselector', 'thirdpartyemails', |
||||
|
get_string('thirdpartyemails', 'mod_attendance'), $options); |
||||
|
$mform->setType('thirdpartyemails', PARAM_TEXT); |
||||
|
$mform->addHelpButton('thirdpartyemails', 'thirdpartyemails', 'mod_attendance'); |
||||
|
$select->setMultiple(true); |
||||
|
|
||||
|
// Need to set hidden elements when adding default options. |
||||
|
$mform->addElement('hidden', 'idnumber', 0); // Default options use 0 as the idnumber. |
||||
|
$mform->setType('idnumber', PARAM_INT); |
||||
|
|
||||
|
$mform->addElement('hidden', 'notid', 0); // The id of warning record. |
||||
|
$mform->setType('notid', PARAM_INT); |
||||
|
|
||||
|
$mform->addElement('hidden', 'id', $this->_customdata['id']); // The id of course module record if attendance level. |
||||
|
$mform->setType('id', PARAM_INT); |
||||
|
|
||||
|
if (!empty($this->_customdata['notid'])) { |
||||
|
$btnstring = get_string('update', 'attendance'); |
||||
|
} else { |
||||
|
$btnstring = get_string('add', 'attendance'); |
||||
|
} |
||||
|
$this->add_action_buttons(true, $btnstring); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,93 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* This file contains an event for when self-marking is blocked because |
||||
|
* another student used the same IP address to self-mark. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Dan Marsden <dan@danmarsden.com> |
||||
|
* @copyright 2018 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
namespace mod_attendance\event; |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
/** |
||||
|
* Event for when self-marking is blocked |
||||
|
* |
||||
|
* @property-read array $other { |
||||
|
* Extra information about event properties. |
||||
|
* |
||||
|
* string mode Mode of the report viewed. |
||||
|
* } |
||||
|
* @package mod_attendance |
||||
|
* @author Dan Marsden <dan@danmarsden.com> |
||||
|
* @copyright 2018 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class session_ip_shared extends \core\event\base { |
||||
|
|
||||
|
/** |
||||
|
* Init method. |
||||
|
*/ |
||||
|
protected function init() { |
||||
|
$this->data['crud'] = 'r'; |
||||
|
$this->data['edulevel'] = self::LEVEL_PARTICIPATING; |
||||
|
$this->data['objecttable'] = 'attendance_log'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns non-localised description of what happened. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function get_description() { |
||||
|
return 'User with id ' . $this->userid . ' was blocked from taking attendance for sessionid: ' . $this->other['sessionid'] . |
||||
|
' because user with id '.$this->other['otheruser'] . ' previously marked attendance with the same IP address.'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns localised general event name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public static function get_name() { |
||||
|
return get_string('eventsessionipshared', 'mod_attendance'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get URL related to the action |
||||
|
* |
||||
|
* @return \moodle_url |
||||
|
*/ |
||||
|
public function get_url() { |
||||
|
return new \moodle_url('/mod/attendance/attendance.php'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get objectid mapping |
||||
|
* |
||||
|
* @return array of parameters for object mapping. |
||||
|
*/ |
||||
|
public static function get_objectid_mapping() { |
||||
|
return array( |
||||
|
'db' => 'attendance', |
||||
|
'restore' => 'attendance' |
||||
|
); |
||||
|
} |
||||
|
} |
@ -0,0 +1,92 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* This file contains an event for when an attendance sessions is imported. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
namespace mod_attendance\event; |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
/** |
||||
|
* Event for when an attendance sessions is imported |
||||
|
* |
||||
|
* @property-read array $other { |
||||
|
* Extra information about event properties. |
||||
|
* |
||||
|
* string mode Mode of the report viewed. |
||||
|
* } |
||||
|
* @package mod_attendance |
||||
|
* @since Moodle 2.7 |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class sessions_imported extends \core\event\base { |
||||
|
|
||||
|
/** |
||||
|
* Init method. |
||||
|
*/ |
||||
|
protected function init() { |
||||
|
$this->data['crud'] = 'c'; |
||||
|
$this->data['edulevel'] = self::LEVEL_OTHER; |
||||
|
$this->data['objecttable'] = 'attendance_sessions'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns non-localised description of what happened. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function get_description() { |
||||
|
return 'User with id ' . $this->userid . ' imported ' . $this->other['count'] . ' sessions'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns localised general event name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public static function get_name() { |
||||
|
return get_string('eventsessionsimported', 'mod_attendance'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get URL related to the action |
||||
|
* |
||||
|
* @return \moodle_url |
||||
|
*/ |
||||
|
public function get_url() { |
||||
|
return new \moodle_url('/mod/attendance/import/sessions.php'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get objectid mapping |
||||
|
* |
||||
|
* @return array of parameters for object mapping. |
||||
|
*/ |
||||
|
public static function get_objectid_mapping() { |
||||
|
return array( |
||||
|
'db' => 'attendance', |
||||
|
'restore' => 'attendance' |
||||
|
); |
||||
|
} |
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* This file contains the form for importing sessions from a file. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
namespace mod_attendance\form\import; |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); |
||||
|
|
||||
|
use core_text; |
||||
|
use csv_import_reader; |
||||
|
use moodleform; |
||||
|
require_once($CFG->libdir . '/formslib.php'); |
||||
|
require_once($CFG->libdir . '/csvlib.class.php'); |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class sessions extends moodleform { |
||||
|
|
||||
|
/** |
||||
|
* Define the form - called by parent constructor |
||||
|
*/ |
||||
|
public function definition() { |
||||
|
global $CFG; |
||||
|
|
||||
|
$mform = $this->_form; |
||||
|
$element = $mform->createElement('filepicker', 'importfile', get_string('importfile', 'mod_attendance')); |
||||
|
$mform->addElement($element); |
||||
|
$mform->addHelpButton('importfile', 'importfile', 'mod_attendance'); |
||||
|
$mform->addRule('importfile', null, 'required'); |
||||
|
$mform->addElement('hidden', 'confirm', 0); |
||||
|
$mform->setType('confirm', PARAM_BOOL); |
||||
|
|
||||
|
$choices = csv_import_reader::get_delimiter_list(); |
||||
|
$mform->addElement('select', 'delimiter_name', get_string('csvdelimiter', 'mod_attendance'), $choices); |
||||
|
if (array_key_exists('cfg', $choices)) { |
||||
|
$mform->setDefault('delimiter_name', 'cfg'); |
||||
|
} else if (get_string('listsep', 'langconfig') == ';') { |
||||
|
$mform->setDefault('delimiter_name', 'semicolon'); |
||||
|
} else { |
||||
|
$mform->setDefault('delimiter_name', 'comma'); |
||||
|
} |
||||
|
|
||||
|
$choices = core_text::get_encodings(); |
||||
|
$mform->addElement('select', 'encoding', get_string('encoding', 'mod_attendance'), $choices); |
||||
|
$mform->setDefault('encoding', 'UTF-8'); |
||||
|
|
||||
|
$this->add_action_buttons(false, get_string('import', 'mod_attendance')); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Display an error on the import form. |
||||
|
* |
||||
|
* @param string $msg |
||||
|
*/ |
||||
|
public function set_import_error($msg) { |
||||
|
$mform = $this->_form; |
||||
|
|
||||
|
$mform->setElementError('importfile', $msg); |
||||
|
} |
||||
|
} |
@ -0,0 +1,73 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
namespace mod_attendance\form\import; |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); |
||||
|
|
||||
|
use moodleform; |
||||
|
require_once($CFG->libdir . '/formslib.php'); |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class sessions_confirm extends moodleform { |
||||
|
|
||||
|
/** |
||||
|
* Define the form - called by parent constructor |
||||
|
*/ |
||||
|
public function definition() { |
||||
|
$importer = $this->_customdata; |
||||
|
|
||||
|
$mform = $this->_form; |
||||
|
$mform->addElement('hidden', 'confirm', 1); |
||||
|
$mform->setType('confirm', PARAM_BOOL); |
||||
|
$mform->addElement('hidden', 'importid', $importer->get_importid()); |
||||
|
$mform->setType('importid', PARAM_INT); |
||||
|
|
||||
|
$requiredheaders = $importer->list_required_headers(); |
||||
|
$foundheaders = $importer->list_found_headers(); |
||||
|
|
||||
|
if (empty($foundheaders)) { |
||||
|
$foundheaders = range(0, count($requiredheaders)); |
||||
|
} |
||||
|
$foundheaders[- 1] = get_string('none'); |
||||
|
|
||||
|
foreach ($requiredheaders as $index => $requiredheader) { |
||||
|
$mform->addElement('select', 'header' . $index, $requiredheader, $foundheaders); |
||||
|
if (isset($foundheaders[$index])) { |
||||
|
$mform->setDefault('header' . $index, $index); |
||||
|
} else { |
||||
|
$mform->setDefault('header' . $index, - 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$this->add_action_buttons(true, get_string('confirm', 'mod_attendance')); |
||||
|
} |
||||
|
} |
@ -0,0 +1,493 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions class. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
namespace mod_attendance\import; |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
use csv_import_reader; |
||||
|
use mod_attendance_notifyqueue; |
||||
|
use mod_attendance_structure; |
||||
|
use stdClass; |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class sessions { |
||||
|
|
||||
|
/** @var string $error The errors message from reading the xml */ |
||||
|
protected $error = ''; |
||||
|
|
||||
|
/** @var array $sessions The sessions info */ |
||||
|
protected $sessions = array(); |
||||
|
|
||||
|
/** @var array $mappings The mappings info */ |
||||
|
protected $mappings = array(); |
||||
|
|
||||
|
/** @var int The id of the csv import */ |
||||
|
protected $importid = 0; |
||||
|
|
||||
|
/** @var csv_import_reader|null $importer */ |
||||
|
protected $importer = null; |
||||
|
|
||||
|
/** @var array $foundheaders */ |
||||
|
protected $foundheaders = array(); |
||||
|
|
||||
|
/** @var bool $useprogressbar Control whether importing should use progress bars or not. */ |
||||
|
protected $useprogressbar = false; |
||||
|
|
||||
|
/** @var \core\progress\display_if_slow|null $progress The progress bar instance. */ |
||||
|
protected $progress = null; |
||||
|
|
||||
|
/** |
||||
|
* Store an error message for display later |
||||
|
* |
||||
|
* @param string $msg |
||||
|
*/ |
||||
|
public function fail($msg) { |
||||
|
$this->error = $msg; |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the CSV import id |
||||
|
* |
||||
|
* @return string The import id. |
||||
|
*/ |
||||
|
public function get_importid() { |
||||
|
return $this->importid; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the list of headers required for import. |
||||
|
* |
||||
|
* @return array The headers (lang strings) |
||||
|
*/ |
||||
|
public static function list_required_headers() { |
||||
|
return array( |
||||
|
get_string('course', 'attendance'), |
||||
|
get_string('groups', 'attendance'), |
||||
|
get_string('sessiondate', 'attendance'), |
||||
|
get_string('from', 'attendance'), |
||||
|
get_string('to', 'attendance'), |
||||
|
get_string('description', 'attendance'), |
||||
|
get_string('repeaton', 'attendance'), |
||||
|
get_string('repeatevery', 'attendance'), |
||||
|
get_string('repeatuntil', 'attendance'), |
||||
|
get_string('studentscanmark', 'attendance'), |
||||
|
get_string('passwordgrp', 'attendance'), |
||||
|
get_string('randompassword', 'attendance'), |
||||
|
get_string('subnet', 'attendance'), |
||||
|
get_string('automark', 'attendance'), |
||||
|
get_string('autoassignstatus', 'attendance'), |
||||
|
get_string('absenteereport', 'attendance'), |
||||
|
get_string('preventsharedip', 'attendance'), |
||||
|
get_string('preventsharediptime', 'attendance') |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the list of headers found in the import. |
||||
|
* |
||||
|
* @return array The found headers (names from import) |
||||
|
*/ |
||||
|
public function list_found_headers() { |
||||
|
return $this->foundheaders; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Read the data from the mapping form. |
||||
|
* |
||||
|
* @param array $data The mapping data. |
||||
|
*/ |
||||
|
protected function read_mapping_data($data) { |
||||
|
if ($data) { |
||||
|
return array( |
||||
|
'course' => $data->header0, |
||||
|
'groups' => $data->header1, |
||||
|
'sessiondate' => $data->header2, |
||||
|
'from' => $data->header3, |
||||
|
'to' => $data->header4, |
||||
|
'description' => $data->header5, |
||||
|
'repeaton' => $data->header6, |
||||
|
'repeatevery' => $data->header7, |
||||
|
'repeatuntil' => $data->header8, |
||||
|
'studentscanmark' => $data->header9, |
||||
|
'passwordgrp' => $data->header10, |
||||
|
'randompassword' => $data->header11, |
||||
|
'subnet' => $data->header12, |
||||
|
'automark' => $data->header13, |
||||
|
'autoassignstatus' => $data->header14, |
||||
|
'absenteereport' => $data->header15, |
||||
|
'preventsharedip' => $data->header16, |
||||
|
'preventsharediptime' => $data->header17, |
||||
|
); |
||||
|
} else { |
||||
|
return array( |
||||
|
'course' => 0, |
||||
|
'groups' => 1, |
||||
|
'sessiondate' => 2, |
||||
|
'from' => 3, |
||||
|
'to' => 4, |
||||
|
'description' => 5, |
||||
|
'repeaton' => 6, |
||||
|
'repeatevery' => 7, |
||||
|
'repeatuntil' => 8, |
||||
|
'studentscanmark' => 9, |
||||
|
'passwordgrp' => 10, |
||||
|
'randompassword' => 11, |
||||
|
'subnet' => 12, |
||||
|
'automark' => 13, |
||||
|
'autoassignstatus' => 14, |
||||
|
'absenteereport' => 15, |
||||
|
'preventsharedip' => 16, |
||||
|
'preventsharediptime' => 17 |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the a column from the imported data. |
||||
|
* |
||||
|
* @param array $row The imported raw row |
||||
|
* @param int $index The column index we want |
||||
|
* @return string The column data. |
||||
|
*/ |
||||
|
protected function get_column_data($row, $index) { |
||||
|
if ($index < 0) { |
||||
|
return ''; |
||||
|
} |
||||
|
return isset($row[$index]) ? $row[$index] : ''; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Constructor - parses the raw text for sanity. |
||||
|
* |
||||
|
* @param string $text The raw csv text. |
||||
|
* @param string $encoding The encoding of the csv file. |
||||
|
* @param string $delimiter The specified delimiter for the file. |
||||
|
* @param string $importid The id of the csv import. |
||||
|
* @param array $mappingdata The mapping data from the import form. |
||||
|
* @param bool $useprogressbar Whether progress bar should be displayed, to avoid html output on CLI. |
||||
|
*/ |
||||
|
public function __construct($text = null, $encoding = null, $delimiter = null, $importid = 0, |
||||
|
$mappingdata = null, $useprogressbar = false) { |
||||
|
global $CFG; |
||||
|
|
||||
|
require_once($CFG->libdir . '/csvlib.class.php'); |
||||
|
|
||||
|
$pluginconfig = get_config('attendance'); |
||||
|
|
||||
|
$type = 'sessions'; |
||||
|
|
||||
|
if (! $importid) { |
||||
|
if ($text === null) { |
||||
|
return; |
||||
|
} |
||||
|
$this->importid = csv_import_reader::get_new_iid($type); |
||||
|
|
||||
|
$this->importer = new csv_import_reader($this->importid, $type); |
||||
|
|
||||
|
if (! $this->importer->load_csv_content($text, $encoding, $delimiter)) { |
||||
|
$this->fail(get_string('invalidimportfile', 'attendance')); |
||||
|
$this->importer->cleanup(); |
||||
|
return; |
||||
|
} |
||||
|
} else { |
||||
|
$this->importid = $importid; |
||||
|
|
||||
|
$this->importer = new csv_import_reader($this->importid, $type); |
||||
|
} |
||||
|
|
||||
|
if (! $this->importer->init()) { |
||||
|
$this->fail(get_string('invalidimportfile', 'attendance')); |
||||
|
$this->importer->cleanup(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
$this->foundheaders = $this->importer->get_columns(); |
||||
|
$this->useprogressbar = $useprogressbar; |
||||
|
$domainid = 1; |
||||
|
|
||||
|
$sessions = array(); |
||||
|
|
||||
|
while ($row = $this->importer->next()) { |
||||
|
// This structure mimics what the UI form returns. |
||||
|
$mapping = $this->read_mapping_data($mappingdata); |
||||
|
|
||||
|
$session = new stdClass(); |
||||
|
$session->course = $this->get_column_data($row, $mapping['course']); |
||||
|
if (empty($session->course)) { |
||||
|
\mod_attendance_notifyqueue::notify_problem(get_string('error:sessioncourseinvalid', 'attendance')); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Handle multiple group assignments per session. Expect semicolon separated group names. |
||||
|
$groups = $this->get_column_data($row, $mapping['groups']); |
||||
|
if (! empty($groups)) { |
||||
|
$session->groups = explode(';', $groups); |
||||
|
$session->sessiontype = \mod_attendance_structure::SESSION_GROUP; |
||||
|
} else { |
||||
|
$session->sessiontype = \mod_attendance_structure::SESSION_COMMON; |
||||
|
} |
||||
|
|
||||
|
// Expect standardised date format, eg YYYY-MM-DD. |
||||
|
$sessiondate = strtotime($this->get_column_data($row, $mapping['sessiondate'])); |
||||
|
if ($sessiondate === false) { |
||||
|
\mod_attendance_notifyqueue::notify_problem(get_string('error:sessiondateinvalid', 'attendance')); |
||||
|
continue; |
||||
|
} |
||||
|
$session->sessiondate = $sessiondate; |
||||
|
|
||||
|
// Expect standardised time format, eg HH:MM. |
||||
|
$from = $this->get_column_data($row, $mapping['from']); |
||||
|
if (empty($from)) { |
||||
|
\mod_attendance_notifyqueue::notify_problem(get_string('error:sessionstartinvalid', 'attendance')); |
||||
|
continue; |
||||
|
} |
||||
|
$from = explode(':', $from); |
||||
|
$session->sestime['starthour'] = $from[0]; |
||||
|
$session->sestime['startminute'] = $from[1]; |
||||
|
|
||||
|
$to = $this->get_column_data($row, $mapping['to']); |
||||
|
if (empty($to)) { |
||||
|
\mod_attendance_notifyqueue::notify_problem(get_string('error:sessionendinvalid', 'attendance')); |
||||
|
continue; |
||||
|
} |
||||
|
$to = explode(':', $to); |
||||
|
$session->sestime['endhour'] = $to[0]; |
||||
|
$session->sestime['endminute'] = $to[1]; |
||||
|
|
||||
|
// Wrap the plain text description in html tags. |
||||
|
$session->sdescription['text'] = '<p>' . $this->get_column_data($row, $mapping['description']) . '</p>'; |
||||
|
$session->sdescription['format'] = FORMAT_HTML; |
||||
|
$session->sdescription['itemid'] = 0; |
||||
|
$session->passwordgrp = $this->get_column_data($row, $mapping['passwordgrp']); |
||||
|
$session->subnet = $this->get_column_data($row, $mapping['subnet']); |
||||
|
// Set session subnet restriction. Use the default activity level subnet if there isn't one set for this session. |
||||
|
if (empty($session->subnet)) { |
||||
|
$session->usedefaultsubnet = '1'; |
||||
|
} else { |
||||
|
$session->usedefaultsubnet = ''; |
||||
|
} |
||||
|
|
||||
|
if ($mapping['studentscanmark'] == -1) { |
||||
|
$session->studentscanmark = $pluginconfig->studentscanmark_default; |
||||
|
} else { |
||||
|
$session->studentscanmark = $this->get_column_data($row, $mapping['studentscanmark']); |
||||
|
} |
||||
|
if ($mapping['randompassword'] == -1) { |
||||
|
$session->randompassword = $pluginconfig->randompassword_default; |
||||
|
} else { |
||||
|
$session->randompassword = $this->get_column_data($row, $mapping['randompassword']); |
||||
|
} |
||||
|
if ($mapping['automark'] == -1) { |
||||
|
$session->automark = $pluginconfig->automark_default; |
||||
|
} else { |
||||
|
$session->automark = $this->get_column_data($row, $mapping['automark']); |
||||
|
} |
||||
|
if ($mapping['autoassignstatus'] == -1) { |
||||
|
$session->autoassignstatus = $pluginconfig->autoassignstatus; |
||||
|
} else { |
||||
|
$session->autoassignstatus = $this->get_column_data($row, $mapping['autoassignstatus']); |
||||
|
} |
||||
|
if ($mapping['absenteereport'] == -1) { |
||||
|
$session->absenteereport = $pluginconfig->absenteereport_default; |
||||
|
} else { |
||||
|
$session->absenteereport = $this->get_column_data($row, $mapping['absenteereport']); |
||||
|
} |
||||
|
if ($mapping['preventsharedip'] == -1) { |
||||
|
$session->preventsharedip = $pluginconfig->preventsharedip; |
||||
|
} else { |
||||
|
$session->preventsharedip = $this->get_column_data($row, $mapping['preventsharedip']); |
||||
|
} |
||||
|
if ($mapping['preventsharediptime'] == -1) { |
||||
|
$session->preventsharediptime = $pluginconfig->preventsharediptime; |
||||
|
} else { |
||||
|
$session->preventsharediptime = $this->get_column_data($row, $mapping['preventsharediptime']); |
||||
|
} |
||||
|
|
||||
|
$session->statusset = 0; |
||||
|
|
||||
|
$sessions[] = $session; |
||||
|
} |
||||
|
$this->sessions = $sessions; |
||||
|
|
||||
|
$this->importer->close(); |
||||
|
if ($this->sessions == null) { |
||||
|
$this->fail(get_string('invalidimportfile', 'attendance')); |
||||
|
return; |
||||
|
} else { |
||||
|
// We are calling from browser, display progress bar. |
||||
|
if ($this->useprogressbar === true) { |
||||
|
$this->progress = new \core\progress\display_if_slow(get_string('processingfile', 'attendance')); |
||||
|
$this->progress->start_html(); |
||||
|
} else { |
||||
|
// Avoid html output on CLI scripts. |
||||
|
$this->progress = new \core\progress\none(); |
||||
|
} |
||||
|
$this->progress->start_progress('', count($this->sessions)); |
||||
|
raise_memory_limit(MEMORY_EXTRA); |
||||
|
$this->progress->end_progress(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get parse errors. |
||||
|
* |
||||
|
* @return array of errors from parsing the xml. |
||||
|
*/ |
||||
|
public function get_error() { |
||||
|
return $this->error; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create sessions using the CSV data. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function import() { |
||||
|
global $DB; |
||||
|
|
||||
|
// Count of sessions added. |
||||
|
$okcount = 0; |
||||
|
|
||||
|
foreach ($this->sessions as $session) { |
||||
|
$groupids = array(); |
||||
|
// Check course shortname matches. |
||||
|
if ($DB->record_exists('course', array( |
||||
|
'shortname' => $session->course |
||||
|
))) { |
||||
|
// Get course. |
||||
|
$course = $DB->get_record('course', array( |
||||
|
'shortname' => $session->course |
||||
|
), '*', MUST_EXIST); |
||||
|
|
||||
|
// Check course has activities. |
||||
|
if ($DB->record_exists('attendance', array( |
||||
|
'course' => $course->id |
||||
|
))) { |
||||
|
// Translate group names to group IDs. They are unique per course. |
||||
|
if ($session->sessiontype === \mod_attendance_structure::SESSION_GROUP) { |
||||
|
foreach ($session->groups as $groupname) { |
||||
|
$gid = groups_get_group_by_name($course->id, $groupname); |
||||
|
if ($gid === false) { |
||||
|
\mod_attendance_notifyqueue::notify_problem(get_string('sessionunknowngroup', |
||||
|
'attendance', $groupname)); |
||||
|
} else { |
||||
|
$groupids[] = $gid; |
||||
|
} |
||||
|
} |
||||
|
$session->groups = $groupids; |
||||
|
} |
||||
|
|
||||
|
// Get activities in course. |
||||
|
$activities = $DB->get_recordset('attendance', array( |
||||
|
'course' => $course->id |
||||
|
), 'id', 'id'); |
||||
|
|
||||
|
foreach ($activities as $activity) { |
||||
|
// Build the session data. |
||||
|
$cm = get_coursemodule_from_instance('attendance', $activity->id, $course->id); |
||||
|
if (!empty($cm->deletioninprogress)) { |
||||
|
// Don't do anything if this attendance is in recycle bin. |
||||
|
continue; |
||||
|
} |
||||
|
$att = new mod_attendance_structure($activity, $cm, $course); |
||||
|
$sessions = attendance_construct_sessions_data_for_add($session, $att); |
||||
|
|
||||
|
foreach ($sessions as $index => $sess) { |
||||
|
// Check for duplicate sessions. |
||||
|
if ($this->session_exists($sess)) { |
||||
|
mod_attendance_notifyqueue::notify_message(get_string('sessionduplicate', 'attendance', (array( |
||||
|
'course' => $session->course, |
||||
|
'activity' => $cm->name |
||||
|
)))); |
||||
|
unset($sessions[$index]); |
||||
|
} else { |
||||
|
$okcount ++; |
||||
|
} |
||||
|
} |
||||
|
if (! empty($sessions)) { |
||||
|
$att->add_sessions($sessions); |
||||
|
} |
||||
|
} |
||||
|
$activities->close(); |
||||
|
} else { |
||||
|
mod_attendance_notifyqueue::notify_problem(get_string('error:coursehasnoattendance', |
||||
|
'attendance', $session->course)); |
||||
|
} |
||||
|
} else { |
||||
|
mod_attendance_notifyqueue::notify_problem(get_string('error:coursenotfound', 'attendance', $session->course)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$message = get_string('sessionsgenerated', 'attendance', $okcount); |
||||
|
if ($okcount < 1) { |
||||
|
mod_attendance_notifyqueue::notify_message($message); |
||||
|
} else { |
||||
|
mod_attendance_notifyqueue::notify_success($message); |
||||
|
} |
||||
|
|
||||
|
// Trigger a sessions imported event. |
||||
|
$event = \mod_attendance\event\sessions_imported::create(array( |
||||
|
'objectid' => 0, |
||||
|
'context' => \context_system::instance(), |
||||
|
'other' => array( |
||||
|
'count' => $okcount |
||||
|
) |
||||
|
)); |
||||
|
|
||||
|
$event->trigger(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check if an identical session exists. |
||||
|
* |
||||
|
* @param stdClass $session |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
private function session_exists(stdClass $session) { |
||||
|
global $DB; |
||||
|
|
||||
|
$check = clone $session; |
||||
|
|
||||
|
// Remove the properties that aren't useful to check. |
||||
|
unset($check->description); |
||||
|
unset($check->descriptionitemid); |
||||
|
unset($check->timemodified); |
||||
|
$check = (array) $check; |
||||
|
|
||||
|
if ($DB->record_exists('attendance_sessions', $check)) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
} |
@ -0,0 +1,230 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Attendance task - auto mark. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
namespace mod_attendance\task; |
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
require_once($CFG->dirroot . '/mod/attendance/locallib.php'); |
||||
|
/** |
||||
|
* get_scores class, used to get scores for submitted files. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @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. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function get_name() { |
||||
|
// Shown in admin screens. |
||||
|
return get_string('automarktask', 'mod_attendance'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Execte the task. |
||||
|
*/ |
||||
|
public function execute() { |
||||
|
global $DB; |
||||
|
// Create some cache vars - might be nice to restructure this and make a smaller number of sql calls. |
||||
|
$cachecm = array(); |
||||
|
$cacheatt = array(); |
||||
|
$cachecourse = array(); |
||||
|
$now = time(); // Store current time to use in queries so they all match nicely. |
||||
|
|
||||
|
$sessions = $DB->get_recordset_select('attendance_sessions', |
||||
|
'automark > 0 AND automarkcompleted < 2 AND sessdate < ? ', array($now)); |
||||
|
|
||||
|
foreach ($sessions as $session) { |
||||
|
if ($session->sessdate + $session->duration < $now || // If session is over. |
||||
|
// OR if session is currently open and automark is set to do all. |
||||
|
($session->sessdate < $now && $session->automark == 1)) { |
||||
|
|
||||
|
$userfirstaccess = array(); |
||||
|
$donesomething = false; // Only trigger grades/events when an update actually occurs. |
||||
|
$sessionover = false; // Is this session over? |
||||
|
if ($session->sessdate + $session->duration < $now) { |
||||
|
$sessionover = true; |
||||
|
} |
||||
|
|
||||
|
// Store cm/att/course in cachefields so we don't make unnecessary db calls. |
||||
|
// Would probably be nice to grab this stuff outside of the loop. |
||||
|
// Make sure this status set has something to setunmarked. |
||||
|
$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)); |
||||
|
} |
||||
|
if (empty($cachecm[$session->attendanceid])) { |
||||
|
$cachecm[$session->attendanceid] = get_coursemodule_from_instance('attendance', |
||||
|
$session->attendanceid, $cacheatt[$session->attendanceid]->course); |
||||
|
} |
||||
|
$courseid = $cacheatt[$session->attendanceid]->course; |
||||
|
if (empty($cachecourse[$courseid])) { |
||||
|
$cachecourse[$courseid] = $DB->get_record('course', array('id' => $courseid)); |
||||
|
} |
||||
|
$context = \context_module::instance($cachecm[$session->attendanceid]->id); |
||||
|
|
||||
|
$pageparams = new \mod_attendance_take_page_params(); |
||||
|
$pageparams->group = $session->groupid; |
||||
|
if (empty($session->groupid)) { |
||||
|
$pageparams->grouptype = 0; |
||||
|
} else { |
||||
|
$pageparams->grouptype = 1; |
||||
|
} |
||||
|
$pageparams->sessionid = $session->id; |
||||
|
|
||||
|
if ($session->automark == 1) { |
||||
|
$userfirstacess = array(); |
||||
|
// If set to do full automarking, get all users that have accessed course during session open. |
||||
|
$id = $DB->sql_concat('userid', 'ip'); // Users may access from multiple ip, make the first field unique. |
||||
|
$sql = "SELECT $id, userid, ip, min(timecreated) as timecreated |
||||
|
FROM {logstore_standard_log} |
||||
|
WHERE courseid = ? AND timecreated > ? AND timecreated < ? |
||||
|
GROUP BY userid, ip"; |
||||
|
|
||||
|
$timestart = $session->sessdate; |
||||
|
if (empty($session->lasttakenby) && $session->lasttaken > $timestart) { |
||||
|
// If the last time session was taken it was done automatically, use the last time taken |
||||
|
// as the start time for the logs we are interested in to help with performance. |
||||
|
$timestart = $session->lasttaken; |
||||
|
} |
||||
|
$duration = $session->duration; |
||||
|
if (empty($duration)) { |
||||
|
$duration = get_config('attendance', 'studentscanmarksessiontimeend') * 60; |
||||
|
} |
||||
|
$timeend = $timestart + $duration; |
||||
|
$logusers = $DB->get_recordset_sql($sql, array($courseid, $timestart, $timeend)); |
||||
|
// Check if user access is in allowed subnet. |
||||
|
foreach ($logusers as $loguser) { |
||||
|
if (!empty($session->subnet) && !address_in_subnet($loguser->ip, $session->subnet)) { |
||||
|
// This record isn't in the right subnet. |
||||
|
continue; |
||||
|
} |
||||
|
if (empty($userfirstaccess[$loguser->userid]) || |
||||
|
$userfirstaccess[$loguser->userid] > $loguser->timecreated) { |
||||
|
// Users may have accessed from mulitple ip addresses, find the earliest access. |
||||
|
$userfirstaccess[$loguser->userid] = $loguser->timecreated; |
||||
|
} |
||||
|
} |
||||
|
$logusers->close(); |
||||
|
} |
||||
|
|
||||
|
// 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)); |
||||
|
$updated = 0; |
||||
|
|
||||
|
foreach ($existinglog as $log) { |
||||
|
if (empty($log->statusid)) { |
||||
|
if ($sessionover || !empty($userfirstaccess[$log->studentid])) { |
||||
|
// Status needs updating. |
||||
|
if ($sessionover) { |
||||
|
$log->statusid = $setunmarked; |
||||
|
} else if (!empty($userfirstaccess[$log->studentid])) { |
||||
|
$log->statusid = $att->get_automark_status($userfirstaccess[$log->studentid], $session->id); |
||||
|
} |
||||
|
if (!empty($log->statusid)) { |
||||
|
$log->timetaken = $now; |
||||
|
$log->takenby = 0; |
||||
|
$log->remarks = get_string('autorecorded', 'attendance'); |
||||
|
|
||||
|
$DB->update_record('attendance_log', $log); |
||||
|
$updated++; |
||||
|
$donesomething = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
unset($users[$log->studentid]); |
||||
|
} |
||||
|
$existinglog->close(); |
||||
|
mtrace($updated . " session status updated"); |
||||
|
|
||||
|
$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())); |
||||
|
|
||||
|
$added = 0; |
||||
|
foreach ($users as $user) { |
||||
|
if ($sessionover || !empty($userfirstaccess[$user->id])) { |
||||
|
if ($sessionover) { |
||||
|
$newlog->statusid = $setunmarked; |
||||
|
} else if (!empty($userfirstaccess[$user->id])) { |
||||
|
$newlog->statusid = $att->get_automark_status($userfirstaccess[$user->id], $session->id); |
||||
|
} |
||||
|
if (!empty($newlog->statusid)) { |
||||
|
$newlog->studentid = $user->id; |
||||
|
$DB->insert_record('attendance_log', $newlog); |
||||
|
$added++; |
||||
|
$donesomething = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
mtrace($added . " session status inserted"); |
||||
|
|
||||
|
// Update lasttaken time and automarkcompleted for this session. |
||||
|
$session->lasttaken = $now; |
||||
|
$session->lasttakenby = 0; |
||||
|
if ($sessionover) { |
||||
|
$session->automarkcompleted = 2; |
||||
|
} else { |
||||
|
$session->automarkcompleted = 1; |
||||
|
} |
||||
|
|
||||
|
$DB->update_record('attendance_sessions', $session); |
||||
|
|
||||
|
if ($donesomething) { |
||||
|
if ($att->grade != 0) { |
||||
|
$att->update_users_grade(array_keys($users)); |
||||
|
} |
||||
|
|
||||
|
$params = array( |
||||
|
'sessionid' => $att->pageparams->sessionid, |
||||
|
'grouptype' => $att->pageparams->grouptype); |
||||
|
$event = \mod_attendance\event\attendance_taken::create(array( |
||||
|
'objectid' => $att->id, |
||||
|
'context' => $att->context, |
||||
|
'other' => $params)); |
||||
|
$event->add_record_snapshot('course_modules', $att->cm); |
||||
|
$event->add_record_snapshot('attendance_sessions', $session); |
||||
|
$event->trigger(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,158 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Attendance task - Send warnings. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
namespace mod_attendance\task; |
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
require_once($CFG->dirroot . '/mod/attendance/locallib.php'); |
||||
|
/** |
||||
|
* Task class |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class notify extends \core\task\scheduled_task { |
||||
|
/** |
||||
|
* Returns localised general event name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function get_name() { |
||||
|
// Shown in admin screens. |
||||
|
return get_string('notifytask', 'mod_attendance'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Execute the task. |
||||
|
*/ |
||||
|
public function execute() { |
||||
|
global $DB; |
||||
|
if (empty(get_config('attendance', 'enablewarnings'))) { |
||||
|
return; // Warnings not enabled. |
||||
|
} |
||||
|
$now = time(); // Store current time to use in queries so they all match nicely. |
||||
|
|
||||
|
$orderby = 'ORDER BY cm.id, atl.studentid, n.warningpercent ASC'; |
||||
|
|
||||
|
// 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; |
||||
|
$numsentthird = 0; |
||||
|
foreach ($records as $record) { |
||||
|
if (empty($sentnotifications[$record->userid])) { |
||||
|
$sentnotifications[$record->userid] = array(); |
||||
|
} |
||||
|
|
||||
|
if (!empty($record->emailuser)) { |
||||
|
// 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)); |
||||
|
$from = \core_user::get_noreply_user(); |
||||
|
$oldforcelang = force_current_language($user->lang); |
||||
|
|
||||
|
$emailcontent = format_text($record->emailcontent, $record->emailcontentformat); |
||||
|
$emailsubject = format_text($record->emailsubject, FORMAT_HTML); |
||||
|
email_to_user($user, $from, $emailsubject, $emailcontent, $emailcontent); |
||||
|
|
||||
|
force_current_language($oldforcelang); |
||||
|
$sentnotifications[$record->userid][] = $record->aid; |
||||
|
$numsentusers++; |
||||
|
} |
||||
|
} |
||||
|
// Only send one warning to this user from each attendance in this run. - flag any higher percent notifications as sent. |
||||
|
if (!empty($record->thirdpartyemails)) { |
||||
|
$sendto = explode(',', $record->thirdpartyemails); |
||||
|
$record->percent = round($record->percent * 100)."%"; |
||||
|
$context = \context_module::instance($record->cmid); |
||||
|
foreach ($sendto as $senduser) { |
||||
|
if (empty($senduser)) { |
||||
|
// Probably an extra comma in the thirdpartyusers field. |
||||
|
continue; |
||||
|
} |
||||
|
// Check user is allowed to receive warningemails. |
||||
|
if (has_capability('mod/attendance:warningemails', $context, $senduser)) { |
||||
|
if (empty($thirdpartynotifications[$senduser])) { |
||||
|
$thirdpartynotifications[$senduser] = array(); |
||||
|
} |
||||
|
if (!isset($thirdpartynotifications[$senduser][$record->aid . '_' . $record->userid])) { |
||||
|
$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; |
||||
|
$notify->timesent = $now; |
||||
|
$DB->insert_record('attendance_warning_done', $notify); |
||||
|
} |
||||
|
if (!empty($numsentusers)) { |
||||
|
mtrace($numsentusers ." user emails sent"); |
||||
|
} |
||||
|
if (!empty($thirdpartynotifications)) { |
||||
|
foreach ($thirdpartynotifications as $sendid => $notifications) { |
||||
|
$user = $DB->get_record('user', array('id' => $sendid)); |
||||
|
$from = \core_user::get_noreply_user(); |
||||
|
$oldforcelang = force_current_language($user->lang); |
||||
|
|
||||
|
$emailcontent = implode("\n", $notifications); |
||||
|
$emailcontent .= "\n\n".get_string('thirdpartyemailtextfooter', 'attendance'); |
||||
|
$emailcontent = format_text($emailcontent); |
||||
|
$emailsubject = get_string('thirdpartyemailsubject', 'attendance'); |
||||
|
|
||||
|
email_to_user($user, $from, $emailsubject, $emailcontent, $emailcontent); |
||||
|
force_current_language($oldforcelang); |
||||
|
$numsentthird++; |
||||
|
} |
||||
|
if (!empty($numsentthird)) { |
||||
|
mtrace($numsentthird ." thirdparty emails sent"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,124 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Attendance course summary report. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
require_once('../../config.php'); |
||||
|
require_once($CFG->libdir.'/adminlib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/locallib.php'); |
||||
|
require_once($CFG->libdir.'/tablelib.php'); |
||||
|
require_once($CFG->libdir.'/coursecatlib.php'); |
||||
|
|
||||
|
$category = optional_param('category', 0, PARAM_INT); |
||||
|
$download = optional_param('download', '', PARAM_ALPHA); |
||||
|
$sort = optional_param('tsort', '', PARAM_ALPHA); |
||||
|
$fromcourse = optional_param('fromcourse', 0, PARAM_INT); |
||||
|
|
||||
|
$admin = false; |
||||
|
if (empty($fromcourse)) { |
||||
|
$admin = true; |
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
} else { |
||||
|
require_login($fromcourse); |
||||
|
} |
||||
|
|
||||
|
if (empty($category)) { |
||||
|
$context = context_system::instance(); |
||||
|
$courses = array(); // Show all courses. |
||||
|
} else { |
||||
|
$context = context_coursecat::instance($category); |
||||
|
$coursecat = coursecat::get($category); |
||||
|
$courses = $coursecat->get_courses(array('recursive' => true, 'idonly' => true)); |
||||
|
} |
||||
|
// Check permissions. |
||||
|
require_capability('mod/attendance:viewsummaryreports', $context); |
||||
|
|
||||
|
$exportfilename = 'attendancecoursesummary.csv'; |
||||
|
|
||||
|
$PAGE->set_url('/mod/attendance/coursesummary.php', array('category' => $category)); |
||||
|
|
||||
|
$PAGE->set_heading($SITE->fullname); |
||||
|
|
||||
|
$table = new flexible_table('attendancecoursesummary'); |
||||
|
$table->define_baseurl($PAGE->url); |
||||
|
|
||||
|
if (!$table->is_downloading($download, $exportfilename)) { |
||||
|
echo $OUTPUT->header(); |
||||
|
$heading = get_string('coursesummary', 'mod_attendance'); |
||||
|
if (!empty($category)) { |
||||
|
$heading .= " (".$coursecat->name.")"; |
||||
|
} |
||||
|
echo $OUTPUT->heading($heading); |
||||
|
if ($admin) { |
||||
|
// Only show tabs if displaying via the admin page. |
||||
|
$tabmenu = attendance_print_settings_tabs('coursesummary'); |
||||
|
echo $tabmenu; |
||||
|
} |
||||
|
$url = new moodle_url('/mod/attendance/coursesummary.php', array('category' => $category, 'fromcourse' => $fromcourse)); |
||||
|
|
||||
|
if ($admin) { |
||||
|
$options = coursecat::make_categories_list('mod/attendance:viewsummaryreports'); |
||||
|
echo $OUTPUT->single_select($url, 'category', $options, $category); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
$table->define_columns(array('course', 'percentage')); |
||||
|
$table->define_headers(array(get_string('course'), |
||||
|
get_string('averageattendance', 'attendance'))); |
||||
|
$table->sortable(true); |
||||
|
$table->no_sorting('course'); |
||||
|
$table->set_attribute('cellspacing', '0'); |
||||
|
$table->set_attribute('class', 'generaltable generalbox'); |
||||
|
$table->show_download_buttons_at(array(TABLE_P_BOTTOM)); |
||||
|
$table->setup(); |
||||
|
|
||||
|
// Work out direction of sort required. |
||||
|
$sortcolumns = $table->get_sort_columns(); |
||||
|
// Now do sorting if specified. |
||||
|
|
||||
|
$orderby = ' ORDER BY percentage ASC'; |
||||
|
if (!empty($sort)) { |
||||
|
$direction = ' DESC'; |
||||
|
if (!empty($sortcolumns[$sort]) && $sortcolumns[$sort] == SORT_ASC) { |
||||
|
$direction = ' ASC'; |
||||
|
} |
||||
|
$orderby = " ORDER BY $sort $direction"; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
$records = attendance_course_users_points($courses, $orderby); |
||||
|
foreach ($records as $record) { |
||||
|
if (!$table->is_downloading($download, $exportfilename)) { |
||||
|
$url = new moodle_url('/mod/attendance/index.php', array('id' => $record->courseid)); |
||||
|
$name = html_writer::link($url, $record->coursename); |
||||
|
} else { |
||||
|
$name = $record->coursename; |
||||
|
} |
||||
|
$table->add_data(array($name, round($record->percentage * 100)."%")); |
||||
|
} |
||||
|
$table->finish_output(); |
||||
|
|
||||
|
if (!$table->is_downloading()) { |
||||
|
echo $OUTPUT->footer(); |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Attendance module tasks. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
$tasks = array( |
||||
|
array( |
||||
|
'classname' => 'mod_attendance\task\auto_mark', |
||||
|
'blocking' => 0, |
||||
|
'minute' => '8', |
||||
|
'hour' => '*', |
||||
|
'day' => '*', |
||||
|
'dayofweek' => '*', |
||||
|
'month' => '*'), |
||||
|
array( |
||||
|
'classname' => 'mod_attendance\task\notify', |
||||
|
'blocking' => 0, |
||||
|
'minute' => '30', |
||||
|
'hour' => '1', |
||||
|
'day' => '*', |
||||
|
'dayofweek' => '*', |
||||
|
'month' => '*') |
||||
|
); |
@ -0,0 +1,94 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Import attendance sessions. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Chris Wharton <chriswharton@catalyst.net.nz> |
||||
|
* @copyright 2017 Catalyst IT |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
define('NO_OUTPUT_BUFFERING', true); |
||||
|
|
||||
|
require_once(__DIR__ . '/../../../config.php'); |
||||
|
require_once($CFG->libdir . '/adminlib.php'); |
||||
|
require_once($CFG->dirroot . '/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot . '/mod/attendance/locallib.php'); |
||||
|
|
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
$pagetitle = get_string('importsessions', 'attendance'); |
||||
|
|
||||
|
$context = context_system::instance(); |
||||
|
|
||||
|
$url = new moodle_url('/mod/attendance/import/sessions.php'); |
||||
|
|
||||
|
$PAGE->set_context($context); |
||||
|
$PAGE->set_url($url); |
||||
|
$PAGE->set_title($pagetitle); |
||||
|
$PAGE->set_pagelayout('admin'); |
||||
|
$PAGE->set_heading($pagetitle); |
||||
|
|
||||
|
echo $OUTPUT->header(); |
||||
|
echo $OUTPUT->heading(get_string('importsessions', 'attendance')); |
||||
|
$tabmenu = attendance_print_settings_tabs('importsessions'); |
||||
|
echo $tabmenu; |
||||
|
|
||||
|
$form = null; |
||||
|
if (optional_param('needsconfirm', 0, PARAM_BOOL)) { |
||||
|
$form = new \mod_attendance\form\import\sessions($url->out(false)); |
||||
|
} else if (optional_param('confirm', 0, PARAM_BOOL)) { |
||||
|
$importer = new \mod_attendance\import\sessions(); |
||||
|
$form = new \mod_attendance\form\import\sessions_confirm(null, $importer); |
||||
|
} else { |
||||
|
$form = new \mod_attendance\form\import\sessions($url->out(false)); |
||||
|
} |
||||
|
|
||||
|
if ($form->is_cancelled()) { |
||||
|
$form = new \mod_attendance\form\import\sessions($url->out(false)); |
||||
|
} else if ($data = $form->get_data()) { |
||||
|
require_sesskey(); |
||||
|
if ($data->confirm) { |
||||
|
$importid = $data->importid; |
||||
|
$importer = new \mod_attendance\import\sessions(null, null, null, $importid, $data, true); |
||||
|
|
||||
|
$error = $importer->get_error(); |
||||
|
if ($error) { |
||||
|
$form = new \mod_attendance\form\import\sessions($url->out(false)); |
||||
|
$form->set_import_error($error); |
||||
|
} else { |
||||
|
$sessions = $importer->import(); |
||||
|
mod_attendance_notifyqueue::show(); |
||||
|
echo $OUTPUT->continue_button($url); |
||||
|
die(); |
||||
|
} |
||||
|
} else { |
||||
|
$text = $form->get_file_content('importfile'); |
||||
|
$encoding = $data->encoding; |
||||
|
$delimiter = $data->delimiter_name; |
||||
|
$importer = new \mod_attendance\import\sessions($text, $encoding, $delimiter, 0, null, true); |
||||
|
$confirmform = new \mod_attendance\form\import\sessions_confirm(null, $importer); |
||||
|
$form = $confirmform; |
||||
|
$pagetitle = get_string('confirmcolumnmappings', 'attendance'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
echo $OUTPUT->heading($pagetitle); |
||||
|
|
||||
|
$form->display(); |
||||
|
|
||||
|
echo $OUTPUT->footer(); |
@ -0,0 +1,51 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Displays help via AJAX call or in a new page |
||||
|
* |
||||
|
* Use {@link core_renderer::help_icon()} or {@link addHelpButton()} to display |
||||
|
* the help icon. |
||||
|
* |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @package mod_attendance |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
require_once(dirname(__FILE__).'/../../config.php'); |
||||
|
|
||||
|
$session = required_param('session', PARAM_INT); |
||||
|
$session = $DB->get_record('attendance_sessions', array('id' => $session), '*', MUST_EXIST); |
||||
|
|
||||
|
$cm = get_coursemodule_from_instance('attendance', $session->attendanceid); |
||||
|
require_login($cm->course, $cm); |
||||
|
|
||||
|
$context = context_module::instance($cm->id); |
||||
|
$capabilities = array('mod/attendance:manageattendances', 'mod/attendance:takeattendances', 'mod/attendance:changeattendances'); |
||||
|
if (!has_any_capability($capabilities, $context)) { |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
$PAGE->set_url('/mod/attendance/password.php'); |
||||
|
$PAGE->set_pagelayout('popup'); |
||||
|
|
||||
|
$PAGE->set_context(context_system::instance()); |
||||
|
|
||||
|
$PAGE->set_title(get_string('password', 'attendance')); |
||||
|
|
||||
|
echo $OUTPUT->header(); |
||||
|
echo html_writer::span($session->studentpassword, 'student-password'); |
||||
|
echo $OUTPUT->footer(); |
@ -0,0 +1,50 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Displays help via AJAX call or in a new page |
||||
|
* |
||||
|
* Use {@link core_renderer::help_icon()} or {@link addHelpButton()} to display |
||||
|
* the help icon. |
||||
|
* |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @package mod_attendance |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
define('AJAX_SCRIPT', true); |
||||
|
require_once(dirname(__FILE__).'/../../config.php'); |
||||
|
|
||||
|
$session = required_param('session', PARAM_INT); |
||||
|
$session = $DB->get_record('attendance_sessions', array('id' => $session), '*', MUST_EXIST); |
||||
|
|
||||
|
$cm = get_coursemodule_from_instance('attendance', $session->attendanceid); |
||||
|
require_login($cm->course, $cm); |
||||
|
|
||||
|
$context = context_module::instance($cm->id); |
||||
|
$capabilities = array('mod/attendance:manageattendances', 'mod/attendance:takeattendances', 'mod/attendance:changeattendances'); |
||||
|
if (!has_any_capability($capabilities, $context)) { |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
$PAGE->set_url('/mod/attendance/password.php'); |
||||
|
$PAGE->set_pagelayout('popup'); |
||||
|
|
||||
|
$PAGE->set_context(context_system::instance()); |
||||
|
|
||||
|
$data->heading = ''; |
||||
|
$data->text = html_writer::span($session->studentpassword, 'student-password'); |
||||
|
|
||||
|
echo json_encode($data); |
Before Width: | Height: | Size: 638 B After Width: | Height: | Size: 638 B |
@ -0,0 +1,92 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Reset Calendar events. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 onwards Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
require_once('../../config.php'); |
||||
|
require_once($CFG->libdir.'/adminlib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/locallib.php'); |
||||
|
|
||||
|
$action = optional_param('action', '', PARAM_ALPHA); |
||||
|
|
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
$context = context_system::instance(); |
||||
|
|
||||
|
// Check permissions. |
||||
|
require_capability('mod/attendance:viewreports', $context); |
||||
|
|
||||
|
$exportfilename = 'attendance-absentee.csv'; |
||||
|
|
||||
|
$PAGE->set_url('/mod/attendance/resetcalendar.php'); |
||||
|
|
||||
|
$PAGE->set_heading($SITE->fullname); |
||||
|
|
||||
|
echo $OUTPUT->header(); |
||||
|
echo $OUTPUT->heading(get_string('resetcalendar', 'mod_attendance')); |
||||
|
$tabmenu = attendance_print_settings_tabs('resetcalendar'); |
||||
|
echo $tabmenu; |
||||
|
|
||||
|
if (get_config('attendance', 'enablecalendar')) { |
||||
|
// Check to see if all sessions have calendar events. |
||||
|
if ($action == 'create' && confirm_sesskey()) { |
||||
|
$sessions = $DB->get_recordset('attendance_sessions', array('caleventid' => 0)); |
||||
|
foreach ($sessions as $session) { |
||||
|
attendance_create_calendar_event($session); |
||||
|
if ($session->caleventid) { |
||||
|
$DB->update_record('attendance_sessions', $session); |
||||
|
} |
||||
|
} |
||||
|
$sessions->close(); |
||||
|
echo $OUTPUT->notification(get_string('eventscreated', 'mod_attendance'), 'notifysuccess'); |
||||
|
} else { |
||||
|
if ($DB->record_exists('attendance_sessions', array('caleventid' => 0))) { |
||||
|
$createurl = new moodle_url('/mod/attendance/resetcalendar.php', array('action' => 'create')); |
||||
|
$returnurl = new moodle_url('/admin/settings.php', array('section' => 'modsettingattendance')); |
||||
|
|
||||
|
echo $OUTPUT->confirm(get_string('resetcaledarcreate', 'mod_attendance'), $createurl, $returnurl); |
||||
|
} else { |
||||
|
echo $OUTPUT->box(get_string("noeventstoreset", "mod_attendance")); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
if ($action == 'delete' && confirm_sesskey()) { |
||||
|
$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'); |
||||
|
} else { |
||||
|
// Check to see if there are any events that need to be deleted. |
||||
|
if ($DB->record_exists_select('attendance_sessions', 'caleventid > 0')) { |
||||
|
$deleteurl = new moodle_url('/mod/attendance/resetcalendar.php', array('action' => 'delete')); |
||||
|
$returnurl = new moodle_url('/admin/settings.php', array('section' => 'modsettingattendance')); |
||||
|
|
||||
|
echo $OUTPUT->confirm(get_string('resetcaledardelete', 'mod_attendance'), $deleteurl, $returnurl); |
||||
|
} else { |
||||
|
echo $OUTPUT->box(get_string("noeventstoreset", "mod_attendance")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
echo $OUTPUT->footer(); |
@ -0,0 +1,21 @@ |
|||||
|
{{! |
||||
|
@template attendance/attendance_password_icon |
||||
|
|
||||
|
attendance_password icon. |
||||
|
|
||||
|
Example context (json): |
||||
|
{ |
||||
|
"title": "Help with something", |
||||
|
"url": "http://example.org/help", |
||||
|
"linktext": "", |
||||
|
"icon":{ |
||||
|
"attributes": [ |
||||
|
{"name": "src", "value": "../pix/key.svg"}, |
||||
|
{"name": "alt", "value": "Password icon"} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}} |
||||
|
<span class="helptooltip"> |
||||
|
<a href="{{url}}" title={{#quote}}{{title}}{{/quote}} aria-haspopup="true" target="_blank">{{#icon}}{{>core/pix_icon}}{{/icon}}{{#linktext}}{{.}}{{/linktext}}</a> |
||||
|
</span> |
@ -0,0 +1,28 @@ |
|||||
|
{{! |
||||
|
@template attendance/attendance_password_icon Boost Example. |
||||
|
This is an example of a template you could copy into a boost based theme to use proper popover. |
||||
|
At the moment we cannot specify different templates to use in plugin so we use |
||||
|
a cross-compatible link based pop-up for the password. |
||||
|
|
||||
|
attendance_password icon. |
||||
|
|
||||
|
Example context (json): |
||||
|
{ |
||||
|
"title": "Help with something", |
||||
|
"url": "http://example.org/help", |
||||
|
"linktext": "", |
||||
|
"icon":{ |
||||
|
"attributes": [ |
||||
|
{"name": "class", "value": "iconhelp"}, |
||||
|
{"name": "src", "value": "../../../pix/help.svg"}, |
||||
|
{"name": "alt", "value": "Help icon"} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}} |
||||
|
<a class="btn btn-link p-a-0" role="button" |
||||
|
data-container="body" data-toggle="popover" |
||||
|
data-placement="{{#ltr}}left{{/ltr}}{{^ltr}}right{{/ltr}}" data-content="<span class='student-pass'>{{text}}</span> {{completedoclink}}" |
||||
|
data-html="true" tabindex="0" data-trigger="focus"> |
||||
|
{{#pix}}key, attendance, {{alt}}{{/pix}} |
||||
|
</a> |
@ -0,0 +1,203 @@ |
|||||
|
<?php |
||||
|
// This file is part of Moodle - http://moodle.org/ |
||||
|
// |
||||
|
// Moodle is free software: you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation, either version 3 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// Moodle is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
/** |
||||
|
* Allows default warnings to be modified. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden http://danmarsden.com |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
require_once(__DIR__.'/../../config.php'); |
||||
|
require_once($CFG->libdir.'/adminlib.php'); |
||||
|
require_once($CFG->libdir.'/formslib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/locallib.php'); |
||||
|
|
||||
|
$action = optional_param('action', '', PARAM_ALPHA); |
||||
|
$notid = optional_param('notid', 0, PARAM_INT); |
||||
|
$id = optional_param('id', 0, PARAM_INT); |
||||
|
|
||||
|
$url = new moodle_url('/mod/attendance/warnings.php'); |
||||
|
|
||||
|
// This page is used for configuring default set and for configuring attendance level set. |
||||
|
if (empty($id)) { |
||||
|
// This is the default status set - show appropriate admin stuff and check admin permissions. |
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
|
||||
|
$output = $PAGE->get_renderer('mod_attendance'); |
||||
|
echo $OUTPUT->header(); |
||||
|
echo $OUTPUT->heading(get_string('defaultwarnings', 'mod_attendance')); |
||||
|
$tabmenu = attendance_print_settings_tabs('defaultwarnings'); |
||||
|
echo $tabmenu; |
||||
|
|
||||
|
} else { |
||||
|
// This is an attendance level config. |
||||
|
$cm = get_coursemodule_from_id('attendance', $id, 0, false, MUST_EXIST); |
||||
|
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); |
||||
|
$att = $DB->get_record('attendance', array('id' => $cm->instance), '*', MUST_EXIST); |
||||
|
|
||||
|
require_login($course, false, $cm); |
||||
|
$context = context_module::instance($cm->id); |
||||
|
require_capability('mod/attendance:changepreferences', $context); |
||||
|
|
||||
|
$att = new mod_attendance_structure($att, $cm, $course, $PAGE->context); |
||||
|
|
||||
|
$PAGE->set_url($url); |
||||
|
$PAGE->set_title($course->shortname. ": ".$att->name); |
||||
|
$PAGE->set_heading($course->fullname); |
||||
|
$PAGE->navbar->add($att->name); |
||||
|
|
||||
|
$output = $PAGE->get_renderer('mod_attendance'); |
||||
|
$tabs = new attendance_tabs($att, attendance_tabs::TAB_WARNINGS); |
||||
|
echo $output->header(); |
||||
|
echo $output->heading(get_string('attendanceforthecourse', 'attendance').' :: ' .format_string($course->fullname)); |
||||
|
echo $output->render($tabs); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
$mform = new mod_attendance_add_warning_form($url, array('notid' => $notid, 'id' => $id)); |
||||
|
|
||||
|
if ($data = $mform->get_data()) { |
||||
|
if (empty($data->notid)) { |
||||
|
// Insert new record. |
||||
|
$notify = new stdClass(); |
||||
|
if (empty($id)) { |
||||
|
$notify->idnumber = 0; |
||||
|
} else { |
||||
|
$notify->idnumber = $att->id; |
||||
|
} |
||||
|
|
||||
|
$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']; |
||||
|
$notify->emailcontentformat = $data->emailcontent['format']; |
||||
|
$notify->thirdpartyemails = ''; |
||||
|
if (!empty($data->thirdpartyemails)) { |
||||
|
$notify->thirdpartyemails = implode(',', $data->thirdpartyemails); |
||||
|
} |
||||
|
$existingrecord = $DB->record_exists('attendance_warning', array('idnumber' => $notify->idnumber, |
||||
|
'warningpercent' => $notify->warningpercent, |
||||
|
'warnafter' => $notify->warnafter)); |
||||
|
if (empty($existingrecord)) { |
||||
|
$DB->insert_record('attendance_warning', $notify); |
||||
|
echo $OUTPUT->notification(get_string('warningupdated', 'mod_attendance'), 'success'); |
||||
|
} else { |
||||
|
echo $OUTPUT->notification(get_string('warningfailed', 'mod_attendance'), 'warning'); |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
$notify = $DB->get_record('attendance_warning', array('id' => $data->notid)); |
||||
|
if (!empty($id) && $data->idnumber != $att->id) { |
||||
|
// Someone is trying to update a record for a different attendance. |
||||
|
print_error('invalidcoursemodule'); |
||||
|
} else { |
||||
|
$notify = new stdClass(); |
||||
|
$notify->id = $data->notid; |
||||
|
$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']; |
||||
|
$notify->emailcontent = $data->emailcontent['text']; |
||||
|
$notify->thirdpartyemails = ''; |
||||
|
if (!empty($data->thirdpartyemails)) { |
||||
|
$notify->thirdpartyemails = implode(',', $data->thirdpartyemails); |
||||
|
} |
||||
|
$existingrecord = $DB->get_record('attendance_warning', array('idnumber' => $notify->idnumber, |
||||
|
'warningpercent' => $notify->warningpercent, 'warnafter' => $notify->warnafter)); |
||||
|
if (empty($existingrecord) || $existingrecord->id == $notify->id) { |
||||
|
$DB->update_record('attendance_warning', $notify); |
||||
|
echo $OUTPUT->notification(get_string('warningupdated', 'mod_attendance'), 'success'); |
||||
|
} else { |
||||
|
echo $OUTPUT->notification(get_string('warningfailed', 'mod_attendance'), 'error'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if ($action == 'delete' && !empty($notid)) { |
||||
|
if (!optional_param('confirm', false, PARAM_BOOL)) { |
||||
|
$cancelurl = $url; |
||||
|
$url->params(array('action' => 'delete', 'notid' => $notid, 'sesskey' => sesskey(), 'confirm' => true, 'id' => $id)); |
||||
|
echo $OUTPUT->confirm(get_string('deletewarningconfirm', 'mod_attendance'), $url, $cancelurl); |
||||
|
echo $OUTPUT->footer(); |
||||
|
exit; |
||||
|
} else { |
||||
|
require_sesskey(); |
||||
|
$params = array('id' => $notid); |
||||
|
if (!empty($att)) { |
||||
|
// Add id/level to array. |
||||
|
$params['idnumber'] = $att->id; |
||||
|
} |
||||
|
$DB->delete_records('attendance_warning', $params); |
||||
|
echo $OUTPUT->notification(get_string('warningdeleted', 'mod_attendance'), 'success'); |
||||
|
} |
||||
|
} |
||||
|
if ($action == 'update' && !empty($notid)) { |
||||
|
$existing = $DB->get_record('attendance_warning', array('id' => $notid)); |
||||
|
$content = $existing->emailcontent; |
||||
|
$existing->emailcontent = array(); |
||||
|
$existing->emailcontent['text'] = $content; |
||||
|
$existing->emailcontent['format'] = $existing->emailcontentformat; |
||||
|
$existing->notid = $existing->id; |
||||
|
$existing->id = $id; |
||||
|
$mform->set_data($existing); |
||||
|
$mform->display(); |
||||
|
} else if ($action == 'add' && confirm_sesskey()) { |
||||
|
$mform->display(); |
||||
|
} else { |
||||
|
if (empty($id)) { |
||||
|
$warningdesc = get_string('warningdesc', 'mod_attendance'); |
||||
|
$idnumber = 0; |
||||
|
} else { |
||||
|
$warningdesc = get_string('warningdesc_course', 'mod_attendance'); |
||||
|
$idnumber = $att->id; |
||||
|
} |
||||
|
echo $OUTPUT->box($warningdesc, 'generalbox attendancedesc', 'notice'); |
||||
|
$existingnotifications = $DB->get_records('attendance_warning', |
||||
|
array('idnumber' => $idnumber), |
||||
|
'warningpercent'); |
||||
|
|
||||
|
if (!empty($existingnotifications)) { |
||||
|
$table = new html_table(); |
||||
|
$table->head = array(get_string('warningthreshold', 'mod_attendance'), |
||||
|
get_string('numsessions', 'mod_attendance'), |
||||
|
get_string('emailsubject', 'mod_attendance'), |
||||
|
''); |
||||
|
foreach ($existingnotifications as $notification) { |
||||
|
$url->params(array('action' => 'delete', 'notid' => $notification->id, 'id' => $id)); |
||||
|
$actionbuttons = $OUTPUT->action_icon($url, new pix_icon('t/delete', |
||||
|
get_string('delete', 'attendance')), null, null); |
||||
|
$url->params(array('action' => 'update', 'notid' => $notification->id, 'id' => $id)); |
||||
|
$actionbuttons .= $OUTPUT->action_icon($url, new pix_icon('t/edit', |
||||
|
get_string('update', 'attendance')), null, null); |
||||
|
$table->data[] = array($notification->warningpercent, $notification->warnafter, |
||||
|
$notification->emailsubject, $actionbuttons); |
||||
|
} |
||||
|
echo html_writer::table($table); |
||||
|
} |
||||
|
$addurl = new moodle_url('/mod/attendance/warnings.php', array('action' => 'add', 'id' => $id)); |
||||
|
echo $OUTPUT->single_button($addurl, get_string('addwarning', 'mod_attendance')); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
echo $OUTPUT->footer(); |
Loading…
Reference in new issue