Index: enrol.php
===================================================================
RCS file: /cvsroot/moodle/moodle/enrol/imsenterprise/enrol.php,v
retrieving revision 1.13.2.3
diff -u -r1.13.2.3 enrol.php
--- enrol.php	8 Jun 2008 15:29:58 -0000	1.13.2.3
+++ enrol.php	28 Jul 2008 13:45:24 -0000
@@ -587,9 +587,13 @@
     if(preg_match('{<name>.*?<n>.*?<family>(.+?)</family>.*?</n>.*?</name>}is', $tagcontents, $matches)){
         $person->lastname = trim($matches[1]);
     }
-    if(preg_match('{<userid>(.*?)</userid>}is', $tagcontents, $matches)){
+    if(preg_match('{<userid.*>(.*?)</userid>}is', $tagcontents, $matches)){ // added .* to <userid> tag, to allow <userid password="(.+)">
         $person->username = trim($matches[1]);
     }
+    if (preg_match('{userid password="(.+)">.*</userid>}is', $tagcontents, $matches)) {  // Password may be specified in IMS documents
+        $person->password = md5($matches[1]);
+        $person->auth     = 'manual'; // A password has been specified in the IMS-E doc, so use it.
+    }
     if($CFG->enrol_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
@@ -638,20 +642,22 @@
 
     }else{ // Add or update record
 
-
-        // If the user exists (matching sourcedid) then we don't need to do anything.
-        if(!get_field('user', 'id', 'idnumber', $person->idnumber) && $CFG->enrol_createnewusers){
+        // If the user exists (either matching sourcedid on idnumber, or userid on username) then we don't need to create the account.
+        $moodleidnumber = get_field('user', 'id', 'idnumber', $person->idnumber);
+        $moodleusername = get_field('user', 'id', 'username', $person->username);
+        
+        if((!$moodleidnumber || !$moodleusername) && $CFG->enrol_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.");
-            }elseif(get_field('user', 'id', 'username', $person->username)){
+            }elseif($moodleusername){
                 // If their idnumber is not registered but their user ID is, then add their idnumber to their record
                 set_field('user', 'idnumber', addslashes($person->idnumber), 'username', $person->username);
             }else{
 
             // If they don't exist and they have a defined username, and $CFG->enrol_createnewusers == true, we create them.
             $person->lang = 'manual'; //TODO: this needs more work due tu multiauth changes
-            $person->auth = $CFG->auth;
+            if (!isset($person->auth)) $person->auth = $CFG->auth;
             $person->confirmed = 1;
             $person->timemodified = time();
             $person->mnethostid = $CFG->mnet_localhost_id;
@@ -715,6 +721,10 @@
         foreach($membermatches as $mmatch){
             unset($member);
             unset($memberstoreobj);
+            if(preg_match('{<userid>(.*?)</userid>}is', $tagcontents, $matches)){
+                // Optional. See http://www.imsglobal.org/enterprise/entv1p1/imsent_bindv1p1.html#1431062
+                $member->username = trim($matches[1]);
+            }
             if(preg_match('{<sourcedid>.*?<id>(.+?)</id>.*?</sourcedid>}is', $mmatch[1], $matches)){
                 $member->idnumber = trim($matches[1]);
             }
@@ -750,7 +760,16 @@
 //print_r($rolecontext);
 
             // Add or remove this student or teacher to the course...
-            $memberstoreobj->userid = get_field('user', 'id', 'idnumber', $member->idnumber);
+            if (isset($member->username)) {  // Optionally specified in membership.member.role.userid
+                                             // See http://www.imsglobal.org/enterprise/entv1p1/imsent_bindv1p1.html#1431062
+                if ($CFG->enrol_fixcaseusernames) {
+                    $member->username = strtolower($member->username);
+                }
+                $memberstoreobj->userid = get_field('user', 'id', 'username', $member->username);
+            }
+            if (!$memberstoreobj->userid) {  // Fall back to using member.sourcedid.id
+                $memberstoreobj->userid = get_field('user', 'id', 'idnumber', $member->idnumber);
+            }
             $memberstoreobj->enrol = 'imsenterprise';
             $memberstoreobj->course = $ship->courseid;
             $memberstoreobj->time = time();
@@ -781,24 +800,31 @@
                             if(isset($groupids[$member->groupname])){
                                 $member->groupid = $groupids[$member->groupname]; // Recall the group ID from cache if available
                             }else{
-                                if($groupid = get_field('groups', 'id', 'name', addslashes($member->groupname), 'courseid', $ship->courseid)){
+                                if ($groupid = groups_get_group_by_name($ship->courseid, $member->groupname)) {
                                     $member->groupid = $groupid;
                                     $groupids[$member->groupname] = $groupid; // Store ID in cache
                                 }else{
                                     // Attempt to create the group
                                     $group->name = addslashes($member->groupname);
-                                    $group->courseid = $ship->courseid;
                                     $group->timecreated = time();
                                     $group->timemodified = time();
-                                    $groupid = insert_record('groups', $group);
-                                    $this->log_line('Added a new group for this course: '.$group->name);
+                                    $groupid = groups_create_group($ship->courseid, $group);
+                                    if($groupid){
+                                        $this->log_line('Added a new group for this course: '.$group->name);
+                                    } else {
+                                        $this->log_line("Couldn't create group '$group->name' for course $ship->courseid");
+                                    }
                                     $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);
+                                if (groups_add_member($member->groupid, $memberstoreobj->userid)) {  // Added logging of group membership changes
+                                    $this->log_line("User #$memberstoreobj->userid ($member->idnumber) added to group '$member->groupname' ($member->groupid)");
+                                } else {
+                                    $this->log_line("Failed to add user #$memberstoreobj->userid ($member->idnumber) to group '$member->groupname' ($member->groupid)");
+                                }
                             }
                         } // End of group-enrolment (from member.role.extension.cohort tag)
 
