Commit | Line | Data |
---|---|---|
df997f84 PS |
1 | <?php |
2 | ||
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | /** | |
19 | * This library includes the basic parts of enrol api. | |
20 | * It is available on each page. | |
21 | * | |
22 | * @package moodlecore | |
23 | * @copyright 2010 Petr Skoda {@link http://skodak.org} | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | */ | |
26 | ||
27 | ||
28 | /** Course enrol instance enabled. (used in enrol->status) */ | |
29 | define('ENROL_INSTANCE_ENABLED', 0); | |
30 | ||
31 | /** Course enrol instance disabled, user may enter course if other enrol instance enabled. (used in enrol->status)*/ | |
32 | define('ENROL_INSTANCE_DISABLED', 1); | |
33 | ||
34 | /** User is active participant (used in user_enrolments->status)*/ | |
35 | define('ENROL_USER_ACTIVE', 0); | |
36 | ||
37 | /** User participation in course is suspended (used in user_enrolments->status) */ | |
38 | define('ENROL_USER_SUSPENDED', 1); | |
39 | ||
40 | /** Enrol info is cached for this number of seconds in require_login() */ | |
41 | define('ENROL_REQUIRE_LOGIN_CACHE_PERIOD', 1800); | |
42 | ||
43 | /** | |
44 | * Returns instances of enrol plugins | |
45 | * @param bool $enable return enabled only | |
46 | * @return array of enrol plugins name=>instance | |
47 | */ | |
48 | function enrol_get_plugins($enabled) { | |
49 | global $CFG; | |
50 | ||
51 | $result = array(); | |
52 | ||
53 | if ($enabled) { | |
54 | // sorted by enabled plugin order | |
55 | $enabled = explode(',', $CFG->enrol_plugins_enabled); | |
56 | $plugins = array(); | |
57 | foreach ($enabled as $plugin) { | |
58 | $plugins[$plugin] = "$CFG->dirroot/enrol/$plugin"; | |
59 | } | |
60 | } else { | |
61 | // sorted alphabetically | |
62 | $plugins = get_plugin_list('enrol'); | |
63 | ksort($plugins); | |
64 | } | |
65 | ||
66 | foreach ($plugins as $plugin=>$location) { | |
67 | if (!file_exists("$location/lib.php")) { | |
68 | continue; | |
69 | } | |
70 | include_once("$location/lib.php"); | |
71 | $class = "enrol_{$plugin}_plugin"; | |
72 | if (!class_exists($class)) { | |
73 | continue; | |
74 | } | |
75 | ||
76 | $result[$plugin] = new $class(); | |
77 | } | |
78 | ||
79 | return $result; | |
80 | } | |
81 | ||
82 | /** | |
83 | * Returns instance of enrol plugin | |
84 | * @param string $name name of enrol plugin ('manual', 'guest', ...) | |
85 | * @return enrol_plugin | |
86 | */ | |
87 | function enrol_get_plugin($name) { | |
88 | global $CFG; | |
89 | ||
90 | if ($name !== clean_param($name, PARAM_SAFEDIR)) { | |
91 | // ignore malformed plugin names completely | |
92 | return null; | |
93 | } | |
94 | ||
95 | $location = "$CFG->dirroot/enrol/$name"; | |
96 | ||
97 | if (!file_exists("$location/lib.php")) { | |
98 | return null; | |
99 | } | |
100 | include_once("$location/lib.php"); | |
101 | $class = "enrol_{$name}_plugin"; | |
102 | if (!class_exists($class)) { | |
103 | return null; | |
104 | } | |
105 | ||
106 | return new $class(); | |
107 | } | |
108 | ||
109 | /** | |
110 | * Returns enrolment instances in given course. | |
111 | * @param int $courseid | |
112 | * @param bool $enabled | |
113 | * @return array of enrol instances | |
114 | */ | |
115 | function enrol_get_instances($courseid, $enabled) { | |
116 | global $DB, $CFG; | |
117 | ||
118 | if (!$enabled) { | |
119 | return $DB->get_records('enrol', array('courseid'=>$courseid), 'sortorder,id'); | |
120 | } | |
121 | ||
122 | $result = $DB->get_records('enrol', array('courseid'=>$courseid, 'status'=>ENROL_INSTANCE_ENABLED), 'sortorder,id'); | |
123 | ||
79721bd3 | 124 | $enabled = explode(',', $CFG->enrol_plugins_enabled); |
df997f84 PS |
125 | foreach ($result as $key=>$instance) { |
126 | if (!in_array($instance->enrol, $enabled)) { | |
127 | unset($result[$key]); | |
128 | continue; | |
129 | } | |
130 | if (!file_exists("$CFG->dirroot/enrol/$instance->enrol/lib.php")) { | |
131 | // broken plugin | |
132 | unset($result[$key]); | |
133 | continue; | |
134 | } | |
135 | } | |
136 | ||
137 | return $result; | |
138 | } | |
139 | ||
140 | /** | |
141 | * Checks if a given plugin is in the list of enabled enrolment plugins. | |
142 | * | |
143 | * @param string $enrol Enrolment plugin name | |
144 | * @return boolean Whether the plugin is enabled | |
145 | */ | |
146 | function enrol_is_enabled($enrol) { | |
147 | global $CFG; | |
148 | ||
149 | if (empty($CFG->enrol_plugins_enabled)) { | |
150 | return false; | |
151 | } | |
152 | return in_array($enrol, explode(',', $CFG->enrol_plugins_enabled)); | |
153 | } | |
154 | ||
155 | /** | |
156 | * Check all the login enrolment information for the given user object | |
157 | * by querying the enrolment plugins | |
158 | * | |
159 | * @param object $user | |
160 | * @return void | |
161 | */ | |
162 | function enrol_check_plugins($user) { | |
163 | global $CFG; | |
164 | ||
165 | if (empty($user->id) or isguestuser($user)) { | |
166 | // shortcut - there is no enrolment work for guests and not-logged-in users | |
167 | return; | |
168 | } | |
169 | ||
170 | static $inprogress = array(); // To prevent this function being called more than once in an invocation | |
171 | ||
172 | if (!empty($inprogress[$user->id])) { | |
173 | return; | |
174 | } | |
175 | ||
176 | $inprogress[$user->id] = true; // Set the flag | |
177 | ||
178 | $enabled = enrol_get_plugins(true); | |
179 | ||
180 | foreach($enabled as $enrol) { | |
181 | $enrol->sync_user_enrolments($user); | |
182 | } | |
183 | ||
184 | unset($inprogress[$user->id]); // Unset the flag | |
185 | } | |
186 | ||
187 | /** | |
188 | * This function adds necessary enrol plugins UI into the course edit form. | |
189 | * | |
190 | * @param MoodleQuickForm $mform | |
191 | * @param object $data course edit form data | |
192 | * @param object $context context of existing course or parent category if course does not exist | |
193 | * @return void | |
194 | */ | |
195 | function enrol_course_edit_form(MoodleQuickForm $mform, $data, $context) { | |
196 | $plugins = enrol_get_plugins(true); | |
197 | if (!empty($data->id)) { | |
198 | $instances = enrol_get_instances($data->id, false); | |
199 | foreach ($instances as $instance) { | |
200 | if (!isset($plugins[$instance->enrol])) { | |
201 | continue; | |
202 | } | |
203 | $plugin = $plugins[$instance->enrol]; | |
204 | $plugin->course_edit_form($instance, $mform, $data, $context); | |
205 | } | |
206 | } else { | |
207 | foreach ($plugins as $plugin) { | |
208 | $plugin->course_edit_form(NULL, $mform, $data, $context); | |
209 | } | |
210 | } | |
211 | } | |
212 | ||
213 | /** | |
214 | * Validate course edit form data | |
215 | * | |
216 | * @param array $data raw form data | |
217 | * @param object $context context of existing course or parent category if course does not exist | |
218 | * @return array errors array | |
219 | */ | |
220 | function enrol_course_edit_validation(array $data, $context) { | |
221 | $errors = array(); | |
222 | $plugins = enrol_get_plugins(true); | |
223 | ||
224 | if (!empty($data['id'])) { | |
225 | $instances = enrol_get_instances($data['id'], false); | |
226 | foreach ($instances as $instance) { | |
227 | if (!isset($plugins[$instance->enrol])) { | |
228 | continue; | |
229 | } | |
230 | $plugin = $plugins[$instance->enrol]; | |
231 | $errors = array_merge($errors, $plugin->course_edit_validation($instance, $data, $context)); | |
232 | } | |
233 | } else { | |
234 | foreach ($plugins as $plugin) { | |
235 | $errors = array_merge($errors, $plugin->course_edit_validation(NULL, $data, $context)); | |
236 | } | |
237 | } | |
238 | ||
239 | return $errors; | |
240 | } | |
241 | ||
242 | /** | |
243 | * Update enrol instances after course edit form submission | |
244 | * @param bool $inserted true means new course added, false course already existed | |
245 | * @param object $course | |
246 | * @param object $data form data | |
247 | * @return void | |
248 | */ | |
249 | function enrol_course_updated($inserted, $course, $data) { | |
250 | global $DB, $CFG; | |
251 | ||
252 | $plugins = enrol_get_plugins(true); | |
253 | ||
254 | foreach ($plugins as $plugin) { | |
255 | $plugin->course_updated($inserted, $course, $data); | |
256 | } | |
257 | } | |
258 | ||
259 | /** | |
260 | * Add navigation nodes | |
261 | * @param navigation_node $coursenode | |
262 | * @param object $course | |
263 | * @return void | |
264 | */ | |
265 | function enrol_add_course_navigation(navigation_node $coursenode, $course) { | |
266 | ||
267 | $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); | |
268 | ||
269 | $instances = enrol_get_instances($course->id, true); | |
270 | $plugins = enrol_get_plugins(true); | |
271 | ||
272 | // we do not want to break all course pages if there is some borked enrol plugin, right? | |
273 | foreach ($instances as $k=>$instance) { | |
274 | if (!isset($plugins[$instance->enrol])) { | |
275 | unset($instances[$k]); | |
276 | } | |
277 | } | |
278 | ||
279 | $usersnode = $coursenode->add(get_string('users'), null, navigation_node::TYPE_CONTAINER); | |
280 | ||
281 | if ($course->id != SITEID) { | |
282 | // list all participants - allows assing roles, groups, etc. | |
283 | if (has_capability('moodle/course:enrolreview', $coursecontext)) { | |
284 | $url = new moodle_url('/enrol/users.php', array('id'=>$course->id)); | |
285 | $usersnode->add(get_string('enrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/users', '')); | |
286 | } | |
287 | ||
288 | // manage enrol plugin instances | |
289 | if (has_capability('moodle/course:enrolconfig', $coursecontext) or has_capability('moodle/course:enrolreview', $coursecontext)) { | |
290 | $url = new moodle_url('/enrol/instances.php', array('id'=>$course->id)); | |
291 | } else { | |
292 | $url = NULL; | |
293 | } | |
294 | $instancesnode = $usersnode->add(get_string('enrolmentinstances', 'enrol'), $url); | |
295 | ||
296 | // each instance decides how to configure itself or how many other nav items are exposed | |
297 | foreach ($instances as $instance) { | |
298 | if (!isset($plugins[$instance->enrol])) { | |
299 | continue; | |
300 | } | |
301 | $plugins[$instance->enrol]->add_course_navigation($instancesnode, $instance); | |
302 | } | |
303 | ||
304 | if (!$url) { | |
305 | $instancesnode->trim_if_empty(); | |
306 | } | |
307 | } | |
308 | ||
309 | // Manage groups in this course or even frontpage | |
310 | if (($course->groupmode || !$course->groupmodeforce) && has_capability('moodle/course:managegroups', $coursecontext)) { | |
311 | $url = new moodle_url('/group/index.php', array('id'=>$course->id)); | |
312 | $usersnode->add(get_string('groups'), $url, navigation_node::TYPE_SETTING, null, 'groups', new pix_icon('i/group', '')); | |
313 | } | |
314 | ||
315 | if (has_any_capability(array( 'moodle/role:assign', 'moodle/role:safeoverride','moodle/role:override', 'moodle/role:review'), $coursecontext)) { | |
316 | // Override roles | |
317 | if (has_capability('moodle/role:review', $coursecontext)) { | |
318 | $url = new moodle_url('/admin/roles/permissions.php', array('contextid'=>$coursecontext->id)); | |
319 | } else { | |
320 | $url = NULL; | |
321 | } | |
322 | $permissionsnode = $usersnode->add(get_string('permissions', 'role'), $url); | |
323 | ||
324 | // Add assign or override roles if allowed | |
325 | if ($course->id == SITEID or (!empty($CFG->adminsassignrolesincourse) and is_siteadmin())) { | |
326 | if (has_capability('moodle/role:assign', $coursecontext)) { | |
327 | $url = new moodle_url('/admin/roles/assign.php', array('contextid'=>$coursecontext->id)); | |
328 | $permissionsnode->add(get_string('assignedroles', 'role'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/roles', '')); | |
329 | } | |
330 | } | |
331 | // Check role permissions | |
332 | if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride','moodle/role:override', 'moodle/role:assign'), $coursecontext)) { | |
333 | $url = new moodle_url('/admin/roles/check.php', array('contextid'=>$coursecontext->id)); | |
334 | $permissionsnode->add(get_string('checkpermissions', 'role'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/checkpermissions', '')); | |
335 | } | |
336 | } | |
337 | ||
338 | // Deal somehow with users that are not enrolled but still got a role somehow | |
339 | if ($course->id != SITEID) { | |
340 | //TODO, create some new UI for role assignments at course level | |
341 | if (has_capability('moodle/role:assign', $coursecontext)) { | |
342 | $url = new moodle_url('/enrol/otherusers.php', array('id'=>$course->id)); | |
343 | $usersnode->add(get_string('notenrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/roles', '')); | |
344 | } | |
345 | } | |
346 | ||
347 | // just in case nothing was actually added | |
348 | $usersnode->trim_if_empty(); | |
349 | ||
350 | if ($course->id != SITEID) { | |
351 | // Unenrol link | |
352 | $unenrolprinted = false; | |
353 | foreach ($instances as $instance) { | |
354 | if (!isset($plugins[$instance->enrol])) { | |
355 | continue; | |
356 | } | |
357 | $plugin = $plugins[$instance->enrol]; | |
358 | if ($unenrollink = $plugin->get_unenrolself_link($instance)) { | |
359 | $coursenode->add(get_string('unenrolme', 'core_enrol', format_string($course->shortname)), $unenrollink, navigation_node::TYPE_SETTING, null, 'unenrolself', new pix_icon('i/user', '')); | |
360 | $unenrolprinted = true; | |
361 | //TODO. deal with multiple unenrol links - not likely case, but still... | |
362 | } | |
363 | } | |
364 | // Enrol link | |
365 | if (!$unenrolprinted and !is_viewing($coursecontext) and !is_enrolled($coursecontext)) { | |
366 | $url = new moodle_url('/enrol/index.php', array('id'=>$course->id)); | |
367 | $coursenode->add(get_string('enrolme', 'core_enrol', format_string($course->shortname)), $url, navigation_node::TYPE_SETTING, null, 'enrolself', new pix_icon('i/user', '')); | |
368 | } | |
369 | } | |
370 | } | |
371 | ||
372 | /** | |
373 | * Returns list of courses current $USER is enrolled in and can access | |
374 | * | |
375 | * - $fields is an array of field names to ADD | |
376 | * so name the fields you really need, which will | |
377 | * be added and uniq'd | |
378 | * | |
379 | * @param strin|array $fields | |
380 | * @param string $sort | |
381 | * @param int $limit max number of courses | |
382 | * @return array | |
383 | */ | |
384 | function enrol_get_my_courses($fields = NULL, $sort = 'visible DESC,sortorder ASC', $limit = 0) { | |
385 | global $DB, $USER; | |
386 | ||
387 | // Guest account does not have any courses | |
388 | if (isguestuser() or !isloggedin()) { | |
389 | return(array()); | |
390 | } | |
391 | ||
392 | $basefields = array('id', 'category', 'sortorder', | |
393 | 'shortname', 'fullname', 'idnumber', | |
394 | 'startdate', 'visible', | |
395 | 'groupmode', 'groupmodeforce'); | |
396 | ||
397 | if (empty($fields)) { | |
398 | $fields = $basefields; | |
399 | } else if (is_string($fields)) { | |
400 | // turn the fields from a string to an array | |
401 | $fields = explode(',', $fields); | |
402 | $fields = array_map('trim', $fields); | |
403 | $fields = array_unique(array_merge($basefields, $fields)); | |
404 | } else if (is_array($fields)) { | |
405 | $fields = array_unique(array_merge($basefields, $fields)); | |
406 | } else { | |
407 | throw new coding_exception('Invalid $fileds parameter in enrol_get_my_courses()'); | |
408 | } | |
409 | if (in_array('*', $fields)) { | |
410 | $fields = array('*'); | |
411 | } | |
412 | ||
413 | $orderby = ""; | |
414 | $sort = trim($sort); | |
415 | if (!empty($sort)) { | |
416 | $rawsorts = explode(',', $sort); | |
417 | $sorts = array(); | |
418 | foreach ($rawsorts as $rawsort) { | |
419 | $rawsort = trim($rawsort); | |
420 | if (strpos($rawsort, 'c.') === 0) { | |
421 | $rawsort = substr($rawsort, 2); | |
422 | } | |
423 | $sorts[] = trim($rawsort); | |
424 | } | |
425 | $sort = 'c.'.implode(',c.', $sorts); | |
426 | $orderby = "ORDER BY $sort"; | |
427 | } | |
428 | ||
429 | $wheres = array("c.id <> :siteid"); | |
430 | $params = array('siteid'=>SITEID); | |
431 | ||
432 | if (isset($USER->loginascontext) and $USER->loginascontext->contextlevel == CONTEXT_COURSE) { | |
433 | // list _only_ this course - anything else is asking for trouble... | |
434 | $wheres[] = "courseid = :loginas"; | |
435 | $params['loginas'] = $USER->loginascontext->instanceid; | |
436 | } | |
437 | ||
438 | $coursefields = 'c.' .join(',c.', $fields); | |
439 | list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); | |
4129338c | 440 | $wheres = implode(" AND ", $wheres); |
df997f84 | 441 | |
4129338c PS |
442 | //note: we can not use DISTINCT + text fields due to Oracle and MS limitations, that is why we have the subselect there |
443 | $sql = "SELECT $coursefields $ccselect | |
df997f84 | 444 | FROM {course} c |
4129338c PS |
445 | JOIN (SELECT DISTINCT e.courseid |
446 | FROM {enrol} e | |
447 | JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid) | |
448 | WHERE ue.status = :active AND e.status = :enabled AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2) | |
449 | ) en ON (en.courseid = c.id) | |
df997f84 | 450 | $ccjoin |
4129338c | 451 | WHERE $wheres |
df997f84 PS |
452 | $orderby"; |
453 | $params['userid'] = $USER->id; | |
454 | $params['active'] = ENROL_USER_ACTIVE; | |
455 | $params['enabled'] = ENROL_INSTANCE_ENABLED; | |
456 | $params['now1'] = round(time(), -2); // improves db caching | |
457 | $params['now2'] = $params['now1']; | |
458 | ||
459 | $courses = $DB->get_records_sql($sql, $params, 0, $limit); | |
460 | ||
461 | // preload contexts and check visibility | |
462 | foreach ($courses as $id=>$course) { | |
463 | context_instance_preload($course); | |
464 | if (!$course->visible) { | |
465 | if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { | |
466 | unset($course[$id]); | |
467 | continue; | |
468 | } | |
469 | if (!has_capability('moodle/course:viewhiddencourses', $context)) { | |
470 | unset($course[$id]); | |
471 | continue; | |
472 | } | |
473 | } | |
474 | $courses[$id] = $course; | |
475 | } | |
476 | ||
477 | //wow! Is that really all? :-D | |
478 | ||
479 | return $courses; | |
480 | } | |
481 | ||
482 | /** | |
483 | * Returns list of courses user is enrolled into. | |
484 | * | |
485 | * - $fields is an array of fieldnames to ADD | |
486 | * so name the fields you really need, which will | |
487 | * be added and uniq'd | |
488 | * | |
489 | * @param int $userid | |
490 | * @param bool $onlyactive return only active enrolments in courses user may see | |
491 | * @param strin|array $fields | |
492 | * @param string $sort | |
493 | * @return array | |
494 | */ | |
495 | function enrol_get_users_courses($userid, $onlyactive = false, $fields = NULL, $sort = 'visible DESC,sortorder ASC') { | |
496 | global $DB; | |
497 | ||
498 | // Guest account does not have any courses | |
87163782 | 499 | if (isguestuser($userid) or empty($userid)) { |
df997f84 PS |
500 | return(array()); |
501 | } | |
502 | ||
503 | $basefields = array('id', 'category', 'sortorder', | |
504 | 'shortname', 'fullname', 'idnumber', | |
505 | 'startdate', 'visible', | |
506 | 'groupmode', 'groupmodeforce'); | |
507 | ||
508 | if (empty($fields)) { | |
509 | $fields = $basefields; | |
510 | } else if (is_string($fields)) { | |
511 | // turn the fields from a string to an array | |
512 | $fields = explode(',', $fields); | |
513 | $fields = array_map('trim', $fields); | |
514 | $fields = array_unique(array_merge($basefields, $fields)); | |
515 | } else if (is_array($fields)) { | |
516 | $fields = array_unique(array_merge($basefields, $fields)); | |
517 | } else { | |
518 | throw new coding_exception('Invalid $fileds parameter in enrol_get_my_courses()'); | |
519 | } | |
520 | if (in_array('*', $fields)) { | |
521 | $fields = array('*'); | |
522 | } | |
523 | ||
524 | $orderby = ""; | |
525 | $sort = trim($sort); | |
526 | if (!empty($sort)) { | |
527 | $rawsorts = explode(',', $sort); | |
528 | $sorts = array(); | |
529 | foreach ($rawsorts as $rawsort) { | |
530 | $rawsort = trim($rawsort); | |
531 | if (strpos($rawsort, 'c.') === 0) { | |
532 | $rawsort = substr($rawsort, 2); | |
533 | } | |
534 | $sorts[] = trim($rawsort); | |
535 | } | |
536 | $sort = 'c.'.implode(',c.', $sorts); | |
537 | $orderby = "ORDER BY $sort"; | |
538 | } | |
539 | ||
df997f84 PS |
540 | $params = array('siteid'=>SITEID); |
541 | ||
542 | if ($onlyactive) { | |
4129338c | 543 | $subwhere = "WHERE ue.status = :active AND e.status = :enabled AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; |
df997f84 PS |
544 | $params['now1'] = round(time(), -2); // improves db caching |
545 | $params['now2'] = $params['now1']; | |
546 | $params['active'] = ENROL_USER_ACTIVE; | |
547 | $params['enabled'] = ENROL_INSTANCE_ENABLED; | |
4129338c PS |
548 | } else { |
549 | $subwhere = ""; | |
df997f84 PS |
550 | } |
551 | ||
552 | $coursefields = 'c.' .join(',c.', $fields); | |
553 | list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); | |
df997f84 | 554 | |
4129338c PS |
555 | //note: we can not use DISTINCT + text fields due to Oracle and MS limitations, that is why we have the subselect there |
556 | $sql = "SELECT $coursefields $ccselect | |
df997f84 | 557 | FROM {course} c |
4129338c PS |
558 | JOIN (SELECT DISTINCT e.courseid |
559 | FROM {enrol} e | |
560 | JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid) | |
561 | $subwhere | |
562 | ) en ON (en.courseid = c.id) | |
df997f84 | 563 | $ccjoin |
4129338c | 564 | WHERE c.id <> :siteid |
df997f84 | 565 | $orderby"; |
87163782 | 566 | $params['userid'] = $userid; |
df997f84 PS |
567 | |
568 | $courses = $DB->get_records_sql($sql, $params); | |
569 | ||
570 | // preload contexts and check visibility | |
571 | foreach ($courses as $id=>$course) { | |
572 | context_instance_preload($course); | |
573 | if ($onlyactive) { | |
574 | if (!$course->visible) { | |
575 | if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { | |
576 | unset($course[$id]); | |
577 | continue; | |
578 | } | |
579 | if (!has_capability('moodle/course:viewhiddencourses', $context, $userid)) { | |
580 | unset($course[$id]); | |
581 | continue; | |
582 | } | |
583 | } | |
584 | } | |
585 | $courses[$id] = $course; | |
586 | } | |
587 | ||
588 | //wow! Is that really all? :-D | |
589 | ||
590 | return $courses; | |
591 | ||
592 | } | |
593 | ||
594 | /** | |
595 | * Called when user is about to be deleted. | |
596 | * @param object $user | |
597 | * @return void | |
598 | */ | |
599 | function enrol_user_delete($user) { | |
600 | global $DB; | |
601 | ||
602 | $plugins = enrol_get_plugins(true); | |
603 | foreach ($plugins as $plugin) { | |
604 | $plugin->user_delete($user); | |
605 | } | |
606 | ||
607 | // force cleanup of all broken enrolments | |
608 | $DB->delete_records('user_enrolments', array('userid'=>$user->id)); | |
609 | } | |
610 | ||
611 | /** | |
612 | * Try to enrol user via default internal auth plugin. | |
613 | * | |
614 | * For now this is always using the manual enrol plugin... | |
615 | * | |
616 | * @param $courseid | |
617 | * @param $userid | |
618 | * @param $roleid | |
619 | * @param $timestart | |
620 | * @param $timeend | |
621 | * @return bool success | |
622 | */ | |
623 | function enrol_try_internal_enrol($courseid, $userid, $roleid = null, $timestart = 0, $timeend = 0) { | |
624 | global $DB; | |
625 | ||
626 | //note: this is hardcoded to manual plugin for now | |
627 | ||
628 | if (!enrol_is_enabled('manual')) { | |
629 | return false; | |
630 | } | |
631 | ||
632 | if (!$enrol = enrol_get_plugin('manual')) { | |
633 | return false; | |
634 | } | |
635 | if (!$instances = $DB->get_records('enrol', array('enrol'=>'manual', 'courseid'=>$courseid, 'status'=>ENROL_INSTANCE_ENABLED), 'sortorder,id ASC')) { | |
636 | return false; | |
637 | } | |
638 | $instance = reset($instances); | |
639 | ||
640 | $enrol->enrol_user($instance, $userid, $roleid, $timestart, $timeend); | |
641 | ||
642 | return true; | |
643 | } | |
644 | ||
645 | /** | |
646 | * All enrol plugins should be based on this class, | |
647 | * this is also the main source of documentation. | |
648 | */ | |
649 | abstract class enrol_plugin { | |
650 | protected $config = null; | |
651 | ||
652 | /** | |
653 | * Returns name of this enrol plugin | |
654 | * @return string | |
655 | */ | |
656 | public function get_name() { | |
657 | // second word in class is always enrol name | |
658 | $words = explode('_', get_class($this)); | |
659 | return $words[1]; | |
660 | } | |
661 | ||
662 | /** | |
663 | * Returns localised name of enrol instance | |
664 | * | |
665 | * @param object $instance (null is accepted too) | |
666 | * @return string | |
667 | */ | |
668 | public function get_instance_name($instance) { | |
669 | if (empty($instance->name)) { | |
670 | $enrol = $this->get_name(); | |
671 | return get_string('pluginname', 'enrol_'.$enrol); | |
672 | } else { | |
673 | return format_string($instance->name); | |
674 | } | |
675 | } | |
676 | ||
677 | /** | |
678 | * Makes sure config is loaded and cached. | |
679 | * @return void | |
680 | */ | |
681 | protected function load_config() { | |
682 | if (!isset($this->config)) { | |
683 | $name = $this->get_name(); | |
684 | if (!$config = get_config("enrol_$name")) { | |
685 | $config = new object(); | |
686 | } | |
687 | $this->config = $config; | |
688 | } | |
689 | } | |
690 | ||
691 | /** | |
692 | * Returns plugin config value | |
693 | * @param string $name | |
694 | * @param string $default value if config does not exist yet | |
695 | * @return string value or default | |
696 | */ | |
697 | public function get_config($name, $default = NULL) { | |
698 | $this->load_config(); | |
699 | return isset($this->config->$name) ? $this->config->$name : $default; | |
700 | } | |
701 | ||
702 | /** | |
703 | * Sets plugin config value | |
704 | * @param string $name name of config | |
705 | * @param string $value string config value, null means delete | |
706 | * @return string value | |
707 | */ | |
708 | public function set_config($name, $value) { | |
47811589 | 709 | $pluginname = $this->get_name(); |
df997f84 PS |
710 | $this->load_config(); |
711 | if ($value === NULL) { | |
712 | unset($this->config->$name); | |
713 | } else { | |
714 | $this->config->$name = $value; | |
715 | } | |
47811589 | 716 | set_config($name, $value, "enrol_$pluginname"); |
df997f84 PS |
717 | } |
718 | ||
719 | /** | |
720 | * Does this plugin assign protected roles are can they be manually removed? | |
721 | * @return bool - false means anybody may tweak roles, it does not use itemid and component when assigning roles | |
722 | */ | |
723 | public function roles_protected() { | |
724 | return true; | |
725 | } | |
726 | ||
727 | /** | |
728 | * Does this plugin allow manual unenrolments? | |
729 | * | |
730 | * @param stdClass $instance course enrol instance | |
731 | * ALl plugins allowing this must implement 'enrol/xxx:unenrol' capability | |
732 | * | |
733 | * @return bool - true means anybody may unenrol others freely, trues means nobody may touch user_enrolments | |
734 | */ | |
735 | public function allow_unenrol(stdClass $instance) { | |
736 | return false; | |
737 | } | |
738 | ||
739 | /** | |
740 | * Does this plugin allow manual changes in user_enrolments table? | |
741 | * | |
742 | * ALl plugins allowing this must implement 'enrol/xxx:manage' capability | |
743 | * | |
744 | * @param stdClass $instance course enrol instance | |
745 | * @return bool - true means it is possible to change enrol period and status in user_enrolments table | |
746 | */ | |
747 | public function allow_manage(stdClass $instance) { | |
748 | return false; | |
749 | } | |
750 | ||
751 | /** | |
752 | * Attempt to automatically enrol current user in course without any interaction, | |
753 | * calling code has to make sure the plugin and instance are active. | |
754 | * | |
755 | * @param stdClass $instance course enrol instance | |
756 | * @param stdClass $user record | |
757 | * @return bool|int false means not enrolled, integer means timeend | |
758 | */ | |
759 | public function try_autoenrol(stdClass $instance) { | |
760 | global $USER; | |
761 | ||
762 | return false; | |
763 | } | |
764 | ||
765 | /** | |
766 | * Attempt to automatically gain temporary guest access to course, | |
767 | * calling code has to make sure the plugin and instance are active. | |
768 | * | |
769 | * @param stdClass $instance course enrol instance | |
770 | * @param stdClass $user record | |
771 | * @return bool|int false means no guest access, integer means timeend | |
772 | */ | |
773 | public function try_guestaccess(stdClass $instance) { | |
774 | global $USER; | |
775 | ||
776 | return false; | |
777 | } | |
778 | ||
779 | /** | |
780 | * Enrol user into course via enrol instance. | |
781 | * | |
782 | * @param stdClass $instance | |
783 | * @param int $userid | |
784 | * @param int $roleid optional role id | |
785 | * @param int $timestart | |
786 | * @param int $timeend | |
787 | * @return void | |
788 | */ | |
789 | public function enrol_user(stdClass $instance, $userid, $roleid = null, $timestart = 0, $timeend = 0) { | |
790 | global $DB, $USER, $CFG; // CFG necessary!!! | |
791 | ||
792 | if ($instance->courseid == SITEID) { | |
793 | throw new coding_exception('invalid attempt to enrol into frontpage course!'); | |
794 | } | |
795 | ||
796 | $name = $this->get_name(); | |
797 | $courseid = $instance->courseid; | |
798 | ||
799 | if ($instance->enrol !== $name) { | |
800 | throw new coding_exception('invalid enrol instance!'); | |
801 | } | |
802 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
803 | ||
804 | $inserted = false; | |
805 | if ($ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
806 | if ($ue->timestart != $timestart or $ue->timeend != $timeend) { | |
807 | $ue->timestart = $timestart; | |
808 | $ue->timeend = $timeend; | |
809 | $ue->modifier = $USER->id; | |
810 | $ue->timemodified = time(); | |
811 | $DB->update_record('user_enrolments', $ue); | |
812 | } | |
813 | } else { | |
814 | $ue = new object(); | |
815 | $ue->enrolid = $instance->id; | |
816 | $ue->status = ENROL_USER_ACTIVE; | |
817 | $ue->userid = $userid; | |
818 | $ue->timestart = $timestart; | |
819 | $ue->timeend = $timeend; | |
820 | $ue->modifier = $USER->id; | |
821 | $ue->timemodified = time(); | |
822 | $ue->id = $DB->insert_record('user_enrolments', $ue); | |
823 | ||
824 | $inserted = true; | |
825 | } | |
826 | ||
827 | if ($roleid) { | |
828 | if ($this->roles_protected()) { | |
829 | role_assign($roleid, $userid, $context->id, 'enrol_'.$name, $instance->id); | |
830 | } else { | |
831 | role_assign($roleid, $userid, $context->id); | |
832 | } | |
833 | } | |
834 | ||
835 | if ($inserted) { | |
836 | // add extra info and trigger event | |
837 | $ue->courseid = $courseid; | |
838 | $ue->enrol = $name; | |
839 | events_trigger('user_enrolled', $ue); | |
840 | } | |
841 | ||
842 | // reset primitive require_login() caching | |
843 | if ($userid == $USER->id) { | |
844 | if (isset($USER->enrol['enrolled'][$courseid])) { | |
845 | unset($USER->enrol['enrolled'][$courseid]); | |
846 | } | |
847 | if (isset($USER->enrol['tempguest'][$courseid])) { | |
848 | unset($USER->enrol['tempguest'][$courseid]); | |
849 | $USER->access = remove_temp_roles($context, $USER->access); | |
850 | } | |
851 | } | |
852 | } | |
853 | ||
854 | /** | |
855 | * Store user_enrolments changes and trigger event. | |
856 | * | |
857 | * @param object $ue | |
858 | * @param int $user id | |
859 | * @param int $status | |
860 | * @param int $timestart | |
861 | * @param int $timeend | |
862 | * @return void | |
863 | */ | |
864 | public function update_user_enrol(stdClass $instance, $userid, $status = NULL, $timestart = NULL, $timeend = NULL) { | |
865 | global $DB, $USER; | |
866 | ||
867 | $name = $this->get_name(); | |
868 | ||
869 | if ($instance->enrol !== $name) { | |
870 | throw new coding_exception('invalid enrol instance!'); | |
871 | } | |
872 | ||
873 | if (!$ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
874 | // weird, user not enrolled | |
875 | return; | |
876 | } | |
877 | ||
878 | $modified = false; | |
879 | if (isset($status) and $ue->status != $status) { | |
880 | $ue->status = $status; | |
881 | $modified = true; | |
882 | } | |
883 | if (isset($timestart) and $ue->timestart != $timestart) { | |
884 | $ue->timestart = $timestart; | |
885 | $modified = true; | |
886 | } | |
887 | if (isset($timeend) and $ue->timeend != $timeend) { | |
888 | $ue->timeend = $timeend; | |
889 | $modified = true; | |
890 | } | |
891 | ||
892 | if (!$modified) { | |
893 | // no change | |
894 | return; | |
895 | } | |
896 | ||
897 | $ue->modifierid = $USER->id; | |
898 | $DB->update_record('user_enrolments', $ue); | |
899 | ||
900 | // trigger event | |
901 | $ue->courseid = $instance->courseid; | |
902 | $ue->enrol = $instance->name; | |
903 | events_trigger('user_unenrol_modified', $ue); | |
904 | } | |
905 | ||
906 | /** | |
907 | * Unenrol user from course, | |
908 | * the last unenrolment removes all remaining roles. | |
909 | * | |
910 | * @param stdClass $instance | |
911 | * @param int $userid | |
912 | * @return void | |
913 | */ | |
914 | public function unenrol_user(stdClass $instance, $userid) { | |
915 | global $CFG, $USER, $DB; | |
916 | ||
917 | $name = $this->get_name(); | |
918 | $courseid = $instance->courseid; | |
919 | ||
920 | if ($instance->enrol !== $name) { | |
921 | throw new coding_exception('invalid enrol instance!'); | |
922 | } | |
923 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
924 | ||
925 | if (!$ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
926 | // weird, user not enrolled | |
927 | return; | |
928 | } | |
929 | ||
930 | role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_'.$name, 'itemid'=>$instance->id)); | |
931 | $DB->delete_records('user_enrolments', array('id'=>$ue->id)); | |
932 | ||
933 | // add extra info and trigger event | |
934 | $ue->courseid = $courseid; | |
935 | $ue->enrol = $name; | |
936 | ||
937 | $sql = "SELECT 'x' | |
938 | FROM {user_enrolments} ue | |
939 | JOIN {enrol} e ON (e.id = ue.enrolid) | |
940 | WHERE ue.userid = :userid AND e.courseid = :courseid"; | |
941 | if ($DB->record_exists_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid))) { | |
942 | $ue->lastenrol = false; | |
943 | events_trigger('user_unenrolled', $ue); | |
944 | // user still has some enrolments, no big cleanup yet | |
945 | } else { | |
946 | // the big cleanup IS necessary! | |
947 | ||
948 | require_once("$CFG->dirroot/group/lib.php"); | |
949 | require_once("$CFG->libdir/gradelib.php"); | |
950 | ||
951 | // remove all remaining roles | |
952 | role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id), true, false); | |
953 | ||
954 | //clean up ALL invisible user data from course if this is the last enrolment - groups, grades, etc. | |
955 | groups_delete_group_members($courseid, $userid); | |
956 | ||
957 | grade_user_unenrol($courseid, $userid); | |
958 | ||
959 | $DB->delete_records('user_lastaccess', array('userid'=>$userid, 'courseid'=>$courseid)); | |
960 | ||
961 | $ue->lastenrol = false; | |
962 | events_trigger('user_unenrolled', $ue); | |
963 | } | |
964 | // reset primitive require_login() caching | |
965 | if ($userid == $USER->id) { | |
966 | if (isset($USER->enrol['enrolled'][$courseid])) { | |
967 | unset($USER->enrol['enrolled'][$courseid]); | |
968 | } | |
969 | if (isset($USER->enrol['tempguest'][$courseid])) { | |
970 | unset($USER->enrol['tempguest'][$courseid]); | |
971 | $USER->access = remove_temp_roles($context, $USER->access); | |
972 | } | |
973 | } | |
974 | } | |
975 | ||
976 | /** | |
977 | * Forces synchronisation of user enrolments. | |
978 | * | |
979 | * This is important especially for external enrol plugins, | |
980 | * this function is called for all enabled enrol plugins | |
981 | * right after every user login. | |
982 | * | |
983 | * @param object $user user record | |
984 | * @return void | |
985 | */ | |
986 | public function sync_user_enrolments($user) { | |
987 | // override if necessary | |
988 | } | |
989 | ||
990 | /** | |
991 | * Returns link to page which may be used to add new instance of enrolment plugin in course. | |
992 | * @param int $courseid | |
993 | * @return moodle_url page url | |
994 | */ | |
995 | public function get_candidate_link($courseid) { | |
996 | // override for most plugins, check if instance already exists in cases only one instance is supported | |
997 | return NULL; | |
998 | } | |
999 | ||
1000 | /** | |
1001 | * Is it possible to delete enrol instance via standard UI? | |
1002 | * | |
1003 | * @param object $instance | |
1004 | * @return bool | |
1005 | */ | |
1006 | public function instance_deleteable($instance) { | |
1007 | return true; | |
1008 | } | |
1009 | ||
1010 | /** | |
1011 | * Returns link to manual enrol UI if exists. | |
1012 | * Does the access control tests automatically. | |
1013 | * | |
1014 | * @param object $instance | |
1015 | * @return moodle_url | |
1016 | */ | |
1017 | public function get_manual_enrol_link($instance) { | |
1018 | return NULL; | |
1019 | } | |
1020 | ||
1021 | /** | |
1022 | * Returns list of unenrol links for all enrol instances in course. | |
1023 | * | |
1024 | * @param int $courseid | |
1025 | * @return moodle_url | |
1026 | */ | |
1027 | public function get_unenrolself_link($instance) { | |
1028 | global $USER, $CFG, $DB; | |
1029 | ||
1030 | $name = $this->get_name(); | |
1031 | if ($instance->enrol !== $name) { | |
1032 | throw new coding_exception('invalid enrol instance!'); | |
1033 | } | |
1034 | ||
1035 | if ($instance->courseid == SITEID) { | |
1036 | return NULL; | |
1037 | } | |
1038 | ||
1039 | if (!enrol_is_enabled($name)) { | |
1040 | return NULL; | |
1041 | } | |
1042 | ||
1043 | if ($instance->status != ENROL_INSTANCE_ENABLED) { | |
1044 | return NULL; | |
1045 | } | |
1046 | ||
1047 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
1048 | $courseid = $instance->courseid; | |
1049 | ||
1050 | if (!file_exists("$CFG->dirroot/enrol/$name/unenrolself.php")) { | |
1051 | return NULL; | |
1052 | } | |
1053 | ||
1054 | $context = get_context_instance(CONTEXT_COURSE, $courseid); | |
1055 | if (!has_capability("enrol/$name:unenrolself", $context)) { | |
1056 | return NULL; | |
1057 | } | |
1058 | ||
1059 | if (!$DB->record_exists('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$USER->id, 'status'=>ENROL_USER_ACTIVE))) { | |
1060 | return NULL; | |
1061 | } | |
1062 | ||
1063 | return new moodle_url("/enrol/$name/unenrolself.php", array('enrolid'=>$instance->id));; | |
1064 | } | |
1065 | ||
1066 | /** | |
1067 | * Adds enrol instance UI to course edit form | |
1068 | * | |
1069 | * @param object $instance enrol instance or null if does not exist yet | |
1070 | * @param MoodleQuickForm $mform | |
1071 | * @param object $data | |
1072 | * @param object $context context of existing course or parent category if course does not exist | |
1073 | * @return void | |
1074 | */ | |
1075 | public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { | |
1076 | // override - usually at least enable/disable switch, has to add own form header | |
1077 | } | |
1078 | ||
1079 | /** | |
1080 | * Validates course edit form data | |
1081 | * | |
1082 | * @param object $instance enrol instance or null if does not exist yet | |
1083 | * @param array $data | |
1084 | * @param object $context context of existing course or parent category if course does not exist | |
1085 | * @return array errors array | |
1086 | */ | |
1087 | public function course_edit_validation($instance, array $data, $context) { | |
1088 | return array(); | |
1089 | } | |
1090 | ||
1091 | /** | |
1092 | * Called after updating/inserting course. | |
1093 | * | |
1094 | * @param bool $inserted true if course just inserted | |
1095 | * @param object $course | |
1096 | * @param object $data form data | |
1097 | * @return void | |
1098 | */ | |
1099 | public function course_updated($inserted, $course, $data) { | |
1100 | // override if settings on course edit page or some automatic sync needed | |
1101 | } | |
1102 | ||
1103 | /** | |
1104 | * Add new instance of enrol plugin settings. | |
1105 | * @param object $course | |
1106 | * @param array instance fields | |
1107 | * @return int id of new instance | |
1108 | */ | |
1109 | public function add_instance($course, array $fields = NULL) { | |
1110 | global $DB; | |
1111 | ||
1112 | if ($course->id == SITEID) { | |
1113 | throw new coding_exception('Invalid request to add enrol instance to frontpage.'); | |
1114 | } | |
1115 | ||
1116 | $instance = new object(); | |
1117 | $instance->enrol = $this->get_name(); | |
1118 | $instance->status = ENROL_INSTANCE_ENABLED; | |
1119 | $instance->courseid = $course->id; | |
1120 | $instance->enrolstartdate = 0; | |
1121 | $instance->enrolenddate = 0; | |
1122 | $instance->timemodified = time(); | |
1123 | $instance->timecreated = $instance->timemodified; | |
1124 | $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); | |
1125 | ||
1126 | $fields = (array)$fields; | |
1127 | unset($fields['enrol']); | |
1128 | unset($fields['courseid']); | |
1129 | unset($fields['sortorder']); | |
1130 | foreach($fields as $field=>$value) { | |
1131 | $instance->$field = $value; | |
1132 | } | |
1133 | ||
1134 | return $DB->insert_record('enrol', $instance); | |
1135 | } | |
1136 | ||
1137 | /** | |
1138 | * Add new instance of enrol plugin with default settings, | |
1139 | * called when adding new instance manually or when adding new course. | |
1140 | * | |
1141 | * Not all plugins support this. | |
1142 | * | |
1143 | * @param object $course | |
1144 | * @return int id of new instance or null if no default supported | |
1145 | */ | |
1146 | public function add_default_instance($course) { | |
1147 | return null; | |
1148 | } | |
1149 | ||
1150 | /** | |
1151 | * Delete course enrol plugin instance, unenrol all users. | |
1152 | * @param object $instance | |
1153 | * @return void | |
1154 | */ | |
1155 | public function delete_instance($instance) { | |
1156 | global $DB; | |
1157 | ||
1158 | $name = $this->get_name(); | |
1159 | if ($instance->enrol !== $name) { | |
1160 | throw new coding_exception('invalid enrol instance!'); | |
1161 | } | |
1162 | ||
1163 | //first unenrol all users | |
1164 | $participants = $DB->get_recordset('user_enrolments', array('enrolid'=>$instance->id)); | |
1165 | foreach ($participants as $participant) { | |
1166 | $this->unenrol_user($instance, $participant->userid); | |
1167 | } | |
1168 | $participants->close(); | |
1169 | ||
1170 | // now clean up all remainders that were not removed correctly | |
1171 | $DB->delete_records('role_assignments', array('itemid'=>$instance->id, 'component'=>$name)); | |
1172 | $DB->delete_records('user_enrolments', array('enrolid'=>$instance->id)); | |
1173 | ||
1174 | // finally drop the enrol row | |
1175 | $DB->delete_records('enrol', array('id'=>$instance->id)); | |
1176 | } | |
1177 | ||
1178 | /** | |
1179 | * Creates course enrol form, checks if form submitted | |
1180 | * and enrols user if necessary. It can also redirect. | |
1181 | * | |
1182 | * @param stdClass $instance | |
1183 | * @return string html text, usually a form in a text box | |
1184 | */ | |
1185 | public function enrol_page_hook(stdClass $instance) { | |
1186 | return null; | |
1187 | } | |
1188 | ||
1189 | /** | |
1190 | * Adds navigation links into course admin block. | |
1191 | * | |
1192 | * By defaults looks for manage links only. | |
1193 | * | |
1194 | * @param navigation_node $instancesnode | |
1195 | * @param object $instance | |
1196 | * @return moodle_url; | |
1197 | */ | |
1198 | public function add_course_navigation($instancesnode, stdClass $instance) { | |
1199 | if ($managelink = $this->get_manage_link($instance)) { | |
1200 | $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); | |
1201 | } | |
1202 | } | |
1203 | ||
1204 | /** | |
1205 | * Returns enrolment instance manage link. | |
1206 | * | |
1207 | * By defaults looks for manage.php file and tests for manage capability. | |
1208 | * | |
1209 | * @param object $instance | |
1210 | * @return moodle_url; | |
1211 | */ | |
1212 | public function get_manage_link($instance) { | |
1213 | global $CFG, $DB; | |
1214 | ||
1215 | $name = $this->get_name(); | |
1216 | ||
1217 | if ($instance->enrol !== $name) { | |
1218 | throw new coding_exception('Invalid enrol instance type!'); | |
1219 | } | |
1220 | ||
1221 | if (!file_exists("$CFG->dirroot/enrol/$name/manage.php")) { | |
1222 | return NULL; | |
1223 | } | |
1224 | ||
1225 | if ($instance->courseid == SITEID) { | |
1226 | // no enrolments on the frontpage, only roles there allowed | |
1227 | return NULL; | |
1228 | } | |
1229 | ||
1230 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); | |
1231 | if (!has_capability('enrol/'.$name.':manage', $context)) { | |
1232 | return NULL; | |
1233 | } | |
1234 | ||
1235 | return new moodle_url("/enrol/$name/manage.php", array('enrolid'=>$instance->id)); | |
1236 | } | |
1237 | ||
1238 | /** | |
1239 | * Reads version.php and determines if it is necessary | |
1240 | * to execute the cron job now. | |
1241 | * @return bool | |
1242 | */ | |
1243 | public function is_cron_required() { | |
1244 | global $CFG; | |
1245 | ||
1246 | $name = $this->get_name(); | |
1247 | $versionfile = "$CFG->dirroot/enrol/$name/version.php"; | |
1248 | $plugin = new object(); | |
1249 | include($versionfile); | |
1250 | if (empty($plugin->cron)) { | |
1251 | return false; | |
1252 | } | |
1253 | $lastexecuted = $this->get_config('lastcron', 0); | |
1254 | if ($lastexecuted + $plugin->cron < time()) { | |
1255 | return true; | |
1256 | } else { | |
1257 | return false; | |
1258 | } | |
1259 | } | |
1260 | ||
1261 | /** | |
1262 | * Called for all enabled enrol plugins that returned true from is_cron_required(). | |
1263 | * @return void | |
1264 | */ | |
1265 | public function cron() { | |
1266 | } | |
1267 | ||
1268 | /** | |
1269 | * Called when user is about to be deleted | |
1270 | * @param object $user | |
1271 | * @return void | |
1272 | */ | |
1273 | public function user_delete($user) { | |
1274 | global $DB; | |
1275 | ||
1276 | $sql = "SELECT e.* | |
1277 | FROM {enrol} e | |
1278 | JOIN {user_enrolments} ue ON (ue.courseid = e.courseid) | |
1279 | WHERE e.enrol = :meta AND ue.userid = :userid"; | |
1280 | $params = array('name'=>$this->get_name(), 'userid'=>$user->id); | |
1281 | ||
1282 | $rs = $DB->get_records_recordset($sql, $params); | |
1283 | foreach($rs as $instance) { | |
1284 | $this->unenrol_user($instance, $user->id); | |
1285 | } | |
1286 | $rs->close(); | |
1287 | } | |
1288 | } | |
1289 |