Commit | Line | Data |
---|---|---|
df997f84 | 1 | <?php |
df997f84 PS |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * Guest access plugin. | |
19 | * | |
20 | * This plugin does not add any entries into the user_enrolments table, | |
21 | * the access control is granted on the fly via the tricks in require_login(). | |
22 | * | |
31ac2aef | 23 | * @package enrol_guest |
f6990871 PS |
24 | * @copyright 2010 Petr Skoda {@link http://skodak.org} |
25 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
df997f84 PS |
26 | */ |
27 | ||
97795859 | 28 | defined('MOODLE_INTERNAL') || die(); |
df997f84 | 29 | |
0c93dda8 AH |
30 | /** |
31 | * Class enrol_guest_plugin | |
32 | * | |
33 | * @copyright 2010 Petr Skoda {@link http://skodak.org} | |
34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
35 | */ | |
df997f84 PS |
36 | class enrol_guest_plugin extends enrol_plugin { |
37 | ||
31680508 PS |
38 | /** |
39 | * Returns optional enrolment information icons. | |
40 | * | |
41 | * This is used in course list for quick overview of enrolment options. | |
42 | * | |
43 | * We are not using single instance parameter because sometimes | |
44 | * we might want to prevent icon repetition when multiple instances | |
45 | * of one type exist. One instance may also produce several icons. | |
46 | * | |
47 | * @param array $instances all enrol instances of this type in one course | |
48 | * @return array of pix_icon | |
49 | */ | |
3ead116a | 50 | public function get_info_icons(array $instances) { |
31680508 | 51 | foreach ($instances as $instance) { |
817e396a | 52 | if ($instance->password !== '') { |
0e61547e | 53 | return array(new pix_icon('withpassword', get_string('guestaccess_withpassword', 'enrol_guest'), 'enrol_guest')); |
8365e25f | 54 | } else { |
0e61547e | 55 | return array(new pix_icon('withoutpassword', get_string('guestaccess_withoutpassword', 'enrol_guest'), 'enrol_guest')); |
31680508 PS |
56 | } |
57 | } | |
3ead116a PS |
58 | } |
59 | ||
0c93dda8 AH |
60 | /** |
61 | * Enrol a user using a given enrolment instance. | |
62 | * | |
63 | * @param stdClass $instance | |
64 | * @param int $userid | |
65 | * @param null $roleid | |
66 | * @param int $timestart | |
67 | * @param int $timeend | |
68 | * @param null $status | |
69 | * @param null $recovergrades | |
70 | */ | |
ef8a733a | 71 | public function enrol_user(stdClass $instance, $userid, $roleid = null, $timestart = 0, $timeend = 0, $status = null, $recovergrades = null) { |
df997f84 PS |
72 | // no real enrolments here! |
73 | return; | |
74 | } | |
75 | ||
0c93dda8 AH |
76 | /** |
77 | * Enrol a user from a given enrolment instance. | |
78 | * | |
79 | * @param stdClass $instance | |
80 | * @param int $userid | |
81 | */ | |
df997f84 PS |
82 | public function unenrol_user(stdClass $instance, $userid) { |
83 | // nothing to do, we never enrol here! | |
84 | return; | |
85 | } | |
86 | ||
0c93dda8 AH |
87 | /** |
88 | * Sets up navigation entries. | |
89 | * | |
90 | * @param stdClass $instancesnode | |
91 | * @param stdClass $instance | |
92 | * @return void | |
93 | * @throws coding_exception | |
94 | */ | |
95 | public function add_course_navigation($instancesnode, stdClass $instance) { | |
96 | if ($instance->enrol !== 'guest') { | |
97 | throw new coding_exception('Invalid enrol instance type!'); | |
98 | } | |
99 | ||
100 | $context = context_course::instance($instance->courseid); | |
101 | if (has_capability('enrol/guest:config', $context)) { | |
102 | $managelink = new moodle_url('/enrol/guest/edit.php', array('courseid' => $instance->courseid, 'id' => $instance->id)); | |
103 | $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); | |
104 | } | |
105 | } | |
106 | ||
107 | /** | |
108 | * Returns edit icons for the page with list of instances | |
109 | * @param stdClass $instance | |
110 | * @return array | |
111 | * @throws coding_exception | |
112 | */ | |
113 | public function get_action_icons(stdClass $instance) { | |
114 | global $OUTPUT; | |
115 | ||
116 | if ($instance->enrol !== 'guest') { | |
117 | throw new coding_exception('invalid enrol instance!'); | |
118 | } | |
119 | $context = context_course::instance($instance->courseid); | |
120 | ||
121 | $icons = array(); | |
122 | ||
123 | if (has_capability('enrol/guest:config', $context)) { | |
124 | $editlink = new moodle_url("/enrol/guest/edit.php", array('courseid' => $instance->courseid, 'id' => $instance->id)); | |
125 | $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core', | |
126 | array('class' => 'iconsmall'))); | |
127 | } | |
128 | ||
129 | return $icons; | |
130 | } | |
131 | ||
df997f84 PS |
132 | /** |
133 | * Attempt to automatically gain temporary guest access to course, | |
134 | * calling code has to make sure the plugin and instance are active. | |
135 | * | |
136 | * @param stdClass $instance course enrol instance | |
df997f84 PS |
137 | * @return bool|int false means no guest access, integer means end of cached time |
138 | */ | |
139 | public function try_guestaccess(stdClass $instance) { | |
140 | global $USER, $CFG; | |
141 | ||
817e396a PS |
142 | $allow = false; |
143 | ||
144 | if ($instance->password === '') { | |
145 | $allow = true; | |
146 | ||
147 | } else if (isset($USER->enrol_guest_passwords[$instance->id])) { // this is a hack, ideally we should not add stuff to $USER... | |
148 | if ($USER->enrol_guest_passwords[$instance->id] === $instance->password) { | |
149 | $allow = true; | |
150 | } | |
151 | } | |
152 | ||
153 | if ($allow) { | |
df997f84 | 154 | // Temporarily assign them some guest role for this context |
55bcef29 | 155 | $context = context_course::instance($instance->courseid); |
e922fe23 | 156 | load_temp_course_role($context, $CFG->guestroleid); |
bbfdff34 | 157 | return ENROL_MAX_TIMESTAMP; |
df997f84 PS |
158 | } |
159 | ||
160 | return false; | |
161 | } | |
162 | ||
163 | /** | |
164 | * Returns link to page which may be used to add new instance of enrolment plugin in course. | |
165 | * @param int $courseid | |
166 | * @return moodle_url page url | |
167 | */ | |
e25f2466 | 168 | public function get_newinstance_link($courseid) { |
df997f84 PS |
169 | global $DB; |
170 | ||
55bcef29 | 171 | $context = context_course::instance($courseid, MUST_EXIST); |
f6990871 PS |
172 | |
173 | if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/guest:config', $context)) { | |
df997f84 PS |
174 | return NULL; |
175 | } | |
176 | ||
177 | if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'guest'))) { | |
178 | return NULL; | |
179 | } | |
180 | ||
0c93dda8 | 181 | return new moodle_url('/enrol/guest/edit.php', array('courseid' => $courseid)); |
df997f84 PS |
182 | } |
183 | ||
184 | /** | |
185 | * Creates course enrol form, checks if form submitted | |
186 | * and enrols user if necessary. It can also redirect. | |
187 | * | |
188 | * @param stdClass $instance | |
189 | * @return string html text, usually a form in a text box | |
190 | */ | |
191 | public function enrol_page_hook(stdClass $instance) { | |
192 | global $CFG, $OUTPUT, $SESSION, $USER; | |
193 | ||
817e396a PS |
194 | if ($instance->password === '') { |
195 | return null; | |
196 | } | |
197 | ||
198 | if (isset($USER->enrol['tempguest'][$instance->courseid]) and $USER->enrol['tempguest'][$instance->courseid] > time()) { | |
199 | // no need to show the guest access when user can already enter course as guest | |
df997f84 PS |
200 | return null; |
201 | } | |
202 | ||
203 | require_once("$CFG->dirroot/enrol/guest/locallib.php"); | |
204 | $form = new enrol_guest_enrol_form(NULL, $instance); | |
205 | $instanceid = optional_param('instance', 0, PARAM_INT); | |
206 | ||
207 | if ($instance->id == $instanceid) { | |
208 | if ($data = $form->get_data()) { | |
df997f84 | 209 | // add guest role |
55bcef29 | 210 | $context = context_course::instance($instance->courseid); |
817e396a PS |
211 | $USER->enrol_guest_passwords[$instance->id] = $data->guestpassword; // this is a hack, ideally we should not add stuff to $USER... |
212 | if (isset($USER->enrol['tempguest'][$instance->courseid])) { | |
213 | remove_temp_course_roles($context); | |
214 | } | |
e922fe23 | 215 | load_temp_course_role($context, $CFG->guestroleid); |
817e396a | 216 | $USER->enrol['tempguest'][$instance->courseid] = ENROL_MAX_TIMESTAMP; |
df997f84 PS |
217 | |
218 | // go to the originally requested page | |
219 | if (!empty($SESSION->wantsurl)) { | |
220 | $destination = $SESSION->wantsurl; | |
221 | unset($SESSION->wantsurl); | |
222 | } else { | |
223 | $destination = "$CFG->wwwroot/course/view.php?id=$instance->courseid"; | |
224 | } | |
225 | redirect($destination); | |
226 | } | |
227 | } | |
228 | ||
229 | ob_start(); | |
230 | $form->display(); | |
231 | $output = ob_get_clean(); | |
232 | ||
233 | return $OUTPUT->box($output, 'generalbox'); | |
234 | } | |
235 | ||
df997f84 PS |
236 | /** |
237 | * Called after updating/inserting course. | |
238 | * | |
239 | * @param bool $inserted true if course just inserted | |
240 | * @param object $course | |
241 | * @param object $data form data | |
242 | * @return void | |
243 | */ | |
244 | public function course_updated($inserted, $course, $data) { | |
245 | global $DB; | |
246 | ||
dba74526 PS |
247 | if ($inserted) { |
248 | if (isset($data->enrol_guest_status_0)) { | |
249 | $fields = array('status'=>$data->enrol_guest_status_0); | |
250 | if ($fields['status'] == ENROL_INSTANCE_ENABLED) { | |
251 | $fields['password'] = $data->enrol_guest_password_0; | |
81bb0556 | 252 | } else { |
dba74526 PS |
253 | if ($this->get_config('requirepassword')) { |
254 | $fields['password'] = generate_password(20); | |
81bb0556 | 255 | } |
df997f84 | 256 | } |
dba74526 | 257 | $this->add_instance($course, $fields); |
df997f84 | 258 | } else { |
dba74526 PS |
259 | if ($this->get_config('defaultenrol')) { |
260 | $this->add_default_instance($course); | |
df997f84 PS |
261 | } |
262 | } | |
263 | ||
264 | } else { | |
dba74526 PS |
265 | $instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'guest')); |
266 | foreach ($instances as $instance) { | |
267 | $i = $instance->id; | |
268 | ||
269 | if (isset($data->{'enrol_guest_status_'.$i})) { | |
270 | $reset = ($instance->status != $data->{'enrol_guest_status_'.$i}); | |
271 | ||
272 | $instance->status = $data->{'enrol_guest_status_'.$i}; | |
273 | $instance->timemodified = time(); | |
274 | if ($instance->status == ENROL_INSTANCE_ENABLED) { | |
275 | if ($instance->password !== $data->{'enrol_guest_password_'.$i}) { | |
276 | $reset = true; | |
277 | } | |
278 | $instance->password = $data->{'enrol_guest_password_'.$i}; | |
279 | } | |
280 | $DB->update_record('enrol', $instance); | |
080c7d47 | 281 | \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); |
dba74526 PS |
282 | |
283 | if ($reset) { | |
284 | $context = context_course::instance($course->id); | |
285 | $context->mark_dirty(); | |
286 | } | |
df997f84 | 287 | } |
df997f84 PS |
288 | } |
289 | } | |
290 | } | |
291 | ||
df05b844 PS |
292 | /** |
293 | * Add new instance of enrol plugin. | |
294 | * @param object $course | |
295 | * @param array instance fields | |
296 | * @return int id of new instance, null if can not be created | |
297 | */ | |
298 | public function add_instance($course, array $fields = NULL) { | |
299 | $fields = (array)$fields; | |
300 | ||
301 | if (!isset($fields['password'])) { | |
302 | $fields['password'] = ''; | |
303 | } | |
304 | ||
305 | return parent::add_instance($course, $fields); | |
306 | } | |
307 | ||
df997f84 PS |
308 | /** |
309 | * Add new instance of enrol plugin with default settings. | |
310 | * @param object $course | |
311 | * @return int id of new instance | |
312 | */ | |
313 | public function add_default_instance($course) { | |
314 | $fields = array('status'=>$this->get_config('status')); | |
315 | ||
316 | if ($this->get_config('requirepassword')) { | |
317 | $fields['password'] = generate_password(20); | |
318 | } | |
319 | ||
320 | return $this->add_instance($course, $fields); | |
321 | } | |
322 | ||
7a7b8a1f PS |
323 | /** |
324 | * Restore instance and map settings. | |
325 | * | |
326 | * @param restore_enrolments_structure_step $step | |
327 | * @param stdClass $data | |
328 | * @param stdClass $course | |
329 | * @param int $oldid | |
330 | */ | |
331 | public function restore_instance(restore_enrolments_structure_step $step, stdClass $data, $course, $oldid) { | |
332 | global $DB; | |
df997f84 | 333 | |
7a7b8a1f PS |
334 | if (!$DB->record_exists('enrol', array('courseid' => $data->courseid, 'enrol' => $this->get_name()))) { |
335 | $this->add_instance($course, (array)$data); | |
336 | } | |
f2a9be5f | 337 | |
7a7b8a1f PS |
338 | // No need to set mapping, we do not restore users or roles here. |
339 | $step->set_mapping('enrol', $oldid, 0); | |
f2a9be5f | 340 | } |
ee9e079d DN |
341 | |
342 | /** | |
343 | * Is it possible to delete enrol instance via standard UI? | |
344 | * | |
345 | * @param object $instance | |
346 | * @return bool | |
347 | */ | |
348 | public function can_delete_instance($instance) { | |
349 | $context = context_course::instance($instance->courseid); | |
350 | return has_capability('enrol/guest:config', $context); | |
351 | } | |
352 | ||
b5a289c4 DNA |
353 | /** |
354 | * Is it possible to hide/show enrol instance via standard UI? | |
355 | * | |
356 | * @param stdClass $instance | |
357 | * @return bool | |
358 | */ | |
359 | public function can_hide_show_instance($instance) { | |
360 | $context = context_course::instance($instance->courseid); | |
5164b76e AN |
361 | if (!has_capability('enrol/guest:config', $context)) { |
362 | return false; | |
363 | } | |
364 | ||
365 | // If the instance is currently disabled, before it can be enabled, we must check whether the password meets the | |
366 | // password policies. | |
367 | if ($instance->status == ENROL_INSTANCE_DISABLED) { | |
368 | if ($this->get_config('requirepassword')) { | |
369 | if (empty($instance->password)) { | |
370 | return false; | |
371 | } | |
372 | } | |
373 | ||
374 | if ($this->get_config('usepasswordpolicy')) { | |
375 | if (!check_password_policy($instance->password, $errmsg)) { | |
376 | return false; | |
377 | } | |
378 | } | |
379 | } | |
380 | ||
381 | return true; | |
b5a289c4 | 382 | } |
0c93dda8 AH |
383 | |
384 | /** | |
385 | * Get default settings for enrol_guest. | |
386 | * | |
387 | * @return array | |
388 | */ | |
389 | public function get_instance_defaults() { | |
390 | $fields = array(); | |
391 | $fields['status'] = $this->get_config('status'); | |
392 | return $fields; | |
393 | } | |
f2a9be5f | 394 | } |