[LON-CAPA-cvs] cvs: loncom / lonsql /enrollment localenroll.pm /interface loncommon.pm lonuserutils.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Wed Aug 5 14:47:26 EDT 2015


raeburn		Wed Aug  5 18:47:26 2015 EDT

  Modified files:              
    /loncom	lonsql 
    /loncom/enrollment	localenroll.pm 
    /loncom/interface	lonuserutils.pm loncommon.pm 
    /loncom/lonnet/perl	lonnet.pm 
  Log:
  - Bug 5596.
    Add a routine to lonnet.pm -- get_multiple_instusers() which makes one call 
    to lond > lonsql > localenroll.pm to retrieve institutional data 
    for multiple users when adding users via file upload, to minimize number
    of sleep() commands needed. Supports up to 1s per query, on localenroll.pm
    side if adding more than 100 new users.
   
  - Add new routine to localenroll.pm -- &get_multusersinfo() -- to retrieve
      institutional data for users being added via user file upload.
  
    Note: if this routine does not exist in localenroll.pm, will fall-back 
    to retrieving institutional data using a separate call to &get_userinfo()
    for each user.
  
  
-------------- next part --------------
Index: loncom/lonsql
diff -u loncom/lonsql:1.93 loncom/lonsql:1.94
--- loncom/lonsql:1.93	Sun Dec  1 21:29:07 2013
+++ loncom/lonsql	Wed Aug  5 18:47:12 2015
@@ -3,7 +3,7 @@
 # The LearningOnline Network
 # lonsql - LON TCP-MySQL-Server Daemon for handling database requests.
 #
-# $Id: lonsql,v 1.93 2013/12/01 21:29:07 raeburn Exp $
+# $Id: lonsql,v 1.94 2015/08/05 18:47:12 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -458,6 +458,8 @@
 		$result = &do_inst_dir_search($searchdomain,$arg1,$arg2,$arg3);
             } elsif ($query eq 'getinstuser') {
                 $result = &get_inst_user($searchdomain,$arg1,$arg2);
+            } elsif ($query eq 'getmultinstusers') {
+                $result = &get_multiple_instusers($searchdomain,$arg3);
             } elsif ($query eq 'prepare activity log') {
                 my ($cid,$domain) = map {&unescape($_);} ($arg1,$arg2);
                 &logthis('preparing activity log tables for '.$cid);
@@ -620,6 +622,33 @@
     return $response;
 }
 
+sub get_multiple_instusers {
+    my ($domain,$data) = @_;
+    my ($type,$users) = split(/=/,$data,2);
+    my $requested = &Apache::lonnet::thaw_unescape($users);
+    my $response;
+    if (ref($requested) eq 'HASH') {
+        my (%instusers,%instids,$result);
+        eval {
+            local($SIG{__DIE__})='DEFAULT';
+            $result=&localenroll::get_multusersinfo($domain,$type,$requested,\%instusers,
+                                                    \%instids);
+        };
+        if ($@) {
+            $response = 'error';
+        } elsif ($result eq 'ok') {
+            if (keys(%instusers)) {
+                $response = $result.':'.&Apache::lonnet::freeze_escape(\%instusers); 
+            }
+        } else {
+            $response = 'unavailable';
+        }
+    } else {
+        $response = 'invalid';
+    }
+    return $response;
+}
+
 ########################################################
 ########################################################
 
Index: loncom/enrollment/localenroll.pm
diff -u loncom/enrollment/localenroll.pm:1.52 loncom/enrollment/localenroll.pm:1.53
--- loncom/enrollment/localenroll.pm:1.52	Sat May 30 18:01:12 2015
+++ loncom/enrollment/localenroll.pm	Wed Aug  5 18:47:17 2015
@@ -1,6 +1,6 @@
 # functions to glue school database system into Lon-CAPA for 
 # automated enrollment
-# $Id: localenroll.pm,v 1.52 2015/05/30 18:01:12 raeburn Exp $
+# $Id: localenroll.pm,v 1.53 2015/08/05 18:47:17 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -937,6 +937,47 @@
 
 =pod
 
+=item get_multusersinfo
+
+ (a) $dom - domain
+ (b) $type - username or id
+ (c) $unamenames - reference to hash containing usernames of users
+ (d) $instusers - reference to hash which will contain info for user
+                 as key = value; keys will be one or all of:
+                 lastname,firstname,middlename,generation,id,inststatus -
+                 institutional status (e.g., faculty,staff,student)
+                 Values are all scalars except inststatus,
+                 which is an array.
+ (e) $instids - reference to hash which will contain ID numbers -
+                 keys will be unique IDs (student or faculty/staff ID)
+                 values will be either: scalar (username) or an array
+                 if a single ID matches multiple usernames.
+
+ returns 1 parameter - 'ok' if no processing error, or other value
+                       if an error occurred.
+
+ side effects - populates the $instusers and $instids refs to hashes.
+                with information for specified username, or specified
+                id, if fifth argument provided, from all available, or
+                specified (e.g., faculty only) institutional datafeeds,
+                if sixth argument provided.
+
+ WARNING: You need to set $outcome to 'ok' once you have customized
+          this routine to communicate with an instititional
+          directory data source, otherwise retrieval of institutional
+          user information will always be reported as being unavailable
+          in domain $dom.
+
+=cut
+
+sub get_multusersinfo {
+    my ($dom,$type,$usernames,$instusers,$instids) = @_;
+    my $outcome = 'unavailable'; 
+    return $outcome;
+}
+
+=pod
+
 =item inst_usertypes() 
 
  Starting with LON-CAPA 2.11.0 use of this subroutine
