From fa36ca3db7ec30639fd87361221916111ef6eaae Mon Sep 17 00:00:00 2001 From: Aaron Barnes Date: Thu, 22 Jul 2010 03:33:28 +0000 Subject: [PATCH] MDL-22783 upgrade enrol/flatfile plugin to use enrolments Adding/removing files missed in last patch --- enrol/imsenterprise/config.html | 199 ---------- enrol/imsenterprise/{enrol.php => lib.php} | 442 ++++++++------------- enrol/imsenterprise/locallib.php | 84 ++++ enrol/imsenterprise/settings.php | 88 ++++ enrol/imsenterprise/version.php | 27 ++ 5 files changed, 362 insertions(+), 478 deletions(-) delete mode 100644 enrol/imsenterprise/config.html rename enrol/imsenterprise/{enrol.php => lib.php} (67%) create mode 100644 enrol/imsenterprise/locallib.php create mode 100644 enrol/imsenterprise/settings.php create mode 100644 enrol/imsenterprise/version.php diff --git a/enrol/imsenterprise/config.html b/enrol/imsenterprise/config.html deleted file mode 100644 index 56ba350ff33..00000000000 --- a/enrol/imsenterprise/config.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - get_string('ignore')) + $assignableroles; - -foreach($this->imsroles as $imsrolenum=>$imsrolename){ -?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
: - -
: - -
: - enrol_mailadmins) echo "checked=\"checked\"" ?> /> - - -
: - enrol_createnewusers) echo "checked=\"checked\"" ?> /> - - old_help_icon('createnewusers', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_imsdeleteusers) echo "checked=\"checked\"" ?> /> - - old_help_icon('deleteusers', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_fixcaseusernames) echo "checked=\"checked\"" ?> /> - - -
: - enrol_fixcasepersonalnames) echo "checked=\"checked\"" ?> /> - - -
: - enrol_imssourcedidfallback) echo "checked=\"checked\"" ?> /> - - old_help_icon('sourceddidfallback', 'More detail about this option', 'enrol/imsenterprise'); ?> -
"" (): - $configref) ? $frm->$configref : $this->determine_default_rolemapping($imsrolenum), false); - ?> - -
: - name="enrol_truncatecoursecodes" size="3" maxlength="3" /> - - old_help_icon('truncatecoursecodes', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_createnewcourses) echo "checked=\"checked\"" ?> /> - - old_help_icon('createnewcourses', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_createnewcategories) echo "checked=\"checked\"" ?> /> - - old_help_icon('categorisation', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_imsunenrol) echo "checked=\"checked\"" ?> /> - - old_help_icon('unenrol', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - name="enrol_imsrestricttarget" size="20" maxlength="32" /> - old_help_icon('target', 'More detail about this option', 'enrol/imsenterprise'); ?> -
: - enrol_imscapitafix) echo "checked=\"checked\"" ?> /> - - old_help_icon('capita', 'More detail about this option', 'enrol/imsenterprise'); ?> -
- -

.

