2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Library of functions and constants for module attendance
20 * @package mod_attendance
21 * @copyright 2011 Artem Andreev <andreev.artem@gmail.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 require_once(dirname(__FILE__
) . '/classes/calendar_helpers.php');
28 * Returns the information if the module supports a feature
30 * @see plugin_supports() in lib/moodlelib.php
31 * @param string $feature FEATURE_xx constant for requested feature
32 * @return mixed true if the feature is supported, null if unknown
34 function attendance_supports($feature) {
36 case FEATURE_GRADE_HAS_GRADE
:
40 case FEATURE_GROUPINGS
:
42 case FEATURE_MOD_INTRO
:
44 case FEATURE_BACKUP_MOODLE2
:
46 // Artem Andreev: AFAIK it's not tested.
47 case FEATURE_COMPLETION_TRACKS_VIEWS
:
54 function att_add_default_statuses($attid) {
57 $statuses = $DB->get_recordset('attendance_statuses', array('attendanceid' => 0), 'id');
58 foreach ($statuses as $st) {
60 $rec->attendanceid
= $attid;
61 $DB->insert_record('attendance_statuses', $rec);
66 function attendance_add_instance($attendance) {
69 $attendance->timemodified
= time();
71 $attendance->id
= $DB->insert_record('attendance', $attendance);
73 att_add_default_statuses($attendance->id
);
75 attendance_grade_item_update($attendance);
77 return $attendance->id
;
81 function attendance_update_instance($attendance) {
84 $attendance->timemodified
= time();
85 $attendance->id
= $attendance->instance
;
87 if (! $DB->update_record('attendance', $attendance)) {
91 attendance_grade_item_update($attendance);
97 function attendance_delete_instance($id) {
100 if (! $attendance = $DB->get_record('attendance', array('id' => $id))) {
104 if ($sessids = array_keys($DB->get_records('attendance_sessions', array('attendanceid' => $id), '', 'id'))) {
105 if (attendance_existing_calendar_events_ids($sessids)) {
106 attendance_delete_calendar_events($sessids);
108 $DB->delete_records_list('attendance_log', 'sessionid', $sessids);
109 $DB->delete_records('attendance_sessions', array('attendanceid' => $id));
111 $DB->delete_records('attendance_statuses', array('attendanceid' => $id));
113 $DB->delete_records('attendance', array('id' => $id));
115 attendance_grade_item_delete($attendance);
120 function attendance_delete_course($course, $feedback=true
) {
123 $attids = array_keys($DB->get_records('attendance', array('course' => $course->id
), '', 'id'));
124 $sessids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id'));
125 if (attendance_existing_calendar_events_ids($sessids)) {
126 attendance_delete_calendar_events($sessids);
129 $DB->delete_records_list('attendance_log', 'sessionid', $sessids);
132 $DB->delete_records_list('attendance_statuses', 'attendanceid', $attids);
133 $DB->delete_records_list('attendance_sessions', 'attendanceid', $attids);
135 $DB->delete_records('attendance', array('course' => $course->id
));
141 * Called by course/reset.php
142 * @param $mform form passed by reference
144 function attendance_reset_course_form_definition(&$mform) {
145 $mform->addElement('header', 'attendanceheader', get_string('modulename', 'attendance'));
147 $mform->addElement('static', 'description', get_string('description', 'attendance'),
148 get_string('resetdescription', 'attendance'));
149 $mform->addElement('checkbox', 'reset_attendance_log', get_string('deletelogs', 'attendance'));
151 $mform->addElement('checkbox', 'reset_attendance_sessions', get_string('deletesessions', 'attendance'));
152 $mform->disabledIf('reset_attendance_sessions', 'reset_attendance_log', 'notchecked');
154 $mform->addElement('checkbox', 'reset_attendance_statuses', get_string('resetstatuses', 'attendance'));
155 $mform->setAdvanced('reset_attendance_statuses');
156 $mform->disabledIf('reset_attendance_statuses', 'reset_attendance_log', 'notchecked');
160 * Course reset form defaults.
162 function attendance_reset_course_form_defaults($course) {
163 return array('reset_attendance_log' => 0, 'reset_attendance_statuses' => 0, 'reset_attendance_sessions' => 0);
166 function attendance_reset_userdata($data) {
171 $attids = array_keys($DB->get_records('attendance', array('course' => $data->courseid
), '', 'id'));
173 if (!empty($data->reset_attendance_log
)) {
174 $sess = $DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id');
176 list($sql, $params) = $DB->get_in_or_equal(array_keys($sess));
177 $DB->delete_records_select('attendance_log', "sessionid $sql", $params);
178 list($sql, $params) = $DB->get_in_or_equal($attids);
179 $DB->set_field_select('attendance_sessions', 'lasttaken', 0, "attendanceid $sql", $params);
182 'component' => get_string('modulenameplural', 'attendance'),
183 'item' => get_string('attendancedata', 'attendance'),
189 if (!empty($data->reset_attendance_statuses
)) {
190 $DB->delete_records_list('attendance_statuses', 'attendanceid', $attids);
191 foreach ($attids as $attid) {
192 att_add_default_statuses($attid);
196 'component' => get_string('modulenameplural', 'attendance'),
197 'item' => get_string('sessions', 'attendance'),
202 if (!empty($data->reset_attendance_sessions
)) {
203 $sessionsids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id'));
204 if (attendance_existing_calendar_events_ids($sessionsids)) {
205 attendance_delete_calendar_events($sessionsids);
207 $DB->delete_records_list('attendance_sessions', 'attendanceid', $attids);
210 'component' => get_string('modulenameplural', 'attendance'),
211 'item' => get_string('statuses', 'attendance'),
219 * Return a small object with summary information about what a
220 * user has done with a given particular instance of this module
221 * Used for user activity reports.
222 * $return->time = the time they did it
223 * $return->info = a short text description
225 function attendance_user_outline($course, $user, $mod, $attendance) {
227 require_once(dirname(__FILE__
).'/locallib.php');
228 require_once($CFG->libdir
.'/gradelib.php');
230 $grades = grade_get_grades($course->id
, 'mod', 'attendance', $attendance->id
, $user->id
);
232 $result = new stdClass();
233 if (!empty($grades->items
[0]->grades
)) {
234 $grade = reset($grades->items
[0]->grades
);
235 $result->time
= $grade->dategraded
;
239 if (has_capability('mod/attendance:canbelisted', $mod->context
, $user->id
)) {
240 $statuses = attendance_get_statuses($attendance->id
);
241 $grade = attendance_get_user_grade(attendance_get_user_statuses_stat($attendance->id
, $course->startdate
,
242 $user->id
, $mod), $statuses);
243 $maxgrade = attendance_get_user_max_grade(attendance_get_user_taken_sessions_count($attendance->id
, $course->startdate
,
244 $user->id
, $mod), $statuses);
246 $result->info
= $grade.' / '.$maxgrade;
252 * Print a detailed representation of what a user has done with
253 * a given particular instance of this module, for user activity reports.
256 function attendance_user_complete($course, $user, $mod, $attendance) {
259 require_once(dirname(__FILE__
).'/renderhelpers.php');
260 require_once($CFG->libdir
.'/gradelib.php');
262 if (has_capability('mod/attendance:canbelisted', $mod->context
, $user->id
)) {
263 echo construct_full_user_stat_html_table($attendance, $user);
267 function attendance_update_grades($attendance, $userid=0, $nullifnone=true
) {
268 // We need this function to exist so that quick editing of module name is passed to gradebook.
271 * Create grade item for given attendance
273 * @param object $attendance object with extra cmidnumber
274 * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
275 * @return int 0 if ok, error code otherwise
277 function attendance_grade_item_update($attendance, $grades=null
) {
280 require_once('locallib.php');
282 if (!function_exists('grade_update')) { // Workaround for buggy PHP versions.
283 require_once($CFG->libdir
.'/gradelib.php');
286 if (!isset($attendance->courseid
)) {
287 $attendance->courseid
= $attendance->course
;
289 if (!$DB->get_record('course', array('id' => $attendance->course
))) {
290 error("Course is misconfigured");
293 if (!empty($attendance->cmidnumber
)) {
294 $params = array('itemname' => $attendance->name
, 'idnumber' => $attendance->cmidnumber
);
297 $params = array('itemname' => $attendance->name
/*, 'idnumber'=>$attendance->id*/);
300 if ($attendance->grade
> 0) {
301 $params['gradetype'] = GRADE_TYPE_VALUE
;
302 $params['grademax'] = $attendance->grade
;
303 $params['grademin'] = 0;
304 } else if ($attendance->grade
< 0) {
305 $params['gradetype'] = GRADE_TYPE_SCALE
;
306 $params['scaleid'] = -$attendance->grade
;
309 $params['gradetype'] = GRADE_TYPE_NONE
;
312 if ($grades === 'reset') {
313 $params['reset'] = true
;
317 return grade_update('mod/attendance', $attendance->courseid
, 'mod', 'attendance', $attendance->id
, 0, $grades, $params);
321 * Delete grade item for given attendance
323 * @param object $attendance object
324 * @return object attendance
326 function attendance_grade_item_delete($attendance) {
328 require_once($CFG->libdir
.'/gradelib.php');
330 if (!isset($attendance->courseid
)) {
331 $attendance->courseid
= $attendance->course
;
334 return grade_update('mod/attendance', $attendance->courseid
, 'mod', 'attendance',
335 $attendance->id
, 0, null
, array('deleted' => 1));
339 * This function returns if a scale is being used by one attendance
340 * it it has support for grading and scales. Commented code should be
341 * modified if necessary. See book, glossary or journal modules
344 * @param int $attendanceid
345 * @param int $scaleid
346 * @return boolean True if the scale is used by any attendance
348 function attendance_scale_used ($attendanceid, $scaleid) {
353 * Checks if scale is being used by any instance of attendance
355 * This is used to find out if scale used anywhere
357 * @param int $scaleid
358 * @return bool true if the scale is used by any book
360 function attendance_scale_used_anywhere($scaleid) {
365 * Serves the attendance sessions descriptions files.
367 * @param object $course
369 * @param object $context
370 * @param string $filearea
372 * @param bool $forcedownload
373 * @return bool false if file not found, does not return if found - justsend the file
375 function attendance_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) {
378 if ($context->contextlevel
!= CONTEXT_MODULE
) {
382 require_login($course, false
, $cm);
384 if (!$DB->record_exists('attendance', array('id' => $cm->instance
))) {
388 // Session area is served by pluginfile.php.
389 $fileareas = array('session');
390 if (!in_array($filearea, $fileareas)) {
394 $sessid = (int)array_shift($args);
395 if (!$DB->record_exists('attendance_sessions', array('id' => $sessid))) {
399 $fs = get_file_storage();
400 $relativepath = implode('/', $args);
401 $fullpath = "/$context->id/mod_attendance/$filearea/$sessid/$relativepath";
402 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
405 send_stored_file($file, 0, 0, true
);