Index: loncom/interface/lonuserutils.pm
diff -u loncom/interface/lonuserutils.pm:1.170 loncom/interface/lonuserutils.pm:1.171
--- loncom/interface/lonuserutils.pm:1.170	Tue Jun  9 21:22:57 2015
+++ loncom/interface/lonuserutils.pm	Wed Aug  5 18:47:21 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Utility functions for managing LON-CAPA user accounts
 #
-# $Id: lonuserutils.pm,v 1.170 2015/06/09 21:22:57 damieng Exp $
+# $Id: lonuserutils.pm,v 1.171 2015/08/05 18:47:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -4297,7 +4297,10 @@
         my $newuserdom = $env{'request.role.domain'};
         map { $cancreate{$_} = &can_create_user($newuserdom,$context,$_); } keys(%longtypes);
         # Get new users list
+        my (%existinguser,%userinfo,%disallow,%rulematch,%inst_results,%idinst_results,%alerts,%checkuname);
+        my $counter = -1;
         foreach my $line (@userdata) {
+            $counter ++;
             my @secs;
             my %entries=&Apache::loncommon::record_sep($line);
             # Determine user name
@@ -4329,23 +4332,20 @@
                     if ($entries{$fields{'username'}} =~ /\s/) {
                         $nowhitespace = ' - '.&mt('usernames may not contain spaces.');
                     }
-                    $r->print(
-                        '<br />'.
+                    $disallow{$counter} =
                         &mt('Unacceptable username [_1] for user [_2] [_3] [_4] [_5]',
-                                '"<b>'.$entries{$fields{'username'}}.'</b>"',
-                                $fname,$mname,$lname,$gen).
-                        $nowhitespace);
+                            '"<b>'.$entries{$fields{'username'}}.'</b>"',
+                            $fname,$mname,$lname,$gen).$nowhitespace;
                     next;
                 } else {
                     $entries{$fields{'domain'}} =~ s/^\s+|\s+$//g;
                     if ($entries{$fields{'domain'}} 
                         ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) {
-                        $r->print(
-                            '<br />'.
+                        $disallow{$counter} =
                             &mt('Unacceptable domain [_1] for user [_2] [_3] [_4] [_5]',
-                                   '"<b>'.$entries{$fields{'domain'}}.'</b>"',
-                                    $fname,$mname,$lname,$gen));
-                    next;
+                                '"<b>'.$entries{$fields{'domain'}}.'</b>"',
+                                $fname,$mname,$lname,$gen);
+                        next;
                     }
                     my $username = $entries{$fields{'username'}};
                     my $userdomain = $entries{$fields{'domain'}};