diff --git a/enrol/imsenterprise/enrol.php b/enrol/imsenterprise/lib.php similarity index 67% rename from enrol/imsenterprise/enrol.php rename to enrol/imsenterprise/lib.php index e10bb2415ae..cf8b0707b2b 100644 --- a/enrol/imsenterprise/enrol.php +++ b/enrol/imsenterprise/lib.php @@ -1,26 +1,30 @@ dirroot.'/group/lib.php'); +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . -// The following flags are set in the configuration -// $CFG->enrol_imsfilelocation: where is the file we are looking for? -// $CFG->enrol_logtolocation: if you want to store a log of processing, specify filepath here -// $CFG->enrol_allowinternal: allow internal enrolment in courses -// $CFG->enrol_emailadmins: email a notification to the admin -// $CFG->enrol_createnewusers: should this script create user accounts for those who don't seem to be registered yet? -// $CFG->enrol_imsdeleteusers: should this script mark user accounts as deleted, if the data requests this? -// $CFG->enrol_fixcaseusernames: whether to force all usernames to lowercase -// $CFG->enrol_fixcasepersonalnames: convert personal names, e.g. from "TOM VEK" to "Tom Vek" -// $CFG->enrol_truncatecoursecodes: if this number is greater than zero, truncate the codes found in the IMS data to the given number of characters -// $CFG->enrol_imsunenrol: allow this script to UNENROL students/tutors from courses (if the data marks them as having left the course) -// $CFG->enrol_createnewcourses: should this script create a (hidden, empty) course for any course that doesn't seem to have been registered yet? -// $CFG->enrol_createnewcategories: should this script create a (hidden) category if Moodle doesn't have one by the same name as the desired one? -// $CFG->enrol_imssourcedidfallback: some systems don't output a element (contrary to the specifications). If this is the case, activating this setting will cause us to use the element instead as the userid. This may or may not be desirable in your situation. -// $CFG->enrol_includephoto: Process IMS tag to create user photo. Be warned that this may add significant server load. +/** + * IMS Enterprise file enrolment plugin. + * + * This plugin lets the user specify an IMS Enterprise file to be processed. + * The IMS Enterprise file is mainly parsed on a regular cron, + * but can also be imported via the UI (Admin Settings). + * @package enrol_imsenterprise + * @copyright 2010 Eugene Venter + * @author Eugene Venter - based on code by Dan Stowell + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ /* @@ -42,176 +46,14 @@ for users and for courses. */ - -class enrolment_plugin_imsenterprise { - - var $log; - -// The "roles" hard-coded in the IMS specification are: -var $imsroles = array( -'01'=>'Learner', -'02'=>'Instructor', -'03'=>'Content Developer', -'04'=>'Member', -'05'=>'Manager', -'06'=>'Mentor', -'07'=>'Administrator', -'08'=>'TeachingAssistant', -); -// PLEASE NOTE: It may seem odd that "Content Developer" has a space in it -// but "TeachingAssistant" doesn't. That's what the spec says though!!! +require_once($CFG->dirroot.'/group/lib.php'); -/** -* This function is only used when first setting up the plugin, to -* decide which role assignments to recommend by default. -* For example, IMS role '01' is 'Learner', so may map to 'student' in Moodle. -*/ -function determine_default_rolemapping($imscode) { - global $DB; +class enrol_imsenterprise_plugin extends enrol_plugin { - switch($imscode) { - case '01': - case '04': - $shortname = 'student'; - break; - case '06': - case '08': - $shortname = 'teacher'; - break; - case '02': - case '03': - $shortname = 'editingteacher'; - break; - case '05': - case '07': - $shortname = 'admin'; - break; - default: - return 0; // Zero for no match - } - return $DB->get_field('role', 'id', array('shortname'=>$shortname)); -} +var $log; - -/// Override the base config_form() function -function config_form($frm) { - global $CFG, $OUTPUT, $imsroles; - - $vars = array('enrol_imsfilelocation', 'enrol_logtolocation', 'enrol_createnewusers', 'enrol_fixcaseusernames', 'enrol_fixcasepersonalnames', 'enrol_truncatecoursecodes', - 'enrol_createnewcourses', 'enrol_createnewcategories', 'enrol_createnewusers', 'enrol_mailadmins', - 'enrol_imsunenrol', 'enrol_imssourcedidfallback', 'enrol_imscapitafix', 'enrol_imsrestricttarget', 'enrol_imsdeleteusers', - 'enrol_imse_imsrolemap01','enrol_imse_imsrolemap02','enrol_imse_imsrolemap03','enrol_imse_imsrolemap04', - 'enrol_imse_imsrolemap05','enrol_imse_imsrolemap06','enrol_imse_imsrolemap07','enrol_imse_imsrolemap08'); - foreach ($vars as $var) { - if (!isset($frm->$var)) { - $frm->$var = ''; - } - } - include ("$CFG->dirroot/enrol/imsenterprise/config.html"); -} - - -/// Override the base process_config() function -function process_config($config) { - - if (!isset($config->enrol_imsfilelocation)) { - $config->enrol_imsfilelocation = ''; - } - set_config('enrol_imsfilelocation', $config->enrol_imsfilelocation); - - if (!isset($config->enrol_logtolocation)) { - $config->enrol_logtolocation = ''; - } - set_config('enrol_logtolocation', $config->enrol_logtolocation); - - if (!isset($config->enrol_fixcaseusernames)) { - $config->enrol_fixcaseusernames = ''; - } - set_config('enrol_fixcaseusernames', $config->enrol_fixcaseusernames); - - if (!isset($config->enrol_fixcasepersonalnames)) { - $config->enrol_fixcasepersonalnames = ''; - } - set_config('enrol_fixcasepersonalnames', $config->enrol_fixcasepersonalnames); - - if (!isset($config->enrol_truncatecoursecodes)) { - $config->enrol_truncatecoursecodes = 0; - } - set_config('enrol_truncatecoursecodes', intval($config->enrol_truncatecoursecodes)); - - if (!isset($config->enrol_createnewcourses)) { - $config->enrol_createnewcourses = ''; - } - set_config('enrol_createnewcourses', $config->enrol_createnewcourses); - - if (!isset($config->enrol_createnewcategories)) { - $config->enrol_createnewcategories = ''; - } - set_config('enrol_createnewcategories', $config->enrol_createnewcategories); - - if (!isset($config->enrol_createnewusers)) { - $config->enrol_createnewusers = ''; - } - set_config('enrol_createnewusers', $config->enrol_createnewusers); - - if (!isset($config->enrol_imsdeleteusers)) { - $config->enrol_imsdeleteusers = ''; - } - set_config('enrol_imsdeleteusers', $config->enrol_imsdeleteusers); - - if (!isset($config->enrol_mailadmins)) { - $config->enrol_mailadmins = ''; - } - set_config('enrol_mailadmins', $config->enrol_mailadmins); - - if (!isset($config->enrol_imsunenrol)) { - $config->enrol_imsunenrol = ''; - } - set_config('enrol_imsunenrol', $config->enrol_imsunenrol); - - if (!isset($config->enrol_imssourcedidfallback)) { - $config->enrol_imssourcedidfallback = ''; - } - set_config('enrol_imssourcedidfallback', $config->enrol_imssourcedidfallback); - - if (!isset($config->enrol_imscapitafix)) { - $config->enrol_imscapitafix = ''; - } - set_config('enrol_imscapitafix', $config->enrol_imscapitafix); - - //Antoni Mas. 07/12/2005. Incloem la opci de la foto dels usuaris - if (!isset($config->enrol_processphoto)) { - $config->enrol_processphoto = ''; - } - set_config('enrol_processphoto', $config->enrol_processphoto); - - if (!isset($config->enrol_imsrestricttarget)) { - $config->enrol_imsrestricttarget = ''; - } - set_config('enrol_imsrestricttarget', $config->enrol_imsrestricttarget); - - - - foreach($this->imsroles as $imsrolenum=>$imsrolename){ - $configref = 'enrol_imse_imsrolemap' . $imsrolenum; - if (!isset($config->$configref)) { - echo "

