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 // Initialise $message
431 // TODO: cache for a while (10 minutes?)
433 // Thunderbirds are go! Do RPC call and store response
434 if ($mnetrequest->send($mnet_sp) === true) {
435 $courses = $mnetrequest->response
;
437 // get the cached courses key'd on remote id - only need remoteid and id fields
438 $cachedcourses = get_records('mnet_enrol_course',
439 'hostid', $mnethostid,
440 'remoteid', 'remoteid, id' );
442 // Update cache and transform $courses into objects
443 // in-place for the benefit of our caller...
444 for ($n=0;$n<count($courses);$n++
) {
446 $course = &$courses[$n];
448 // add/update cached data in mnet_enrol_courses
450 $course = (object)$course;
451 $course->remoteid
= (int)$course->remoteid
;
452 $course->hostid
= $mnethostid;
453 $course->cat_id
= (int)$course->cat_id
;
454 $course->sortorder
= (int)$course->sortorder
;
455 $course->startdate
= (int)$course->startdate
;
456 $course->cost
= (int)$course->cost
;
457 $course->defaultroleid
= (int)$course->defaultroleid
;
459 // sanitise strings for DB NOTE - these are not sane
460 // for printing, so we'll use a different object
461 $dbcourse = clone($course);
462 $dbcourse->cat_name
= addslashes($dbcourse->cat_name
);
463 $dbcourse->cat_description
= addslashes($dbcourse->cat_description
);
464 $dbcourse->fullname
= addslashes($dbcourse->fullname
);
465 $dbcourse->shortname
= addslashes($dbcourse->shortname
);
466 $dbcourse->idnumber
= addslashes($dbcourse->idnumber
);
467 $dbcourse->summary
= addslashes($dbcourse->summary
);
468 $dbcourse->currency
= addslashes($dbcourse->currency
);
469 $dbcourse->defaultrolename
= addslashes($dbcourse->defaultrolename
);
472 if (empty($cachedcourses[$course->remoteid
])) {
473 $course->id
= insert_record('mnet_enrol_course', $dbcourse);
475 $course->id
= $cachedcourses[$course->remoteid
]->id
;
476 $cachedcourses[$course->remoteid
]->seen
=true;
477 update_record('mnet_enrol_course', $dbcourse);
483 // prune stale data from cache
484 if (!empty($cachedcourses)) {
486 foreach ($cachedcourses as $id => $cc) {
487 // TODO: maybe set a deleted flag instead
488 if (empty($cc->seen
)) {
492 if (!empty($stale)) {
493 delete_records_select('mnet_enrol_course', 'id IN ('.join(',',$stale).')');
499 foreach ($mnetrequest->error
as $errormessage) {
500 list($code, $errormessage) = array_map('trim',explode(':', $errormessage, 2));
501 $message .= "ERROR $code:<br/>$errormessage<br/>";
503 error("RPC enrol/mnet/available_courses:<br/>$message");
511 * @param int $mnethostid The id of the remote mnethost
512 * @return array Whether the user can login from the remote host
514 function req_enrol_user($userid, $courseid) {
518 require_once $CFG->dirroot
. '/mnet/xmlrpc/client.php';
520 // Prepare a basic user record
521 // in case the remote host doesn't have it
522 $user = get_record('user', 'id', $userid, '','','','', 'username, email, firstname, lastname');
523 $user = (array)$user;
525 $course = get_record('mnet_enrol_course', 'id', $courseid);
527 // get the Service Provider info
528 $mnet_sp = new mnet_peer();
529 $mnet_sp->set_id($course->hostid
);
531 // set up the RPC request
532 $mnetrequest = new mnet_xmlrpc_client();
533 $mnetrequest->set_method('enrol/mnet/enrol.php/enrol_user');
534 $mnetrequest->add_param($user);
535 $mnetrequest->add_param($course->remoteid
);
537 // Thunderbirds are go! Do RPC call and store response
538 if ($mnetrequest->send($mnet_sp) === true) {
539 if ($mnetrequest->response
== true) {
540 // now store it in the mnet_enrol_assignments table
541 $assignment = new StdClass
;
542 $assignment->userid
= $userid;
543 $assignment->hostid
= $course->hostid
;
544 $assignment->courseid
= $course->id
;
545 $assignment->enroltype
= 'mnet';
546 // TODO: other fields
547 if (insert_record('mnet_enrol_assignments', $assignment)) {
559 * @param int $mnethostid The id of the remote mnethost
560 * @return array Whether the user can login from the remote host
562 function req_unenrol_user($userid, $courseid) {
566 require_once $CFG->dirroot
. '/mnet/xmlrpc/client.php';
568 // in case the remote host doesn't have it
569 $user = get_record('user', 'id', $userid, '','','','', 'username, email');
570 $user = $user->username
;
572 $course = get_record('mnet_enrol_course', 'id', $courseid);
574 // get the Service Provider info
575 $mnet_sp = new mnet_peer();
576 $mnet_sp->set_id($course->hostid
);
578 // set up the RPC request
579 $mnetrequest = new mnet_xmlrpc_client();
580 $mnetrequest->set_method('enrol/mnet/enrol.php/unenrol_user');
581 $mnetrequest->add_param($user);
582 $mnetrequest->add_param($course->remoteid
);
584 // TODO - prevent removal of enrolments that are not of
588 // Thunderbirds are go! Do RPC call and store response
589 if ($mnetrequest->send($mnet_sp) === true) {
590 if ($mnetrequest->response
== true) {
591 // remove enrolment cached in mnet_enrol_assignments
592 delete_records_select('mnet_enrol_assignments',
593 "userid={$userid} AND courseid={$course->id}");