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'); | |
440 | $wheres = " AND ".implode(" AND ", $wheres); | |
441 | ||
442 | $sql = "SELECT DISTINCT $coursefields $ccselect | |
443 | FROM {course} c | |
444 | JOIN {enrol} e ON (e.courseid = c.id AND e.status = :enabled) | |
445 | JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid AND ue.status = :active) | |
446 | $ccjoin | |
447 | WHERE ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2) | |
448 | $wheres | |
449 | $orderby"; | |
450 | $params['userid'] = $USER->id; | |
451 | $params['active'] = ENROL_USER_ACTIVE; | |
452 | $params['enabled'] = ENROL_INSTANCE_ENABLED; | |
453 | $params['now1'] = round(time(), -2); // improves db caching | |
454 | $params['now2'] = $params['now1']; | |
455 | ||
456 | $courses = $DB->get_records_sql($sql, $params, 0, $limit); | |
457 | ||
458 | // preload contexts and check visibility | |
459 | foreach ($courses as $id=>$course) { | |
460 | context_instance_preload($course); | |
461 | if (!$course->visible) { | |
462 | if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { | |
463 | unset($course[$id]); | |
464 | continue; | |
465 | } | |
466 | if (!has_capability('moodle/course:viewhiddencourses', $context)) { | |
467 | unset($course[$id]); | |
468 | continue; | |
469 | } | |
470 | } | |
471 | $courses[$id] = $course; | |
472 | } | |
473 | ||
474 | //wow! Is that really all? :-D | |
475 | ||
476 | return $courses; | |
477 | } | |
478 | ||
479 | /** | |
480 | * Returns list of courses user is enrolled into. | |
481 | * | |
482 | * - $fields is an array of fieldnames to ADD | |
483 | * so name the fields you really need, which will | |
484 | * be added and uniq'd | |
485 | * | |
486 | * @param int $userid | |
487 | * @param bool $onlyactive return only active enrolments in courses user may see | |
488 | * @param strin|array $fields | |
489 | * @param string $sort | |
490 | * @return array | |
491 | */ | |
492 | function enrol_get_users_courses($userid, $onlyactive = false, $fields = NULL, $sort = 'visible DESC,sortorder ASC') { | |
493 | global $DB; | |
494 | ||
495 | // Guest account does not have any courses | |
87163782 | 496 | if (isguestuser($userid) or empty($userid)) { |
df997f84 PS |
497 | return(array()); |
498 | } | |
499 | ||
500 | $basefields = array('id', 'category', 'sortorder', | |
501 | 'shortname', 'fullname', 'idnumber', | |
502 | 'startdate', 'visible', | |
503 | 'groupmode', 'groupmodeforce'); | |
504 | ||
505 | if (empty($fields)) { | |
506 | $fields = $basefields; | |
507 | } else if (is_string($fields)) { | |
508 | // turn the fields from a string to an array | |
509 | $fields = explode(',', $fields); | |
510 | $fields = array_map('trim', $fields); | |
511 | $fields = array_unique(array_merge($basefields, $fields)); | |
512 | } else if (is_array($fields)) { | |
513 | $fields = array_unique(array_merge($basefields, $fields)); | |
514 | } else { | |
515 | throw new coding_exception('Invalid $fileds parameter in enrol_get_my_courses()'); | |
516 | } | |
517 | if (in_array('*', $fields)) { | |
518 | $fields = array('*'); | |
519 | } | |
520 | ||
521 | $orderby = ""; | |
522 | $sort = trim($sort); | |
523 | if (!empty($sort)) { | |
524 | $rawsorts = explode(',', $sort); | |
525 | $sorts = array(); | |
526 | foreach ($rawsorts as $rawsort) { | |
527 | $rawsort = trim($rawsort); | |
528 | if (strpos($rawsort, 'c.') === 0) { | |
529 | $rawsort = substr($rawsort, 2); | |
530 | } | |
531 | $sorts[] = trim($rawsort); | |
532 | } | |
533 | $sort = 'c.'.implode(',c.', $sorts); | |
534 | $orderby = "ORDER BY $sort"; | |
535 | } | |
536 | ||
537 | $wheres = array("c.id <> :siteid"); | |
538 | $params = array('siteid'=>SITEID); | |
539 | ||
540 | if ($onlyactive) { | |
541 | $wheres[] = "ue.status = :active"; | |
542 | $wheres[] = "e.status = :enabled"; | |
543 | $wheres[] = "ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; | |
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; | |
548 | } | |
549 | ||
550 | $coursefields = 'c.' .join(',c.', $fields); | |
551 | list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); | |
552 | $wheres = "WHERE ".implode(" AND ", $wheres); | |
553 | ||
554 | $sql = "SELECT DISTINCT $coursefields $ccselect | |
555 | FROM {course} c | |
556 | JOIN {enrol} e ON (e.courseid = c.id) | |
557 | JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid) | |
558 | $ccjoin | |
559 | $wheres | |
560 | $orderby"; | |
87163782 | 561 | $params['userid'] = $userid; |
df997f84 PS |
562 | |
563 | $courses = $DB->get_records_sql($sql, $params); | |
564 | ||
565 | // preload contexts and check visibility | |
566 | foreach ($courses as $id=>$course) { | |
567 | context_instance_preload($course); | |
568 | if ($onlyactive) { | |
569 | if (!$course->visible) { | |
570 | if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { | |
571 | unset($course[$id]); | |
572 | continue; | |
573 | } | |
574 | if (!has_capability('moodle/course:viewhiddencourses', $context, $userid)) { | |
575 | unset($course[$id]); | |
576 | continue; | |
577 | } | |
578 | } | |
579 | } | |
580 | $courses[$id] = $course; | |
581 | } | |
582 | ||
583 | //wow! Is that really all? :-D | |
584 | ||
585 | return $courses; | |
586 | ||
587 | } | |
588 | ||
589 | /** | |
590 | * Called when user is about to be deleted. | |
591 | * @param object $user | |
592 | * @return void | |
593 | */ | |
594 | function enrol_user_delete($user) { | |
595 | global $DB; | |
596 | ||
597 | $plugins = enrol_get_plugins(true); | |
598 | foreach ($plugins as $plugin) { | |
599 | $plugin->user_delete($user); | |
600 | } | |
601 | ||
602 | // force cleanup of all broken enrolments | |
603 | $DB->delete_records('user_enrolments', array('userid'=>$user->id)); | |
604 | } | |
605 | ||
606 | /** | |
607 | * Try to enrol user via default internal auth plugin. | |
608 | * | |
609 | * For now this is always using the manual enrol plugin... | |
610 | * | |
611 | * @param $courseid | |
612 | * @param $userid | |
613 | * @param $roleid | |
614 | * @param $timestart | |
615 | * @param $timeend | |
616 | * @return bool success | |
617 | */ | |
618 | function enrol_try_internal_enrol($courseid, $userid, $roleid = null, $timestart = 0, $timeend = 0) { | |
619 | global $DB; | |
620 | ||
621 | //note: this is hardcoded to manual plugin for now | |
622 | ||
623 | if (!enrol_is_enabled('manual')) { | |
624 | return false; | |
625 | } | |
626 | ||
627 | if (!$enrol = enrol_get_plugin('manual')) { | |
628 | return false; | |
629 | } | |
630 | if (!$instances = $DB->get_records('enrol', array('enrol'=>'manual', 'courseid'=>$courseid, 'status'=>ENROL_INSTANCE_ENABLED), 'sortorder,id ASC')) { | |
631 | return false; | |
632 | } | |
633 | $instance = reset($instances); | |
634 | ||
635 | $enrol->enrol_user($instance, $userid, $roleid, $timestart, $timeend); | |
636 | ||
637 | return true; | |
638 | } | |
639 | ||
640 | /** | |
641 | * All enrol plugins should be based on this class, | |
642 | * this is also the main source of documentation. | |
643 | */ | |
644 | abstract class enrol_plugin { | |
645 | protected $config = null; | |
646 | ||
647 | /** | |
648 | * Returns name of this enrol plugin | |
649 | * @return string | |
650 | */ | |
651 | public function get_name() { | |
652 | // second word in class is always enrol name | |
653 | $words = explode('_', get_class($this)); | |
654 | return $words[1]; | |
655 | } | |
656 | ||
657 | /** | |
658 | * Returns localised name of enrol instance | |
659 | * | |
660 | * @param object $instance (null is accepted too) | |
661 | * @return string | |
662 | */ | |
663 | public function get_instance_name($instance) { | |
664 | if (empty($instance->name)) { | |
665 | $enrol = $this->get_name(); | |
666 | return get_string('pluginname', 'enrol_'.$enrol); | |
667 | } else { | |
668 | return format_string($instance->name); | |
669 | } | |
670 | } | |
671 | ||
672 | /** | |
673 | * Makes sure config is loaded and cached. | |
674 | * @return void | |
675 | */ | |
676 | protected function load_config() { | |
677 | if (!isset($this->config)) { | |
678 | $name = $this->get_name(); | |
679 | if (!$config = get_config("enrol_$name")) { | |
680 | $config = new object(); | |
681 | } | |
682 | $this->config = $config; | |
683 | } | |
684 | } | |
685 | ||
686 | /** | |
687 | * Returns plugin config value | |
688 | * @param string $name | |
689 | * @param string $default value if config does not exist yet | |
690 | * @return string value or default | |
691 | */ | |
692 | public function get_config($name, $default = NULL) { | |
693 | $this->load_config(); | |
694 | return isset($this->config->$name) ? $this->config->$name : $default; | |
695 | } | |
696 | ||
697 | /** | |
698 | * Sets plugin config value | |
699 | * @param string $name name of config | |
700 | * @param string $value string config value, null means delete | |
701 | * @return string value | |
702 | */ | |
703 | public function set_config($name, $value) { | |
704 | $name = $this->get_name(); | |
705 | $this->load_config(); | |
706 | if ($value === NULL) { | |
707 | unset($this->config->$name); | |
708 | } else { | |
709 | $this->config->$name = $value; | |
710 | } | |
711 | set_config($name, $value, "enrol_$name"); | |
712 | } | |
713 | ||
714 | /** | |
715 | * Does this plugin assign protected roles are can they be manually removed? | |
716 | * @return bool - false means anybody may tweak roles, it does not use itemid and component when assigning roles | |
717 | */ | |
718 | public function roles_protected() { | |
719 | return true; | |
720 | } | |
721 | ||
722 | /** | |
723 | * Does this plugin allow manual unenrolments? | |
724 | * | |
725 | * @param stdClass $instance course enrol instance | |
726 | * ALl plugins allowing this must implement 'enrol/xxx:unenrol' capability | |
727 | * | |
728 | * @return bool - true means anybody may unenrol others freely, trues means nobody may touch user_enrolments | |
729 | */ | |
730 | public function allow_unenrol(stdClass $instance) { | |
731 | return false; | |
732 | } | |
733 | ||
734 | /** | |
735 | * Does this plugin allow manual changes in user_enrolments table? | |
736 | * | |
737 | * ALl plugins allowing this must implement 'enrol/xxx:manage' capability | |
738 | * | |
739 | * @param stdClass $instance course enrol instance | |
740 | * @return bool - true means it is possible to change enrol period and status in user_enrolments table | |
741 | */ | |
742 | public function allow_manage(stdClass $instance) { | |
743 | return false; | |
744 | } | |
745 | ||
746 | /** | |
747 | * Attempt to automatically enrol current user in course without any interaction, | |
748 | * calling code has to make sure the plugin and instance are active. | |
749 | * | |
750 | * @param stdClass $instance course enrol instance | |
751 | * @param stdClass $user record | |
752 | * @return bool|int false means not enrolled, integer means timeend | |
753 | */ | |
754 | public function try_autoenrol(stdClass $instance) { | |
755 | global $USER; | |
756 | ||
757 | return false; | |
758 | } | |
759 | ||
760 | /** | |
761 | * Attempt to automatically gain temporary guest access to course, | |
762 | * calling code has to make sure the plugin and instance are active. | |
763 | * | |
764 | * @param stdClass $instance course enrol instance | |
765 | * @param stdClass $user record | |
766 | * @return bool|int false means no guest access, integer means timeend | |
767 | */ | |
768 | public function try_guestaccess(stdClass $instance) { | |
769 | global $USER; | |
770 | ||
771 | return false; | |
772 | } | |
773 | ||
774 | /** | |
775 | * Enrol user into course via enrol instance. | |
776 | * | |
777 | * @param stdClass $instance | |
778 | * @param int $userid | |
779 | * @param int $roleid optional role id | |
780 | * @param int $timestart | |
781 | * @param int $timeend | |
782 | * @return void | |
783 | */ | |
784 | public function enrol_user(stdClass $instance, $userid, $roleid = null, $timestart = 0, $timeend = 0) { | |
785 | global $DB, $USER, $CFG; // CFG necessary!!! | |
786 | ||
787 | if ($instance->courseid == SITEID) { | |
788 | throw new coding_exception('invalid attempt to enrol into frontpage course!'); | |
789 | } | |
790 | ||
791 | $name = $this->get_name(); | |
792 | $courseid = $instance->courseid; | |
793 | ||
794 | if ($instance->enrol !== $name) { | |
795 | throw new coding_exception('invalid enrol instance!'); | |
796 | } | |
797 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
798 | ||
799 | $inserted = false; | |
800 | if ($ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
801 | if ($ue->timestart != $timestart or $ue->timeend != $timeend) { | |
802 | $ue->timestart = $timestart; | |
803 | $ue->timeend = $timeend; | |
804 | $ue->modifier = $USER->id; | |
805 | $ue->timemodified = time(); | |
806 | $DB->update_record('user_enrolments', $ue); | |
807 | } | |
808 | } else { | |
809 | $ue = new object(); | |
810 | $ue->enrolid = $instance->id; | |
811 | $ue->status = ENROL_USER_ACTIVE; | |
812 | $ue->userid = $userid; | |
813 | $ue->timestart = $timestart; | |
814 | $ue->timeend = $timeend; | |
815 | $ue->modifier = $USER->id; | |
816 | $ue->timemodified = time(); | |
817 | $ue->id = $DB->insert_record('user_enrolments', $ue); | |
818 | ||
819 | $inserted = true; | |
820 | } | |
821 | ||
822 | if ($roleid) { | |
823 | if ($this->roles_protected()) { | |
824 | role_assign($roleid, $userid, $context->id, 'enrol_'.$name, $instance->id); | |
825 | } else { | |
826 | role_assign($roleid, $userid, $context->id); | |
827 | } | |
828 | } | |
829 | ||
830 | if ($inserted) { | |
831 | // add extra info and trigger event | |
832 | $ue->courseid = $courseid; | |
833 | $ue->enrol = $name; | |
834 | events_trigger('user_enrolled', $ue); | |
835 | } | |
836 | ||
837 | // reset primitive require_login() caching | |
838 | if ($userid == $USER->id) { | |
839 | if (isset($USER->enrol['enrolled'][$courseid])) { | |
840 | unset($USER->enrol['enrolled'][$courseid]); | |
841 | } | |
842 | if (isset($USER->enrol['tempguest'][$courseid])) { | |
843 | unset($USER->enrol['tempguest'][$courseid]); | |
844 | $USER->access = remove_temp_roles($context, $USER->access); | |
845 | } | |
846 | } | |
847 | } | |
848 | ||
849 | /** | |
850 | * Store user_enrolments changes and trigger event. | |
851 | * | |
852 | * @param object $ue | |
853 | * @param int $user id | |
854 | * @param int $status | |
855 | * @param int $timestart | |
856 | * @param int $timeend | |
857 | * @return void | |
858 | */ | |
859 | public function update_user_enrol(stdClass $instance, $userid, $status = NULL, $timestart = NULL, $timeend = NULL) { | |
860 | global $DB, $USER; | |
861 | ||
862 | $name = $this->get_name(); | |
863 | ||
864 | if ($instance->enrol !== $name) { | |
865 | throw new coding_exception('invalid enrol instance!'); | |
866 | } | |
867 | ||
868 | if (!$ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
869 | // weird, user not enrolled | |
870 | return; | |
871 | } | |
872 | ||
873 | $modified = false; | |
874 | if (isset($status) and $ue->status != $status) { | |
875 | $ue->status = $status; | |
876 | $modified = true; | |
877 | } | |
878 | if (isset($timestart) and $ue->timestart != $timestart) { | |
879 | $ue->timestart = $timestart; | |
880 | $modified = true; | |
881 | } | |
882 | if (isset($timeend) and $ue->timeend != $timeend) { | |
883 | $ue->timeend = $timeend; | |
884 | $modified = true; | |
885 | } | |
886 | ||
887 | if (!$modified) { | |
888 | // no change | |
889 | return; | |
890 | } | |
891 | ||
892 | $ue->modifierid = $USER->id; | |
893 | $DB->update_record('user_enrolments', $ue); | |
894 | ||
895 | // trigger event | |
896 | $ue->courseid = $instance->courseid; | |
897 | $ue->enrol = $instance->name; | |
898 | events_trigger('user_unenrol_modified', $ue); | |
899 | } | |
900 | ||
901 | /** | |
902 | * Unenrol user from course, | |
903 | * the last unenrolment removes all remaining roles. | |
904 | * | |
905 | * @param stdClass $instance | |
906 | * @param int $userid | |
907 | * @return void | |
908 | */ | |
909 | public function unenrol_user(stdClass $instance, $userid) { | |
910 | global $CFG, $USER, $DB; | |
911 | ||
912 | $name = $this->get_name(); | |
913 | $courseid = $instance->courseid; | |
914 | ||
915 | if ($instance->enrol !== $name) { | |
916 | throw new coding_exception('invalid enrol instance!'); | |
917 | } | |
918 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
919 | ||
920 | if (!$ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) { | |
921 | // weird, user not enrolled | |
922 | return; | |
923 | } | |
924 | ||
925 | role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_'.$name, 'itemid'=>$instance->id)); | |
926 | $DB->delete_records('user_enrolments', array('id'=>$ue->id)); | |
927 | ||
928 | // add extra info and trigger event | |
929 | $ue->courseid = $courseid; | |
930 | $ue->enrol = $name; | |
931 | ||
932 | $sql = "SELECT 'x' | |
933 | FROM {user_enrolments} ue | |
934 | JOIN {enrol} e ON (e.id = ue.enrolid) | |
935 | WHERE ue.userid = :userid AND e.courseid = :courseid"; | |
936 | if ($DB->record_exists_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid))) { | |
937 | $ue->lastenrol = false; | |
938 | events_trigger('user_unenrolled', $ue); | |
939 | // user still has some enrolments, no big cleanup yet | |
940 | } else { | |
941 | // the big cleanup IS necessary! | |
942 | ||
943 | require_once("$CFG->dirroot/group/lib.php"); | |
944 | require_once("$CFG->libdir/gradelib.php"); | |
945 | ||
946 | // remove all remaining roles | |
947 | role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id), true, false); | |
948 | ||
949 | //clean up ALL invisible user data from course if this is the last enrolment - groups, grades, etc. | |
950 | groups_delete_group_members($courseid, $userid); | |
951 | ||
952 | grade_user_unenrol($courseid, $userid); | |
953 | ||
954 | $DB->delete_records('user_lastaccess', array('userid'=>$userid, 'courseid'=>$courseid)); | |
955 | ||
956 | $ue->lastenrol = false; | |
957 | events_trigger('user_unenrolled', $ue); | |
958 | } | |
959 | // reset primitive require_login() caching | |
960 | if ($userid == $USER->id) { | |
961 | if (isset($USER->enrol['enrolled'][$courseid])) { | |
962 | unset($USER->enrol['enrolled'][$courseid]); | |
963 | } | |
964 | if (isset($USER->enrol['tempguest'][$courseid])) { | |
965 | unset($USER->enrol['tempguest'][$courseid]); | |
966 | $USER->access = remove_temp_roles($context, $USER->access); | |
967 | } | |
968 | } | |
969 | } | |
970 | ||
971 | /** | |
972 | * Forces synchronisation of user enrolments. | |
973 | * | |
974 | * This is important especially for external enrol plugins, | |
975 | * this function is called for all enabled enrol plugins | |
976 | * right after every user login. | |
977 | * | |
978 | * @param object $user user record | |
979 | * @return void | |
980 | */ | |
981 | public function sync_user_enrolments($user) { | |
982 | // override if necessary | |
983 | } | |
984 | ||
985 | /** | |
986 | * Returns link to page which may be used to add new instance of enrolment plugin in course. | |
987 | * @param int $courseid | |
988 | * @return moodle_url page url | |
989 | */ | |
990 | public function get_candidate_link($courseid) { | |
991 | // override for most plugins, check if instance already exists in cases only one instance is supported | |
992 | return NULL; | |
993 | } | |
994 | ||
995 | /** | |
996 | * Is it possible to delete enrol instance via standard UI? | |
997 | * | |
998 | * @param object $instance | |
999 | * @return bool | |
1000 | */ | |
1001 | public function instance_deleteable($instance) { | |
1002 | return true; | |
1003 | } | |
1004 | ||
1005 | /** | |
1006 | * Returns link to manual enrol UI if exists. | |
1007 | * Does the access control tests automatically. | |
1008 | * | |
1009 | * @param object $instance | |
1010 | * @return moodle_url | |
1011 | */ | |
1012 | public function get_manual_enrol_link($instance) { | |
1013 | return NULL; | |
1014 | } | |
1015 | ||
1016 | /** | |
1017 | * Returns list of unenrol links for all enrol instances in course. | |
1018 | * | |
1019 | * @param int $courseid | |
1020 | * @return moodle_url | |
1021 | */ | |
1022 | public function get_unenrolself_link($instance) { | |
1023 | global $USER, $CFG, $DB; | |
1024 | ||
1025 | $name = $this->get_name(); | |
1026 | if ($instance->enrol !== $name) { | |
1027 | throw new coding_exception('invalid enrol instance!'); | |
1028 | } | |
1029 | ||
1030 | if ($instance->courseid == SITEID) { | |
1031 | return NULL; | |
1032 | } | |
1033 | ||
1034 | if (!enrol_is_enabled($name)) { | |
1035 | return NULL; | |
1036 | } | |
1037 | ||
1038 | if ($instance->status != ENROL_INSTANCE_ENABLED) { | |
1039 | return NULL; | |
1040 | } | |
1041 | ||
1042 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); | |
1043 | $courseid = $instance->courseid; | |
1044 | ||
1045 | if (!file_exists("$CFG->dirroot/enrol/$name/unenrolself.php")) { | |
1046 | return NULL; | |
1047 | } | |
1048 | ||
1049 | $context = get_context_instance(CONTEXT_COURSE, $courseid); | |
1050 | if (!has_capability("enrol/$name:unenrolself", $context)) { | |
1051 | return NULL; | |
1052 | } | |
1053 | ||
1054 | if (!$DB->record_exists('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$USER->id, 'status'=>ENROL_USER_ACTIVE))) { | |
1055 | return NULL; | |
1056 | } | |
1057 | ||
1058 | return new moodle_url("/enrol/$name/unenrolself.php", array('enrolid'=>$instance->id));; | |
1059 | } | |
1060 | ||
1061 | /** | |
1062 | * Adds enrol instance UI to course edit form | |
1063 | * | |
1064 | * @param object $instance enrol instance or null if does not exist yet | |
1065 | * @param MoodleQuickForm $mform | |
1066 | * @param object $data | |
1067 | * @param object $context context of existing course or parent category if course does not exist | |
1068 | * @return void | |
1069 | */ | |
1070 | public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { | |
1071 | // override - usually at least enable/disable switch, has to add own form header | |
1072 | } | |
1073 | ||
1074 | /** | |
1075 | * Validates course edit form data | |
1076 | * | |
1077 | * @param object $instance enrol instance or null if does not exist yet | |
1078 | * @param array $data | |
1079 | * @param object $context context of existing course or parent category if course does not exist | |
1080 | * @return array errors array | |
1081 | */ | |
1082 | public function course_edit_validation($instance, array $data, $context) { | |
1083 | return array(); | |
1084 | } | |
1085 | ||
1086 | /** | |
1087 | * Called after updating/inserting course. | |
1088 | * | |
1089 | * @param bool $inserted true if course just inserted | |
1090 | * @param object $course | |
1091 | * @param object $data form data | |
1092 | * @return void | |
1093 | */ | |
1094 | public function course_updated($inserted, $course, $data) { | |
1095 | // override if settings on course edit page or some automatic sync needed | |
1096 | } | |
1097 | ||
1098 | /** | |
1099 | * Add new instance of enrol plugin settings. | |
1100 | * @param object $course | |
1101 | * @param array instance fields | |
1102 | * @return int id of new instance | |
1103 | */ | |
1104 | public function add_instance($course, array $fields = NULL) { | |
1105 | global $DB; | |
1106 | ||
1107 | if ($course->id == SITEID) { | |
1108 | throw new coding_exception('Invalid request to add enrol instance to frontpage.'); | |
1109 | } | |
1110 | ||
1111 | $instance = new object(); | |
1112 | $instance->enrol = $this->get_name(); | |
1113 | $instance->status = ENROL_INSTANCE_ENABLED; | |
1114 | $instance->courseid = $course->id; | |
1115 | $instance->enrolstartdate = 0; | |
1116 | $instance->enrolenddate = 0; | |
1117 | $instance->timemodified = time(); | |
1118 | $instance->timecreated = $instance->timemodified; | |
1119 | $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); | |
1120 | ||
1121 | $fields = (array)$fields; | |
1122 | unset($fields['enrol']); | |
1123 | unset($fields['courseid']); | |
1124 | unset($fields['sortorder']); | |
1125 | foreach($fields as $field=>$value) { | |
1126 | $instance->$field = $value; | |
1127 | } | |
1128 | ||
1129 | return $DB->insert_record('enrol', $instance); | |
1130 | } | |
1131 | ||
1132 | /** | |
1133 | * Add new instance of enrol plugin with default settings, | |
1134 | * called when adding new instance manually or when adding new course. | |
1135 | * | |
1136 | * Not all plugins support this. | |
1137 | * | |
1138 | * @param object $course | |
1139 | * @return int id of new instance or null if no default supported | |
1140 | */ | |
1141 | public function add_default_instance($course) { | |
1142 | return null; | |
1143 | } | |
1144 | ||
1145 | /** | |
1146 | * Delete course enrol plugin instance, unenrol all users. | |
1147 | * @param object $instance | |
1148 | * @return void | |
1149 | */ | |
1150 | public function delete_instance($instance) { | |
1151 | global $DB; | |
1152 | ||
1153 | $name = $this->get_name(); | |
1154 | if ($instance->enrol !== $name) { | |
1155 | throw new coding_exception('invalid enrol instance!'); | |
1156 | } | |
1157 | ||
1158 | //first unenrol all users | |
1159 | $participants = $DB->get_recordset('user_enrolments', array('enrolid'=>$instance->id)); | |
1160 | foreach ($participants as $participant) { | |
1161 | $this->unenrol_user($instance, $participant->userid); | |
1162 | } | |
1163 | $participants->close(); | |
1164 | ||
1165 | // now clean up all remainders that were not removed correctly | |
1166 | $DB->delete_records('role_assignments', array('itemid'=>$instance->id, 'component'=>$name)); | |
1167 | $DB->delete_records('user_enrolments', array('enrolid'=>$instance->id)); | |
1168 | ||
1169 | // finally drop the enrol row | |
1170 | $DB->delete_records('enrol', array('id'=>$instance->id)); | |
1171 | } | |
1172 | ||
1173 | /** | |
1174 | * Creates course enrol form, checks if form submitted | |
1175 | * and enrols user if necessary. It can also redirect. | |
1176 | * | |
1177 | * @param stdClass $instance | |
1178 | * @return string html text, usually a form in a text box | |
1179 | */ | |
1180 | public function enrol_page_hook(stdClass $instance) { | |
1181 | return null; | |
1182 | } | |
1183 | ||
1184 | /** | |
1185 | * Adds navigation links into course admin block. | |
1186 | * | |
1187 | * By defaults looks for manage links only. | |
1188 | * | |
1189 | * @param navigation_node $instancesnode | |
1190 | * @param object $instance | |
1191 | * @return moodle_url; | |
1192 | */ | |
1193 | public function add_course_navigation($instancesnode, stdClass $instance) { | |
1194 | if ($managelink = $this->get_manage_link($instance)) { | |
1195 | $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); | |
1196 | } | |
1197 | } | |
1198 | ||
1199 | /** | |
1200 | * Returns enrolment instance manage link. | |
1201 | * | |
1202 | * By defaults looks for manage.php file and tests for manage capability. | |
1203 | * | |
1204 | * @param object $instance | |
1205 | * @return moodle_url; | |
1206 | */ | |
1207 | public function get_manage_link($instance) { | |
1208 | global $CFG, $DB; | |
1209 | ||
1210 | $name = $this->get_name(); | |
1211 | ||
1212 | if ($instance->enrol !== $name) { | |
1213 | throw new coding_exception('Invalid enrol instance type!'); | |
1214 | } | |
1215 | ||
1216 | if (!file_exists("$CFG->dirroot/enrol/$name/manage.php")) { | |
1217 | return NULL; | |
1218 | } | |
1219 | ||
1220 | if ($instance->courseid == SITEID) { | |
1221 | // no enrolments on the frontpage, only roles there allowed | |
1222 | return NULL; | |
1223 | } | |
1224 | ||
1225 | $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); | |
1226 | if (!has_capability('enrol/'.$name.':manage', $context)) { | |
1227 | return NULL; | |
1228 | } | |
1229 | ||
1230 | return new moodle_url("/enrol/$name/manage.php", array('enrolid'=>$instance->id)); | |
1231 | } | |
1232 | ||
1233 | /** | |
1234 | * Reads version.php and determines if it is necessary | |
1235 | * to execute the cron job now. | |
1236 | * @return bool | |
1237 | */ | |
1238 | public function is_cron_required() { | |
1239 | global $CFG; | |
1240 | ||
1241 | $name = $this->get_name(); | |
1242 | $versionfile = "$CFG->dirroot/enrol/$name/version.php"; | |
1243 | $plugin = new object(); | |
1244 | include($versionfile); | |
1245 | if (empty($plugin->cron)) { | |
1246 | return false; | |
1247 | } | |
1248 | $lastexecuted = $this->get_config('lastcron', 0); | |
1249 | if ($lastexecuted + $plugin->cron < time()) { | |
1250 | return true; | |
1251 | } else { | |
1252 | return false; | |
1253 | } | |
1254 | } | |
1255 | ||
1256 | /** | |
1257 | * Called for all enabled enrol plugins that returned true from is_cron_required(). | |
1258 | * @return void | |
1259 | */ | |
1260 | public function cron() { | |
1261 | } | |
1262 | ||
1263 | /** | |
1264 | * Called when user is about to be deleted | |
1265 | * @param object $user | |
1266 | * @return void | |
1267 | */ | |
1268 | public function user_delete($user) { | |
1269 | global $DB; | |
1270 | ||
1271 | $sql = "SELECT e.* | |
1272 | FROM {enrol} e | |
1273 | JOIN {user_enrolments} ue ON (ue.courseid = e.courseid) | |
1274 | WHERE e.enrol = :meta AND ue.userid = :userid"; | |
1275 | $params = array('name'=>$this->get_name(), 'userid'=>$user->id); | |
1276 | ||
1277 | $rs = $DB->get_records_recordset($sql, $params); | |
1278 | foreach($rs as $instance) { | |
1279 | $this->unenrol_user($instance, $user->id); | |
1280 | } | |
1281 | $rs->close(); | |
1282 | } | |
1283 | } | |
1284 |