Resetting config->$configref

"; - $config->$configref = 0; - } - set_config('enrol_imse_imsrolemap' . $imsrolenum, $config->$configref); - } - - - set_config('enrol_ims_prev_md5', ''); // Forget the MD5 - to force re-processing if we change the config setting - set_config('enrol_ims_prev_time', ''); // Ditto - return true; - -} - -function get_access_icons($course){} - /** * Read in an IMS Enterprise file. * Originally designed to handle v1.1 files but should be able to handle @@ -221,20 +63,26 @@ function get_access_icons($course){} function cron() { global $CFG; - if (empty($CFG->enrol_imsfilelocation)) { + // Get configs + $imsfilelocation = $this->get_config('imsfilelocation'); + $logtolocation = $this->get_config('logtolocation'); + $mailadmins = $this->get_config('mailadmins'); + $prev_time = $this->get_config('prev_time'); + $prev_md5 = $this->get_config('prev_md5'); + $prev_path = $this->get_config('prev_path'); + + if (empty($imsfilelocation)) { // $filename = "$CFG->dirroot/enrol/imsenterprise/example.xml"; // Default location $filename = "$CFG->dataroot/1/imsenterprise-enrol.xml"; // Default location } else { - $filename = $CFG->enrol_imsfilelocation; + $filename = $imsfilelocation; } $this->logfp = false; // File pointer for writing log data to - if(!empty($CFG->enrol_logtolocation)) { - $this->logfp = fopen($CFG->enrol_logtolocation, 'a'); + if(!empty($logtolocation)) { + $this->logfp = fopen($logtolocation, 'a'); } - - if ( file_exists($filename) ) { @set_time_limit(0); $starttime = time(); @@ -252,19 +100,19 @@ function cron() { // Decide if we want to process the file (based on filepath, modification time, and MD5 hash) // This is so we avoid wasting the server's efforts processing a file unnecessarily - if(empty($CFG->enrol_ims_prev_path) || ($filename != $CFG->enrol_ims_prev_path)){ + if(empty($prev_path) || ($filename != $prev_path)) { $fileisnew = true; - }elseif(isset($CFG->enrol_ims_prev_time) && ($filemtime <= $CFG->enrol_ims_prev_time)){ + } elseif(isset($prev_time) && ($filemtime <= $prev_time)) { $fileisnew = false; $this->log_line('File modification time is not more recent than last update - skipping processing.'); - }elseif(isset($CFG->enrol_ims_prev_md5) && ($md5 == $CFG->enrol_ims_prev_md5)){ + } elseif(isset($prev_md5) && ($md5 == $prev_md5)) { $fileisnew = false; $this->log_line('File MD5 hash is same as on last update - skipping processing.'); - }else{ + } else { $fileisnew = true; // Let's process it! } - if($fileisnew){ + if($fileisnew) { $listoftags = array('group', 'person', 'member', 'membership', 'comments', 'properties'); // The list of tags which should trigger action (even if only cache trimming) $this->continueprocessing = true; // The tag is allowed to halt processing if we're demanding a matching target @@ -279,27 +127,27 @@ function cron() { $curline = fgets($fh); $this->xmlcache .= $curline; // Add a line onto the XML cache - while(true){ + while (true) { // If we've got a full tag (i.e. the most recent line has closed the tag) then process-it-and-forget-it. // Must always make sure to remove tags from cache so they don't clog up our memory - if($tagcontents = $this->full_tag_found_in_cache('group', $curline)){ + if($tagcontents = $this->full_tag_found_in_cache('group', $curline)) { $this->process_group_tag($tagcontents); $this->remove_tag_from_cache('group'); - }elseif($tagcontents = $this->full_tag_found_in_cache('person', $curline)){ + } elseif($tagcontents = $this->full_tag_found_in_cache('person', $curline)) { $this->process_person_tag($tagcontents); $this->remove_tag_from_cache('person'); - }elseif($tagcontents = $this->full_tag_found_in_cache('membership', $curline)){ + } elseif($tagcontents = $this->full_tag_found_in_cache('membership', $curline)) { $this->process_membership_tag($tagcontents); $this->remove_tag_from_cache('membership'); - }elseif($tagcontents = $this->full_tag_found_in_cache('comments', $curline)){ + } elseif($tagcontents = $this->full_tag_found_in_cache('comments', $curline)) { $this->remove_tag_from_cache('comments'); - }elseif($tagcontents = $this->full_tag_found_in_cache('properties', $curline)){ + } elseif($tagcontents = $this->full_tag_found_in_cache('properties', $curline)) { $this->process_properties_tag($tagcontents); $this->remove_tag_from_cache('properties'); - }else{ - break; - } - } // End of while-tags-are-detected + } else { + break; + } + } // End of while-tags-are-detected } // end of while loop fclose($fh); fix_course_sortorder(); @@ -355,9 +203,9 @@ function cron() { // These variables are stored so we can compare them against the IMS file, next time round. - set_config('enrol_ims_prev_time', $filemtime); - set_config('enrol_ims_prev_md5', $md5); - set_config('enrol_ims_prev_path', $filename); + $this->set_config('prev_time', $filemtime); + $this->set_config('prev_md5', $md5); + $this->set_config('prev_path', $filename); @@ -365,16 +213,16 @@ function cron() { $this->log_line('File not found: '.$filename); } - if (!empty($CFG->enrol_mailadmins)) { + if (!empty($mailadmins)) { $msg = "An IMS enrolment has been carried out within Moodle.\nTime taken: $timeelapsed seconds.\n\n"; - if(!empty($CFG->enrol_logtolocation)){ + if(!empty($logtolocation)){ if($this->logfp){ $msg .= "Log data has been written to:\n"; - $msg .= "$CFG->enrol_logtolocation\n"; - $msg .= "(Log file size: ".ceil(filesize($CFG->enrol_logtolocation)/1024)."Kb)\n\n"; + $msg .= "$logtolocation\n"; + $msg .= "(Log file size: ".ceil(filesize($logtolocation)/1024)."Kb)\n\n"; }else{ $msg .= "The log file appears not to have been successfully written.\nCheck that the file is writeable by the server:\n"; - $msg .= "$CFG->enrol_logtolocation\n\n"; + $msg .= "$logtolocation\n\n"; } }else{ $msg .= "Logging is currently not active."; @@ -382,6 +230,8 @@ function cron() { $eventdata = new object(); $eventdata->modulename = 'moodle'; + $eventdata->component = 'imsenterprise'; + $eventdata->name = 'imsenterprise_enrolment'; $eventdata->userfrom = get_admin(); $eventdata->userto = get_admin(); $eventdata->subject = "Moodle IMS Enterprise enrolment notification"; @@ -450,7 +300,12 @@ function get_recstatus($tagdata, $tagname){ * @param string $tagconents The raw contents of the XML element */ function process_group_tag($tagcontents){ - global $CFG, $DB; + global $DB; + + // Get configs + $truncatecoursecodes = $this->get_config('truncatecoursecodes'); + $createnewcourses = $this->get_config('createnewcourses'); + $createnewcategories = $this->get_config('createnewcategories'); // Process tag contents unset($group); @@ -471,9 +326,9 @@ function process_group_tag($tagcontents){ $this->log_line('Error at line '.$line.': Unable to find course code in \'group\' element.'); }else{ // First, truncate the course code if desired - if(intval($CFG->enrol_truncatecoursecodes)>0){ - $group->coursecode = ($CFG->enrol_truncatecoursecodes > 0) - ? substr($group->coursecode, 0, intval($CFG->enrol_truncatecoursecodes)) + if(intval($truncatecoursecodes)>0){ + $group->coursecode = ($truncatecoursecodes > 0) + ? substr($group->coursecode, 0, intval($truncatecoursecodes)) : $group->coursecode; } @@ -494,7 +349,7 @@ function process_group_tag($tagcontents){ foreach($group->coursecode as $coursecode){ $coursecode = trim($coursecode); if(!$DB->get_field('course', 'id', array('idnumber'=>$coursecode))) { - if(!$CFG->enrol_createnewcourses) { + if(!$createnewcourses) { $this->log_line("Course $coursecode not found in Moodle's course idnumbers."); } else { // Create the (hidden) course(s) if not found @@ -512,7 +367,7 @@ function process_group_tag($tagcontents){ // If the category is defined and exists in Moodle, we want to store it in that one if($catid = $DB->get_field('course_categories', 'id', array('name'=>$group->category))){ $course->category = $catid; - }elseif($CFG->enrol_createnewcategories){ + } elseif($createnewcategories) { // Else if we're allowed to create new categories, let's create this one $newcat->name = $group->category; $newcat->visible = 0; @@ -570,6 +425,13 @@ function process_group_tag($tagcontents){ function process_person_tag($tagcontents){ global $CFG, $DB; + // Get plugin configs + $imssourcedidfallback = $this->get_config('imssourcedidfallback'); + $fixcaseusernames = $this->get_config('fixcaseusernames'); + $fixcasepersonalnames = $this->get_config('fixcasepersonalnames'); + $imsdeleteusers = $this->get_config('imsdeleteusers'); + $createnewusers = $this->get_config('createnewusers'); + if(preg_match('{.*?(.+?).*?}is', $tagcontents, $matches)){ $person->idnumber = trim($matches[1]); } @@ -582,7 +444,7 @@ function process_person_tag($tagcontents){ if(preg_match('{(.*?)}is', $tagcontents, $matches)){ $person->username = trim($matches[1]); } - if($CFG->enrol_imssourcedidfallback && trim($person->username)==''){ + if($imssourcedidfallback && trim($person->username)==''){ // This is the point where we can fall back to useing the "sourcedid" if "userid" is not supplied // NB We don't use an "elseif" because the tag may be supplied-but-empty $person->username = $person->idnumber; @@ -601,10 +463,10 @@ function process_person_tag($tagcontents){ } // Fix case of some of the fields if required - if($CFG->enrol_fixcaseusernames && isset($person->username)){ + if($fixcaseusernames && isset($person->username)){ $person->username = strtolower($person->username); } - if($CFG->enrol_fixcasepersonalnames){ + if($fixcasepersonalnames){ if(isset($person->firstname)){ $person->firstname = ucwords(strtolower($person->firstname)); } @@ -620,7 +482,7 @@ function process_person_tag($tagcontents){ // In the "users" table we can do this by setting deleted=1 if($recstatus==3){ - if($CFG->enrol_imsdeleteusers){ // If we're allowed to delete user records + if($imsdeleteusers){ // If we're allowed to delete user records // Make sure their "deleted" field is set to one $DB->set_field('user', 'deleted', 1, array('username'=>$person->username)); $this->log_line("Marked user record for user '$person->username' (ID number $person->idnumber) as deleted."); @@ -632,7 +494,7 @@ function process_person_tag($tagcontents){ // If the user exists (matching sourcedid) then we don't need to do anything. - if(!$DB->get_field('user', 'id', array('idnumber'=>$person->idnumber)) && $CFG->enrol_createnewusers){ + if(!$DB->get_field('user', 'id', array('idnumber'=>$person->idnumber)) && $createnewusers){ // If they don't exist and haven't a defined username, we log this as a potential problem. if((!isset($person->username)) || (strlen($person->username)==0)){ $this->log_line("Cannot create new user for ID # $person->idnumber - no username listed in IMS data for this person."); @@ -641,7 +503,7 @@ function process_person_tag($tagcontents){ $DB->set_field('user', 'idnumber', $person->idnumber, array('username'=>$person->username)); } else { - // If they don't exist and they have a defined username, and $CFG->enrol_createnewusers == true, we create them. + // If they don't exist and they have a defined username, and $createnewusers == true, we create them. $person->lang = 'manual'; //TODO: this needs more work due tu multiauth changes $person->auth = $CFG->auth; $person->confirmed = 1; @@ -671,7 +533,7 @@ function process_person_tag($tagcontents){ $this->log_line("Database error while trying to create user record for user '$person->username' (ID number $person->idnumber)."); } } - }elseif($CFG->enrol_createnewusers){ + } elseif ($createnewusers) { $this->log_line("User record already exists for user '$person->username' (ID number $person->idnumber)."); // Make sure their "deleted" field is set to zero. @@ -690,7 +552,12 @@ function process_person_tag($tagcontents){ * @param string $tagconents The raw contents of the XML element */ function process_membership_tag($tagcontents){ - global $CFG, $DB; + global $DB; + + // Get plugin configs + $truncatecoursecodes = $this->get_config('truncatecoursecodes'); + $imscapitafix = $this->get_config('imscapitafix'); + $memberstally = 0; $membersuntally = 0; @@ -698,12 +565,15 @@ function process_membership_tag($tagcontents){ $groupids = array(); if(preg_match('{.*?(.+?).*?}is', $tagcontents, $matches)){ - $ship->coursecode = ($CFG->enrol_truncatecoursecodes > 0) - ? substr(trim($matches[1]), 0, intval($CFG->enrol_truncatecoursecodes)) + $ship->coursecode = ($truncatecoursecodes > 0) + ? substr(trim($matches[1]), 0, intval($truncatecoursecodes)) : trim($matches[1]); $ship->courseid = $DB->get_field('course', 'id', array('idnumber'=>$ship->coursecode)); } if($ship->courseid && preg_match_all('{(.*?)}is', $tagcontents, $membermatches, PREG_SET_ORDER)){ + $courseobj = new stdClass(); + $courseobj->id = $ship->courseid; + foreach($membermatches as $mmatch){ unset($member); unset($memberstoreobj); @@ -712,7 +582,7 @@ function process_membership_tag($tagcontents){ } if(preg_match('{}is', $mmatch[1], $matches)){ $member->roletype = trim($matches[1]); // 01 means Student, 02 means Instructor, 3 means ContentDeveloper, and there are more besides - }elseif($CFG->enrol_imscapitafix && preg_match('{(.+?)}is', $mmatch[1], $matches)){ + } elseif($imscapitafix && preg_match('{(.+?)}is', $mmatch[1], $matches)){ // The XML that comes out of Capita Student Records seems to contain a misinterpretation of the IMS specification! $member->roletype = trim($matches[1]); // 01 means Student, 02 means Instructor, 3 means ContentDeveloper, and there are more besides } @@ -752,54 +622,64 @@ function process_membership_tag($tagcontents){ // Decide the "real" role (i.e. the Moodle role) that this user should be assigned to. // Zero means this roletype is supposed to be skipped. $moodleroleid = $this->rolemappings[$member->roletype]; - if(!$moodleroleid){ + if(!$moodleroleid) { $this->log_line("SKIPPING role $member->roletype for $memberstoreobj->userid ($member->idnumber) in course $memberstoreobj->course"); continue; } - if(intval($member->status) == 1){ - - // Enrol unsing the generic role_assign() function - - //TODO: some real enrolment here - if ((!role_assign($moodleroleid, $memberstoreobj->userid, $rolecontext, 'enrol_imsenterprise')) && (trim($memberstoreobj->userid)!='')) { - $this->log_line("Error enrolling user #$memberstoreobj->userid ($member->idnumber) to role $member->roletype in course $memberstoreobj->course"); - }else{ - $this->log_line("Enrolled user #$memberstoreobj->userid ($member->idnumber) to role $member->roletype in course $memberstoreobj->course"); - $memberstally++; - - // At this point we can also ensure the group membership is recorded if present - if(isset($member->groupname)){ - // Create the group if it doesn't exist - either way, make sure we know the group ID - if(isset($groupids[$member->groupname])){ - $member->groupid = $groupids[$member->groupname]; // Recall the group ID from cache if available - }else{ - if($groupid = $DB->get_field('groups', 'id', 'name', $member->groupname, array('courseid'=>$ship->courseid))){ - $member->groupid = $groupid; - $groupids[$member->groupname] = $groupid; // Store ID in cache - }else{ - // Attempt to create the group - $group->name = $member->groupname; - $group->courseid = $ship->courseid; - $group->timecreated = time(); - $group->timemodified = time(); - $groupid = $DB->insert_record('groups', $group); - $this->log_line('Added a new group for this course: '.$group->name); - $groupids[$member->groupname] = $groupid; // Store ID in cache - $member->groupid = $groupid; - } - } - // Add the user-to-group association if it doesn't already exist - if($member->groupid) { - groups_add_member($member->groupid, $memberstoreobj->userid); - } - } // End of group-enrolment (from member.role.extension.cohort tag) + if(intval($member->status) == 1) { + // Enrol the member + $einstance = $DB->get_record('enrol', + array('courseid' => $courseobj->id, 'enrol' => $memberstoreobj->enrol)); + if (empty($einstance)) { + // Only add an enrol instance to the course if non-existent + $enrolid = $this->add_instance($courseobj); + $einstance = $DB->get_record('enrol', array('id' => $enrolid)); + } + + $this->enrol_user($einstance, $memberstoreobj->userid, $moodleroleid, $timeframe->begin, $timeframe->end); + + $this->log_line("Enrolled user #$memberstoreobj->userid ($member->idnumber) to role $member->roletype in course $memberstoreobj->course"); + $memberstally++; + + // At this point we can also ensure the group membership is recorded if present + if(isset($member->groupname)){ + // Create the group if it doesn't exist - either way, make sure we know the group ID + if(isset($groupids[$member->groupname])) { + $member->groupid = $groupids[$member->groupname]; // Recall the group ID from cache if available + } else { + if($groupid = $DB->get_field('groups', 'id', 'name', $member->groupname, array('courseid'=>$ship->courseid))){ + $member->groupid = $groupid; + $groupids[$member->groupname] = $groupid; // Store ID in cache + } else { + // Attempt to create the group + $group->name = $member->groupname; + $group->courseid = $ship->courseid; + $group->timecreated = time(); + $group->timemodified = time(); + $groupid = $DB->insert_record('groups', $group); + $this->log_line('Added a new group for this course: '.$group->name); + $groupids[$member->groupname] = $groupid; // Store ID in cache + $member->groupid = $groupid; + } + } + // Add the user-to-group association if it doesn't already exist + if($member->groupid) { + groups_add_member($member->groupid, $memberstoreobj->userid); + } + } // End of group-enrolment (from member.role.extension.cohort tag) + + } elseif ($this->get_config('imsunenrol')) { + // Unenrol member + + $einstances = $DB->get_records('enrol', + array('enrol' => $memberstoreobj->enrol, 'courseid' => $courseobj->id)); + foreach ($einstances as $einstance) { + // Unenrol the user from all imsenterprise enrolment instances + $this->unenrol_user($einstance, $memberstoreobj->userid); } - }elseif($CFG->enrol_imsunenrol){ - // Unenrol - role_unassign($moodleroleid, $memberstoreobj->userid, 0, $rolecontext, 'imsenterprise'); $membersuntally++; $this->log_line("Unenrolled $member->idnumber from role $moodleroleid in course"); } @@ -819,11 +699,11 @@ function process_membership_tag($tagcontents){ * @param string $tagconents The raw contents of the XML element */ function process_properties_tag($tagcontents){ - global $CFG; + $imsrestricttarget = $this->get_config('imsrestricttarget'); - if($CFG->enrol_imsrestricttarget){ - if(!(preg_match('{'.preg_quote($CFG->enrol_imsrestricttarget).'}is', $tagcontents, $matches))){ - $this->log_line("Skipping processing: required target \"$CFG->enrol_imsrestricttarget\" not specified in this data."); + if ($imsrestricttarget) { + if(!(preg_match('{'.preg_quote($imsrestricttarget).'}is', $tagcontents, $matches))){ + $this->log_line("Skipping processing: required target \"$imsrestricttarget\" not specified in this data."); $this->continueprocessing = false; } } @@ -864,12 +744,16 @@ function decode_timeframe($string){ // Pass me the INNER CONTENTS of a get_imsroles(); + $this->rolemappings = array(); - foreach($this->imsroles as $imsrolenum=>$imsrolename) { + foreach($imsroles as $imsrolenum=>$imsrolename) { $this->rolemappings[$imsrolenum] = $this->rolemappings[$imsrolename] - = $DB->get_field('config', 'value', array('name'=>'enrol_imse_imsrolemap' . $imsrolenum)); + = $DB->get_field('config_plugins', 'value', array('name'=>'imsrolemap' . $imsrolenum)); } } diff --git a/enrol/imsenterprise/locallib.php b/enrol/imsenterprise/locallib.php new file mode 100644 index 00000000000..ea6214c8b6f --- /dev/null +++ b/enrol/imsenterprise/locallib.php @@ -0,0 +1,84 @@ +. + +/** + * IMS Enterprise enrol plugin implementation. + * + * @package enrol_imsenterprise + * @copyright 2010 Eugene Venter + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Eugene Venter + */ + +defined('MOODLE_INTERNAL') || die; + + +class imsenterprise_roles { + private $imsroles; + + function __construct() { + $this->imsroles = array( + '01'=>'Learner', + '02'=>'Instructor', + '03'=>'Content Developer', + '04'=>'Member', + '05'=>'Manager', + '06'=>'Mentor', + '07'=>'Administrator', + '08'=>'TeachingAssistant', + ); + // PLEASE NOTE: It may seem odd that "Content Developer" has a space in it + // but "TeachingAssistant" doesn't. That's what the spec says though!!! + } + + function get_imsroles() { + return $this->imsroles; + } + + /** + * This function is only used when first setting up the plugin, to + * decide which role assignments to recommend by default. + * For example, IMS role '01' is 'Learner', so may map to 'student' in Moodle. + */ + function determine_default_rolemapping($imscode) { + global $DB; + + switch($imscode) { + case '01': + case '04': + $shortname = 'student'; + break; + case '06': + case '08': + $shortname = 'teacher'; + break; + case '02': + case '03': + $shortname = 'editingteacher'; + break; + case '05': + case '07': + $shortname = 'admin'; + break; + default: + return 0; // Zero for no match + } + return (string)$DB->get_field('role', 'id', array('shortname'=>$shortname)); + } + + +} // class diff --git a/enrol/imsenterprise/settings.php b/enrol/imsenterprise/settings.php new file mode 100644 index 00000000000..5c76b766841 --- /dev/null +++ b/enrol/imsenterprise/settings.php @@ -0,0 +1,88 @@ +. + +/** + * IMS Enterprise enrolments plugin settings and presets. + * + * @package enrol_imsenterprise + * @copyright 2010 Eugene Venter + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +if ($ADMIN->fulltree) { + require_once('locallib.php'); + + $settings->add(new admin_setting_heading('enrol_imsenterprise_settings', '', get_string('pluginname_desc', 'enrol_imsenterprise'))); + + //--- general settings ----------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_imsenterprise_basicsettings', get_string('basicsettings', 'enrol_imsenterprise'), '')); + + $settings->add(new admin_setting_configtext('enrol_imsenterprise/imsfilelocation', get_string('location', 'enrol_imsenterprise'), '', '')); + + $settings->add(new admin_setting_configtext('enrol_imsenterprise/logtolocation', get_string('logtolocation', 'enrol_imsenterprise'), '', '')); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/mailadmins', get_string('mailadmins', 'enrol_imsenterprise'), '', 0)); + + //--- user data options --------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_imsenterprise_usersettings', get_string('usersettings', 'enrol_imsenterprise'), '')); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/createnewusers', get_string('createnewusers', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/imsdeleteusers', get_string('deleteusers', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/fixcaseusernames', get_string('fixcaseusernames', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/fixcasepersonalnames', get_string('fixcasepersonalnames', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/imssourcedidfallback', get_string('sourcedidfallback', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_heading('enrol_imsenterprise_usersettings_roles', get_string('roles', 'enrol_imsenterprise'), get_string('imsrolesdescription', 'enrol_imsenterprise'))); + + if (!during_initial_install()) { + $sitecontext = get_context_instance(CONTEXT_SYSTEM); + $assignableroles = get_assignable_roles($sitecontext); + $assignableroles = array('0' => get_string('ignore', 'enrol_imsenterprise')) + $assignableroles; + $imsroles = new imsenterprise_roles(); + + foreach ($imsroles->get_imsroles() as $imsrolenum => $imsrolename) { + $settings->add(new admin_setting_configselect('enrol_imsenterprise/imsrolemap'.$imsrolenum, format_string('"'.$imsrolename.'" ('.$imsrolenum.')'), '', $imsroles->determine_default_rolemapping($imsrolenum), $assignableroles)); + } + } + + //--- course data options ------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_imsenterprise_coursesettings', get_string('coursesettings', 'enrol_imsenterprise'), '')); + + $settings->add(new admin_setting_configtext('enrol_imsenterprise/truncatecoursecodes', get_string('truncatecoursecodes', 'enrol_imsenterprise'), '', 0, PARAM_INT, 2)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/createnewcourses', get_string('createnewcourses', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/createnewcategories', get_string('createnewcategories', 'enrol_imsenterprise'), '', 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/imsunenrol', get_string('allowunenrol', 'enrol_imsenterprise'), '', 0)); + + //--- miscellaneous ------------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_imsenterprise_miscsettings', get_string('miscsettings', 'enrol_imsenterprise'), '')); + + $settings->add(new admin_setting_configtext('enrol_imsenterprise/imsrestricttarget', get_string('restricttarget', 'enrol_imsenterprise'), '', '')); + + $settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/imscapitafix', get_string('usecapitafix', 'enrol_imsenterprise'), '', 0)); + + $importnowstring = get_string('aftersaving...', 'enrol_imsenterprise').' '.get_string('doitnow', 'enrol_imsenterprise').''; + $settings->add(new admin_setting_heading('enrol_imsenterprise_doitnowmessage', '', $importnowstring)); +} diff --git a/enrol/imsenterprise/version.php b/enrol/imsenterprise/version.php new file mode 100644 index 00000000000..14eb3c84c35 --- /dev/null +++ b/enrol/imsenterprise/version.php @@ -0,0 +1,27 @@ +. + +/** + * IMS Enterprise file enrolment plugin version specification. + * + * @package enrol_imsenterprise + * @copyright 2010 Eugene Venter + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$plugin->version = 2010071200; +$plugin->cron = 60;