Merge pull request #83 from barrysspace/expired_self_enrolments_MDL26
[moodle-mod_attendance.git] / lib.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
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.
8 //
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.
13 //
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/>.
16
17 /**
18 * Library of functions and constants for module attendance
19 *
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
23 */
24
25 /**
26 * Returns the information if the module supports a feature
27 *
28 * @see plugin_supports() in lib/moodlelib.php
29 * @param string $feature FEATURE_xx constant for requested feature
30 * @return mixed true if the feature is supported, null if unknown
31 */
32 function attendance_supports($feature) {
33 switch($feature) {
34 case FEATURE_GRADE_HAS_GRADE:
35 return true;
36 case FEATURE_GROUPS:
37 return true;
38 case FEATURE_GROUPINGS:
39 return true;
40 case FEATURE_GROUPMEMBERSONLY:
41 return true;
42 case FEATURE_MOD_INTRO:
43 return false;
44 case FEATURE_BACKUP_MOODLE2:
45 return true;
46 // Artem Andreev: AFAIK it's not tested.
47 case FEATURE_COMPLETION_TRACKS_VIEWS:
48 return false;
49 default:
50 return null;
51 }
52 }
53
54 function att_add_default_statuses($attid) {
55 global $DB;
56
57 $statuses = $DB->get_recordset('attendance_statuses', array('attendanceid'=> 0), 'id');
58 foreach ($statuses as $st) {
59 $rec = $st;
60 $rec->attendanceid = $attid;
61 $DB->insert_record('attendance_statuses', $rec);
62 }
63 $statuses->close();
64 }
65
66 function attendance_add_instance($attendance) {
67 global $DB;
68
69 $attendance->timemodified = time();
70
71 $attendance->id = $DB->insert_record('attendance', $attendance);
72
73 att_add_default_statuses($attendance->id);
74
75 attendance_grade_item_update($attendance);
76
77 return $attendance->id;
78 }
79
80
81 function attendance_update_instance($attendance) {
82 global $DB;
83
84 $attendance->timemodified = time();
85 $attendance->id = $attendance->instance;
86
87 if (! $DB->update_record('attendance', $attendance)) {
88 return false;
89 }
90
91 attendance_grade_item_update($attendance);
92
93 return true;
94 }
95
96
97 function attendance_delete_instance($id) {
98 global $DB;
99
100 if (! $attendance = $DB->get_record('attendance', array('id'=> $id))) {
101 return false;
102 }
103
104 if ($sessids = array_keys($DB->get_records('attendance_sessions', array('attendanceid'=> $id), '', 'id'))) {
105 $DB->delete_records_list('attendance_log', 'sessionid', $sessids);
106 $DB->delete_records('attendance_sessions', array('attendanceid'=> $id));
107 }
108 $DB->delete_records('attendance_statuses', array('attendanceid'=> $id));
109
110 $DB->delete_records('attendance', array('id'=> $id));
111
112 attendance_grade_item_delete($attendance);
113
114 return true;
115 }
116
117 function attendance_delete_course($course, $feedback=true) {
118 global $DB;
119
120 $attids = array_keys($DB->get_records('attendance', array('course'=> $course->id), '', 'id'));
121 $sessids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id'));
122 if ($sessids) {
123 $DB->delete_records_list('attendance_log', 'sessionid', $sessids);
124 }
125 if ($attids) {
126 $DB->delete_records_list('attendance_statuses', 'attendanceid', $attids);
127 $DB->delete_records_list('attendance_sessions', 'attendanceid', $attids);
128 }
129 $DB->delete_records('attendance', array('course'=> $course->id));
130
131 return true;
132 }
133
134 /**
135 * Called by course/reset.php
136 * @param $mform form passed by reference
137 */
138 function attendance_reset_course_form_definition(&$mform) {
139 $mform->addElement('header', 'attendanceheader', get_string('modulename', 'attendance'));
140
141 $mform->addElement('static', 'description', get_string('description', 'attendance'),
142 get_string('resetdescription', 'attendance'));
143 $mform->addElement('checkbox', 'reset_attendance_log', get_string('deletelogs', 'attendance'));
144
145 $mform->addElement('checkbox', 'reset_attendance_sessions', get_string('deletesessions', 'attendance'));
146 $mform->disabledIf('reset_attendance_sessions', 'reset_attendance_log', 'notchecked');
147
148 $mform->addElement('checkbox', 'reset_attendance_statuses', get_string('resetstatuses', 'attendance'));
149 $mform->setAdvanced('reset_attendance_statuses');
150 $mform->disabledIf('reset_attendance_statuses', 'reset_attendance_log', 'notchecked');
151 }
152
153 /**
154 * Course reset form defaults.
155 */
156 function attendance_reset_course_form_defaults($course) {
157 return array('reset_attendance_log'=>0, 'reset_attendance_statuses'=>0, 'reset_attendance_sessions'=>0);
158 }
159
160 function attendance_reset_userdata($data) {
161 global $DB;
162
163 $status = array();
164
165 $attids = array_keys($DB->get_records('attendance', array('course'=> $data->courseid), '', 'id'));
166
167 if (!empty($data->reset_attendance_log)) {
168 $sess = $DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id');
169 if (!empty($sess)) {
170 list($sql, $params) = $DB->get_in_or_equal(array_keys($sess));
171 $DB->delete_records_select('attendance_log', "sessionid $sql", $params);
172 list($sql, $params) = $DB->get_in_or_equal($attids);
173 $DB->set_field_select('attendance_sessions', 'lasttaken', 0, "attendanceid $sql", $params);
174
175 $status[] = array(
176 'component' => get_string('modulenameplural', 'attendance'),
177 'item' => get_string('attendancedata', 'attendance'),
178 'error' => false
179 );
180 }
181 }
182
183 if (!empty($data->reset_attendance_statuses)) {
184 $DB->delete_records_list('attendance_statuses', 'attendanceid', $attids);
185 foreach ($attids as $attid) {
186 att_add_default_statuses($attid);
187 }
188
189 $status[] = array(
190 'component' => get_string('modulenameplural', 'attendance'),
191 'item' => get_string('sessions', 'attendance'),
192 'error' => false
193 );
194 }
195
196 if (!empty($data->reset_attendance_sessions)) {
197 $DB->delete_records_list('attendance_sessions', 'attendanceid', $attids);
198
199 $status[] = array(
200 'component' => get_string('modulenameplural', 'attendance'),
201 'item' => get_string('statuses', 'attendance'),
202 'error' => false
203 );
204 }
205
206 return $status;
207 }
208 /*
209 * Return a small object with summary information about what a
210 * user has done with a given particular instance of this module
211 * Used for user activity reports.
212 * $return->time = the time they did it
213 * $return->info = a short text description
214 */
215 function attendance_user_outline($course, $user, $mod, $attendance) {
216 global $CFG;
217 require_once(dirname(__FILE__).'/locallib.php');
218 require_once($CFG->libdir.'/gradelib.php');
219
220 $grades = grade_get_grades($course->id, 'mod', 'attendance', $attendance->id, $user->id);
221
222 $result = new stdClass();
223 if (!empty($grades->items[0]->grades)) {
224 $grade = reset($grades->items[0]->grades);
225 $result->time = $grade->dategraded;
226 } else {
227 $result->time = 0;
228 }
229 if (has_capability('mod/attendance:canbelisted', $mod->context, $user->id)) {
230 $statuses = att_get_statuses($attendance->id);
231 $grade = att_get_user_grade(att_get_user_statuses_stat($attendance->id, $course->startdate,
232 $user->id, $mod), $statuses);
233 $maxgrade = att_get_user_max_grade(att_get_user_taken_sessions_count($attendance->id, $course->startdate,
234 $user->id, $mod), $statuses);
235
236 $result->info = $grade.' / '.$maxgrade;
237 }
238
239 return $result;
240 }
241 /*
242 * Print a detailed representation of what a user has done with
243 * a given particular instance of this module, for user activity reports.
244 *
245 */
246 function attendance_user_complete($course, $user, $mod, $attendance) {
247 global $CFG;
248
249 require_once(dirname(__FILE__).'/renderhelpers.php');
250 require_once($CFG->libdir.'/gradelib.php');
251
252 if (has_capability('mod/attendance:canbelisted', $mod->context, $user->id)) {
253 echo construct_full_user_stat_html_table($attendance, $course, $user, $mod);
254 }
255 }
256 function attendance_print_recent_activity($course, $isteacher, $timestart) {
257 return false;
258 }
259
260 function attendance_cron () {
261 return true;
262 }
263
264 function attendance_update_grades($attendance, $userid=0, $nullifnone=true) {
265 // We need this function to exist so that quick editing of module name is passed to gradebook.
266 }
267 /**
268 * Create grade item for given attendance
269 *
270 * @param object $attendance object with extra cmidnumber
271 * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
272 * @return int 0 if ok, error code otherwise
273 */
274 function attendance_grade_item_update($attendance, $grades=null) {
275 global $CFG, $DB;
276
277 require_once('locallib.php');
278
279 if (!function_exists('grade_update')) { // Workaround for buggy PHP versions.
280 require_once($CFG->libdir.'/gradelib.php');
281 }
282
283 if (!isset($attendance->courseid)) {
284 $attendance->courseid = $attendance->course;
285 }
286 if (! $course = $DB->get_record('course', array('id'=> $attendance->course))) {
287 error("Course is misconfigured");
288 }
289
290 if (!empty($attendance->cmidnumber)) {
291 $params = array('itemname'=>$attendance->name, 'idnumber'=>$attendance->cmidnumber);
292 } else {
293 // MDL-14303.
294 $cm = get_coursemodule_from_instance('attendance', $attendance->id);
295 $params = array('itemname'=>$attendance->name/*, 'idnumber'=>$attendance->id*/);
296 }
297
298 if ($attendance->grade > 0) {
299 $params['gradetype'] = GRADE_TYPE_VALUE;
300 $params['grademax'] = $attendance->grade;
301 $params['grademin'] = 0;
302 } else if ($attendance->grade < 0) {
303 $params['gradetype'] = GRADE_TYPE_SCALE;
304 $params['scaleid'] = -$attendance->grade;
305
306 } else {
307 $params['gradetype'] = GRADE_TYPE_NONE;
308 }
309
310 if ($grades === 'reset') {
311 $params['reset'] = true;
312 $grades = null;
313 }
314
315 return grade_update('mod/attendance', $attendance->courseid, 'mod', 'attendance', $attendance->id, 0, $grades, $params);
316 }
317
318 /**
319 * Delete grade item for given attendance
320 *
321 * @param object $attendance object
322 * @return object attendance
323 */
324 function attendance_grade_item_delete($attendance) {
325 global $CFG;
326 require_once($CFG->libdir.'/gradelib.php');
327
328 if (!isset($attendance->courseid)) {
329 $attendance->courseid = $attendance->course;
330 }
331
332 return grade_update('mod/attendance', $attendance->courseid, 'mod', 'attendance',
333 $attendance->id, 0, null, array('deleted'=>1));
334 }
335
336 function attendance_get_participants($attendanceid) {
337 return false;
338 }
339
340 /**
341 * This function returns if a scale is being used by one attendance
342 * it it has support for grading and scales. Commented code should be
343 * modified if necessary. See book, glossary or journal modules
344 * as reference.
345 *
346 * @param int $attendanceid
347 * @param int $scaleid
348 * @return boolean True if the scale is used by any attendance
349 */
350 function attendance_scale_used ($attendanceid, $scaleid) {
351 return false;
352 }
353
354 /**
355 * Checks if scale is being used by any instance of attendance
356 *
357 * This is used to find out if scale used anywhere
358 *
359 * @param int $scaleid
360 * @return bool true if the scale is used by any book
361 */
362 function attendance_scale_used_anywhere($scaleid) {
363 return false;
364 }
365
366 /**
367 * Serves the attendance sessions descriptions files.
368 *
369 * @param object $course
370 * @param object $cm
371 * @param object $context
372 * @param string $filearea
373 * @param array $args
374 * @param bool $forcedownload
375 * @return bool false if file not found, does not return if found - justsend the file
376 */
377 function attendance_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) {
378 global $CFG, $DB;
379
380 if ($context->contextlevel != CONTEXT_MODULE) {
381 return false;
382 }
383
384 require_login($course, false, $cm);
385
386 if (!$att = $DB->get_record('attendance', array('id' => $cm->instance))) {
387 return false;
388 }
389
390 // Session area is served by pluginfile.php.
391 $fileareas = array('session');
392 if (!in_array($filearea, $fileareas)) {
393 return false;
394 }
395
396 $sessid = (int)array_shift($args);
397 if (!$sess = $DB->get_record('attendance_sessions', array('id' => $sessid))) {
398 return false;
399 }
400
401 $fs = get_file_storage();
402 $relativepath = implode('/', $args);
403 $fullpath = "/$context->id/mod_attendance/$filearea/$sessid/$relativepath";
404 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
405 return false;
406 }
407 send_stored_file($file, 0, 0, true);
408 }