]> git.mjollnir.org Git - moodle.git/commitdiff
mnet: new enrolment plugin
authormartinlanghoff <martinlanghoff>
Thu, 4 Jan 2007 03:05:48 +0000 (03:05 +0000)
committermartinlanghoff <martinlanghoff>
Thu, 4 Jan 2007 03:05:48 +0000 (03:05 +0000)
enrol/mnet/allowed_courses.php [new file with mode: 0644]
enrol/mnet/config.html [new file with mode: 0644]
enrol/mnet/enrol.php [new file with mode: 0644]
enrol/mnet/remote_courses.php [new file with mode: 0644]
enrol/mnet/remote_enrolment.html [new file with mode: 0755]
enrol/mnet/remote_enrolment.php [new file with mode: 0644]
enrol/mnet/remote_hosts.php [new file with mode: 0644]
lang/en_utf8/enrol_mnet.php [new file with mode: 0644]

diff --git a/enrol/mnet/allowed_courses.php b/enrol/mnet/allowed_courses.php
new file mode 100644 (file)
index 0000000..2407dc9
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+
+/*
+ * Created on 12/12/2006
+ *
+ * MNET enrol allowed courses and categories form
+ */
+
+require_once dirname(dirname(dirname(__FILE__))) . '/config.php';
+require_once $CFG->libdir . '/adminlib.php';
+include_once $CFG->dirroot . '/mnet/lib.php';
+
+require_login();
+$adminroot = admin_get_root();
+admin_externalpage_setup('ssoaccesscontrol', $adminroot);
+admin_externalpage_print_header($adminroot);
+
+$addcategory    = optional_param('addcategory', 0, PARAM_BOOL);
+$removecategory = optional_param('removecategory', 0, PARAM_BOOL);
+$addcourse      = optional_param('addcourse', 0, PARAM_BOOL);
+$removecourse   = optional_param('removecourse', 0, PARAM_BOOL);
+
+$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
+$sesskey = sesskey();
+$formerror = array();
+
+require_capability('moodle/user:delete', $sitecontext);
+
+// process returned form data
+if ($form = data_submitted() and confirm_sesskey()) {
+
+    // add and remove categories as needed
+    if (!empty($CFG->enrol_mnet_allowed_categories)) {
+        $allowedcategories = explode(',', $CFG->enrol_mnet_allowed_categories);
+    }
+    if ($addcategory and !empty($form->addcategories)) {
+        foreach ($form->addcategories as $category) {
+            if (!$category = clean_param($category, PARAM_INT)) {
+                continue;
+            }
+            $allowedcategories[] = $category;
+        }
+    }
+    if ($removecategory and !empty($form->removecategories)) {
+        foreach ($form->removecategories as $category) {
+            if ($category = clean_param($category, PARAM_INT)) {
+                $removedcategories[] = $category;
+            }
+        }
+        $allowedcategories = array_diff($allowedcategories, $removedcategories);
+    }
+
+    // add and remove courses as needed
+    if (!empty($CFG->enrol_mnet_allowed_courses)) {
+        $allowedcourses = explode(',', $CFG->enrol_mnet_allowed_courses);
+    }
+    if ($addcourse and !empty($form->addcourses)) {
+        foreach ($form->addcourses as $course) {
+            if ($course = clean_param($course, PARAM_INT)) {
+                $allowedcourses[] = $course;
+            }
+        }
+    }
+    if ($removecourse and !empty($form->removecourses)) {
+        foreach ($form->removecourses as $course) {
+            if (!$course = clean_param($course, PARAM_INT)) {
+                continue;
+            }
+            $removedcourses[] = $course;
+        }
+        $allowedcourses = array_diff($allowedcourses, $removedcourses);
+    }
+
+    // save config
+    $cfg = empty($allowedcategories) ? '' : implode(',', $allowedcategories);
+    set_config('enrol_mnet_allowed_categories', $cfg);
+    $cfg = empty($allowedcourses) ? '' : implode(',', $allowedcourses);
+    set_config('enrol_mnet_allowed_courses', $cfg);
+
+    // redirect('allowed_courses.php', get_string('changessaved'));
+}
+
+
+
+// setup arrays for allowed categories and courses
+$categories = array();
+if ($categories = get_records('course_categories', '', '', 'name', 'id, name')) {
+    if (empty($CFG->enrol_mnet_allowed_categories)) {
+        $allowedcategories = array();
+        $potentialcategories = $categories;
+    } else {
+        $allowedcategories = array_intersect_key($categories, array_flip(explode(',', $CFG->enrol_mnet_allowed_categories)));
+        $potentialcategories = array_diff_key($categories, array_flip(explode(',', $CFG->enrol_mnet_allowed_categories)));
+    }
+}
+$courses = array();
+if ($courses = get_records('course', '', '', 'shortname', 'id, shortname')) {
+    if (empty($CFG->enrol_mnet_allowed_courses)) {
+        $allowedcourses = array();
+        $potentialcourses = $courses;
+    } else {
+        $allowedcourses = array_intersect_key($courses, array_flip(explode(',', $CFG->enrol_mnet_allowed_courses)));
+        $potentialcourses = array_diff_key($courses, array_flip(explode(',', $CFG->enrol_mnet_allowed_courses)));
+    }
+}
+
+
+
+// output the form
+print_simple_box_start('center','90%','','20');
+
+?>
+ <div class="allowedcoursesdiv"> 
+  <form name="allowedcoursesform" method="post">
+    <input type="hidden" name="sesskey" value="<?php echo $sesskey; ?>">
+<?php
+
+// display course category selector
+if (count($categories) < 1) {
+    echo get_string('nocategoriesdefined', 'enrol_mnet', "$CFG->wwwroot/course/index.php?categoryedit=on");
+} else {
+
+?>
+   <table align="center" border="0" cellpadding="5" cellspacing="0">
+    <tr>
+      <td valign="top">
+          <?php print_string('allowedcategories', 'enrol_mnet', count($allowedcategories)); ?>
+      </td>
+      <td></td>
+      <td valign="top">
+          <?php print_string('allcategories', 'enrol_mnet', count($potentialcategories)); ?>
+      </td>
+    </tr>
+
+    <tr>
+      <td valign="top">
+          <select name="removecategories[]" size="20" id="removecategories" multiple
+                  onFocus="document.allowedcoursesform.addcategory.disabled=true;
+                           document.allowedcoursesform.removecategory.disabled=false;
+                           document.allowedcoursesform.addcategories.selectedIndex=-1;" />
+          <?php
+              foreach ($allowedcategories as $category) {
+                  echo "<option value=\"$category->id\"> $category->name </option>\n";
+              }
+          ?>
+          </select>
+      </td>
+
+      <td valign="top">
+        <br />
+        <input name="addcategory" type="submit" id="add" value="&larr;" />
+        <br />
+        <input name="removecategory" type="submit" id="remove" value="&rarr;" />
+        <br />
+      </td>
+
+      <td valign="top">
+          <select name="addcategories[]" size="20" id="addcategories" multiple
+                  onFocus="document.allowedcoursesform.addcategory.disabled=false;
+                           document.allowedcoursesform.removecategory.disabled=true;
+                           document.allowedcoursesform.removecategories.selectedIndex=-1;">
+          <?php
+            foreach ($potentialcategories as $category) {
+                echo "<option value=\"$category->id\"> $category->name </option>\n";
+            }
+        ?>
+        </select>
+       </td>
+    </tr>
+   </table>
+<?php
+
+}
+
+// display course selector
+if (count($courses) < 1) {
+    echo get_string('nocoursesdefined', 'enrol_mnet', "TODO: $course_admin_url"); // TODO
+} else {
+
+?>
+   <table align="center" border="0" cellpadding="5" cellspacing="0">
+    <tr>
+      <td valign="top">
+          <?php print_string('allowedcourses', 'enrol_mnet', count($allowedcourses)); ?>
+      </td>
+      <td></td>
+      <td valign="top">
+          <?php print_string('allcourses', 'enrol_mnet', count($potentialcourses)); ?>
+      </td>
+    </tr>
+
+    <tr>
+      <td valign="top">
+          <select name="removecourses[]" size="20" id="removecourses" multiple
+                  onFocus="document.allowedcoursesform.addcourse.disabled=true;
+                           document.allowedcoursesform.removecourse.disabled=false;
+                           document.allowedcoursesform.addcourses.selectedIndex=-1;" />
+          <?php
+              foreach ($allowedcourses as $course) {
+                  echo "<option value=\"$course->id\"> $course->shortname </option>\n";
+              }
+          ?>
+          </select>
+      </td>
+
+      <td valign="top">
+        <br />
+        <input name="addcourse" type="submit" id="add" value="&larr;" />
+        <br />
+        <input name="removecourse" type="submit" id="remove" value="&rarr;" />
+        <br />
+      </td>
+
+      <td valign="top">
+          <select name="addcourses[]" size="20" id="addcourses" multiple
+                  onFocus="document.allowedcoursesform.addcourse.disabled=false;
+                           document.allowedcoursesform.removecourse.disabled=true;
+                           document.allowedcoursesform.removecourses.selectedIndex=-1;">
+          <?php
+            foreach ($potentialcourses as $course) {
+                echo "<option value=\"$course->id\"> $course->shortname </option>\n";
+            }
+        ?>
+        </select>
+       </td>
+    </tr>
+   </table>
+<?php
+
+}
+
+?>
+   </form>
+  </div>
+<?php
+
+print_simple_box_end();
+admin_externalpage_print_footer($adminroot);
+
+?>
diff --git a/enrol/mnet/config.html b/enrol/mnet/config.html
new file mode 100644 (file)
index 0000000..987bc4e
--- /dev/null
@@ -0,0 +1,36 @@
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+
+<tr valign="top">
+    <th align="center" colspan="3">Remote Servers:</td>
+</tr>
+<tr valign="top">
+    <td align="left" colspan="3">
+    <a href="<?php echo $CFG->wwwroot .'/enrol/mnet/remote_hosts.php?sesskey=' . sesskey(); ?>" >Manage Moodle Network Enrolments.</a><br>
+    Servers configured: <?php echo count(array_keys($mnethosts)); ?>
+
+    </td>
+</tr>
+
+<tr valign="top">
+    <th align="center" colspan="3">Local courses for external users:</td>
+</tr>
+
+<tr valign="top">
+    <td align="right">allow_allcourses:</td>
+    <td>
+    <?php print choose_from_menu_yesno('enrol_mnet_allow_allcourses', $frm->enrol_mnet_allow_allcourses); ?>
+    </td>
+    <td>
+    <?php  print_string("allow_allcourses", "enrol_mnet") ?>
+    </td>
+</tr>
+
+<tr>
+  <td align="right">allowed_courses:</td>
+  <td>
+   <a href="<?php echo "$CFG->wwwroot/enrol/mnet/allowed_courses.php" ?>"><?php print_string('allowedcourseslinktext', 'enrol_mnet') ?></a>
+  </td>
+</tr>
+
+
+</table>
diff --git a/enrol/mnet/enrol.php b/enrol/mnet/enrol.php
new file mode 100644 (file)
index 0000000..d2346fc
--- /dev/null
@@ -0,0 +1,541 @@
+<?php
+// The following flags are set in the configuration
+// $config->allow_allcourses:       expose all courses to external enrolment
+// $config->allowed_categories:     serialised array of courses allowed
+// $config->allowed_courses:        serialised array of courses allowed
+
+class enrolment_plugin_mnet {
+
+    /// Override the base config_form() function
+    function config_form($frm) {
+        global $CFG;
+
+       $vars = array('enrol_mnet_allow_allcourses',
+                     'enrol_mnet_allowed_categories',
+                     'enrol_mnet_allowed_courses');
+
+        foreach ($vars as $var) {
+            if (!isset($frm->$var)) {
+                $frm->$var = '';
+            }
+        }
+
+        $mnethosts = $this->list_remote_servers();
+
+        include ("$CFG->dirroot/enrol/mnet/config.html");
+    }
+
+
+    /// Override the base process_config() function
+    function process_config($config) {
+
+        if (!isset($config->enrol_mnet_allow_allcourses)) {
+            $config->enrol_mnet_allow_allcourses = false;
+        }
+        set_config('enrol_mnet_allow_allcourses', $config->enrol_mnet_allow_allcourses);
+
+        if (!isset($config->enrol_mnet_allowed_categories)) {
+            $config->enrol_mnet_allowed_categories = '';
+        }
+        set_config('enrol_mnet_allowed_categories', $config->enrol_mnet_allowed_categories);
+
+        if (!isset($config->enrol_mnet_allowed_courses)) {
+            $config->enrol_mnet_allowed_courses = '';
+        }
+        set_config('enrol_mnet_allowed_courses', $config->enrol_mnet_allowed_courses);
+
+        return true;
+
+    }
+
+    /// Override the get_access_icons() function
+    function get_access_icons($course) {
+    }
+
+    /**
+     * Override the base cron() function
+     */
+    //function cron() {
+    //
+    //} // end of cron()
+
+
+
+    /***
+     *** MNET functions
+     ***
+     ***/
+    function mnet_publishes() {
+        
+        $enrol = array();
+        $enrol['name']        = 'mnet_enrol'; // Name & Description go in lang file
+        $enrol['apiversion']  = 1;
+        $enrol['methods']     = array('available_courses','user_enrolments', 'enrol_user', 'unenrol_user' );
+
+        return array($enrol);
+    }
+
+    /**
+    * Does Foo
+    *
+    * @param string $username   The username
+    * @param int    $mnethostid The id of the remote mnethost
+    * @return bool              Whether the user can login from the remote host
+    */
+    function available_courses() {
+        global $CFG;
+
+        if (!empty($CFG->enrol_mnet_allow_allcourses)) {
+
+            $query =
+            "SELECT
+                co.id as remoteid,
+                ca.id as cat_id,
+                ca.name as cat_name,
+                ca.description as cat_description,
+                co.sortorder,
+                co.fullname,
+                co.shortname,
+                co.idnumber,
+                co.summary,
+                co.startdate,
+                co.cost,
+                co.currency,
+                co.defaultrole as defaultroleid,
+                r.name
+            FROM
+                {$CFG->prefix}course_categories ca
+            JOIN
+                {$CFG->prefix}course co ON
+                ca.id = co.category
+            LEFT JOIN
+                {$CFG->prefix}role r ON
+                r.id = co.defaultrole
+            WHERE
+                co.visible = '1' AND
+                co.enrollable = '1'
+            ORDER BY
+                sortorder ASC
+                ";
+
+            return get_records_sql($query);
+
+        } elseif (!empty($CFG->enrol_mnet_allowed_categories)) {
+
+            $cats = preg_split('/\s*,\s*/', $CFG->enrol_mnet_allowed_categories);
+            for ($n=0;$n < count($cats); $n++) {
+                $cats[$n] = " ca.path LIKE '%/" . (int)$cats[$n] . "/%' ";
+            }
+            $cats = join(' OR ', $cats);
+
+            $query =
+            "SELECT
+                id, name
+            FROM
+                {$CFG->prefix}course_categories ca
+            WHERE
+                ca.id IN ({$CFG->enrol_mnet_allowed_categories})
+                OR ( $cats )
+            ORDER BY
+                path ASC,
+                depth ASC
+                ";
+            unset($cats);
+
+            error_log($query);
+
+            $rs = get_records_sql($query);
+
+            if (!empty($rs)) {
+                $cats = array_keys($rs);
+            }
+            $where = ' AND ( ca.id IN (' . join(',', $cats) . ') ';
+
+
+            if (!empty($CFG->enrol_mnet_allowed_courses)) {
+                $where .=  " OR co.id in ('{$CFG->enrol_mnet_allowed_courses}') ";
+            }
+
+            $where .= ')';
+
+            $query =
+            "SELECT
+                co.id as remoteid,
+                ca.id as cat_id,
+                ca.name as cat_name,
+                ca.description as cat_description,
+                co.sortorder,
+                co.fullname,
+                co.shortname,
+                co.idnumber,
+                co.summary,
+                co.startdate,
+                co.cost,
+                co.currency,
+                co.defaultrole as defaultroleid,
+                r.name
+            FROM
+                {$CFG->prefix}course_categories ca
+            JOIN
+                {$CFG->prefix}course co ON
+                ca.id = co.category
+            LEFT JOIN
+                {$CFG->prefix}role r ON
+                r.id = co.defaultrole
+            WHERE
+                co.visible = '1' AND
+                co.enrollable = '1' $where
+            ORDER BY
+                sortorder ASC
+                ";
+
+            error_log($query);
+
+            return get_records_sql($query);
+
+        } elseif (!empty($CFG->enrol_mnet_allowed_courses)) {
+
+            $query =
+                "SELECT
+                    co.id as remoteid,
+                    ca.id as cat_id,
+                    ca.name as cat_name,
+                    ca.description as cat_description,
+                    co.sortorder,
+                    co.fullname,
+                    co.shortname,
+                    co.idnumber,
+                    co.summary,
+                    co.startdate,
+                    co.cost,
+                    co.currency,
+                    co.defaultrole as defaultroleid,
+                    r.name
+                FROM
+                    {$CFG->prefix}course_categories ca
+                JOIN
+                    {$CFG->prefix}course co ON
+                    ca.id = co.category
+                LEFT JOIN
+                    {$CFG->prefix}role r ON
+                    r.id = co.defaultrole
+                WHERE
+                    co.visible = '1' AND
+                    co.enrollable = '1' AND
+                    co.id in ({$CFG->enrol_mnet_allowed_courses})
+                ORDER BY
+                    sortorder ASC
+                    ";
+
+            return get_records_sql($query);
+
+        }
+
+        return array();
+    }
+
+    /**
+    * Does Foo
+    *
+    * @param string $username   The username
+    * @return array             Whether the user can login from the remote host
+    */
+    function user_enrolments() {
+
+        return array();
+    }
+
+    /**
+    * Enrols user to course with the default role
+    *
+    * @param string $username   The username of the remote use
+    * @param int    $courseid   The id of the local course
+    * @return bool              Whether the enrolment has been successful
+    */
+    function enrol_user($user, $courseid) {
+        global $MNET, $MNET_REMOTE_CLIENT;
+
+        $userrecord = get_record('user','username',addslashes($user['username']), 'mnethostid',$MNET_REMOTE_CLIENT->id);
+
+        if ($userrecord == false) {
+            $userrecord = new stdClass();
+            $userrecord->username   = addslashes($user['username']);
+            $userrecord->email      = addslashes($user['email']);
+            $userrecord->firstname  = addslashes($user['firstname']);
+            $userrecord->lastname   = addslashes($user['lastname']);
+            $userrecord->mnethostid = $MNET_REMOTE_CLIENT->id;
+
+            if ($userrecord->id = insert_record('user', $userrecord)) {
+                $userrecord = get_record('user','id', $userrecord->id);
+            } else {
+                // TODO: Error out
+                return false;
+            }
+        }
+
+        if (! $course = get_record('course', 'id', $courseid) ) {
+            // TODO: Error out
+            return false;
+        }
+
+        $courses = $this->available_courses();
+
+        if (!empty($courses[$courseid])) {
+            error_log("remote enrolling $courseid, $userrecord->id,");
+            //TODO: rewire enrol_into_course
+            if (enrol_into_course($course, $userrecord, 'mnet')) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    * Unenrol a user from a course
+    *
+    * @param string $username   The username
+    * @param int    $courseid   The id of the local course
+    * @return bool              Whether the user can login from the remote host
+    */
+    function unenrol_user($user, $courseid) {
+        global $MNET_REMOTE_CLIENT;
+
+        $userrecord = get_record('user','username',$user['username'], 'mnethostid',$MNET_REMOTE_CLIENT->id);
+
+        if ($userrecord == false) {
+            // TODO: Error out
+        }
+
+        if (! $course = get_record('course', 'id', $courseid) ) {
+            // TODO: Error out
+        }
+
+        if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) {
+            // TODO: Error out (Invalid context)
+        }
+
+        // Are we a *real* user or the shady MNET Daemon?
+        // require_capability('moodle/role:assign', $context, NULL, false);
+
+        if (! role_unassign(0, $userrecord->id, 0, $context->id)) {
+            error("An error occurred while trying to unenrol that person.");
+        }
+
+        return true;
+    }
+
+    /***
+     *** Client RPC behaviour
+     ***
+     ***
+     ***/
+
+    /**
+    * Lists remote servers we use 'enrol' services from.
+    *
+    * @return array
+    */
+    function list_remote_servers() {
+        global $CFG;
+
+        $sql = "
+            SELECT DISTINCT 
+                h.id, 
+                h.name
+            FROM 
+                {$CFG->prefix}mnet_host h,
+                {$CFG->prefix}mnet_host2service h2s,
+                {$CFG->prefix}mnet_service s
+            WHERE
+                h.id = h2s.hostid AND
+                h2s.serviceid = s.id AND
+                s.name = 'mnet_enrol'";
+
+        return get_records_sql($sql);
+    }
+
+    /**
+    * Does Foo
+    *
+    * @param int    $mnethostid The id of the remote mnethost
+    * @return array              Whether the user can login from the remote host
+    */
+    function fetch_remote_courses($mnethostid) {
+        global $CFG;
+        global $USER;
+        global $MNET;
+        require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
+
+        // get the Service Provider info
+        $mnet_sp = new mnet_peer();
+        $mnet_sp->set_id($mnethostid);
+
+        // set up the RPC request
+        $mnetrequest = new mnet_xmlrpc_client();
+        $mnetrequest->set_method('enrol/mnet/enrol.php/available_courses');
+
+        // TODO: cache for a while (10 minutes?)
+
+        // Thunderbirds are go! Do RPC call and store response
+        if ($mnetrequest->send($mnet_sp) === true) {
+            $courses = $mnetrequest->response;
+
+            // get the cached courses key'd on remote id - only need remoteid and id fields
+            $cachedcourses = get_records('mnet_enrol_course',
+                                         'hostid', $mnethostid,
+                                         'remoteid', 'remoteid, id' );
+
+            // Update cache and transform $courses into objects
+            // in-place for the benefit of our caller...
+            for ($n=0;$n<count($courses);$n++) {
+
+                $course = &$courses[$n];
+
+                // add/update cached data in mnet_enrol_courses
+                $course = (object)$course;
+                $course->remoteid        = (int)$course->remoteid;
+                $course->hostid          = $mnethostid;
+                $course->categoryid      = (int)$course->categoryid;
+                $course->categoryname    = addslashes($course->categoryname);
+                $course->description     = addslashes($course->description);
+                $course->sortorder       = (int)$course->sortorder ;
+                $course->fullname        = addslashes($course->fullname);
+                $course->shortname       = addslashes($course->shortname);
+                $course->idnumber        = addslashes($course->idnumber);
+                $course->summary         = addslashes($course->summary);
+                $course->startdate       = (int)$course->startdate;
+                $course->cost            = (int)$course->cost;
+                $course->currency        = addslashes($course->currency);
+                $course->defaultroleid   = (int)$course->defaultroleid;
+                $course->defaultrolename = addslashes($course->defaultrolename);
+
+                // insert or update
+                if (empty($cachedcourses[$course->remoteid])) {
+                    $course->id = insert_record('mnet_enrol_course', $course);
+                } else {
+                    $course->id = $cachedcourses[$course->remoteid]->id;
+                    $cachedcourses[$course->remoteid]->seen=true;
+                    update_record('mnet_enrol_course', $course);
+                }
+            }
+
+            // prune stale data from cache
+            if (!empty($cachedcourses)) {
+                $stale = array();
+                foreach ($cachedcourses as $id => $cc) {
+                    // TODO: maybe set a deleted flag instead
+                    if (empty($cc->seen)) {
+                        $stale[] = $cc->id;
+                    }
+                }
+                if (!empty($stale)) {
+                    delete_records_select('mnet_enrol_course', 'id IN ('.join(',',$stale).')');
+                }
+            }
+
+            return $courses;
+        } else {
+            foreach ($mnetrequest->error as $code => $errormessage) {
+                $message .= "ERROR $code:<br>$errormessage<br>";
+            }
+            error("RPC enrol/mnet/available_courses:<br>$message");
+        }
+        return false;
+    }
+
+    /**
+    * Does Foo
+    *
+    * @param int    $mnethostid The id of the remote mnethost
+    * @return array              Whether the user can login from the remote host
+    */
+    function req_enrol_user($userid, $courseid) {
+        global $CFG;
+        global $USER;
+        global $MNET;
+        require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
+
+        // Prepare a basic user record
+        // in case the remote host doesn't have it
+        $user = get_record('user', 'id', $userid, '','','','', 'username, email, firstname, lastname');
+        $user = (array)$user;
+
+        $course = get_record('mnet_enrol_course', 'id', $courseid);
+
+        // get the Service Provider info
+        $mnet_sp = new mnet_peer();
+        $mnet_sp->set_id($course->hostid);
+
+        // set up the RPC request
+        $mnetrequest = new mnet_xmlrpc_client();
+        $mnetrequest->set_method('enrol/mnet/enrol.php/enrol_user');
+        $mnetrequest->add_param($user);
+        $mnetrequest->add_param($course->remoteid);
+
+        // Thunderbirds are go! Do RPC call and store response
+        if ($mnetrequest->send($mnet_sp) === true) {
+            if ($mnetrequest->response == true) {
+                // now store it in the mnet_enrol_assignments table
+                $assignment = new StdClass;
+                $assignment->userid = $userid;
+                $assignment->hostid = $course->hostid;
+                $assignment->courseid = $course->id;
+                $assignment->enroltype = 'mnet';
+                // TODO: other fields
+                if (insert_record('mnet_enrol_assignments', $assignment)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+    * Does Foo
+    *
+    * @param int    $mnethostid The id of the remote mnethost
+    * @return array              Whether the user can login from the remote host
+    */
+    function req_unenrol_user($userid, $courseid) {
+        global $CFG;
+        global $USER;
+        global $MNET;
+        require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
+
+        // in case the remote host doesn't have it
+        $user = get_record('user', 'id', $userid, '','','','', 'username, email');
+        $user = $user->username;
+
+        $course = get_record('mnet_enrol_course', 'id', $courseid);
+
+        // get the Service Provider info
+        $mnet_sp = new mnet_peer();
+        $mnet_sp->set_id($course->hostid);
+
+        // set up the RPC request
+        $mnetrequest = new mnet_xmlrpc_client();
+        $mnetrequest->set_method('enrol/mnet/enrol.php/unenrol_user');
+        $mnetrequest->add_param($user);
+        $mnetrequest->add_param($course->remoteid);
+
+        // TODO - prevent removal of enrolments that are not of
+        // type mnet...
+
+
+        // Thunderbirds are go! Do RPC call and store response
+        if ($mnetrequest->send($mnet_sp) === true) {
+            if ($mnetrequest->response == true) {
+                // remove enrolment cached in mnet_enrol_assignments
+                delete_records_select('mnet_enrol_assignments',
+                                      "userid={$userid} AND courseid={$course->id}");
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+} // end of class
+
+?>
diff --git a/enrol/mnet/remote_courses.php b/enrol/mnet/remote_courses.php
new file mode 100644 (file)
index 0000000..f9b60dc
--- /dev/null
@@ -0,0 +1,52 @@
+<?PHP  // $Id$
+       // enrol_config.php - allows admin to edit all enrollment variables
+       //                    Yes, enrol is correct English spelling.
+
+    require_once(dirname(__FILE__) . "/../../config.php");
+    require_once($CFG->libdir.'/adminlib.php');
+
+    $adminroot = admin_get_root();
+    admin_externalpage_setup('enrolment', $adminroot);
+
+    $CFG->pagepath = 'enrol/mnet';
+    require_once("$CFG->dirroot/enrol/enrol.class.php");   /// Open the factory class
+    $enrolment = enrolment_factory::factory('mnet');
+
+    $mnethost = required_param('host', PARAM_INT);
+
+    $courses = $enrolment->fetch_remote_courses($mnethost);
+
+/// Print the page
+
+    /// get language strings
+    $str = get_strings(array('enrolmentplugins', 'configuration', 'users', 'administration'));
+
+    admin_externalpage_print_header($adminroot);
+
+    print_simple_box_start("center", "80%");
+
+    print_simple_box_start("center", "60%", '', 5, 'informationbox');
+    print_string("description", "enrol_mnet");
+    print_simple_box_end();
+
+    echo "<hr />";
+
+    print ('<table align="center">'
+           . '</tr>');
+
+    foreach ($courses as $course) {
+        print ('<tr>'
+               . "<td colspan=\"2\"><a href=\"{$CFG->wwwroot}/enrol/mnet/remote_enrolment.php?host={$mnethost}&amp;courseid={$course->id}\">{$course->fullname}</a></td>"
+               . '</tr><tr>'
+               . "<td align=\"left\" valign=\"top\">{$course->shortname}<br />"
+               . '</td>'
+               . "<td align=\"left\" >{$course->summary}</td>"
+               . '</tr>');
+    }
+    print ('</table>');
+
+    print_simple_box_end();
+
+    admin_externalpage_print_footer($adminroot);
+
+?>
diff --git a/enrol/mnet/remote_enrolment.html b/enrol/mnet/remote_enrolment.html
new file mode 100755 (executable)
index 0000000..4016c76
--- /dev/null
@@ -0,0 +1,94 @@
+
+<form name="assignform" id="assignform" method="post" action="">
+<input type="hidden" name="previoussearch" value="<?php p($previoussearch) ?>" />
+<input type="hidden" name="courseid" value="<?php p($courseid) ?>" />
+<input type="hidden" name="host" value="<?php p($mnethost->id) ?>" />
+<input type="hidden" name="sesskey" value="<?php p(sesskey()) ?>" />
+  <table align="center" border="0" cellpadding="5" cellspacing="0">
+    <tr>
+      <td valign="top">
+          <?php print_string('existingusers', 'role', count($enrolledusers)); ?>
+      </td>
+      <td></td>
+      <td valign="top">
+          <?php print_string('potentialusers', 'role', $usercount); ?>
+      </td>
+    </tr>
+    <tr>
+      <td valign="top">
+          <select name="removeselect[]" size="20" id="removeselect" multiple
+                  onFocus="document.assignform.add.disabled=true;
+                           document.assignform.remove.disabled=false;
+                           document.assignform.addselect.selectedIndex=-1;" />
+          <?php
+              foreach ($enrolledusers as $enrolleduser) {
+                  $fullname = fullname($enrolleduser, true);
+                  echo "<option value=\"$enrolleduser->id\">".$fullname.", ".$enrolleduser->email."</option>\n";
+              }
+          ?>
+
+          </select></td>
+      <td valign="top">
+        <br />
+        <input name="add" type="submit" id="add" value="&larr;" />
+        <br />
+        <input name="remove" type="submit" id="remove" value="&rarr;" />
+        <br />
+      </td>
+      <td valign="top">
+          <select name="addselect[]" size="20" id="addselect" multiple
+                  onFocus="document.assignform.add.disabled=false;
+                           document.assignform.remove.disabled=true;
+                           document.assignform.removeselect.selectedIndex=-1;">
+          <?php
+
+              if (!empty($searchtext)) {
+                  echo "<optgroup label=\"$strsearchresults (" . $availableusers->_numOfRows . ")\">\n";
+                  while (! $availableusers->EOF) {
+                      $user = $availableusers->FetchObj();
+                      if (!isset($enrolledusers[$user->id])) {
+                          $fullname = fullname($user, true);
+                          echo "<option value=\"$user->id\">".$fullname.", ".$user->email."</option>\n";
+                      }
+                      $availableusers->MoveNext();
+                  }
+                  echo "</optgroup>\n";
+
+              } else {
+                  if ($usercount > MAX_USERS_PER_PAGE) {
+                      echo '<optgroup label="'.get_string('toomanytoshow').'"><option></option></optgroup>'."\n"
+                          .'<optgroup label="'.get_string('trysearching').'"><option></option></optgroup>'."\n";
+                  } else {
+                      while (! $availableusers->EOF) {
+                          $user = $availableusers->FetchObj();
+                          if (!isset($enrolledusers[$user->id])) {
+                              $fullname = fullname($user, true);
+                              echo "<option value=\"$user->id\">".$fullname.", ".$user->email."</option>\n";
+                          }
+                          $availableusers->MoveNext();
+                      }
+                  }
+              }
+          ?>
+         </select>
+         <br />
+         <input type="text" name="searchtext" size="30" value="<?php p($searchtext, true) ?>"
+                  onFocus ="document.assignform.add.disabled=true;
+                            document.assignform.remove.disabled=true;
+                            document.assignform.removeselect.selectedIndex=-1;
+                            document.assignform.addselect.selectedIndex=-1;"
+                  onkeydown = "var keyCode = event.which ? event.which : event.keyCode;
+                               if (keyCode == 13) {
+                                    document.assignform.previoussearch.value=1;
+                                    document.assignform.submit();
+                               } " />
+         <input name="search" id="search" type="submit" value="<?php p($strsearch) ?>" />
+         <?php
+              if (!empty($searchusers)) {
+                  echo '<input name="showall" id="showall" type="submit" value="'.$strshowall.'" />'."\n";
+              }
+         ?>
+       </td>
+    </tr>
+  </table>
+</form>
diff --git a/enrol/mnet/remote_enrolment.php b/enrol/mnet/remote_enrolment.php
new file mode 100644 (file)
index 0000000..7b14eac
--- /dev/null
@@ -0,0 +1,146 @@
+<?PHP  // $Id$
+       // enrol_config.php - allows admin to edit all enrollment variables
+       //                    Yes, enrol is correct English spelling.
+
+    require_once(dirname(__FILE__) . "/../../config.php");
+    require_once($CFG->libdir.'/adminlib.php');
+
+    $adminroot = admin_get_root();
+    admin_externalpage_setup('enrolment', $adminroot);
+
+    $CFG->pagepath = 'enrol/mnet';
+    require_once("$CFG->dirroot/enrol/enrol.class.php");   /// Open the factory class
+    $enrolment = enrolment_factory::factory('mnet');
+
+    $mnethost = required_param('host', PARAM_INT);
+    $courseid = required_param('courseid', PARAM_INT);
+
+    $mnethost = get_record('mnet_host', 'id', $mnethost);
+     $course = get_record('mnet_enrol_course', 'id', $courseid, 'hostid', $mnethost->id);
+
+    if (empty($mnethost) || empty($course)) {
+        error("Host or course not found");
+    }
+
+    define("MAX_USERS_PER_PAGE", 5000);
+
+    $add            = optional_param('add', 0, PARAM_BOOL);
+    $remove         = optional_param('remove', 0, PARAM_BOOL);
+    $showall        = optional_param('showall', 0, PARAM_BOOL);
+    $searchtext     = optional_param('searchtext', '', PARAM_RAW); // search string
+    $previoussearch = optional_param('previoussearch', 0, PARAM_BOOL);
+    $userid         = optional_param('userid', 0, PARAM_INT); // needed for user tabs
+
+    $errors = array();
+
+    $previoussearch = ($searchtext != '') or ($previoussearch) ? 1:0;
+
+    $baseurl = "remote_enrolment.php?courseid={$course->id}&amp;host={$mnethost->id}";
+    if (!empty($userid)) {
+        $baseurl .= '&amp;userid='.$userid;
+    }
+
+/// Process incoming role assignment
+
+    if ($frm = data_submitted()) {
+        if ($add and !empty($frm->addselect) and confirm_sesskey()) {
+            $timemodified = time();
+
+            foreach ($frm->addselect as $adduser) {
+                if (!$adduser = clean_param($adduser, PARAM_INT)) {
+                    continue;
+                }
+                if (! $enrolment->req_enrol_user($adduser, $course->id)) {
+                    $errors[] = "Could not add user with id $adduser to this role!";
+                }
+            }
+        } else if ($remove and !empty($frm->removeselect) and confirm_sesskey()) {
+            foreach ($frm->removeselect as $removeuser) {
+                $removeuser = clean_param($removeuser, PARAM_INT);
+                if (! $enrolment->req_unenrol_user($removeuser, $course->id)) {
+                    $errors[] = "Could not remove user with id $removeuser from this role!";
+                }
+            }
+        } else if ($showall) {
+            $searchtext = '';
+            $previoussearch = 0;
+        }
+    }
+
+/// Prepare data for users / enrolled users panes
+    $sql = "SELECT u.id, u.firstname, u.lastname, u.email
+            FROM {$CFG->prefix}mnet_enrol_assignments a
+            JOIN {$CFG->prefix}user u ON a.userid=u.id
+            WHERE a.courseid={$courseid}
+            ORDER BY u.id";
+    if (!$enrolledusers = get_records_sql($sql)) {
+        $enrolledusers = array();
+    }
+
+    $select  = "username != 'guest' AND username != 'changeme' AND deleted = 0 AND confirmed = 1 AND mnethostid = {$CFG->mnet_localhost_id}";
+    
+    $usercount = count_records_select('user', $select) - count($enrolledusers);
+
+    $searchtext = trim($searchtext);
+
+    if ($searchtext !== '') {   // Search for a subset of remaining users
+        $LIKE      = sql_ilike();
+        $FULLNAME  = sql_fullname();
+
+        $select  .= " AND ($FULLNAME $LIKE '%$searchtext%' OR email $LIKE '%$searchtext%') ";
+    }
+    $availableusers = get_recordset_sql('SELECT id, firstname, lastname, email 
+                                         FROM '.$CFG->prefix.'user 
+                                         WHERE '.$select.'
+                                         ORDER BY lastname ASC, firstname ASC');
+
+
+
+/// Print the page
+
+/// get language strings
+$str = get_strings(array('enrolmentplugins', 'configuration', 'users', 'administration'));
+/// Get some language strings
+
+$strassignusers = get_string('assignusers', 'role');
+$strpotentialusers = get_string('potentialusers', 'role');
+$strexistingusers = get_string('existingusers', 'role');
+$straction = get_string('assignroles', 'role');
+$strroletoassign = get_string('roletoassign', 'role');
+$strcurrentcontext = get_string('currentcontext', 'role');
+$strsearch = get_string('search');
+$strshowall = get_string('showall');
+$strparticipants = get_string('participants');
+$strsearchresults = get_string('searchresults');
+
+admin_externalpage_print_header($adminroot);
+
+print_simple_box_start("center", "80%");
+
+print_simple_box_start("center", "60%", '', 5, 'informationbox');
+print "Enrolling in course " . s($course->shortname) . ' on host ' . s($mnethost->name) ."</p>";
+print_string("description", "enrol_mnet");
+print_simple_box_end();
+
+echo "<hr />";
+
+        print_simple_box_start('center');
+        include('remote_enrolment.html');
+        print_simple_box_end();
+
+        if (!empty($errors)) {
+            $msg = '<p>';
+            foreach ($errors as $e) {
+                $msg .= $e.'<br />';
+            }
+            $msg .= '</p>';
+            print_simple_box_start('center');
+            notify($msg);
+            print_simple_box_end();
+        }
+
+
+
+admin_externalpage_print_footer($adminroot);
+
+?>
diff --git a/enrol/mnet/remote_hosts.php b/enrol/mnet/remote_hosts.php
new file mode 100644 (file)
index 0000000..8a4c688
--- /dev/null
@@ -0,0 +1,64 @@
+<?PHP  // $Id$
+       // enrol_config.php - allows admin to edit all enrollment variables
+       //                    Yes, enrol is correct English spelling.
+
+    require_once(dirname(__FILE__) . "/../../config.php");
+    require_once($CFG->libdir.'/adminlib.php');
+
+    $adminroot = admin_get_root();
+    admin_externalpage_setup('enrolment', $adminroot);
+
+    $CFG->pagepath = 'enrol/mnet';
+
+
+    require_once("$CFG->dirroot/enrol/enrol.class.php");   /// Open the factory class
+
+    $enrolment = enrolment_factory::factory('mnet');
+
+/// If data submitted, then process and store.
+
+    if ($frm = data_submitted()) {
+
+    }
+
+/// Otherwise fill and print the form.
+
+    /// get language strings
+    $str = get_strings(array('enrolmentplugins', 'configuration', 'users', 'administration'));
+
+    admin_externalpage_print_header($adminroot);
+
+
+/// Print current enrolment type description
+    print_simple_box_start("center", "80%");
+    print_heading($options[$enrol]);
+
+    print_simple_box_start("center", "60%", '', 5, 'informationbox');
+    print_string("description", "enrol_$enrol");
+    print_simple_box_end();
+
+    echo "<hr />";
+
+    print ('<table align="center">'
+           . '<tr>'
+           . '<th> Name </th>'
+           . '<th> Enrolments </th>'
+           . '<th> Available Courses </th>'
+           . '<th> Activity </th>'
+           . '</tr>');
+    $hosts = $enrolment->list_remote_servers();
+    foreach ($hosts as $host) {
+        print ('<tr>'
+               . "<td><a href=\"{$CFG->wwwroot}/enrol/mnet/remote_courses.php?host={$host->id}\">{$host->name}</a></td>"
+               . '<td align="center" > - (View)  </td>'
+               . "<td align=\"center\" > - (<a href=\"{$CFG->wwwroot}/enrol/mnet/remote_courses.php?host={$host->id}\">Enrol</a>) </td>"
+               . '<td align="center" > <a href="">Logs</a> </td>'
+               . '</tr>');
+    }
+    print ('</table>');
+
+    print_simple_box_end();
+
+    admin_externalpage_print_footer($adminroot);
+
+?>
diff --git a/lang/en_utf8/enrol_mnet.php b/lang/en_utf8/enrol_mnet.php
new file mode 100644 (file)
index 0000000..de6b0a4
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+$string['description'] = 'Description of enrolment over Moodle Networking.';
+$string['enrolname'] = 'Moodle Networking';
+$string['enrolname'] = 'Moodle Networking';
+$string['allow_allcourses'] = 'Allow enrolment in all remote courses.';
+$string['allcategories'] = '$a potential categories';
+$string['allowedcategories'] = '$a allowed categories';
+$string['nocategoriesdefined'] = 'No course categories found. Define new categories <a href=\"$a\">here</a>.';
+$string['allcourses'] = '$a potential courses';
+$string['allowedcourses'] = '$a allowed courses';
+$string['nocoursesdefined'] = 'No courses found. Define new courses <a href=\"$a\">here</a>.';
+$string['allowedcourseslinktext'] = 'Edit allowed courses and categories here.';
+$string['mnet_enrol_name']             = 'Moodle Networked Enrolment';
+$string['mnet_enrol_description']      = 'Publish this service to allow administrators at $a to enrol their students in courses you have created on your server.<br>' .
+                                         '<ul><li><em>Dependency</em>: You must also <strong>publish</strong> the SSO (Service Provider) service to $a.</li>'.
+                                         '<li><em>Dependency</em>: You must also <strong>subscribe</strong> to the SSO (Identity Provider) service on $a.</li></ul><br>'.
+                                         'Subscribe to this service to be able to enrol your students in courses  on $a.<br>'.
+                                         '<ul><li><em>Dependency</em>: You must also <strong>subscribe</strong> to the SSO (Service Provider) service on $a.</li>'.
+                                         '<li><em>Dependency</em>: You must also <strong>publish</strong> the SSO (Identity Provider) service to $a.</li></ul><br>';
+
+?>