Compare commits
176 Commits
40-behatfi
...
MOODLE_32_
Author | SHA1 | Date |
---|---|---|
Morgan Harris | de770cd85e | 6 years ago |
Dan Marsden | 2a4a6e346f | 6 years ago |
Dan Marsden | 9fed2b2b56 | 6 years ago |
Dan Marsden | 67a4d16038 | 6 years ago |
Tõnis Tartes | 90648f0797 | 6 years ago |
Dan Marsden | 73ef68c1e2 | 6 years ago |
Dan Marsden | b9e65039e1 | 7 years ago |
Dan Marsden | 6f96016904 | 7 years ago |
Dan Marsden | 0de2abeede | 7 years ago |
Dan Marsden | 95d90eb931 | 7 years ago |
Dan Marsden | 7fd0d7770b | 7 years ago |
Dan Marsden | 7ee4db4c64 | 7 years ago |
Dan Marsden | 6479912c3b | 7 years ago |
Dan Marsden | 297edb8d8c | 7 years ago |
Dan Marsden | 9befe0c66c | 7 years ago |
Dan Marsden | 267a947b41 | 7 years ago |
Dan Marsden | 6798c344c8 | 7 years ago |
Dan Marsden | dc94a0ed54 | 7 years ago |
Dan Marsden | 52363e7b89 | 7 years ago |
Dan Marsden | 5597f5f0ce | 7 years ago |
Nick Phillips | b365a6facb | 7 years ago |
Nick Phillips | 2941e69810 | 7 years ago |
Dan Marsden | 6462700904 | 7 years ago |
Nick Phillips | 7a5a69df23 | 7 years ago |
Dan Marsden | 377c0b5408 | 7 years ago |
Dan Marsden | 69dc833194 | 7 years ago |
Dan Marsden | f045c7f34d | 7 years ago |
Dan Marsden | 3a700014c8 | 7 years ago |
Dan Marsden | bed019e33d | 7 years ago |
Dan Marsden | 561cccb681 | 7 years ago |
Dan Marsden | c33127770f | 7 years ago |
Dan Marsden | 464e0d1c5d | 7 years ago |
Dan Marsden | ab8a5455be | 7 years ago |
Dan Marsden | 25e3f42638 | 7 years ago |
Dan Marsden | d72613065f | 7 years ago |
Dan Marsden | 5f405665f7 | 7 years ago |
Dan Marsden | f6902c2bc6 | 7 years ago |
Dan Marsden | f8ab61f9f4 | 7 years ago |
Dan Marsden | 66acd7e0ef | 7 years ago |
Dan Marsden | ebaef74abf | 7 years ago |
Dan Marsden | c17174598f | 7 years ago |
Dan Marsden | 0e1e449109 | 7 years ago |
Dan Marsden | b3ed9f6217 | 7 years ago |
Dan Marsden | bb30545010 | 7 years ago |
Dan Marsden | a55eadcc72 | 7 years ago |
Dan Marsden | 7fb1fbfd01 | 7 years ago |
James Voong | d69d70172e | 7 years ago |
Dan Marsden | 109a1f02af | 7 years ago |
Dan Marsden | 2c5a2c8e89 | 7 years ago |
Dan Marsden | ec75d8095b | 7 years ago |
Dan Marsden | c38a02cd0e | 7 years ago |
Dan Marsden | 39732e8c2f | 7 years ago |
Dan Marsden | 11362ad458 | 7 years ago |
Chris Wharton | c1f1f9f765 | 7 years ago |
Dan Marsden | 105ae71bf1 | 7 years ago |
Dan Marsden | b88244a706 | 7 years ago |
Dan Marsden | 2e8387442c | 7 years ago |
Dan Marsden | 9bb37e5668 | 7 years ago |
Dan Marsden | c56313c9f6 | 7 years ago |
Dan Marsden | 8d8322229e | 7 years ago |
Dan Marsden | c0a1d50e52 | 7 years ago |
Dan Marsden | b64c0ead61 | 7 years ago |
Dan Marsden | 9b71d5ee4d | 7 years ago |
Dan Marsden | 9c13beca74 | 7 years ago |
Dan Marsden | 96fb1017f7 | 7 years ago |
Dan Marsden | fe20e88964 | 7 years ago |
Dan Marsden | bf7e16f2c9 | 7 years ago |
Dan Marsden | 37f5a2735f | 7 years ago |
Dan Marsden | c75a060d65 | 7 years ago |
Dan Marsden | 5ce7ee488c | 7 years ago |
Dan Marsden | 9488a5585b | 7 years ago |
Dan Marsden | e8f7cbcc0b | 8 years ago |
Dan Marsden | d8357769cc | 8 years ago |
Dan Marsden | fc3078ecd3 | 8 years ago |
Dan Marsden | afe0a72e7f | 8 years ago |
Dan Marsden | b9c07817f6 | 8 years ago |
Dan Marsden | d9c1236772 | 8 years ago |
Dan Marsden | 2aea1988e9 | 8 years ago |
Dan Marsden | 9f2251c315 | 8 years ago |
Dan Marsden | ea32a3535f | 8 years ago |
Dan Marsden | 4bbed2c160 | 8 years ago |
Dan Marsden | e2580f491d | 8 years ago |
Dan Marsden | 332ee78344 | 8 years ago |
Dan Marsden | 782f4086e0 | 8 years ago |
Dan Marsden | a27adac3e9 | 8 years ago |
Dan Marsden | 3260294bfe | 8 years ago |
Dan Marsden | 9fc4221a81 | 8 years ago |
Dan Marsden | ad6919e3ec | 8 years ago |
Dan Marsden | e487adaccc | 8 years ago |
Dan Marsden | 49b7ca4999 | 8 years ago |
Dan Marsden | 296a696904 | 8 years ago |
Dan Marsden | 181cd6234b | 8 years ago |
Dan Marsden | 60a2f79bbb | 8 years ago |
Dan Marsden | a985d1dab3 | 8 years ago |
Dan Marsden | 2eb0517644 | 8 years ago |
Dan Marsden | 39644e9476 | 8 years ago |
Dan Marsden | 70e1bb6e59 | 8 years ago |
Dan Marsden | 18d46879c5 | 8 years ago |
Dan Marsden | 478d7fee2c | 8 years ago |
Dan Marsden | 2d9fb84dd1 | 8 years ago |
Dan Marsden | ae91534ddc | 8 years ago |
Dan Marsden | bf93d84aa9 | 8 years ago |
Dan Marsden | 959f576025 | 8 years ago |
Dan Marsden | 34183f0c5c | 8 years ago |
Dan Marsden | 5547855ad0 | 8 years ago |
Dan Marsden | f8420243ff | 8 years ago |
Dan Marsden | 1e65aa6785 | 8 years ago |
Dan Marsden | f6b5190fe0 | 8 years ago |
Dan Marsden | 5337794927 | 8 years ago |
Dan Marsden | 201601e359 | 8 years ago |
Dan Marsden | 39f2b19832 | 8 years ago |
Dan Marsden | 8a94c10a09 | 8 years ago |
Dan Marsden | 35c1712ed4 | 8 years ago |
Dan Marsden | 38f5469cf6 | 8 years ago |
Dan Marsden | 70569a53df | 8 years ago |
Dan Marsden | 8fdf17d30f | 8 years ago |
Dan Marsden | 7ca915eb68 | 8 years ago |
Dan Marsden | 17f51afaf1 | 8 years ago |
Dan Marsden | 142bafb5ef | 8 years ago |
Dan Marsden | 142fc543cc | 8 years ago |
Dan Marsden | 2d9c88224c | 8 years ago |
Dan Marsden | eccf8784d1 | 8 years ago |
Dan Marsden | af7d666777 | 8 years ago |
Dan Marsden | f34760ca17 | 8 years ago |
Dan Marsden | 9eaf63b746 | 8 years ago |
Dan Marsden | d4498ccebe | 8 years ago |
Dan Marsden | 00ce366a41 | 8 years ago |
Dan Marsden | e89c46aaa9 | 8 years ago |
Dan Marsden | f2df0d239e | 8 years ago |
Dan Marsden | 3569d778d5 | 8 years ago |
Dan Marsden | 40721dc1d5 | 8 years ago |
Dan Marsden | 22a98145cf | 8 years ago |
Dan Marsden | be48371a17 | 8 years ago |
Dan Marsden | 913c35aa35 | 8 years ago |
Dan Marsden | c668a63213 | 8 years ago |
Dan Marsden | 1617ce7cdd | 8 years ago |
Dan Marsden | 9de4a283fe | 8 years ago |
Dan Marsden | f9c61f4efc | 8 years ago |
Dan Marsden | c6739acf7f | 8 years ago |
Dan Marsden | 9766cae6ef | 8 years ago |
Dan Marsden | c55d38af16 | 8 years ago |
Dan Marsden | 6122dc179d | 8 years ago |
Dan Marsden | 848e1f6349 | 8 years ago |
Dan Marsden | 92ddadb87f | 8 years ago |
Dan Marsden | d73402bf7a | 8 years ago |
Dan Marsden | 67fc97868d | 8 years ago |
Dan Marsden | 4ad3201de8 | 8 years ago |
Dan Marsden | 2e0bfea6bf | 8 years ago |
Dan Marsden | d5618de89d | 8 years ago |
Dan Marsden | 25e3f2f7a0 | 8 years ago |
Dan Marsden | cc8db5bab9 | 8 years ago |
Dan Marsden | 4ba19a86ca | 8 years ago |
Dan Marsden | 51751271f1 | 8 years ago |
Dan Marsden | fb96b30c29 | 8 years ago |
Dan Marsden | f1311f3cf2 | 8 years ago |
Dan Marsden | 84d0609ac6 | 8 years ago |
Dan Marsden | 8ca6c26f96 | 8 years ago |
Dan Marsden | c2282bc6ae | 8 years ago |
Dan Marsden | 6d8c2c2418 | 8 years ago |
Dan Marsden | 9bf96ab3bc | 8 years ago |
Dan Marsden | 0e31f6796a | 8 years ago |
Dan Marsden | 73011e5bdb | 8 years ago |
Dan Marsden | f02845a616 | 8 years ago |
Dan Marsden | 1936ddf929 | 8 years ago |
Dan Marsden | 64e6df0154 | 8 years ago |
Dan Marsden | 7c3845ae58 | 8 years ago |
Daniel Thee Roperto | b79dac055f | 8 years ago |
Dan Marsden | a624a59139 | 8 years ago |
Dan Marsden | 4a7789f1df | 8 years ago |
Dan Marsden | 682ce4af85 | 8 years ago |
Dan Marsden | 27095c459e | 8 years ago |
Dan Marsden | 9ef35c4ea4 | 8 years ago |
Dan Marsden | 49714bf427 | 8 years ago |
Dan Marsden | eef7cf7afe | 8 years ago |
Dan Marsden | 6895d64c92 | 8 years ago |
Dan Marsden | 4cff027414 | 8 years ago |
84 changed files with 6784 additions and 989 deletions
@ -0,0 +1,35 @@ |
|||||
|
### Date: 2017-June-22 |
||||
|
### Release: 3.2.14 |
||||
|
- 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.2.12 |
||||
|
- 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,80 @@ |
|||||
|
<?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/>. |
||||
|
|
||||
|
/** |
||||
|
* Class definition for mod_attendance_header |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net> |
||||
|
* @copyright 2017 Catalyst IT Australia {@link http://www.catalyst-au.net} |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
/** |
||||
|
* Used to render the page header. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net> |
||||
|
* @copyright 2017 Catalyst IT Australia {@link http://www.catalyst-au.net} |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class mod_attendance_header implements renderable { |
||||
|
/** @var mod_attendance_structure */ |
||||
|
private $attendance; |
||||
|
|
||||
|
/** @var string */ |
||||
|
private $title; |
||||
|
|
||||
|
/** |
||||
|
* mod_attendance_header constructor. |
||||
|
* |
||||
|
* @param mod_attendance_structure $attendance |
||||
|
* @param null $title |
||||
|
*/ |
||||
|
public function __construct(mod_attendance_structure $attendance, $title = null) { |
||||
|
$this->attendance = $attendance; |
||||
|
$this->title = $title; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Gets the attendance data. |
||||
|
* |
||||
|
* @return mod_attendance_structure |
||||
|
*/ |
||||
|
public function get_attendance() { |
||||
|
return $this->attendance; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Gets the title. If title was not provided, use the module name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function get_title() { |
||||
|
return is_null($this->title) ? $this->attendance->name : $this->title; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks if the header should be rendered. |
||||
|
* |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function should_render() { |
||||
|
return !is_null($this->title) || !empty($this->attendance->intro); |
||||
|
} |
||||
|
} |
@ -0,0 +1,497 @@ |
|||||
|
<?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->repeaton = $this->get_column_data($row, $mapping['repeaton']); |
||||
|
$session->repeatevery = $this->get_column_data($row, $mapping['repeatevery']); |
||||
|
$session->repeatuntil = $this->get_column_data($row, $mapping['repeatuntil']); |
||||
|
$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,57 @@ |
|||||
|
<?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/>. |
||||
|
|
||||
|
/** |
||||
|
* Event observers supported by this module |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
/** |
||||
|
* Event observers supported by this module |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
class mod_attendance_observer { |
||||
|
|
||||
|
/** |
||||
|
* Observer for the event course_content_deleted - delete all attendance stuff. |
||||
|
* |
||||
|
* @param \core\event\course_content_deleted $event |
||||
|
*/ |
||||
|
public static function course_content_deleted(\core\event\course_content_deleted $event) { |
||||
|
global $DB; |
||||
|
|
||||
|
$attids = array_keys($DB->get_records('attendance', array('course' => $event->objectid), '', 'id')); |
||||
|
$sessids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id')); |
||||
|
if (attendance_existing_calendar_events_ids($sessids)) { |
||||
|
attendance_delete_calendar_events($sessids); |
||||
|
} |
||||
|
if ($sessids) { |
||||
|
$DB->delete_records_list('attendance_log', 'sessionid', $sessids); |
||||
|
} |
||||
|
if ($attids) { |
||||
|
$DB->delete_records_list('attendance_statuses', 'attendanceid', $attids); |
||||
|
$DB->delete_records_list('attendance_sessions', 'attendanceid', $attids); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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,36 @@ |
|||||
|
<?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 event handler definition. |
||||
|
* |
||||
|
* @package mod_attendance |
||||
|
* @category event |
||||
|
* @copyright 2017 Dan Marsden |
||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
||||
|
*/ |
||||
|
|
||||
|
defined('MOODLE_INTERNAL') || die(); |
||||
|
|
||||
|
// List of observers. |
||||
|
$observers = array( |
||||
|
|
||||
|
array( |
||||
|
'eventname' => '\core\event\course_content_deleted', |
||||
|
'callback' => 'mod_attendance_observer::course_content_deleted', |
||||
|
), |
||||
|
|
||||
|
); |
@ -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,131 @@ |
|||||
|
<?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 status set 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->dirroot.'/mod/attendance/lib.php'); |
||||
|
require_once($CFG->dirroot.'/mod/attendance/locallib.php'); |
||||
|
|
||||
|
$action = optional_param('action', null, PARAM_INT); |
||||
|
$statusid = optional_param('statusid', null, PARAM_INT); |
||||
|
admin_externalpage_setup('managemodules'); |
||||
|
$url = new moodle_url('/mod/attendance/defaultstatus.php', array('statusid' => $statusid, 'action' => $action)); |
||||
|
|
||||
|
// Check sesskey if we are performing an action. |
||||
|
if (!empty($action)) { |
||||
|
require_sesskey(); |
||||
|
} |
||||
|
|
||||
|
$output = $PAGE->get_renderer('mod_attendance'); |
||||
|
echo $OUTPUT->header(); |
||||
|
echo $OUTPUT->heading(get_string('defaultstatus', 'mod_attendance')); |
||||
|
$tabmenu = attendance_print_settings_tabs('defaultstatus'); |
||||
|
echo $tabmenu; |
||||
|
|
||||
|
// TODO: Would be good to combine this code block with the one in preferences to avoid duplication. |
||||
|
$errors = array(); |
||||
|
switch ($action) { |
||||
|
case mod_attendance_preferences_page_params::ACTION_ADD: |
||||
|
$newacronym = optional_param('newacronym', null, PARAM_TEXT); |
||||
|
$newdescription = optional_param('newdescription', null, PARAM_TEXT); |
||||
|
$newgrade = optional_param('newgrade', 0, PARAM_RAW); |
||||
|
$newstudentavailability = optional_param('newstudentavailability', null, PARAM_INT); |
||||
|
$newgrade = unformat_float($newgrade); |
||||
|
|
||||
|
// Default value uses setnumber/attendanceid = 0. |
||||
|
$status = new stdClass(); |
||||
|
$status->attendanceid = 0; |
||||
|
$status->acronym = $newacronym; |
||||
|
$status->description = $newdescription; |
||||
|
$status->grade = $newgrade; |
||||
|
$status->studentavailability = $newstudentavailability; |
||||
|
$status->setnumber = 0; |
||||
|
attendance_add_status($status); |
||||
|
|
||||
|
break; |
||||
|
case mod_attendance_preferences_page_params::ACTION_DELETE: |
||||
|
$confirm = optional_param('confirm', null, PARAM_INT); |
||||
|
$statuses = attendance_get_statuses(0, false); |
||||
|
$status = $statuses[$statusid]; |
||||
|
|
||||
|
if (isset($confirm)) { |
||||
|
attendance_remove_status($status); |
||||
|
echo $OUTPUT->notification(get_string('statusdeleted', 'attendance'), 'success'); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
$message = get_string('deletecheckfull', '', get_string('variable', 'attendance')); |
||||
|
$message .= str_repeat(html_writer::empty_tag('br'), 2); |
||||
|
$message .= $status->acronym.': '. |
||||
|
($status->description ? $status->description : get_string('nodescription', 'attendance')); |
||||
|
$confirmurl = $url; |
||||
|
$confirmurl->param('confirm', 1); |
||||
|
|
||||
|
echo $OUTPUT->confirm($message, $confirmurl, $url); |
||||
|
echo $OUTPUT->footer(); |
||||
|
exit; |
||||
|
case mod_attendance_preferences_page_params::ACTION_HIDE: |
||||
|
$statuses = attendance_get_statuses(0, false); |
||||
|
$status = $statuses[$statusid]; |
||||
|
attendance_update_status($status, null, null, null, 0); |
||||
|
break; |
||||
|
case mod_attendance_preferences_page_params::ACTION_SHOW: |
||||
|
$statuses = attendance_get_statuses(0, false); |
||||
|
$status = $statuses[$statusid]; |
||||
|
attendance_update_status($status, null, null, null, 1); |
||||
|
break; |
||||
|
case mod_attendance_preferences_page_params::ACTION_SAVE: |
||||
|
$acronym = required_param_array('acronym', PARAM_TEXT); |
||||
|
$description = required_param_array('description', PARAM_TEXT); |
||||
|
$grade = required_param_array('grade', PARAM_RAW); |
||||
|
$studentavailability = optional_param_array('studentavailability', '0', PARAM_RAW); |
||||
|
$unmarkedstatus = optional_param('setunmarked', null, PARAM_INT); |
||||
|
foreach ($grade as &$val) { |
||||
|
$val = unformat_float($val); |
||||
|
} |
||||
|
$statuses = attendance_get_statuses(0, false); |
||||
|
|
||||
|
foreach ($acronym as $id => $v) { |
||||
|
$status = $statuses[$id]; |
||||
|
$setunmarked = false; |
||||
|
if ($unmarkedstatus == $id) { |
||||
|
$setunmarked = true; |
||||
|
} |
||||
|
if (!isset($studentavailability[$id]) || !is_numeric($studentavailability[$id])) { |
||||
|
$studentavailability[$id] = 0; |
||||
|
} |
||||
|
$errors[$id] = attendance_update_status($status, $acronym[$id], $description[$id], $grade[$id], |
||||
|
null, null, null, $studentavailability[$id], $setunmarked); |
||||
|
} |
||||
|
echo $OUTPUT->notification(get_string('eventstatusupdated', 'attendance'), 'success'); |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
$statuses = attendance_get_statuses(0, false); |
||||
|
$prefdata = new attendance_default_statusset($statuses, $errors); |
||||
|
echo $output->render($prefdata); |
||||
|
|
||||
|
echo $OUTPUT->footer(); |
@ -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 |
File diff suppressed because it is too large
@ -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,31 @@ |
|||||
|
@mod @mod_attendance |
||||
|
Feature: Admin can set default status set for use in new attendance |
||||
|
|
||||
|
Background: |
||||
|
Given the following "courses" exist: |
||||
|
| fullname | shortname | summary | category | timecreated | timemodified | |
||||
|
| Course 1 | C1 | Prove the attendance activity works | 0 | ##yesterday## | ##yesterday## | |
||||
|
And the following "users" exist: |
||||
|
| username | firstname | lastname | email | |
||||
|
| teacher1 | Teacher | 1 | teacher1@example.com | |
||||
|
And the following "course enrolments" exist: |
||||
|
| course | user | role | timestart | |
||||
|
| C1 | teacher1 | editingteacher | ##yesterday## | |
||||
|
And I log in as "admin" |
||||
|
And I navigate to "Attendance" node in "Site administration > Plugins" |
||||
|
And I follow "Default status set" |
||||
|
And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[2]/td[3]/input" to "customstatusdescription" |
||||
|
And I click on "Update" "button" in the "#preferencesform" "css_element" |
||||
|
And I should see "Status updated" |
||||
|
And I log out |
||||
|
|
||||
|
@javascript |
||||
|
Scenario: Modified default status set added to new attendance |
||||
|
Given I log in as "teacher1" |
||||
|
And I follow "Course 1" |
||||
|
And I turn editing mode on |
||||
|
And I add a "Attendance" to section "1" and I fill the form with: |
||||
|
| Name | Attendance1 | |
||||
|
And I follow "Attendance1" |
||||
|
And I follow "Status set" |
||||
|
Then the field with xpath "//*[@id='preferencesform']/table/tbody/tr[2]/td[3]/input" matches value "customstatusdescription" |
@ -1,242 +1,250 @@ |
|||||
@javascript @mod @uon @mod_attendance |
@javascript @mod @uon @mod_attendance |
||||
Feature: Visiting reports |
Feature: Visiting reports |
||||
As a teacher I visit the reports |
As a teacher I visit the reports |
||||
|
|
||||
Background: |
Background: |
||||
Given the following "courses" exist: |
Given the following "courses" exist: |
||||
| fullname | shortname | summary | category | timecreated | timemodified | |
| fullname | shortname | summary | category | timecreated | timemodified | |
||||
| Course 1 | C1 | Prove the attendance activity works | 0 | ##yesterday## | ##yesterday## | |
| Course 1 | C1 | Prove the attendance activity works | 0 | ##yesterday## | ##yesterday## | |
||||
And the following "users" exist: |
And the following "users" exist: |
||||
| username | firstname | lastname | email | idnumber | department | institution | |
| username | firstname | lastname | email | idnumber | department | institution | |
||||
| student1 | Student | 1 | student1@asd.com | 1234 | computer science | University of Nottingham | |
| student1 | Student | 1 | student1@asd.com | 1234 | computer science | University of Nottingham | |
||||
| teacher1 | Teacher | 1 | teacher1@asd.com | 5678 | computer science | University of Nottingham | |
| teacher1 | Teacher | 1 | teacher1@asd.com | 5678 | computer science | University of Nottingham | |
||||
And the following "course enrolments" exist: |
And the following "course enrolments" exist: |
||||
| course | user | role | timestart | |
| course | user | role | timestart | |
||||
| C1 | student1 | student | ##yesterday## | |
| C1 | student1 | student | ##yesterday## | |
||||
| C1 | teacher1 | editingteacher | ##yesterday## | |
| C1 | teacher1 | editingteacher | ##yesterday## | |
||||
|
And the following config values are set as admin: |
||||
And I log in as "teacher1" |
| enablewarnings | 1 | attendance | |
||||
And I follow "Course 1" |
And I log in as "teacher1" |
||||
And I turn editing mode on |
And I follow "Course 1" |
||||
And I add a "Attendance" to section "1" and I fill the form with: |
And I turn editing mode on |
||||
| Name | Attendance | |
And I add a "Attendance" to section "1" and I fill the form with: |
||||
And I follow "Attendance" |
| Name | Attendance | |
||||
And I follow "Add a block" |
And I follow "Attendance" |
||||
And I follow "Administration" |
And I follow "Add a block" |
||||
And I follow "Add session" |
And I follow "Administration" |
||||
And I set the following fields to these values: |
And I follow "Add session" |
||||
| id_sestime_starthour | 01 | |
And I set the following fields to these values: |
||||
| id_sestime_endhour | 02 | |
| id_sestime_starthour | 01 | |
||||
And I click on "id_submitbutton" "button" |
| id_sestime_endhour | 02 | |
||||
|
And I click on "id_submitbutton" "button" |
||||
And I log out |
And I follow "Warnings set" |
||||
|
And I press "Add warning" |
||||
Scenario: Teacher takes attendance |
And I set the following fields to these values: |
||||
When I log in as "teacher1" |
| id_warningpercent | 84 | |
||||
And I follow "Course 1" |
| id_warnafter | 2 | |
||||
And I follow "Attendance" |
And I click on "id_submitbutton" "button" |
||||
And I follow "Edit settings" |
And I log out |
||||
Then I set the following fields to these values: |
|
||||
| id_grade_modgrade_type | Point | |
Scenario: Teacher takes attendance |
||||
| id_grade_modgrade_point | 50 | |
When I log in as "teacher1" |
||||
And I press "Save and display" |
And I follow "Course 1" |
||||
|
And I follow "Attendance" |
||||
When I follow "Report" |
And I follow "Edit settings" |
||||
Then "0 / 0" "text" should exist in the "Student 1" "table_row" |
Then I set the following fields to these values: |
||||
And "0.0%" "text" should exist in the "Student 1" "table_row" |
| id_grade_modgrade_type | Point | |
||||
|
| id_grade_modgrade_point | 50 | |
||||
When I follow "Grades" in the user menu |
And I press "Save and display" |
||||
And I follow "Course 1" |
|
||||
And "-" "text" should exist in the "Student 1" "table_row" |
When I follow "Report" |
||||
|
Then "0 / 0" "text" should exist in the "Student 1" "table_row" |
||||
When I follow "Attendance" |
And "0.0%" "text" should exist in the "Student 1" "table_row" |
||||
Then I click on "Take attendance" "link" in the "1am - 2am" "table_row" |
|
||||
# Late |
When I follow "Grades" in the user menu |
||||
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
And I follow "Course 1" |
||||
And I press "Save attendance" |
And "-" "text" should exist in the "Student 1" "table_row" |
||||
|
|
||||
When I follow "Report" |
When I follow "Attendance" |
||||
Then "1 / 2" "text" should exist in the "Student 1" "table_row" |
Then I click on "Take attendance" "link" in the "1AM - 2AM" "table_row" |
||||
And "50.0%" "text" should exist in the "Student 1" "table_row" |
# Late |
||||
|
And I click on "td.c4 input" "css_element" in the "Student 1" "table_row" |
||||
When I follow "Grades" in the user menu |
And I press "Save attendance" |
||||
And I follow "Course 1" |
|
||||
And "25.00" "text" should exist in the "Student 1" "table_row" |
When I follow "Report" |
||||
|
Then "1 / 2" "text" should exist in the "Student 1" "table_row" |
||||
And I log out |
And "50.0%" "text" should exist in the "Student 1" "table_row" |
||||
|
|
||||
Scenario: Teacher changes the maximum points in the attendance settings |
When I follow "Grades" in the user menu |
||||
When I log in as "teacher1" |
And I follow "Course 1" |
||||
And I follow "Course 1" |
And "25.00" "text" should exist in the "Student 1" "table_row" |
||||
And I follow "Attendance" |
|
||||
And I follow "Edit settings" |
And I log out |
||||
Then I set the following fields to these values: |
|
||||
| id_grade_modgrade_type | Point | |
Scenario: Teacher changes the maximum points in the attendance settings |
||||
| id_grade_modgrade_point | 50 | |
When I log in as "teacher1" |
||||
And I press "Save and display" |
And I follow "Course 1" |
||||
|
And I follow "Attendance" |
||||
When I follow "Attendance" |
And I follow "Edit settings" |
||||
Then I click on "Take attendance" "link" in the "1am - 2am" "table_row" |
Then I set the following fields to these values: |
||||
# Excused |
| id_grade_modgrade_type | Point | |
||||
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
| id_grade_modgrade_point | 50 | |
||||
And I press "Save attendance" |
And I press "Save and display" |
||||
|
|
||||
When I follow "Attendance" |
When I follow "Attendance" |
||||
And I follow "Edit settings" |
Then I click on "Take attendance" "link" in the "1AM - 2AM" "table_row" |
||||
Then I set the following fields to these values: |
# Excused |
||||
| id_grade_modgrade_type | Point | |
And I click on "td.c4 input" "css_element" in the "Student 1" "table_row" |
||||
| id_grade_modgrade_point | 70 | |
And I press "Save attendance" |
||||
And I press "Save and display" |
|
||||
|
When I follow "Attendance" |
||||
When I follow "Report" |
And I follow "Edit settings" |
||||
Then "1 / 2" "text" should exist in the "Student 1" "table_row" |
Then I set the following fields to these values: |
||||
And "50.0%" "text" should exist in the "Student 1" "table_row" |
| id_grade_modgrade_type | Point | |
||||
|
| id_grade_modgrade_point | 70 | |
||||
When I follow "Grades" in the user menu |
And I press "Save and display" |
||||
And I follow "Course 1" |
|
||||
Then "35.00" "text" should exist in the "Student 1" "table_row" |
When I follow "Report" |
||||
|
Then "1 / 2" "text" should exist in the "Student 1" "table_row" |
||||
And I log out |
And "50.0%" "text" should exist in the "Student 1" "table_row" |
||||
|
|
||||
Scenario: Teacher take attendance of group session |
When I follow "Grades" in the user menu |
||||
Given the following "groups" exist: |
And I follow "Course 1" |
||||
| course | name | idnumber | |
Then "35.00" "text" should exist in the "Student 1" "table_row" |
||||
| C1 | Group1 | Group1 | |
|
||||
And the following "group members" exist: |
And I log out |
||||
| group | user | |
|
||||
| Group1 | student1 | |
Scenario: Teacher take attendance of group session |
||||
|
Given the following "groups" exist: |
||||
When I log in as "teacher1" |
| course | name | idnumber | |
||||
And I follow "Course 1" |
| C1 | Group1 | Group1 | |
||||
And I follow "Attendance" |
And the following "group members" exist: |
||||
And I follow "Edit settings" |
| group | user | |
||||
And I set the following fields to these values: |
| Group1 | student1 | |
||||
| id_grade_modgrade_type | Point | |
|
||||
| id_grade_modgrade_point | 50 | |
When I log in as "teacher1" |
||||
| id_groupmode | Visible groups | |
And I follow "Course 1" |
||||
And I press "Save and display" |
And I follow "Attendance" |
||||
|
And I follow "Edit settings" |
||||
When I follow "Attendance" |
And I set the following fields to these values: |
||||
Then I click on "Take attendance" "link" in the "1am - 2am" "table_row" |
| id_grade_modgrade_type | Point | |
||||
# Excused |
| id_grade_modgrade_point | 50 | |
||||
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
| id_groupmode | Visible groups | |
||||
And I press "Save attendance" |
And I press "Save and display" |
||||
|
|
||||
When I follow "Add session" |
When I follow "Attendance" |
||||
And I set the following fields to these values: |
Then I click on "Take attendance" "link" in the "1AM - 2AM" "table_row" |
||||
| id_sestime_starthour | 03 | |
# Excused |
||||
| id_sestime_endhour | 04 | |
And I click on "td.c4 input" "css_element" in the "Student 1" "table_row" |
||||
| id_sessiontype_1 | 1 | |
And I press "Save attendance" |
||||
| id_groups | Group1 | |
|
||||
And I click on "id_submitbutton" "button" |
When I follow "Add session" |
||||
Then I should see "3am - 4am" |
And I set the following fields to these values: |
||||
And "Group: Group1" "text" should exist in the "3am - 4am" "table_row" |
| id_sestime_starthour | 03 | |
||||
|
| id_sestime_endhour | 04 | |
||||
When I click on "Take attendance" "link" in the "3am - 4am" "table_row" |
| id_sessiontype_1 | 1 | |
||||
# Present |
| id_groups | Group1 | |
||||
And I click on "td.c2 input" "css_element" in the "Student 1" "table_row" |
And I click on "id_submitbutton" "button" |
||||
And I press "Save attendance" |
Then I should see "3AM - 4AM" |
||||
|
And "Group: Group1" "text" should exist in the "3AM - 4AM" "table_row" |
||||
When I follow "Report" |
|
||||
Then "3 / 4" "text" should exist in the "Student 1" "table_row" |
When I click on "Take attendance" "link" in the "3AM - 4AM" "table_row" |
||||
And "75.0%" "text" should exist in the "Student 1" "table_row" |
# Present |
||||
|
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
||||
When I follow "Grades" in the user menu |
And I press "Save attendance" |
||||
And I follow "Course 1" |
|
||||
Then "37.50" "text" should exist in the "Student 1" "table_row" |
When I follow "Report" |
||||
|
Then "3 / 4" "text" should exist in the "Student 1" "table_row" |
||||
And I log out |
And "75.0%" "text" should exist in the "Student 1" "table_row" |
||||
|
|
||||
Scenario: Teacher visit summary report |
When I follow "Grades" in the user menu |
||||
When I log in as "teacher1" |
And I follow "Course 1" |
||||
And I follow "Course 1" |
Then "37.50" "text" should exist in the "Student 1" "table_row" |
||||
And I follow "Attendance" |
|
||||
And I follow "Edit settings" |
And I log out |
||||
And I set the following fields to these values: |
|
||||
| id_grade_modgrade_type | Point | |
Scenario: Teacher visit summary report and absentee report |
||||
| id_grade_modgrade_point | 50 | |
When I log in as "teacher1" |
||||
And I press "Save and display" |
And I follow "Course 1" |
||||
|
And I follow "Attendance" |
||||
When I click on "Take attendance" "link" in the "1am - 2am" "table_row" |
And I follow "Edit settings" |
||||
# Late |
And I set the following fields to these values: |
||||
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
| id_grade_modgrade_type | Point | |
||||
And I press "Save attendance" |
| id_grade_modgrade_point | 50 | |
||||
|
And I press "Save and display" |
||||
When I follow "Add session" |
|
||||
And I set the following fields to these values: |
When I click on "Take attendance" "link" in the "1AM - 2AM" "table_row" |
||||
| id_sestime_starthour | 03 | |
# Late |
||||
| id_sestime_endhour | 04 | |
And I click on "td.c4 input" "css_element" in the "Student 1" "table_row" |
||||
And I click on "id_submitbutton" "button" |
And I press "Save attendance" |
||||
Then I should see "3am - 4am" |
|
||||
|
When I follow "Add session" |
||||
When I click on "Take attendance" "link" in the "3am - 4am" "table_row" |
And I set the following fields to these values: |
||||
# Present |
| id_sestime_starthour | 03 | |
||||
And I click on "td.c2 input" "css_element" in the "Student 1" "table_row" |
| id_sestime_endhour | 04 | |
||||
And I press "Save attendance" |
And I click on "id_submitbutton" "button" |
||||
|
Then I should see "3AM - 4AM" |
||||
When I follow "Add session" |
|
||||
And I set the following fields to these values: |
When I click on "Take attendance" "link" in the "3AM - 4AM" "table_row" |
||||
| id_sestime_starthour | 05 | |
# Present |
||||
| id_sestime_endhour | 06 | |
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
||||
And I click on "id_submitbutton" "button" |
And I press "Save attendance" |
||||
Then I should see "05:00 - 06:00" |
|
||||
|
When I follow "Add session" |
||||
When I follow "Report" |
And I set the following fields to these values: |
||||
And I click on "Summary" "link" in the "All" "table_row" |
| id_sestime_starthour | 05 | |
||||
|
| id_sestime_endhour | 06 | |
||||
Then "3 / 6" "text" should exist in the "Student 1" "table_row" |
And I click on "id_submitbutton" "button" |
||||
And "50.0%" "text" should exist in the "Student 1" "table_row" |
Then I should see "5AM - 6AM" |
||||
And "5 / 6" "text" should exist in the "Student 1" "table_row" |
|
||||
And "83.3%" "text" should exist in the "Student 1" "table_row" |
When I follow "Report" |
||||
|
And I click on "Summary" "link" in the "All" "table_row" |
||||
And I log out |
|
||||
|
Then "3 / 6" "text" should exist in the "Student 1" "table_row" |
||||
Scenario: Student visit user report |
And "50.0%" "text" should exist in the "Student 1" "table_row" |
||||
When I log in as "teacher1" |
And "5 / 6" "text" should exist in the "Student 1" "table_row" |
||||
And I follow "Course 1" |
And "83.3%" "text" should exist in the "Student 1" "table_row" |
||||
And I follow "Attendance" |
And I follow "Absentee report" |
||||
And I follow "Edit settings" |
And I should see "Student 1" |
||||
Then I set the following fields to these values: |
|
||||
| id_grade_modgrade_type | Point | |
And I log out |
||||
| id_grade_modgrade_point | 50 | |
|
||||
And I press "Save and display" |
Scenario: Student visit user report |
||||
|
When I log in as "teacher1" |
||||
When I click on "Take attendance" "link" in the "1am - 2am" "table_row" |
And I follow "Course 1" |
||||
# Late |
And I follow "Attendance" |
||||
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
And I follow "Edit settings" |
||||
And I press "Save attendance" |
Then I set the following fields to these values: |
||||
|
| id_grade_modgrade_type | Point | |
||||
When I follow "Add session" |
| id_grade_modgrade_point | 50 | |
||||
And I set the following fields to these values: |
And I press "Save and display" |
||||
| id_sestime_starthour | 03 | |
|
||||
| id_sestime_endhour | 04 | |
When I click on "Take attendance" "link" in the "1AM - 2AM" "table_row" |
||||
And I click on "id_submitbutton" "button" |
# Late |
||||
|
And I click on "td.c4 input" "css_element" in the "Student 1" "table_row" |
||||
When I click on "Take attendance" "link" in the "3am - 4am" "table_row" |
And I press "Save attendance" |
||||
# Present |
|
||||
And I click on "td.c2 input" "css_element" in the "Student 1" "table_row" |
When I follow "Add session" |
||||
And I press "Save attendance" |
And I set the following fields to these values: |
||||
|
| id_sestime_starthour | 03 | |
||||
When I follow "Add session" |
| id_sestime_endhour | 04 | |
||||
And I set the following fields to these values: |
And I click on "id_submitbutton" "button" |
||||
| id_sestime_starthour | 05 | |
|
||||
| id_sestime_endhour | 06 | |
When I click on "Take attendance" "link" in the "3AM - 4AM" "table_row" |
||||
And I click on "id_submitbutton" "button" |
# Present |
||||
|
And I click on "td.c3 input" "css_element" in the "Student 1" "table_row" |
||||
Then I log out |
And I press "Save attendance" |
||||
|
|
||||
When I log in as "student1" |
When I follow "Add session" |
||||
And I follow "Course 1" |
And I set the following fields to these values: |
||||
And I follow "Attendance" |
| id_sestime_starthour | 05 | |
||||
And I follow "All" |
| id_sestime_endhour | 06 | |
||||
|
And I click on "id_submitbutton" "button" |
||||
Then "2" "text" should exist in the "Taken sessions" "table_row" |
|
||||
And "3 / 4" "text" should exist in the "Points over taken sessions:" "table_row" |
Then I log out |
||||
And "75.0%" "text" should exist in the "Percentage over taken sessions:" "table_row" |
|
||||
And "3" "text" should exist in the "Total number of sessions:" "table_row" |
When I log in as "student1" |
||||
And "3 / 6" "text" should exist in the "Points over all sessions:" "table_row" |
And I follow "Course 1" |
||||
And "50.0%" "text" should exist in the "Percentage over all sessions:" "table_row" |
And I follow "Attendance" |
||||
And "5 / 6" "text" should exist in the "Maximum possible points:" "table_row" |
And I click on "All" "link" in the ".attfiltercontrols" "css_element" |
||||
And "83.3%" "text" should exist in the "Maximum possible percentage:" "table_row" |
|
||||
|
Then "2" "text" should exist in the "Taken sessions" "table_row" |
||||
And I log out |
And "3 / 4" "text" should exist in the "Points over taken sessions:" "table_row" |
||||
|
And "75.0%" "text" should exist in the "Percentage over taken sessions:" "table_row" |
||||
|
And "3" "text" should exist in the "Total number of sessions:" "table_row" |
||||
|
And "3 / 6" "text" should exist in the "Points over all sessions:" "table_row" |
||||
|
And "50.0%" "text" should exist in the "Percentage over all sessions:" "table_row" |
||||
|
And "5 / 6" "text" should exist in the "Maximum possible points:" "table_row" |
||||
|
And "83.3%" "text" should exist in the "Maximum possible percentage:" "table_row" |
||||
|
|
||||
|
And I log out |
@ -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