@@ -4357,10 +4357,15 @@
                             $entries{$fields{'sec'}} =~ s/\W//g;
                             my $item = $entries{$fields{'sec'}};
                             if ($item eq "none" || $item eq 'all') {
-                                $r->print('<br />'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.','<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$item));
+                                $disallow{$counter} =
+                                    &mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.',
+                                        '<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$item);
                                 next;
                             } elsif (exists($curr_groups{$item})) {
-                                $r->print('<br />'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.','<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$item).' '.&mt('Section names and group names must be distinct.'));
+                                $disallow{$counter} =
+                                    &mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.',
+                                        '<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$item).' '.
+                                    &mt('Section names and group names must be distinct.');
                                 next;
                             } else {
                                 push(@secs,$item);
@@ -4372,14 +4377,21 @@
                         if (ref($userlist{$username.':'.$userdomain}) eq 'ARRAY') {
                             my $currsec = $userlist{$username.':'.$userdomain}[$secidx];
                             if ($currsec ne $env{'request.course.sec'}) {
-                                $r->print('<br />'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".','<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$secs[0]).'<br />');
+                                $disallow{$counter} =
+                                    &mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".',
+                                        '<b>'.$username.'</b>',$fname,$mname,$lname,$gen,$secs[0]);
                                 if ($currsec eq '') {
-                                    $r->print(&mt('This user already has an active/future student role in the course, unaffiliated to any section.'));
+                                    $disallow{$counter} .=
+                                        &mt('This user already has an active/future student role in the course, unaffiliated to any section.');
 
                                 } else {
-                                    $r->print(&mt('This user already has an active/future role in section "[_1]" of the course.',$currsec));
+                                    $disallow{$counter} .=
+                                        &mt('This user already has an active/future role in section "[_1]" of the course.',$currsec);
                                 }
-                                $r->print('<br />'.&mt('Although your current role has privileges to add students to section "[_1]", you do not have privileges to modify existing enrollments in other sections.',$secs[0]).'<br />');
+                                $disallow{$counter} .=
+                                    '<br />'.
+                                    &mt('Although your current role has privileges to add students to section "[_1]", you do not have privileges to modify existing enrollments in other sections.',
+                                        $secs[0]);
                                 next;
                             }
                         }
@@ -4431,13 +4443,12 @@
                             }
                             if ($role eq '') {
                                 my $rolestr = join(', ', at permitted_roles);
-                                $r->print('<br />'
-                                         .&mt('[_1]: You do not have permission to add the requested role [_2] for the user.'
-                                             ,'<b>'.$entries{$fields{'username'}}.'</b>'
-                                             ,$entries{$fields{'role'}})
-                                         .'<br />'
-                                         .&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n"
-                                );
+                                $disallow{$counter} =
+                                    &mt('[_1]: You do not have permission to add the requested role [_2] for the user.'
+                                        ,'<b>'.$entries{$fields{'username'}}.'</b>'
+                                        ,$entries{$fields{'role'}})
+                                        .'<br />'
+                                        .&mt('Allowable role(s) is/are: [_1].',$rolestr);
                                 next;
                             }
                         }
@@ -4467,55 +4478,36 @@
                     # check against rules
                     my $checkid = 0;
                     my $newuser = 0;
-                    my (%rulematch,%inst_results,%idinst_results);
                     my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
                     if ($uhome eq 'no_host') {
                         if ($userdomain ne $newuserdom) {
                             if ($context eq 'course') {
-                                $r->print('<br />'.
-                                          &mt('[_1]: The domain specified ([_2]) is different to that of the course.',
-                                          '<b>'.$username.'</b>',$userdomain).'<br />');
+                                $disallow{$counter} =
+                                    &mt('[_1]: The domain specified ([_2]) is different to that of the course.',
+                                       '<b>'.$username.'</b>',$userdomain);
                             } elsif ($context eq 'author') {
-                                $r->print(&mt('[_1]: The domain specified ([_2]) is different to that of the author.',
-                                        '<b>'.$username.'</b>',$userdomain).'<br />'); 
+                                $disallow{$counter} =
+                                    &mt('[_1]: The domain specified ([_2]) is different to that of the author.',
+                                        '<b>'.$username.'</b>',$userdomain); 
                             } else {
-                                $r->print(&mt('[_1]: The domain specified ([_2]) is different to that of your current role.',
-                                        '<b>'.$username.'</b>',$userdomain).'<br />');
+                                $disallow{$counter} =
+                                    &mt('[_1]: The domain specified ([_2]) is different to that of your current role.',
+                                        '<b>'.$username.'</b>',$userdomain);
                             }
-                            $r->print(&mt('The user does not already exist, and you may not create a new user in a different domain.'));
+                            $disallow{$counter} .=
+                                &mt('The user does not already exist, and you may not create a new user in a different domain.');
                             next;
+                        } else {
+                            unless ($password || $env{'form.login'} eq 'loc') {
+                                $disallow{$counter} =
+                                    &mt('[_1]: This is a new user but no default password was provided, and the authentication type requires one.',
+                                        '<b>'.$username.'</b>');
+                                next;
+                            }
                         }
                         $checkid = 1;
                         $newuser = 1;
-                        my $user = $username.':'.$newuserdom;
-                        my $checkhash;
-                        my $checks = { 'username' => 1 };
-                        $checkhash->{$username.':'.$newuserdom} = { 'newuser' => 1, };
-                        &Apache::loncommon::user_rule_check($checkhash,$checks,
-                            \%alerts,\%rulematch,\%inst_results,\%curr_rules,
-                            \%got_rules);
-                        if (ref($alerts{'username'}) eq 'HASH') {
-                            if (ref($alerts{'username'}{$newuserdom}) eq 'HASH') {
-                                if ($alerts{'username'}{$newuserdom}{$username}) {
-                                    $r->print('<br />'.
-                                              &mt('[_1]: matches the username format at your institution, but is not known to your directory service.','<b>'.$username.'</b>').'<br />'.
-                                              &mt('Consequently, the user was not created.'));
-                                    next;
-                                }
-                            }
-                        }
-                        my $usertype = 'unofficial';
-                        if (ref($rulematch{$user}) eq 'HASH') {
-                            if ($rulematch{$user}{'username'}) {
-                                $usertype = 'official';
-                            }
-                        }
-                        unless ($cancreate{$usertype}) {
-                            my $showtype = $longtypes{$usertype};
-                            $r->print('<br />'.
-                                      &mt('[_1]: The user does not exist, and you are not permitted to create users of type: [_2].','<b>'.$username.'</b>',$showtype));
-                            next;
-                        }
+                        $checkuname{$username.':'.$newuserdom} = { 'newuser' => 1, 'id' => 1 };
                     } else {
                         if ($context eq 'course' || $context eq 'author') {
                             if ($userdomain eq $domain ) {
@@ -4548,77 +4540,165 @@
                                 }
                             }
                         }
