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
7 class enrolment_plugin_mnet
{
9 /// Override the base config_form() function
10 function config_form($frm) {
13 $vars = array('enrol_mnet_allow_allcourses',
14 'enrol_mnet_allowed_categories',
15 'enrol_mnet_allowed_courses');
17 foreach ($vars as $var) {
18 if (!isset($frm->$var)) {
23 $mnethosts = $this->list_remote_servers();
25 include ("$CFG->dirroot/enrol/mnet/config.html");
29 /// Override the base process_config() function
30 function process_config($config) {
32 if (!isset($config->enrol_mnet_allow_allcourses
)) {
33 $config->enrol_mnet_allow_allcourses
= false;
35 set_config('enrol_mnet_allow_allcourses', $config->enrol_mnet_allow_allcourses
);
37 if (!isset($config->enrol_mnet_allowed_categories
)) {
38 $config->enrol_mnet_allowed_categories
= '';
40 set_config('enrol_mnet_allowed_categories', $config->enrol_mnet_allowed_categories
);
42 if (!isset($config->enrol_mnet_allowed_courses
)) {
43 $config->enrol_mnet_allowed_courses
= '';
45 set_config('enrol_mnet_allowed_courses', $config->enrol_mnet_allowed_courses
);
51 /// Override the get_access_icons() function
52 function get_access_icons($course) {
56 * Override the base cron() function
68 function mnet_publishes() {
71 $enrol['name'] = 'mnet_enrol'; // Name & Description go in lang file
72 $enrol['apiversion'] = 1;
73 $enrol['methods'] = array('available_courses','user_enrolments', 'enrol_user', 'unenrol_user', 'course_enrolments' );
81 * @param string $username The username
82 * @param int $mnethostid The id of the remote mnethost
83 * @return bool Whether the user can login from the remote host
85 function available_courses() {
88 if (!empty($CFG->enrol_mnet_allow_allcourses
)) {
95 ca.description AS cat_description,
104 co.defaultrole AS defaultroleid,
105 r.name AS defaultrolename
107 {$CFG->prefix}course_categories ca
109 {$CFG->prefix}course co ON
112 {$CFG->prefix}role r ON
113 r.id = co.defaultrole
121 return get_records_sql($query);
123 } elseif (!empty($CFG->enrol_mnet_allowed_categories
)) {
125 $cats = preg_split('/\s*,\s*/', $CFG->enrol_mnet_allowed_categories
);
126 for ($n=0;$n < count($cats); $n++
) {
127 $cats[$n] = " ca.path LIKE '%/" . (int)$cats[$n] . "/%' ";
129 $cats = join(' OR ', $cats);
135 {$CFG->prefix}course_categories ca
137 ca.id IN ({$CFG->enrol_mnet_allowed_categories})
145 $rs = get_records_sql($query);
148 $cats = array_keys($rs);
150 $where = ' AND ( ca.id IN (' . join(',', $cats) . ') ';
153 if (!empty($CFG->enrol_mnet_allowed_courses
)) {
154 $where .= " OR co.id in ('{$CFG->enrol_mnet_allowed_courses}') ";
164 ca.description as cat_description,
173 co.defaultrole as defaultroleid,
176 {$CFG->prefix}course_categories ca
178 {$CFG->prefix}course co ON
181 {$CFG->prefix}role r ON
182 r.id = co.defaultrole
185 co.enrollable = '1' $where
190 return get_records_sql($query);
192 } elseif (!empty($CFG->enrol_mnet_allowed_courses
)) {
199 ca.description as cat_description,
208 co.defaultrole as defaultroleid,
211 {$CFG->prefix}course_categories ca
213 {$CFG->prefix}course co ON
216 {$CFG->prefix}role r ON
217 r.id = co.defaultrole
220 co.enrollable = '1' AND
221 co.id in ({$CFG->enrol_mnet_allowed_courses})
226 return get_records_sql($query);
236 function user_enrolments($userid) {
241 * Get a list of users from the client server who are enrolled in a course
243 * @param int $courseid The Course ID
244 * @param string $roles Comma-separated list of role shortnames
245 * @return array Array of usernames who are homed on the
248 function course_enrolments($courseid, $roles = '') {
249 global $MNET_REMOTE_CLIENT, $CFG;
251 if (! $course = get_record('course', 'id', $courseid) ) {
253 //error("That's an invalid course id");
256 $context = get_context_instance(CONTEXT_COURSE
, $courseid);
267 {$CFG->prefix}role_assignments a,
268 {$CFG->prefix}role r,
271 a.contextid = '{$context->id}' AND
274 u.mnethostid = '{$MNET_REMOTE_CLIENT->id}'
278 // $default_role = get_default_course_role($course); ???
280 a.roleid in ('".str_replace(',', "', '", $roles)."')";
283 $enrolments = get_records_sql($sql);
285 $returnarray = array();
286 foreach($enrolments as $user) {
287 $returnarray[$user->username
] = array('enrol' => $user->enrol
,
288 'timemodified' => $user->timemodified
,
289 'shortname' => $user->shortname
,
290 'name' => $user->name
);
296 * Enrols user to course with the default role
298 * @param string $username The username of the remote use
299 * @param int $courseid The id of the local course
300 * @return bool Whether the enrolment has been successful
302 function enrol_user($user, $courseid) {
303 global $MNET, $MNET_REMOTE_CLIENT;
305 $userrecord = get_record('user','username',addslashes($user['username']), 'mnethostid',$MNET_REMOTE_CLIENT->id
);
307 if ($userrecord == false) {
308 $userrecord = new stdClass();
309 $userrecord->username
= addslashes($user['username']);
310 $userrecord->email
= addslashes($user['email']);
311 $userrecord->firstname
= addslashes($user['firstname']);
312 $userrecord->lastname
= addslashes($user['lastname']);
313 $userrecord->mnethostid
= $MNET_REMOTE_CLIENT->id
;
315 if ($userrecord->id
= insert_record('user', $userrecord)) {
316 $userrecord = get_record('user','id', $userrecord->id
);
323 if (! $course = get_record('course', 'id', $courseid) ) {
328 $courses = $this->available_courses();
330 if (!empty($courses[$courseid])) {
331 if (enrol_into_course($course, $userrecord, 'mnet')) {
339 * Unenrol a user from a course
341 * @param string $username The username
342 * @param int $courseid The id of the local course
343 * @return bool Whether the user can login from the remote host
345 function unenrol_user($user, $courseid) {
346 global $MNET_REMOTE_CLIENT;
348 $userrecord = get_record('user','username',$user['username'], 'mnethostid',$MNET_REMOTE_CLIENT->id
);
350 if ($userrecord == false) {
354 if (! $course = get_record('course', 'id', $courseid) ) {
358 if (! $context = get_context_instance(CONTEXT_COURSE
, $course->id
)) {
359 // TODO: Error out (Invalid context)
362 // Are we a *real* user or the shady MNET Daemon?
363 // require_capability('moodle/role:assign', $context, NULL, false);
365 if (! role_unassign(0, $userrecord->id
, 0, $context->id
)) {
366 error("An error occurred while trying to unenrol that person.");
373 *** Client RPC behaviour
379 * Lists remote servers we use 'enrol' services from.
383 function list_remote_servers() {
391 {$CFG->prefix}mnet_host h,
392 {$CFG->prefix}mnet_host2service h2s,
393 {$CFG->prefix}mnet_service s
395 h.id = h2s.hostid AND
396 h2s.serviceid = s.id AND
397 s.name = 'mnet_enrol' AND
400 $res = get_records_sql($sql);
401 if (is_array($res)) {
411 * @param int $mnethostid The id of the remote mnethost
412 * @return array Whether the user can login from the remote host
414 function fetch_remote_courses($mnethostid) {
418 require_once $CFG->dirroot
. '/mnet/xmlrpc/client.php';
420 // get the Service Provider info
421 $mnet_sp = new mnet_peer();
422 $mnet_sp->set_id($mnethostid);
424 // set up the RPC request
425 $mnetrequest = new mnet_xmlrpc_client();
426 $mnetrequest->set_method('enrol/mnet/enrol.php/available_courses');
428 // TODO: cache for a while (10 minutes?)
430 // Thunderbirds are go! Do RPC call and store response
431 if ($mnetrequest->send($mnet_sp) === true) {
432 $courses = $mnetrequest->response
;
434 // get the cached courses key'd on remote id - only need remoteid and id fields
435 $cachedcourses = get_records('mnet_enrol_course',
436 'hostid', $mnethostid,
437 'remoteid', 'remoteid, id' );
439 // Update cache and transform $courses into objects
440 // in-place for the benefit of our caller...
441 for ($n=0;$n<count($courses);$n++
) {
443 $course = &$courses[$n];
445 // add/update cached data in mnet_enrol_courses
447 $course = (object)$course;
448 $course->remoteid
= (int)$course->remoteid
;
449 $course->hostid
= $mnethostid;
450 $course->cat_id
= (int)$course->cat_id
;
451 $course->sortorder
= (int)$course->sortorder
;
452 $course->startdate
= (int)$course->startdate
;
453 $course->cost
= (int)$course->cost
;
454 $course->defaultroleid
= (int)$course->defaultroleid
;
456 // sanitise strings for DB NOTE - these are not sane
457 // for printing, so we'll use a different object
458 $dbcourse = clone($course);
459 $dbcourse->cat_name
= addslashes($dbcourse->cat_name
);
460 $dbcourse->cat_description
= addslashes($dbcourse->cat_description
);
461 $dbcourse->fullname
= addslashes($dbcourse->fullname
);
462 $dbcourse->shortname
= addslashes($dbcourse->shortname
);
463 $dbcourse->idnumber
= addslashes($dbcourse->idnumber
);
464 $dbcourse->summary
= addslashes($dbcourse->summary
);
465 $dbcourse->currency
= addslashes($dbcourse->currency
);
466 $dbcourse->defaultrolename
= addslashes($dbcourse->defaultrolename
);
469 if (empty($cachedcourses[$course->remoteid
])) {
470 $course->id
= insert_record('mnet_enrol_course', $dbcourse);
472 $course->id
= $cachedcourses[$course->remoteid
]->id
;
473 $cachedcourses[$course->remoteid
]->seen
=true;
474 update_record('mnet_enrol_course', $dbcourse);
480 // prune stale data from cache
481 if (!empty($cachedcourses)) {
483 foreach ($cachedcourses as $id => $cc) {
484 // TODO: maybe set a deleted flag instead
485 if (empty($cc->seen
)) {
489 if (!empty($stale)) {
490 delete_records_select('mnet_enrol_course', 'id IN ('.join(',',$stale).')');
496 foreach ($mnetrequest->error
as $errormessage) {
497 list($code, $errormessage) = array_map('trim',explode(':', $errormessage, 2));
498 $message .= "ERROR $code:<br/>$errormessage<br/>";
500 error("RPC enrol/mnet/available_courses:<br/>$message");
508 * @param int $mnethostid The id of the remote mnethost
509 * @return array Whether the user can login from the remote host
511 function req_enrol_user($userid, $courseid) {
515 require_once $CFG->dirroot
. '/mnet/xmlrpc/client.php';
517 // Prepare a basic user record
518 // in case the remote host doesn't have it
519 $user = get_record('user', 'id', $userid, '','','','', 'username, email, firstname, lastname');
520 $user = (array)$user;
522 $course = get_record('mnet_enrol_course', 'id', $courseid);
524 // get the Service Provider info
525 $mnet_sp = new mnet_peer();
526 $mnet_sp->set_id($course->hostid
);
528 // set up the RPC request
529 $mnetrequest = new mnet_xmlrpc_client();
530 $mnetrequest->set_method('enrol/mnet/enrol.php/enrol_user');
531 $mnetrequest->add_param($user);
532 $mnetrequest->add_param($course->remoteid
);
534 // Thunderbirds are go! Do RPC call and store response
535 if ($mnetrequest->send($mnet_sp) === true) {
536 if ($mnetrequest->response
== true) {
537 // now store it in the mnet_enrol_assignments table
538 $assignment = new StdClass
;
539 $assignment->userid
= $userid;
540 $assignment->hostid
= $course->hostid
;
541 $assignment->courseid
= $course->id
;
542 $assignment->enroltype
= 'mnet';
543 // TODO: other fields
544 if (insert_record('mnet_enrol_assignments', $assignment)) {
556 * @param int $mnethostid The id of the remote mnethost
557 * @return array Whether the user can login from the remote host
559 function req_unenrol_user($userid, $courseid) {
563 require_once $CFG->dirroot
. '/mnet/xmlrpc/client.php';
565 // in case the remote host doesn't have it
566 $user = get_record('user', 'id', $userid, '','','','', 'username, email');
567 $user = $user->username
;
569 $course = get_record('mnet_enrol_course', 'id', $courseid);
571 // get the Service Provider info
572 $mnet_sp = new mnet_peer();
573 $mnet_sp->set_id($course->hostid
);
575 // set up the RPC request
576 $mnetrequest = new mnet_xmlrpc_client();
577 $mnetrequest->set_method('enrol/mnet/enrol.php/unenrol_user');
578 $mnetrequest->add_param($user);
579 $mnetrequest->add_param($course->remoteid
);
581 // TODO - prevent removal of enrolments that are not of
585 // Thunderbirds are go! Do RPC call and store response
586 if ($mnetrequest->send($mnet_sp) === true) {
587 if ($mnetrequest->response
== true) {
588 // remove enrolment cached in mnet_enrol_assignments
589 delete_records_select('mnet_enrol_assignments',
590 "userid={$userid} AND courseid={$course->id}");