MDL-22148 backup - support for manual/self/guest enrolments. Credit goes to Petr.
[moodle.git] / enrol / guest / lib.php
CommitLineData
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 * Guest access plugin.
20 *
21 * This plugin does not add any entries into the user_enrolments table,
22 * the access control is granted on the fly via the tricks in require_login().
23 *
f6990871
PS
24 * @package enrol
25 * @subpackage guest
26 * @copyright 2010 Petr Skoda {@link http://skodak.org}
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
df997f84
PS
28 */
29
97795859 30defined('MOODLE_INTERNAL') || die();
df997f84
PS
31
32class enrol_guest_plugin extends enrol_plugin {
33
31680508
PS
34 /**
35 * Returns optional enrolment information icons.
36 *
37 * This is used in course list for quick overview of enrolment options.
38 *
39 * We are not using single instance parameter because sometimes
40 * we might want to prevent icon repetition when multiple instances
41 * of one type exist. One instance may also produce several icons.
42 *
43 * @param array $instances all enrol instances of this type in one course
44 * @return array of pix_icon
45 */
3ead116a 46 public function get_info_icons(array $instances) {
31680508
PS
47 foreach ($instances as $instance) {
48 if ($instance->password) {
49 return array(new pix_icon('withoutpassword', get_string('pluginname', 'enrol_guest'), 'enrol_guest'));
50 } else {
51 return array(new pix_icon('withpassword', get_string('pluginname', 'enrol_guest'), 'enrol_guest'));
52 }
53 }
3ead116a
PS
54 }
55
f2a9be5f 56 public function enrol_user(stdClass $instance, $userid, $roleid = NULL, $timestart = 0, $timeend = 0, $status = NULL) {
df997f84
PS
57 // no real enrolments here!
58 return;
59 }
60
61 public function unenrol_user(stdClass $instance, $userid) {
62 // nothing to do, we never enrol here!
63 return;
64 }
65
66 /**
67 * Attempt to automatically gain temporary guest access to course,
68 * calling code has to make sure the plugin and instance are active.
69 *
70 * @param stdClass $instance course enrol instance
71 * @param stdClass $user record
72 * @return bool|int false means no guest access, integer means end of cached time
73 */
74 public function try_guestaccess(stdClass $instance) {
75 global $USER, $CFG;
76
77 if (empty($instance->password)) {
78 // Temporarily assign them some guest role for this context
79 $context = get_context_instance(CONTEXT_COURSE, $instance->courseid);
80 $USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access);
81 return ENROL_REQUIRE_LOGIN_CACHE_PERIOD;
82 }
83
84 return false;
85 }
86
87 /**
88 * Returns link to page which may be used to add new instance of enrolment plugin in course.
89 * @param int $courseid
90 * @return moodle_url page url
91 */
e25f2466 92 public function get_newinstance_link($courseid) {
df997f84
PS
93 global $DB;
94
f6990871
PS
95 $context = get_context_instance(CONTEXT_COURSE, $courseid, MUST_EXIST);
96
97 if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/guest:config', $context)) {
df997f84
PS
98 return NULL;
99 }
100
101 if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'guest'))) {
102 return NULL;
103 }
104
105 return new moodle_url('/enrol/guest/addinstance.php', array('sesskey'=>sesskey(), 'id'=>$courseid));
106 }
107
108 /**
109 * Creates course enrol form, checks if form submitted
110 * and enrols user if necessary. It can also redirect.
111 *
112 * @param stdClass $instance
113 * @return string html text, usually a form in a text box
114 */
115 public function enrol_page_hook(stdClass $instance) {
116 global $CFG, $OUTPUT, $SESSION, $USER;
117
118 if (empty($instance->password)) {
119 return null;
120 }
121
122 require_once("$CFG->dirroot/enrol/guest/locallib.php");
123 $form = new enrol_guest_enrol_form(NULL, $instance);
124 $instanceid = optional_param('instance', 0, PARAM_INT);
125
126 if ($instance->id == $instanceid) {
127 if ($data = $form->get_data()) {
128 // set up primitive require_login() caching
129 unset($USER->enrol['enrolled'][$instance->courseid]);
130 $USER->enrol['tempguest'][$instance->courseid] = time() + 60*60*8; // 8 hours access before asking for pw again
131
132 // add guest role
133 $context = get_context_instance(CONTEXT_COURSE, $instance->courseid);
134 $USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access);
135
136 // go to the originally requested page
137 if (!empty($SESSION->wantsurl)) {
138 $destination = $SESSION->wantsurl;
139 unset($SESSION->wantsurl);
140 } else {
141 $destination = "$CFG->wwwroot/course/view.php?id=$instance->courseid";
142 }
143 redirect($destination);
144 }
145 }
146
147 ob_start();
148 $form->display();
149 $output = ob_get_clean();
150
151 return $OUTPUT->box($output, 'generalbox');
152 }
153
154 /**
155 * Adds enrol instance UI to course edit form
156 *
157 * @param object $instance enrol instance or null if does not exist yet
158 * @param MoodleQuickForm $mform
159 * @param object $data
160 * @param object $context context of existing course or parent category if course does not exist
161 * @return void
162 */
163 public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) {
164
165 $i = isset($instance->id) ? $instance->id : 0;
166 $plugin = enrol_get_plugin('guest');
167 $header = $plugin->get_instance_name($instance);
168 $config = has_capability('enrol/guest:config', $context);
169
170 $mform->addElement('header', 'enrol_guest_header_'.$i, $header);
171
172
173 $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
174 ENROL_INSTANCE_DISABLED => get_string('no'));
175 $mform->addElement('select', 'enrol_guest_status_'.$i, get_string('status', 'enrol_guest'), $options);
9f38cdce 176 $mform->addHelpButton('enrol_guest_status_'.$i, 'status', 'enrol_guest');
df997f84
PS
177 $mform->setDefault('enrol_guest_status_'.$i, $this->get_config('status'));
178 $mform->setAdvanced('enrol_guest_status_'.$i, $this->get_config('status_adv'));
179 if (!$config) {
180 $mform->hardFreeze('enrol_guest_status_'.$i);
181 }
182
183 $mform->addElement('passwordunmask', 'enrol_guest_password_'.$i, get_string('password', 'enrol_guest'));
9f38cdce 184 $mform->addHelpButton('enrol_guest_password_'.$i, 'password', 'enrol_guest');
df997f84
PS
185 if (!$config) {
186 $mform->hardFreeze('enrol_guest_password_'.$i);
187 } else {
188 $mform->disabledIf('enrol_guest_password_'.$i, 'enrol_guest_status_'.$i, 'noteq', ENROL_INSTANCE_ENABLED);
189 }
190
191
192 // now add all values from enrol table
193 if ($instance) {
194 foreach($instance as $key=>$val) {
195 $data->{'enrol_guest_'.$key.'_'.$i} = $val;
196 }
197 }
198 }
199
200 /**
201 * Validates course edit form data
202 *
203 * @param object $instance enrol instance or null if does not exist yet
204 * @param array $data
205 * @param object $context context of existing course or parent category if course does not exist
206 * @return array errors array
207 */
208 public function course_edit_validation($instance, array $data, $context) {
209 $errors = array();
210
211 if (!has_capability('enrol/guest:config', $context)) {
212 // we are going to ignore the data later anyway, they would nto be able to fix the form anyway
213 return $errors;
214 }
215
216 $i = isset($instance->id) ? $instance->id : 0;
217
218 $password = empty($data['enrol_guest_password_'.$i]) ? '' : $data['enrol_guest_password_'.$i];
219 $checkpassword = false;
220
221 if ($instance) {
222 if ($data['enrol_guest_status_'.$i] == ENROL_INSTANCE_ENABLED) {
223 if ($instance->password !== $password) {
224 $checkpassword = true;
225 }
226 }
227 } else {
228 if ($data['enrol_guest_status_'.$i] == ENROL_INSTANCE_ENABLED) {
229 $checkpassword = true;
230 }
231 }
232
233 if ($checkpassword) {
234 $require = $this->get_config('requirepassword');
235 $policy = $this->get_config('usepasswordpolicy');
236 if ($require and empty($password)) {
237 $errors['enrol_guest_password_'.$i] = get_string('required');
238 } else if ($policy) {
239 $errmsg = '';//prevent eclipse warning
240 if (!check_password_policy($password, $errmsg)) {
241 $errors['enrol_guest_password_'.$i] = $errmsg;
242 }
243 }
244 }
245
246 return $errors;
247 }
248
249 /**
250 * Called after updating/inserting course.
251 *
252 * @param bool $inserted true if course just inserted
253 * @param object $course
254 * @param object $data form data
255 * @return void
256 */
257 public function course_updated($inserted, $course, $data) {
258 global $DB;
259
260 $context = get_context_instance(CONTEXT_COURSE, $course->id);
261
262 if (has_capability('enrol/guest:config', $context)) {
263 if ($inserted) {
264 if (isset($data->enrol_guest_status_0)) {
265 $fields = array('status'=>$data->enrol_guest_status_0);
266 if ($fields['status'] == ENROL_INSTANCE_ENABLED) {
267 $fields['password'] = $data->enrol_guest_password_0;
268 } else {
269 if ($this->get_config('requirepassword')) {
270 $fields['password'] = generate_password(20);
271 }
272 }
273 $this->add_instance($course, $fields);
274 }
275 } else {
276 $instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'guest'));
277 foreach ($instances as $instance) {
278 $i = $instance->id;
279
280 if (isset($data->{'enrol_guest_status_'.$i})) {
281 $instance->status = $data->{'enrol_guest_status_'.$i};
282 $instance->timemodified = time();
283 if ($instance->status == ENROL_INSTANCE_ENABLED) {
284 $instance->password = $data->{'enrol_guest_password_'.$i};
285 }
286 $DB->update_record('enrol', $instance);
287 }
288 }
289 }
290
291 } else {
292 if ($inserted) {
293 if ($this->get_config('defaultenrol')) {
294 $this->add_default_instance($course);
295 }
296 } else {
297 // bad luck, user can not change anything
298 }
299 }
300 }
301
302 /**
303 * Add new instance of enrol plugin with default settings.
304 * @param object $course
305 * @return int id of new instance
306 */
307 public function add_default_instance($course) {
308 $fields = array('status'=>$this->get_config('status'));
309
310 if ($this->get_config('requirepassword')) {
311 $fields['password'] = generate_password(20);
312 }
313
314 return $this->add_instance($course, $fields);
315 }
316
317}
318
f2a9be5f
EL
319/**
320 * Indicates API features that the enrol plugin supports.
321 *
322 * @param string $feature
323 * @return mixed True if yes (some features may use other values)
324 */
325function enrol_guest_supports($feature) {
326 switch($feature) {
327 case ENROL_RESTORE_TYPE: return ENROL_RESTORE_NOUSERS;
328
329 default: return null;
330 }
331}