NOBUG xmldb editor - make php code generated to follow the 2-slash coding style
[moodle.git] / enrol / mnet / enrol.php
CommitLineData
bf1a3d20 1<?php
2// The following flags are set in the configuration
3// $config->allow_allcourses: expose all courses to external enrolment
4// $config->allowed_categories: serialised array of courses allowed
5// $config->allowed_courses: serialised array of courses allowed
6
7class enrolment_plugin_mnet {
8
287efec6
PL
9 /** * mnet environment - constructor makes sure its set up */
10 private $mnet;
11
12 function __construct() {
13 $this->mnet = get_mnet_environment();
14 }
15
bf1a3d20 16 /// Override the base config_form() function
17 function config_form($frm) {
8e7328a2 18 global $CFG, $OUTPUT, $PAGE;
bf1a3d20 19
20 $vars = array('enrol_mnet_allow_allcourses',
21 'enrol_mnet_allowed_categories',
22 'enrol_mnet_allowed_courses');
23
24 foreach ($vars as $var) {
25 if (!isset($frm->$var)) {
26 $frm->$var = '';
27 }
28 }
29
30 $mnethosts = $this->list_remote_servers();
31
32 include ("$CFG->dirroot/enrol/mnet/config.html");
33 }
34
35
36 /// Override the base process_config() function
37 function process_config($config) {
38
39 if (!isset($config->enrol_mnet_allow_allcourses)) {
40 $config->enrol_mnet_allow_allcourses = false;
41 }
42 set_config('enrol_mnet_allow_allcourses', $config->enrol_mnet_allow_allcourses);
43
44 if (!isset($config->enrol_mnet_allowed_categories)) {
45 $config->enrol_mnet_allowed_categories = '';
46 }
47 set_config('enrol_mnet_allowed_categories', $config->enrol_mnet_allowed_categories);
48
49 if (!isset($config->enrol_mnet_allowed_courses)) {
50 $config->enrol_mnet_allowed_courses = '';
51 }
52 set_config('enrol_mnet_allowed_courses', $config->enrol_mnet_allowed_courses);
53
54 return true;
55
56 }
57
58 /// Override the get_access_icons() function
59 function get_access_icons($course) {
60 }
61
62 /**
63 * Override the base cron() function
64 */
0a127169 65 //function cron() {
66 //
67 //} // end of cron()
bf1a3d20 68
69
70
71 /***
72 *** MNET functions
73 ***
74 ***/
bf1a3d20 75
76 /**
de260e0f 77 * Returns a list of all courses available for remote login
bf1a3d20 78 *
de260e0f 79 * @return array Array of courses
bf1a3d20 80 */
81 function available_courses() {
50c5bef4 82 global $CFG, $DB;
bf1a3d20 83
84 if (!empty($CFG->enrol_mnet_allow_allcourses)) {
85
86 $query =
87 "SELECT
e395caaa 88 co.id AS remoteid,
89 ca.id AS cat_id,
90 ca.name AS cat_name,
91 ca.description AS cat_description,
bf1a3d20 92 co.sortorder,
93 co.fullname,
94 co.shortname,
95 co.idnumber,
96 co.summary,
97 co.startdate,
98 co.cost,
99 co.currency,
e395caaa 100 co.defaultrole AS defaultroleid,
4317f92f 101 r.name AS defaultrolename
bf1a3d20 102 FROM
50c5bef4 103 {course_categories} ca
bf1a3d20 104 JOIN
50c5bef4 105 {course} co ON ca.id = co.category
bf1a3d20 106 LEFT JOIN
50c5bef4 107 {role} r ON r.id = co.defaultrole
bf1a3d20 108 WHERE
50c5bef4 109 co.visible = 1 AND
0a127169 110 co.enrollable = 1
bf1a3d20 111 ORDER BY
112 sortorder ASC
113 ";
114
50c5bef4 115 return $DB->get_records_sql($query);
bf1a3d20 116
117 } elseif (!empty($CFG->enrol_mnet_allowed_categories)) {
118
119 $cats = preg_split('/\s*,\s*/', $CFG->enrol_mnet_allowed_categories);
120 for ($n=0;$n < count($cats); $n++) {
121 $cats[$n] = " ca.path LIKE '%/" . (int)$cats[$n] . "/%' ";
122 }
123 $cats = join(' OR ', $cats);
124
125 $query =
126 "SELECT
127 id, name
128 FROM
50c5bef4 129 {course_categories} ca
bf1a3d20 130 WHERE
131 ca.id IN ({$CFG->enrol_mnet_allowed_categories})
132 OR ( $cats )
133 ORDER BY
134 path ASC,
135 depth ASC
136 ";
137 unset($cats);
138
50c5bef4 139 $rs = $DB->get_records_sql($query);
bf1a3d20 140
141 if (!empty($rs)) {
142 $cats = array_keys($rs);
143 }
144 $where = ' AND ( ca.id IN (' . join(',', $cats) . ') ';
145
146
147 if (!empty($CFG->enrol_mnet_allowed_courses)) {
a67a5531 148 $where .= " OR co.id in ({$CFG->enrol_mnet_allowed_courses}) ";
bf1a3d20 149 }
150
151 $where .= ')';
152
153 $query =
154 "SELECT
155 co.id as remoteid,
156 ca.id as cat_id,
157 ca.name as cat_name,
158 ca.description as cat_description,
159 co.sortorder,
160 co.fullname,
161 co.shortname,
162 co.idnumber,
163 co.summary,
164 co.startdate,
165 co.cost,
166 co.currency,
167 co.defaultrole as defaultroleid,
168 r.name
169 FROM
50c5bef4 170 {course_categories} ca
bf1a3d20 171 JOIN
50c5bef4 172 {course} co ON ca.id = co.category
bf1a3d20 173 LEFT JOIN
50c5bef4 174 {role} r ON r.id = co.defaultrole
bf1a3d20 175 WHERE
50c5bef4 176 co.visible = 1 AND
0a127169 177 co.enrollable = 1 $where
bf1a3d20 178 ORDER BY
179 sortorder ASC
180 ";
181
50c5bef4 182 return $DB->get_records_sql($query);
bf1a3d20 183
184 } elseif (!empty($CFG->enrol_mnet_allowed_courses)) {
185
186 $query =
187 "SELECT
188 co.id as remoteid,
189 ca.id as cat_id,
190 ca.name as cat_name,
191 ca.description as cat_description,
192 co.sortorder,
193 co.fullname,
194 co.shortname,
195 co.idnumber,
196 co.summary,
197 co.startdate,
198 co.cost,
199 co.currency,
200 co.defaultrole as defaultroleid,
201 r.name
202 FROM
50c5bef4 203 {course_categories} ca
bf1a3d20 204 JOIN
50c5bef4 205 {course} co ON ca.id = co.category
bf1a3d20 206 LEFT JOIN
50c5bef4 207 {role} r ON r.id = co.defaultrole
bf1a3d20 208 WHERE
50c5bef4 209 co.visible = 1 AND
210 co.enrollable = 1 AND
0a127169 211 co.id IN ({$CFG->enrol_mnet_allowed_courses})
bf1a3d20 212 ORDER BY
213 sortorder ASC
214 ";
215
50c5bef4 216 return $DB->get_records_sql($query);
bf1a3d20 217
218 }
219
220 return array();
221 }
222
68ea70b4 223 /**
4317f92f 224 *
68ea70b4 225 */
226 function user_enrolments($userid) {
227 return array();
228 }
229
bf1a3d20 230 /**
5291907c 231 * Get a list of users from the client server who are enrolled in a course
232 *
233 * @param int $courseid The Course ID
234 * @param string $roles Comma-separated list of role shortnames
4317f92f 235 * @return array Array of usernames who are homed on the
5291907c 236 * client machine
237 */
68ea70b4 238 function course_enrolments($courseid, $roles = '') {
287efec6 239 global $CFG, $DB;
bf1a3d20 240
50c5bef4 241 if (! $course = $DB->get_record('course', array('id'=>$courseid))) {
5291907c 242 return 'no course';
243 //error("That's an invalid course id");
244 }
245
287efec6
PL
246 $remoteclient = get_mnet_remote_client();
247
5291907c 248 $context = get_context_instance(CONTEXT_COURSE, $courseid);
249
250 $sql = "
251 SELECT
252 u.id,
68ea70b4 253 u.username,
0855c4ca 254 a.enrol,
255 a.timemodified,
256 r.name,
257 r.shortname
5291907c 258 FROM
50c5bef4 259 {role_assignments} a,
260 {role} r,
261 {user} u
5291907c 262 WHERE
50c5bef4 263 a.contextid = {$context->id} AND
0855c4ca 264 a.roleid = r.id AND
5291907c 265 a.userid = u.id AND
287efec6 266 u.mnethostid = '{$remoteclient->id}'
5291907c 267 ";
268
269 if(!empty($roles)) {
270 // $default_role = get_default_course_role($course); ???
271 $sql .= " AND
272 a.roleid in ('".str_replace(',', "', '", $roles)."')";
4317f92f 273 }
5291907c 274
50c5bef4 275 $enrolments = $DB->get_records_sql($sql);
5291907c 276
277 $returnarray = array();
278 foreach($enrolments as $user) {
4317f92f
PS
279 $returnarray[$user->username] = array('enrol' => $user->enrol,
280 'timemodified' => $user->timemodified,
281 'shortname' => $user->shortname,
d3080510 282 'username' => $user->username,
0855c4ca 283 'name' => $user->name);
5291907c 284 }
285 return $returnarray;
bf1a3d20 286 }
287
288 /**
289 * Enrols user to course with the default role
290 *
291 * @param string $username The username of the remote use
292 * @param int $courseid The id of the local course
293 * @return bool Whether the enrolment has been successful
294 */
295 function enrol_user($user, $courseid) {
287efec6
PL
296 global $DB;
297 $remoteclient = get_mnet_remote_client();
bf1a3d20 298
287efec6 299 $userrecord = $DB->get_record('user',array('username'=>$user['username'], 'mnethostid'=>$remoteclient->id));
bf1a3d20 300
301 if ($userrecord == false) {
61506902 302 $userrecord = mnet_strip_user((object)$user, mnet_fields_to_import($remoteclient));
94cf0a1e 303 /* there used to be a setting in auth_mnet called auto_add_remote_users
4a3c3308
PL
304 * which we should have been checking here (but weren't).
305 * this setting has now been removed. See MDL-21327
306 */
287efec6 307 $userrecord->mnethostid = $remoteclient->id;
bf1a3d20 308
50c5bef4 309 if ($userrecord->id = $DB->insert_record('user', $userrecord)) {
310 $userrecord = $DB->get_record('user', array('id'=>$userrecord->id));
bf1a3d20 311 } else {
d234faf3 312 throw new mnet_server_exception(5011, 'couldnotcreateuser', 'enrol_mnet');
bf1a3d20 313 }
314 }
315
50c5bef4 316 if (! $course = $DB->get_record('course', array('id'=>$courseid))) {
d234faf3 317 throw new mnet_server_exception(5012, 'coursenotfound', 'enrol_mnet');
bf1a3d20 318 }
319
320 $courses = $this->available_courses();
321
322 if (!empty($courses[$courseid])) {
bf1a3d20 323 if (enrol_into_course($course, $userrecord, 'mnet')) {
324 return true;
325 }
d234faf3 326 throw new mnet_server_exception(5016, 'couldnotenrol', 'enrol_mnet');
bf1a3d20 327 }
d234faf3 328 throw new mnet_server_exception(5013, 'courseunavailable', 'enrol_mnet');
bf1a3d20 329 }
330
331 /**
332 * Unenrol a user from a course
333 *
334 * @param string $username The username
335 * @param int $courseid The id of the local course
336 * @return bool Whether the user can login from the remote host
337 */
b7f2b8e6 338 function unenrol_user($username, $courseid) {
287efec6
PL
339 global $DB;
340 $remoteclient = get_mnet_remote_client();
bf1a3d20 341
287efec6 342 if (!$userrecord = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>$remoteclient->id))) {
d234faf3 343 throw new mnet_exception(5014, 'usernotfound', 'enrol_mnet');
bf1a3d20 344 }
345
50c5bef4 346 if (! $course = $DB->get_record('course', array('id'=>$courseid))) {
d234faf3 347 throw new mnet_server_exception(5012, 'coursenotfound', 'enrol_mnet');
bf1a3d20 348 }
349
4416da02 350 $context = get_context_instance(CONTEXT_COURSE, $course->id);
bf1a3d20 351
352 // Are we a *real* user or the shady MNET Daemon?
353 // require_capability('moodle/role:assign', $context, NULL, false);
354
df997f84 355 role_unassign_all(array('userid'=>$userrecord->id, 'contextiod'=>$context->id, 'component'=>'enrol_mnet'), true, true);
bf1a3d20 356
357 return true;
358 }
359
360 /***
361 *** Client RPC behaviour
362 ***
363 ***
364 ***/
365
366 /**
367 * Lists remote servers we use 'enrol' services from.
368 *
369 * @return array
370 */
371 function list_remote_servers() {
50c5bef4 372 global $CFG, $DB;
bf1a3d20 373
374 $sql = "
4317f92f
PS
375 SELECT DISTINCT
376 h.id,
bf1a3d20 377 h.name
4317f92f 378 FROM
0a127169 379 {mnet_host} h,
380 {mnet_host2service} h2s,
50c5bef4 381 {mnet_service} s
bf1a3d20 382 WHERE
0a127169 383 h.id = h2s.hostid AND
384 h2s.serviceid = s.id AND
385 s.name = 'mnet_enrol' AND
ccb60df8 386 h2s.subscribe = 1";
bf1a3d20 387
50c5bef4 388 $res = $DB->get_records_sql($sql);
79b84c93 389 if (is_array($res)) {
390 return $res;
391 } else {
392 return array();
393 }
bf1a3d20 394 }
395
396 /**
397 * Does Foo
398 *
399 * @param int $mnethostid The id of the remote mnethost
400 * @return array Whether the user can login from the remote host
401 */
402 function fetch_remote_courses($mnethostid) {
287efec6 403 global $CFG, $USER, $DB;
bf1a3d20 404 require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
405
406 // get the Service Provider info
407 $mnet_sp = new mnet_peer();
408 $mnet_sp->set_id($mnethostid);
409
410 // set up the RPC request
411 $mnetrequest = new mnet_xmlrpc_client();
412 $mnetrequest->set_method('enrol/mnet/enrol.php/available_courses');
413
254f0c07 414 // Initialise $message
415 $message = '';
416
bf1a3d20 417 // TODO: cache for a while (10 minutes?)
418
419 // Thunderbirds are go! Do RPC call and store response
420 if ($mnetrequest->send($mnet_sp) === true) {
421 $courses = $mnetrequest->response;
422
423 // get the cached courses key'd on remote id - only need remoteid and id fields
50c5bef4 424 $cachedcourses = $DB->get_records('mnet_enrol_course', array('hostid'=>$mnethostid), 'remoteid', 'remoteid, id' );
bf1a3d20 425
426 // Update cache and transform $courses into objects
427 // in-place for the benefit of our caller...
428 for ($n=0;$n<count($courses);$n++) {
429
430 $course = &$courses[$n];
431
432 // add/update cached data in mnet_enrol_courses
4317f92f 433 // sanitise data
bf1a3d20 434 $course = (object)$course;
435 $course->remoteid = (int)$course->remoteid;
436 $course->hostid = $mnethostid;
e395caaa 437 $course->cat_id = (int)$course->cat_id;
bf1a3d20 438 $course->sortorder = (int)$course->sortorder ;
bf1a3d20 439 $course->startdate = (int)$course->startdate;
440 $course->cost = (int)$course->cost;
bf1a3d20 441 $course->defaultroleid = (int)$course->defaultroleid;
e395caaa 442
443 // sanitise strings for DB NOTE - these are not sane
444 // for printing, so we'll use a different object
445 $dbcourse = clone($course);
11b9852e 446 $dbcourse->cat_name = substr($dbcourse->cat_name,0,255);
50c5bef4 447 $dbcourse->cat_description = $dbcourse->cat_description;
11b9852e 448 $dbcourse->fullname = substr($dbcourse->fullname,0,254);
449 $dbcourse->shortname = substr($dbcourse->shortname,0,15);
450 $dbcourse->idnumber = substr($dbcourse->idnumber,0,100);
50c5bef4 451 $dbcourse->summary = $dbcourse->summary;
11b9852e 452 $dbcourse->currency = substr($dbcourse->currency,0,3);
453 $dbcourse->defaultrolename = substr($dbcourse->defaultrolename,0,255);
bf1a3d20 454
455 // insert or update
456 if (empty($cachedcourses[$course->remoteid])) {
50c5bef4 457 $course->id = $DB->insert_record('mnet_enrol_course', $dbcourse);
bf1a3d20 458 } else {
30ec3eef 459 $course->id = $dbcourse->id = $cachedcourses[$course->remoteid]->id;
bf1a3d20 460 $cachedcourses[$course->remoteid]->seen=true;
50c5bef4 461 $DB->update_record('mnet_enrol_course', $dbcourse);
bf1a3d20 462 }
e395caaa 463 // free tmp obj
464 unset($dbcourse);
bf1a3d20 465 }
466
467 // prune stale data from cache
468 if (!empty($cachedcourses)) {
469 $stale = array();
470 foreach ($cachedcourses as $id => $cc) {
471 // TODO: maybe set a deleted flag instead
472 if (empty($cc->seen)) {
473 $stale[] = $cc->id;
474 }
475 }
476 if (!empty($stale)) {
50c5bef4 477 $DB->delete_records_select('mnet_enrol_course', 'id IN ('.join(',',$stale).')');
bf1a3d20 478 }
479 }
480
481 return $courses;
482 } else {
e6976ae1 483 foreach ($mnetrequest->error as $errormessage) {
d452439a 484 list($code, $errormessage) = array_map('trim',explode(':', $errormessage, 2));
970dc366 485 $message .= "ERROR $code:<br/>$errormessage<br/>";
bf1a3d20 486 }
f945d59b 487 print_error("rpcerror", '', '', $message);
bf1a3d20 488 }
489 return false;
490 }
491
492 /**
493 * Does Foo
494 *
495 * @param int $mnethostid The id of the remote mnethost
496 * @return array Whether the user can login from the remote host
497 */
498 function req_enrol_user($userid, $courseid) {
287efec6 499 global $CFG, $USER, $DB;
bf1a3d20 500 require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
501
61506902 502 // Prepare a user record
bf1a3d20 503 // in case the remote host doesn't have it
61506902 504 $user = $DB->get_record('user', array('id'=>$userid));
bf1a3d20 505 $user = (array)$user;
506
50c5bef4 507 $course = $DB->get_record('mnet_enrol_course', array('id'=>$courseid));
bf1a3d20 508
509 // get the Service Provider info
510 $mnet_sp = new mnet_peer();
511 $mnet_sp->set_id($course->hostid);
512
513 // set up the RPC request
514 $mnetrequest = new mnet_xmlrpc_client();
515 $mnetrequest->set_method('enrol/mnet/enrol.php/enrol_user');
61506902 516 $mnetrequest->add_param(mnet_strip_user($user, mnet_fields_to_send($mnet_sp)));
bf1a3d20 517 $mnetrequest->add_param($course->remoteid);
518
519 // Thunderbirds are go! Do RPC call and store response
520 if ($mnetrequest->send($mnet_sp) === true) {
521 if ($mnetrequest->response == true) {
522 // now store it in the mnet_enrol_assignments table
523 $assignment = new StdClass;
524 $assignment->userid = $userid;
525 $assignment->hostid = $course->hostid;
526 $assignment->courseid = $course->id;
527 $assignment->enroltype = 'mnet';
528 // TODO: other fields
50c5bef4 529 if ($DB->insert_record('mnet_enrol_assignments', $assignment)) {
bf1a3d20 530 return true;
531 }
532 }
533 }
534
535 return false;
536 }
537
538 /**
539 * Does Foo
540 *
541 * @param int $mnethostid The id of the remote mnethost
542 * @return array Whether the user can login from the remote host
543 */
544 function req_unenrol_user($userid, $courseid) {
287efec6 545 global $CFG, $USER, $DB;
bf1a3d20 546 require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
547
548 // in case the remote host doesn't have it
b7f2b8e6 549 $username = $DB->get_field('user', 'username', array('id'=>$userid));
bf1a3d20 550
50c5bef4 551 $course = $DB->get_record('mnet_enrol_course', array('id'=>$courseid));
bf1a3d20 552
553 // get the Service Provider info
554 $mnet_sp = new mnet_peer();
555 $mnet_sp->set_id($course->hostid);
556
557 // set up the RPC request
558 $mnetrequest = new mnet_xmlrpc_client();
559 $mnetrequest->set_method('enrol/mnet/enrol.php/unenrol_user');
b7f2b8e6 560 $mnetrequest->add_param($username);
bf1a3d20 561 $mnetrequest->add_param($course->remoteid);
562
563 // TODO - prevent removal of enrolments that are not of
564 // type mnet...
565
566
567 // Thunderbirds are go! Do RPC call and store response
568 if ($mnetrequest->send($mnet_sp) === true) {
569 if ($mnetrequest->response == true) {
570 // remove enrolment cached in mnet_enrol_assignments
50c5bef4 571 $DB->delete_records_select('mnet_enrol_assignments',
572 "userid=? AND courseid=?", array($userid, $course->id));
bf1a3d20 573
574 return true;
575 }
576 }
577 return false;
578 }
579
580} // end of class
581
4317f92f 582