+                        if ($id) {
+                            $existinguser{$userdomain}{$username} = $id;
+                        }
                     }
-                    if ($id ne '') {
-                        if (!$newuser) {
-                            my %idhash = &Apache::lonnet::idrget($userdomain,($username));
-                            if ($idhash{$username} ne $id) {
-                                $checkid = 1;
+                    $userinfo{$counter} = {
+                                          username   => $username,
+                                          domain     => $userdomain,
+                                          fname      => $fname,
+                                          mname      => $mname,
+                                          lname      => $lname,
+                                          gen        => $gen,
+                                          email      => $email,
+                                          id         => $id, 
+                                          password   => $password,
+                                          inststatus => $inststatus,
+                                          role       => $role,
+                                          sections   => \@secs,
+                                          credits    => $credits,
+                                          newuser    => $newuser,
+                                          checkid    => $checkid,
+                                        };
+                }
+            }
+        } # end of foreach (@userdata)
+        if ($counter > -1) {
+            my $total = $counter + 1;
+            my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,$total);
+            my %checkids;
+            if (keys(%existinguser)) {
+                foreach my $dom (keys(%existinguser)) {
+                    if (ref($existinguser{$dom}) eq 'HASH') {
+                        my %idhash = &Apache::lonnet::idrget($dom,keys(%{$existinguser{$dom}}));
+                        foreach my $username (keys(%{$existinguser{$dom}})) {
+                            if ($idhash{$username} ne $existinguser{$dom}{$username}) {
+                                $checkids{$username.':'.$dom} = { 'id' => $existinguser{$dom}{$username} };
                             }
                         }
-                        if ($checkid) {
-                            my $checkhash;
-                            my $checks = { 'id' => 1 };
-                            $checkhash->{$username.':'.$userdomain} = { 'newuser' => $newuser,
-                                                                    'id'  => $id };
-                            &Apache::loncommon::user_rule_check($checkhash,$checks,
-                                \%alerts,\%rulematch,\%idinst_results,\%curr_rules,
-                                \%got_rules);
+                        if (keys(%checkids)) {
+                            &Apache::loncommon::user_rule_check(\%checkids,{ 'id' => 1 },
+                                                                \%alerts,\%rulematch,
+                                                                \%idinst_results,\%curr_rules,
+                                                                \%got_rules);
+                        }
+                    }
+                }
+            }
+            if (keys(%checkuname)) {
+                &Apache::loncommon::user_rule_check(\%checkuname,{ 'username' => 1 },
+                                                    \%alerts,\%rulematch,\%inst_results,
+                                                    \%curr_rules,\%got_rules);
+            }
+            $r->print('<ul>');
+            for (my $i=0; $i<=$counter; $i++) {
+                &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state);
+                if ($disallow{$i}) {
+                    $r->print('<li>'.$disallow{$i}.'</li>');
+                } elsif (ref($userinfo{$i}) eq 'HASH') {
+                    my $password = $userinfo{$i}{'password'}; 
+                    my $newuser = $userinfo{$i}{'newuser'};
+                    my $checkid = $userinfo{$i}{'checkid'};
+                    my $id = $userinfo{$i}{'id'};
+                    my $role = $userinfo{$i}{'role'};
+                    my @secs;
+                    if (ref($userinfo{$i}{'sections'}) eq 'ARRAY') {
+                        @secs = @{$userinfo{$i}{'sections'}};
+                    }
+                    my $fname = $userinfo{$i}{'fname'};
+                    my $mname = $userinfo{$i}{'mname'}; 
+                    my $lname = $userinfo{$i}{'lname'};
+                    my $gen = $userinfo{$i}{'gen'};
+                    my $email = $userinfo{$i}{'email'};
+                    my $inststatus = $userinfo{$i}{'inststatus'};
+                    my $credits = $userinfo{$i}{'credits'};
+                    my $username = $userinfo{$i}{'username'};
+                    my $userdomain = $userinfo{$i}{'domain'};
+                    my $user = $username.':'.$userdomain;
+                    if ($newuser) {
+                        if (ref($alerts{'username'}) eq 'HASH') {
+                            if (ref($alerts{'username'}{$userdomain}) eq 'HASH') {
+                                if ($alerts{'username'}{$userdomain}{$username}) {
+                                    $r->print('<li>'.
+                                              &mt('[_1]: matches the username format at your institution, but is not known to your directory service.','<b>'.$username.'</b>').'<br />'.
+                                              &mt('Consequently, the user was not created.').'</li>');
+                                    next;
+                                }
+                            }
+                        }
+                        my $usertype = 'unofficial';
+                        if (ref($rulematch{$user}) eq 'HASH') {
+                            if ($rulematch{$user}{'username'}) {
+                                $usertype = 'official';
+                            }
+                        }
+                        unless ($cancreate{$usertype}) {
+                            my $showtype = $longtypes{$usertype};
+                            $r->print('<li>'.
+                                      &mt('[_1]: The user does not exist, and you are not permitted to create users of type: [_2].','<b>'.$username.'</b>',$showtype).'</li>');
+                            next;
+                        }
+                    }
+                    if ($id ne '') {
+                        if (exists($checkids{$user})) {
+                            $checkid = 1; 
                             if (ref($alerts{'id'}) eq 'HASH') {
                                 if (ref($alerts{'id'}{$userdomain}) eq 'HASH') {
                                     if ($alerts{'id'}{$userdomain}{$id}) {
-                                        $r->print(&mt('[_1]: has a student/employee ID matching the format at your institution, but the ID is found by your directory service.',
+                                        $r->print('<li>'.
+                                                  &mt('[_1]: has a student/employee ID matching the format at your institution, but the ID is found by your directory service.',
                                                   '<b>'.$username.'</b>').'<br />'.
-                                                  &mt('Consequently, the user was not created.'));
+                                                  &mt('Consequently, the user was not created.').'</li>');
                                         next;
                                     }
                                 }
                             }
                         }
                     }
-                    if ($password || $env{'form.login'} eq 'loc') {
-                        my $multiple = 0;
-                        my ($userresult,$authresult,$roleresult,$idresult);
-                        my (%userres,%authres,%roleres,%idres);
-                        my $singlesec = '';
-                        if ($role eq 'st') {
-                            my $sec;
+                    my $multiple = 0;
+                    my ($userresult,$authresult,$roleresult,$idresult);
+                    my (%userres,%authres,%roleres,%idres);
+                    my $singlesec = '';
+                    if ($role eq 'st') {
+                        my $sec;
+                        if (ref($userinfo{$i}{'sections'}) eq 'ARRAY') {
                             if (@secs > 0) {
                                 $sec = $secs[0];
                             }
-                            &modifystudent($userdomain,$username,$cid,$sec,
-                                           $desiredhost,$context);
-                            $roleresult =
-                                &Apache::lonnet::modifystudent
-                                    ($userdomain,$username,$id,$amode,$password,
-                                     $fname,$mname,$lname,$gen,$sec,$enddate,
-                                     $startdate,$env{'form.forceid'},
-                                     $desiredhost,$email,'manual','',$cid,
-                                     '',$context,$inststatus,$credits);
-                            $userresult = $roleresult;
-                        } else {
-                            if ($role ne '') { 
-                                if ($context eq 'course' || $setting eq 'course') {
-                                    if ($customroles{$role}) {
-                                        $role = 'cr_'.$env{'user.domain'}.'_'.
-                                                $env{'user.name'}.'_'.$role;
-                                    }
-                                    if (($role ne 'cc') && ($role ne 'co')) { 
-                                        if (@secs > 1) {
-                                            $multiple = 1;
-                                            foreach my $sec (@secs) {
-                                                ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) =
-                                                &modifyuserrole($context,$setting,
-                                                    $changeauth,$cid,$userdomain,$username,
-                                                    $id,$amode,$password,$fname,
-                                                    $mname,$lname,$gen,$sec,
-                                                    $env{'form.forceid'},$desiredhost,
-                                                    $email,$role,$enddate,
-                                                    $startdate,$checkid,$inststatus);
-                                            }
-                                        } elsif (@secs > 0) {
-                                            $singlesec = $secs[0];
+                        }
+                        &modifystudent($userdomain,$username,$cid,$sec,
+                                       $desiredhost,$context);
+                        $roleresult =
+                            &Apache::lonnet::modifystudent
+                                ($userdomain,$username,$id,$amode,$password,
+                                 $fname,$mname,$lname,$gen,$sec,$enddate,
+                                 $startdate,$env{'form.forceid'},
+                                 $desiredhost,$email,'manual','',$cid,
+                                 '',$context,$inststatus,$credits);
+                        $userresult = $roleresult;
+                    } else {
+                        if ($role ne '') { 
+                            if ($context eq 'course' || $setting eq 'course') {
+                                if ($customroles{$role}) {
+                                    $role = 'cr_'.$env{'user.domain'}.'_'.
+                                            $env{'user.name'}.'_'.$role;
+                                }
+                                if (($role ne 'cc') && ($role ne 'co')) { 
+                                   if (@secs > 1) {
+                                        $multiple = 1;
+                                        foreach my $sec (@secs) {
+                                            ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) =
+                                            &modifyuserrole($context,$setting,
+                                                $changeauth,$cid,$userdomain,$username,
+                                                $id,$amode,$password,$fname,
+                                                $mname,$lname,$gen,$sec,
+                                                $env{'form.forceid'},$desiredhost,
+                                                $email,$role,$enddate,
+                                                $startdate,$checkid,$inststatus);
                                         }
+                                    } elsif (@secs > 0) {
+                                        $singlesec = $secs[0];
                                     }
                                 }
                             }
@@ -4633,38 +4713,26 @@
                                                     $checkid,$inststatus);
                             }
                         }
-                        if ($multiple) {
-                            foreach my $sec (sort(keys(%userres))) {
-                                $flushc =
+                    }
+                    if ($multiple) {
+                        foreach my $sec (sort(keys(%userres))) {
+                            $flushc =
                                 &user_change_result($r,$userres{$sec},$authres{$sec},
                                                     $roleres{$sec},$idres{$sec},\%counts,$flushc,
                                                     $username,$userdomain,\%userchg);
 
-                            }
-                        } else {
-                            $flushc = 
-                                &user_change_result($r,$userresult,$authresult,
-                                                    $roleresult,$idresult,\%counts,$flushc,
-                                                    $username,$userdomain,\%userchg);
                         }
                     } else {
-                        if ($context eq 'course') {
-                            $r->print('<br />'. 
-      &mt('[_1]: Unable to enroll. No password specified.','<b>'.$username.'</b>')
-                                     );
-                        } elsif ($context eq 'author') {
-                            $r->print('<br />'.
-      &mt('[_1]: Unable to add co-author. No password specified.','<b>'.$username.'</b>')
-                                     );
-                        } else {
-                            $r->print('<br />'.
-      &mt('[_1]: Unable to add user. No password specified.','<b>'.$username.'</b>')
-                                     );
-                        }
+                        $flushc = 
+                            &user_change_result($r,$userresult,$authresult,
+                                                $roleresult,$idresult,\%counts,$flushc,
+                                                $username,$userdomain,\%userchg);
                     }
                 }
-            }
-        } # end of foreach (@userdata)
+                $r->print('</ul>');
+            } # end of loop
+            &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
+        }
         # Flush the course logs so reverse user roles immediately updated
         $r->register_cleanup(\&Apache::lonnet::flushcourselogs);
         $r->print("</p>\n<p>\n".&mt('Processed [quant,_1,user].',$counts{'user'}).
@@ -4757,11 +4825,12 @@
     my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
         $username,$userdomain,$userchg) = @_;
     my $okresult = 0;
+    my @status;
     if ($userresult ne 'ok') {
         if ($userresult =~ /^error:(.+)$/) {
             my $error = $1;
-            $r->print('<br />'.
-                  &mt('[_1]: Unable to add/modify: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
+            push(@status,
+                 &mt('[_1]: Unable to add/modify: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         }
     } else {
         $counts->{'user'} ++;
@@ -4770,8 +4839,8 @@
     if ($authresult ne 'ok') {
         if ($authresult =~ /^error:(.+)$/) {
             my $error = $1;
-            $r->print('<br />'.
-                  &mt('[_1]: Unable to modify authentication: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
+            push(@status, 
+                 &mt('[_1]: Unable to modify authentication: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         } 
     } else {
         $counts->{'auth'} ++;
@@ -4780,8 +4849,8 @@
     if ($roleresult ne 'ok') {
         if ($roleresult =~ /^error:(.+)$/) {
             my $error = $1;
-            $r->print('<br />'.
-                  &mt('[_1]: Unable to add role: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
+            push(@status,
+                 &mt('[_1]: Unable to add role: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         }
     } else {
         $counts->{'role'} ++;
@@ -4790,14 +4859,16 @@
     if ($okresult) {
         $flushc++;
         $userchg->{$username.':'.$userdomain}=1;
-        $r->print('. ');
         if ($flushc>15) {
             $r->rflush;
             $flushc=0;
         }
     }
     if ($idresult) {
-        $r->print($idresult);
+        push(@status,$idresult);
+    }
+    if (@status) {
+        $r->print('<li>'.join('<br />', at status).'</li>');
     }
     return $flushc;
 }
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1225 loncom/interface/loncommon.pm:1.1226
--- loncom/interface/loncommon.pm:1.1225	Tue Jul 14 00:08:06 2015
+++ loncom/interface/loncommon.pm	Wed Aug  5 18:47:21 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1225 2015/07/14 00:08:06 raeburn Exp $
+# $Id: loncommon.pm,v 1.1226 2015/08/05 18:47:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -9764,52 +9764,131 @@
 
 sub user_rule_check {
     my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_;
-    my $response;
+    my ($response,%inst_response);
     if (ref($usershash) eq 'HASH') {
-        foreach my $user (keys(%{$usershash})) {
-            my ($uname,$udom) = split(/:/,$user);
-            next if ($udom eq '' || $uname eq '');
-            my ($id,$newuser);
-            if (ref($usershash->{$user}) eq 'HASH') {
-                $newuser = $usershash->{$user}->{'newuser'};
-                $id = $usershash->{$user}->{'id'};
-            }
-            my $inst_response;
+        if (keys(%{$usershash}) > 1) {
+            my (%by_username,%by_id,%userdoms);
+            my $checkid; 
             if (ref($checks) eq 'HASH') {
-                if (defined($checks->{'username'})) {
-                    ($inst_response,%{$inst_results->{$user}}) = 
-                        &Apache::lonnet::get_instuser($udom,$uname);
-                } elsif (defined($checks->{'id'})) {
-                    ($inst_response,%{$inst_results->{$user}}) =
-                        &Apache::lonnet::get_instuser($udom,undef,$id);
+                if ((!defined($checks->{'username'})) && (defined($checks->{'id'}))) {
+                    $checkid = 1;
+                }
+            }
+            foreach my $user (keys(%{$usershash})) {
+                my ($uname,$udom) = split(/:/,$user);
+                if ($checkid) {
+                    if (ref($usershash->{$user}) eq 'HASH') {
+                        if ($usershash->{$user}->{'id'} ne '') {
+                            $by_id{$udom}{$usershash->{$user}->{'id'}} = 1; 
+                            $userdoms{$udom} = 1;
+                        }
+                    }
+                } else {
+                    $by_username{$udom}{$uname} = 1;
+                    $userdoms{$udom} = 1;
+                }
+            }
+            foreach my $udom (keys(%userdoms)) {
+                if (!$got_rules->{$udom}) {
+                    my %domconfig = &Apache::lonnet::get_dom('configuration',
+                                                             ['usercreation'],$udom);
+                    if (ref($domconfig{'usercreation'}) eq 'HASH') {
+                        foreach my $item ('username','id') {
+                            if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
+                               $$curr_rules{$udom}{$item} =
+                                   $domconfig{'usercreation'}{$item.'_rule'};
+                            }
+                        }
+                    }
+                    $got_rules->{$udom} = 1;
+                }
+            }
+            if ($checkid) {
+                foreach my $udom (keys(%by_id)) {
+                    my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_id{$udom},'id');
+                    if ($outcome eq 'ok') {
+                        if (ref($results) eq 'HASH') {
+                            foreach my $uname (keys(%{$results})) {
+                                $inst_response{$uname.':'.$udom} = $outcome;
+                                $inst_results->{$uname.':'.$udom} = $results->{$uname};
+                            }
+                        }
+                    }
                 }
             } else {
-                ($inst_response,%{$inst_results->{$user}}) =
-                    &Apache::lonnet::get_instuser($udom,$uname);
-                return;
+                foreach my $udom (keys(%by_username)) {
+                    my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_username{$udom});
+                    if ($outcome eq 'ok') {
+                        if (ref($results) eq 'HASH') {
+                            foreach my $uname (keys(%{$results})) {
+                                $inst_response{$uname.':'.$udom} = $outcome;
+                                $inst_results->{$uname.':'.$udom} = $results->{$uname};
+                            }
+                        }
+                    }
+                }
             }
-            if (!$got_rules->{$udom}) {
-                my %domconfig = &Apache::lonnet::get_dom('configuration',
-                                                  ['usercreation'],$udom);
-                if (ref($domconfig{'usercreation'}) eq 'HASH') {
-                    foreach my $item ('username','id') {
-                        if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
-                            $$curr_rules{$udom}{$item} = 
-                                $domconfig{'usercreation'}{$item.'_rule'};
+        } elsif (keys(%{$usershash}) == 1) {
+            my $user = (keys(%{$usershash}))[0];
+            my ($uname,$udom) = split(/:/,$user);
+            if (($udom ne '') && ($uname ne '')) {
+                if (ref($usershash->{$user}) eq 'HASH') {
+                    if (ref($checks) eq 'HASH') {
+                        if (defined($checks->{'username'})) {
+                            ($inst_response{$user},%{$inst_results->{$user}}) = 
+                                &Apache::lonnet::get_instuser($udom,$uname);
+                        } elsif (defined($checks->{'id'})) {
+                            if ($usershash->{$user}->{'id'} ne '') {
+                                ($inst_response{$user},%{$inst_results->{$user}}) =
+                                    &Apache::lonnet::get_instuser($udom,undef,
+                                                                  $usershash->{$user}->{'id'});
+                            } else {
+                                ($inst_response{$user},%{$inst_results->{$user}}) =
+                                    &Apache::lonnet::get_instuser($udom,$uname);
+                            }
                         }
+                    } else {
+                       ($inst_response{$user},%{$inst_results->{$user}}) =
+                            &Apache::lonnet::get_instuser($udom,$uname);
+                       return;
+                    }
+                    if (!$got_rules->{$udom}) {
+                        my %domconfig = &Apache::lonnet::get_dom('configuration',
+                                                                 ['usercreation'],$udom);
+                        if (ref($domconfig{'usercreation'}) eq 'HASH') {
+                            foreach my $item ('username','id') {
+                                if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
+                                   $$curr_rules{$udom}{$item} = 
+                                       $domconfig{'usercreation'}{$item.'_rule'};
+                                }
+                            }
+                        }
+                        $got_rules->{$udom} = 1;
                     }
                 }
-                $got_rules->{$udom} = 1;  
+            } else {
+                return;
+            }
+        } else {
+            return;
+        }
+        foreach my $user (keys(%{$usershash})) {
+            my ($uname,$udom) = split(/:/,$user);
+            next if (($udom eq '') || ($uname eq ''));
+            my $id;
+            if (ref($usershash->{$user})) {
+                $id = $usershash->{$user}->{'id'};
             }
             foreach my $item (keys(%{$checks})) {
                 if (ref($$curr_rules{$udom}) eq 'HASH') {
                     if (ref($$curr_rules{$udom}{$item}) eq 'ARRAY') {
                         if (@{$$curr_rules{$udom}{$item}} > 0) {
-                            my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item,$$curr_rules{$udom}{$item});
+                            my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item,
+                                                                             $$curr_rules{$udom}{$item});
                             foreach my $rule (@{$$curr_rules{$udom}{$item}}) {
                                 if ($rule_check{$rule}) {
                                     $$rulematch{$user}{$item} = $rule;
-                                    if ($inst_response eq 'ok') {
+                                    if ($inst_response{$user} eq 'ok') {
                                         if (ref($inst_results) eq 'HASH') {
                                             if (ref($inst_results->{$user}) eq 'HASH') {
                                                 if (keys(%{$inst_results->{$user}}) == 0) {
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1289 loncom/lonnet/perl/lonnet.pm:1.1290
--- loncom/lonnet/perl/lonnet.pm:1.1289	Tue Jun 16 20:24:59 2015
+++ loncom/lonnet/perl/lonnet.pm	Wed Aug  5 18:47:25 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1289 2015/06/16 20:24:59 damieng Exp $
+# $Id: lonnet.pm,v 1.1290 2015/08/05 18:47:25 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1939,6 +1939,64 @@
     return ($outcome,%userinfo);
 }
 
+sub get_multiple_instusers {
+    my ($udom,$users,$caller) = @_;
+    my ($outcome,$results);
+    if (ref($users) eq 'HASH') {
+        my $count = keys(%{$users}); 
+        my $requested = &freeze_escape($users);
+        my $homeserver = &domain($udom,'primary');
+        if ($homeserver ne '') {
+            my $queryid=&reply('querysend:getmultinstusers:::'.$caller.'='.$requested,$homeserver);
+            my $host=&hostname($homeserver);
+            if ($queryid !~/^\Q$host\E\_/) {
+                &logthis('get_multiple_instusers invalid queryid: '.$queryid.
+                         ' for host: '.$homeserver.'in domain '.$udom);
+                return ($outcome,$results);
+            }
+            my $response = &get_query_reply($queryid);
+            my $maxtries = 5;
+            if ($count > 100) {
+                $maxtries = 1+int($count/20);
+            }
+            my $tries = 1;
+            while (($response=~/^timeout/) && ($tries <= $maxtries)) {
+                $response = &get_query_reply($queryid);
+                $tries ++;
+            }
+            if ($response eq '') {
+                $results = {};
+                foreach my $key (keys(%{$users})) {
+                    my ($uname,$id);
+                    if ($caller eq 'id') {
+                        $id = $key;
+                    } else {
+                        $uname = $key;
+                    }
+                    my ($resp,%info) = &get_instuser($udom,$uname,$id);
+                    if ($resp eq 'ok') {
+                        %{$results} = (%{$results}, %info);
+                        $outcome = 'ok';
+                    } else {
+                        $outcome = $resp;
+                        last;
+                    }
+                }
+            } elsif(!&error($response) && ($response ne 'refused')) {
+                if (($response eq 'unavailable') || ($response eq 'invalid') || ($response eq 'timeout')) {
+                    $outcome = $response;
+                } else {
+                    ($outcome,my $userdata) = split(/:/,$response,2);
+                    if ($outcome eq 'ok') {
+                        $results = &thaw_unescape($userdata); 
+                    }
+                }
+            }
+        }
+    }
+    return ($outcome,$results);
+}
+
 sub inst_rulecheck {
     my ($udom,$uname,$id,$item,$rules) = @_;
     my %returnhash;


More information about the LON-CAPA-cvs mailing list