Diff for /loncom/interface/lonuserutils.pm between versions 1.90 and 1.218

version 1.90, 2009/05/04 16:45:58 version 1.218, 2023/11/03 01:12:15
Line 30 Line 30
   
 package Apache::lonuserutils;  package Apache::lonuserutils;
   
   =pod
   
   =head1 NAME
   
   Apache::lonuserutils.pm
   
   =head1 SYNOPSIS
   
       Utilities for management of users and custom roles
   
       Provides subroutines called by loncreateuser.pm
   
   =head1 OVERVIEW
   
   =cut
   
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
   use Apache::loncoursequeueadmin;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::longroup;  use Apache::longroup;
   use HTML::Entities;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
 ###############################################################  ###############################################################
Line 91  sub modifyuserrole { Line 109  sub modifyuserrole {
     if ($setting eq 'course' || $context eq 'course') {      if ($setting eq 'course' || $context eq 'course') {
         $scope = '/'.$cid;          $scope = '/'.$cid;
         $scope =~ s/\_/\//g;          $scope =~ s/\_/\//g;
         if ($role ne 'cc' && $sec ne '') {          if (($role ne 'cc') && ($role ne 'co') && ($sec ne '')) {
             $scope .='/'.$sec;              $scope .='/'.$sec;
         }          }
     } elsif ($context eq 'domain') {      } elsif ($context eq 'domain') {
         $scope = '/'.$env{'request.role.domain'}.'/';          $scope = '/'.$env{'request.role.domain'}.'/';
     } elsif ($context eq 'author') {      } elsif ($context eq 'author') {
         $scope =  '/'.$env{'user.domain'}.'/'.$env{'user.name'};          if ($env{'request.role'} =~ m{^ca\.(/$match_domain/$match_username)$}) {
               $scope = $1;
           } else {
               $scope =  '/'.$env{'user.domain'}.'/'.$env{'user.name'};
           }
     }      }
     if ($context eq 'domain') {      if ($context eq 'domain') {
         my $uhome = &Apache::lonnet::homeserver($uname,$udom);          my $uhome = &Apache::lonnet::homeserver($uname,$udom);
Line 136  sub modifyuserrole { Line 158  sub modifyuserrole {
     return ($userresult,$authresult,$roleresult,$idresult);      return ($userresult,$authresult,$roleresult,$idresult);
 }  }
   
   sub role_approval {
       my ($dom,$context,$process_by,$notifydc) = @_;
       if (ref($process_by) eq 'HASH') {
           my %domconfig = &Apache::lonnet::get_dom('configuration',['privacy'],$dom);
           if (ref($domconfig{'privacy'}) eq 'HASH') {
               if (ref($notifydc) eq 'ARRAY') {
                   if ($domconfig{'privacy'}{'notify'} ne '') {
                       @{$notifydc} = split(/,/,$domconfig{'privacy'}{'notify'});
                   }
               }
               if (ref($domconfig{'privacy'}{'approval'}) eq 'HASH') {
                   my %approvalconf = %{$domconfig{'privacy'}{'approval'}};
                   foreach my $key ('instdom','extdom') {
                       if (ref($approvalconf{$key}) eq 'HASH') {
                           if (keys(%{$approvalconf{$key}})) {
                               $process_by->{$key} = $approvalconf{$key}{$context};
                           }
                       }
                   }
               }
           }
       }
       return;
   }
   
   sub get_instdoms {
       my ($udom,$instdoms) = @_;
       return unless (ref($instdoms) eq 'ARRAY');
       my @intdoms;
       my %iphost = &Apache::lonnet::get_iphost();
       my $primary_id = &Apache::lonnet::domain($udom,'primary');
       my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
       if (ref($iphost{$primary_ip}) eq 'ARRAY') {
           foreach my $id (@{$iphost{$primary_ip}}) {
               my $intdom = &Apache::lonnet::internet_dom($id);
               unless(grep(/^\Q$intdom\E$/,@intdoms)) {
                   push(@intdoms,$intdom);
               }
           }
       }
       foreach my $ip (keys(%iphost)) {
           if (ref($iphost{$ip}) eq 'ARRAY') {
               foreach my $id (@{$iphost{$ip}}) {
                   my $location = &Apache::lonnet::internet_dom($id);
                   if ($location) {
                       if (grep(/^\Q$location\E$/,@intdoms)) {
                           my $dom = &Apache::lonnet::host_domain($id);
                           unless (grep(/^\Q$dom\E/,@{$instdoms})) {
                               push(@{$instdoms},$dom);
                           }
                       }
                   }
               }
           }
       }
       return;
   }
   
   sub restricted_dom {
       my ($context,$key,$udom,$uname,$role,$start,$end,$cdom,$cnum,$csec,$credits,
           $process_by,$instdoms,$got_role_approvals,$got_instdoms,$reject,$pending,
           $notifydc,$status,$unauthorized,$currqueued) = @_;
       return if ($udom eq $cdom);
       return unless ((ref($process_by) eq 'HASH') && (ref($instdoms) eq 'HASH') &&
                      (ref($got_role_approvals) eq 'HASH') && (ref($got_instdoms) eq 'HASH') &&
                      (ref($reject) eq 'HASH') && (ref($pending) eq 'HASH') &&
                      (ref($notifydc) eq 'HASH') && (ref($status) eq 'HASH') &&
                      (ref($unauthorized) eq 'HASH') && (ref($currqueued) eq 'HASH'));
       my (%approval,@notify,$gotdata,$skip);
       if (ref($got_role_approvals->{$context}) eq 'HASH') {
           if ($got_role_approvals->{$context}{$udom}) {
               $gotdata = 1;
               if (ref($process_by->{$context}{$udom}) eq 'HASH') {
                   %approval = %{$process_by->{$context}{$udom}};
               }
           }
       }
       unless ($gotdata) {
           &role_approval($udom,$context,\%approval,\@notify);
           $process_by->{$context} = {
                                       $udom => \%approval,
                                     };
           $got_role_approvals->{$context} = {
                                               $udom => 1,
                                             };
           $notifydc->{$udom} = \@notify;
       }
       if (ref($process_by->{$context}) eq 'HASH') {
           if (ref($process_by->{$context}{$udom}) eq 'HASH') {
               my @inst;
               if ($got_instdoms->{$udom}) {
                   if (ref($instdoms->{$udom}) eq 'ARRAY') {
                       @inst = @{$instdoms->{$udom}};
                   }
               } else {
                   &get_instdoms(\@inst);
                   $instdoms->{$udom} = \@inst;
                   $got_instdoms->{$udom} = 1;
               }
               if (grep(/^\Q$cdom\E$/,@inst)) {
                   if (exists($approval{'instdom'})) {
                       my $rule = $approval{'instdom'};
                       if (($rule eq 'none') || ($rule eq 'user') || ($rule eq 'domain')) {
                           my ($id,$currstatus,$curradj) = &get_othdomreq_status($key,$uname,$udom,$role,$cdom,$cnum,$csec);
                           if (($currstatus ne '') && ($curradj eq $rule)) {
                               $status->{$key}->{$uname.':'.$udom} = $currstatus;
                           }
                           if ($rule eq 'none') {
                                $reject->{$key}->{$uname.':'.$udom} = {
                                                                        cdom  => $cdom,
                                                                        cnum  => $cnum,
                                                                        csec  => $csec,
                                                                        udom  => $udom,
                                                                        uname => $uname,
                                                                        role  => $role,
                                                                      };
                               $skip = 1;
                           } elsif (($rule eq 'user') || ($rule eq 'domain')) {
                               if ($curradj eq $rule) {
                                   unless ($currstatus eq 'approved') {
                                       if ($currstatus eq 'rejected') {
                                           $unauthorized->{$key}->{$uname.':'.$udom} = {
                                                                                         cdom  => $cdom,
                                                                                         cnum  => $cnum,
                                                                                         csec  => $csec,
                                                                                         udom  => $udom,
                                                                                         uname => $uname,
                                                                                         role  => $role,
                                                                                       };
                                       } elsif ($currstatus eq 'pending') {
                                           $currqueued->{$key}->{$uname.':'.$udom} = {
                                                                                       cdom  => $cdom,
                                                                                       cnum  => $cnum,
                                                                                       csec  => $csec,
                                                                                       udom  => $udom,
                                                                                       uname => $uname,
                                                                                       role  => $role,
                                                                                       adj   => $rule,
                                                                          };
                                       }
                                       $skip = 1;
                                   }
                               } else {
                                   $pending->{$key}->{$uname.':'.$udom} = {
                                                                            cdom  => $cdom,
                                                                            cnum  => $cnum,
                                                                            csec  => $csec,
                                                                            udom  => $udom,
                                                                            uname => $uname,
                                                                            role  => $role,
                                                                            start => $start,
                                                                            end   => $end,
                                                                            adj   => $rule,
                                                                          };
                                   if (($role eq 'st') && ($credits ne '')) {
                                       $pending->{$key}->{$uname.':'.$udom}->{'credits'} = $credits;
                                   }
                                   $skip = 1;
                               }
                           }
                       }
                   }
               } elsif (exists($approval{'extdom'})) {
                   my $rule = $approval{'extdom'};
                   if (($rule eq 'none') || ($rule eq 'user') || ($rule eq 'domain')) {
                       my ($id,$currstatus,$curradj) = &get_othdomreq_status($key,$uname,$udom,$role,$cdom,$cnum,$csec);
                       if (($currstatus ne '') && ($curradj eq $rule)) {
                           $status->{$key}->{$uname.':'.$udom} = $currstatus;
                       }
                       if ($rule eq 'none') {
                           $reject->{$key}->{$uname.':'.$udom} = {
                                                                   cdom  => $cdom,
                                                                   cnum  => $cnum,
                                                                   csec  => $csec,
                                                                   udom  => $udom,
                                                                   uname => $uname,
                                                                   role  => $role,
                                                                 };
                           $skip = 1;
                       } elsif (($rule eq 'user') || ($rule eq 'domain')) {
                           if ($curradj eq $rule) {
                               unless ($currstatus eq 'approved') {
                                   if ($currstatus eq 'rejected') {
                                       $unauthorized->{$key}->{$uname.':'.$udom} = {
                                                                                     cdom  => $cdom,
                                                                                     cnum  => $cnum,
                                                                                     csec  => $csec,
                                                                                     udom  => $udom,
                                                                                     uname => $uname,
                                                                                     role  => $role,
                                                                                   };
                                   } elsif ($currstatus eq 'pending') {
                                       $currqueued->{$key}->{$uname.':'.$udom} = {
                                                                                   cdom  => $cdom,
                                                                                   cnum  => $cnum,
                                                                                   csec  => $csec,
                                                                                   udom  => $udom,
                                                                                   uname => $uname,
                                                                                   role  => $role,
                                                                                   adj   => $rule,
                                                                          };
                                   }
                                   $skip = 1;
                               }
                           } else {
                               $pending->{$key}->{$uname.':'.$udom} = {
                                                                        cdom  => $cdom,
                                                                        cnum  => $cnum,
                                                                        csec  => $csec,
                                                                        udom  => $udom,
                                                                        uname => $uname,
                                                                        role  => $role,
                                                                        start => $start,
                                                                        end   => $end,
                                                                        adj   => $rule,
                                                                      };
                               if (($role eq 'st') && ($credits ne '')) {
                                   $pending->{$key}->{$uname.':'.$udom}->{'credits'} = $credits;
                               }
                               $skip = 1;
                           }
                       }
                   }
               }
           }
       }
       return $skip;
   }
   
   sub get_othdomreq_status {
       my ($key,$uname,$udom,$role,$cdom,$cnum,$csec) = @_;
       my $id = $uname.':'.$udom.':'.$role; 
       my ($dbnum,$currstatus,$curradj);
       if (($role eq 'ca') || ($role eq 'aa')) {
           $dbnum = $cnum;
       } elsif ($key eq $cdom.'_'.$role) {
           $dbnum = &Apache::lonnet::get_domainconfiguser($cdom);
       } else {
           $id .= ':'.$csec;
           $dbnum = $cnum;
       }
       my $statusid = 'status&'.$id;
       my %curr = &Apache::lonnet::get('nohist_othdomqueued',[$id,$statusid],$cdom,$dbnum);
       if (ref($curr{$id}) eq 'HASH') {
           $curradj = $curr{$id}{'adj'};
       }
       $currstatus = $curr{$statusid};
       return ($id,$currstatus,$curradj);
   }
   
   sub print_roles_rejected {
       my ($context,$reject,$unauthorized) = @_;
       return unless ((ref($reject) eq 'HASH') || (ref($unauthorized) eq 'HASH'));
       my $output;
       if (keys(%{$reject}) > 0) {
           $output = '<p class="LC_warning">'.
                     &mt("The following roles could not be assigned because the user is from another domain, and that domain's policies disallow it").'<ul>';
           foreach my $key (sort(keys(%{$reject}))) {
               if (ref($reject->{$key}) eq 'HASH') {
                   foreach my $user (sort(keys(%{$reject->{$key}}))) {
                       if (ref($reject->{$key}->{$user}) eq 'HASH') {
                           my ($crstype,$role,$cdom,$cnum,$csec,$title,$plainrole);
                           $role = $reject->{$key}->{$user}{'role'};
                           $cdom = $reject->{$key}->{$user}{'cdom'};
                           $cnum = $reject->{$key}->{$user}{'cnum'};
                           $csec = $reject->{$key}->{$user}{'csec'};
                           if (($context eq 'domain') && ($cnum ne '')) {
                               if (($role eq 'ca') || ($role eq 'aa')) {
                                   $title = &Apache::loncommon::plainname($cnum,$cdom);
                               } else {
                                   if (&Apache::lonnet::is_course($cdom,$cnum)) {
                                       my %coursedata = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
                                       $crstype = $coursedata{'type'};
                                       $title = $coursedata{'description'};
                                   }
                               }
                           } elsif ($context eq 'course') {
                               $crstype = &Apache::loncommon::course_type();
                           }
                           my $plainrole = &Apache::lonnet::plaintext($role,$crstype);
                           $output .= '<li>'.&mt('User: [_1]',$reject->{$key}->{$user}{'uname'}).' | '.
                                             &mt('Domain: [_1]',$reject->{$key}->{$user}{'udom'}).' | '.
                                             &mt('Role: [_1]',$plainrole);
                           if ($crstype) {
                               if ($csec ne'') {
                                   $output .= ' | '.&mt('Section: [_1]',$csec);
                               }
                           } elsif (($context eq 'domain') && (($role eq 'ca') || ($role eq 'aa'))) {
                               $output .= ' | '.&mt('Authoring Space belonging to: [_1]',$title);
                                                   
                           }
                           if (($context eq 'domain') && ($crstype)) {
                               $output .= ' | '.&mt("$crstype: [_1]",$title);
                           }
                           $output .= '</li>';
                       }
                   }
               }
           }
           $output .= '</ul></p>';
       }
       if (keys(%{$unauthorized}) > 0) {
           $output = '<p class="LC_warning">'.
                     &mt("The following roles could not be assigned because the user is from another domain, and that domain's policies require approval by the user themselves or by a domain coordinator in that domain, and approval has been withheld.").'<ul>';
           foreach my $key (sort(keys(%{$unauthorized}))) {
               if (ref($unauthorized->{$key}) eq 'HASH') {
                   foreach my $user (sort(keys(%{$unauthorized->{$key}}))) {
                       if (ref($unauthorized->{$key}->{$user}) eq 'HASH') {
                           my ($crstype,$role,$cdom,$cnum,$csec,$title,$plainrole);
                           $role = $unauthorized->{$key}->{$user}{'role'};
                           $cdom = $unauthorized->{$key}->{$user}{'cdom'};
                           $cnum = $unauthorized->{$key}->{$user}{'cnum'};
                           $csec = $unauthorized->{$key}->{$user}{'csec'};
                           if (($context eq 'domain') && ($cnum ne '')) {
                               if (($role eq 'ca') || ($role eq 'aa')) {
                                   $title = &mt('Authoring Space belonging to: [_1]',
                                                &Apache::loncommon::plainname($cnum,$cdom));
                               } else {
                                   if (&Apache::lonnet::is_course($cdom,$cnum)) {
                                       my %coursedata = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
                                       $crstype = $coursedata{'type'};
                                       $title = &mt("$crstype: [_1]",$coursedata{'description'});
                                   }
                               }
                           } elsif ($context eq 'course') {
                               $crstype = &Apache::loncommon::course_type();
                           }
                           $plainrole = &Apache::lonnet::plaintext($role,$crstype);
                           $output .= '<li>'.&mt('User: [_1]',$unauthorized->{$key}->{$user}{'uname'}).' | '.
                                             &mt('Domain: [_1]',$unauthorized->{$key}->{$user}{'udom'}).' | '.
                                             &mt('Role: [_1]',$plainrole);
                           if ($crstype) {
                               if ($csec ne'') {
                                   $output .= ' | '.&mt('Section: [_1]',$csec);
                               }
                           }
                           if ($title ne '') {
                               $output .= ' | '.$title;
                           }
                           $output .= '</li>';
                       }
                   }
               }
           }
           $output .= '</ul></p>'; 
       }
       return $output;
   }
   
   sub print_roles_queued {
       my ($context,$pending,$notifydc,$currqueued) = @_;
       return unless ((ref($pending) eq 'HASH') && (ref($notifydc) eq 'HASH') &&
                      (ref($currqueued) eq 'HASH'));
       my $output;
       if (keys(%{$pending}) > 0) {
           my $now = time;
           $output = '<p class="LC_warning">'.
                     &mt("The following role assignments have been queued because the user is from another domain, and that domain's policies require approval by the user themselves or by a domain coordinator in that domain").'<ul>';
           my (%todom,%touser,%crsqueue,%caqueue,%domqueue);
           my $requester = $env{'user.name'}.':'.$env{'user.domain'};
           foreach my $key (sort(keys(%{$pending}))) {
               if (ref($pending->{$key}) eq 'HASH') {
                   foreach my $user (sort(keys(%{$pending->{$key}}))) {
                       if (ref($pending->{$key}->{$user}) eq 'HASH') {
                           my $role = $pending->{$key}->{$user}{'role'};
                           my $uname = $pending->{$key}->{$user}{'uname'};
                           my $udom = $pending->{$key}->{$user}{'udom'};
                           my $csec = $pending->{$key}->{$user}{'csec'};
                           my $cdom = $pending->{$key}->{$user}{'cdom'};
                           my $cnum = $pending->{$key}->{$user}{'cnum'};
                           my $adj = $pending->{$key}->{$user}{'adj'};
                           my $start = $pending->{$key}->{$user}{'start'};
                           my $end = $pending->{$key}->{$user}{'end'};
                           my $credits = $pending->{$key}->{$user}{'credits'};
                           my $now = time;
                           my ($crstype,$title,$plainrole,$extent,$id,$status);
                           if ($context eq 'course') {
                               $crstype = &Apache::loncommon::course_type();
                               $title = $env{'course.'.$env{'request.course.id'}.'.description'};
                           } elsif ($context eq 'domain') {
                               if (&Apache::lonnet::is_course($cdom,$cnum)) {
                                   my %coursedata = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
                                   $crstype = $coursedata{'type'};
                                   $title = $coursedata{'description'};
                               } elsif (($role eq 'ca') || ($role eq 'aa')) {
                                   $title = &Apache::loncommon::plainname($cnum,$cdom);
                               }
                           }
                           $plainrole = &Apache::lonnet::plaintext($role,$crstype);
                           $extent = "/$cdom/$cnum";
                           $id = $uname.':'.$udom.':'.$role;
                           if (($context eq 'course') || ($crstype)) {
                               $id .= ':'.$csec;
                           }
                           $output .= '<li>'.&mt('User: [_1]',$uname).' | '.
                                             &mt('Domain: [_1]',$udom).' | '.
                                             &mt('Role: [_1]',$plainrole);
                           if ($crstype) {
                               if ($csec ne'') {
                                   $output .= ' | '.&mt('Section: [_1]',$csec);
                               }
                           } elsif (($context eq 'domain') && (($role eq 'ca') || ($role eq 'aa'))) {
                               $output .= ' | '.&mt('Authoring Space belonging to: [_1]',$title);
                           }
                           if (($context eq 'domain') && ($crstype)) {
                               $output .= ' | '.&mt("$crstype: [_1]",$title);
                           }
                           if (($crstype) && ($csec ne '')) {
                               $extent .= "/$csec";
                           }
                           if ($adj eq 'user') {
                               $output .= '<br />'.&mt('Message sent to user for approval');
                               $touser{$uname.':'.$udom}{'pending:'.$extent.':'.$role} = {
                                                                                           timestamp => $now,
                                                                                           requester => $requester,
                                                                                           start     => $start,
                                                                                           end       => $end,
                                                                                           credits   => $credits,
                                                                                           context   => $context,
                                                                                         };
                           } elsif ($adj eq 'domain') {
                               $output .= '<br />'.&mt("Message sent to user's domain coordinator for approval");
                               $todom{$udom}{'pending:'.$uname.':'.$extent.':'.$role} = {
                                                                                          timestamp => $now,
                                                                                          requester => $requester,
                                                                                          start     => $start,
                                                                                          end       => $end,
                                                                                          credits   => $credits,
                                                                                          context   => $context,
                                                                                        };
                           }
                           $output .= '</li>';
                           if (($context eq 'course') || ($crstype)) {
                               $crsqueue{$cdom.'_'.$cnum}{$id} = {
                                                                   timestamp => $now,
                                                                   requester => $requester,
                                                                   adj       => $adj,
                                                                 };
                               $crsqueue{$cdom.'_'.$cnum}{'status&'.$id} = 'pending';
                           } elsif (($context eq 'author') ||
                                    (($context eq 'domain') && (($role eq 'ca') || ($role eq 'aa')))) {
                               $caqueue{$cnum.':'.$cdom}{$id} = {
                                                                  timestamp => $now,
                                                                  requester => $requester,
                                                                  adj       => $adj,
                                                                };
                               $caqueue{$cnum.':'.$cdom}{'status&'.$id} = 'pending';
                           } elsif ($context eq 'domain') {
                               $domqueue{$id} = {
                                                  timestamp => $now,
                                                  requester => $requester,
                                                  adj       => $adj,
                                                };
                               $domqueue{'status&'.$id} = 'pending';
                           }
                       }
                   }
               }
           }
           $output .= '</ul></p>';
           if (keys(%touser)) {
               foreach my $key (keys(%touser)) {
                   my ($uname,$udom) = split(/:/,$key);
                   if (&Apache::lonnet::put('nohist_queuedrolereqs',$touser{$key},$udom,$uname) eq 'ok') {
                       my $owndomdesc = &Apache::lonnet::domain($udom);
                       &Apache::loncoursequeueadmin::send_selfserve_notification($uname.':'.$udom,
                           '','',$owndomdesc,$now,'othdomroleuser',$requester);
                   }
               }
           }
           if (keys(%todom)) {
               foreach my $dom (keys(%todom)) {
                   if (ref($todom{$dom}) eq 'HASH') {
                       my $confname = &Apache::lonnet::get_domainconfiguser($dom);
                       if (&Apache::lonnet::put('nohist_queuedrolereqs',$todom{$dom},$dom,$confname) eq 'ok') {
                           if (ref($notifydc->{$dom}) eq 'ARRAY') {
                               if (@{$notifydc->{$dom}} > 0) {
                                   my $notifylist = join(',',@{$notifydc->{$dom}});
                                   &Apache::loncoursequeueadmin::send_selfserve_notification($notifylist,
                                       '','','',$now,'othdomroledc',$requester);
                               }
                           }
                       }
                   }
               }
           }
           if (keys(%crsqueue)) {
               foreach my $key (keys(%crsqueue)) {
                   my ($cdom,$cnum) = split(/_/,$key);
                   if (ref($crsqueue{$key}) eq 'HASH') {
                       &Apache::lonnet::put('nohist_othdomqueued',$crsqueue{$key},$cdom,$cnum);
                   }
               }
           }
           if (keys(%caqueue)) {
               foreach my $key (keys(%caqueue)) {
                   my ($auname,$audom) = split(/:/,$key);
                   if (ref($caqueue{$key}) eq 'HASH') {
                       &Apache::lonnet::put('nohist_othdomqueued',$caqueue{$key},$audom,$auname);
                   }
               }
           }
           if (keys(%domqueue)) {
               my $confname = &Apache::lonnet::get_domainconfiguser($env{'request.role.domain'});
               &Apache::lonnet::put('nohist_othdomqueued',\%domqueue,$env{'request.role.domain'},$confname);
           }
       }
       if (keys(%{$currqueued}) > 0) {
           $output = '<p class="LC_warning">'.
                     &mt("The following role assignments were already queued because the user is from another domain, and that domain's policies require approval by the user themselves or by a domain coordinator in that domain").'<ul>';
           my $requester = $env{'user.name'}.':'.$env{'user.domain'};
           foreach my $key (sort(keys(%{$currqueued}))) {
               if (ref($currqueued->{$key}) eq 'HASH') {
                   foreach my $user (sort(keys(%{$currqueued->{$key}}))) {
                       if (ref($currqueued->{$key}->{$user}) eq 'HASH') {
                           my $role = $currqueued->{$key}->{$user}{'role'};
                           my $csec = $currqueued->{$key}->{$user}{'csec'};
                           my $cdom = $currqueued->{$key}->{$user}{'cdom'};
                           my $cnum = $currqueued->{$key}->{$user}{'cnum'};
                           my ($crstype,$title,$plainrole);
                           if ($context eq 'course') {
                               $crstype = &Apache::loncommon::course_type();
                           } elsif (($context eq 'domain') && ($cnum ne '')) {
                               if (($role eq 'ca') || ($role eq 'aa')) {
                                   $title = &mt('Authoring Space belonging to: [_1]',
                                                &Apache::loncommon::plainname($cnum,$cdom));
                               } elsif (&Apache::lonnet::is_course($cdom,$cnum)) {
                                   my %coursedata = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
                                   $crstype = $coursedata{'type'};
                                   $title = &mt("$crstype: [_1]",$coursedata{'description'});
                               }
                           }
                           $plainrole = &Apache::lonnet::plaintext($role,$crstype);
                           $output .= '<li>'.&mt('User: [_1]',$currqueued->{$key}->{$user}{'uname'}).' | '.
                                             &mt('Domain: [_1]',$currqueued->{$key}->{$user}{'udom'}).' | '.
                                             &mt('Role: [_1]',$plainrole);
                           if ($title ne '') {
                               $output .= ' | '.$title;
                           }
                           if ($crstype) {
                               if ($csec ne '') {
                                   $output .= ' | '.&mt('Section: [_1]',$csec);
                               }
                           }
                           $output .= '</li>';
                       }
                   }
               }
           }
           $output .= '</ul></p>';
       }
       return $output;
   }
   
 sub propagate_id_change {  sub propagate_id_change {
     my ($uname,$udom,$user) = @_;      my ($uname,$udom,$user) = @_;
     my (@types,@roles);      my (@types,@roles);
Line 235  sub domain_roles_select { Line 811  sub domain_roles_select {
     # domain context         # domain context   
     #      #
     # Role types      # Role types
     my @roletypes = ('domain','author','course');      my @roletypes = ('domain','author','course','community');
     my %lt = &role_type_names();      my %lt = &role_type_names();
       my $onchangefirst = "updateCols('showrole')";
       my $onchangesecond = "updateCols('showrole')";
     #      #
     # build up the menu information to be passed to      # build up the menu information to be passed to
     # &Apache::loncommon::linked_select_forms      # &Apache::loncommon::linked_select_forms
Line 247  sub domain_roles_select { Line 825  sub domain_roles_select {
     foreach my $roletype (@roletypes) {      foreach my $roletype (@roletypes) {
         # set up the text for this domain          # set up the text for this domain
         $select_menus{$roletype}->{'text'}= $lt{$roletype};          $select_menus{$roletype}->{'text'}= $lt{$roletype};
           my $crstype;
           if ($roletype eq 'community') {
               $crstype = 'Community';
           }
         # we want a choice of 'default' as the default in the second menu          # we want a choice of 'default' as the default in the second menu
         if ($env{'form.roletype'} ne '') {          if ($env{'form.roletype'} ne '') {
             $select_menus{$roletype}->{'default'} = $env{'form.showrole'};              $select_menus{$roletype}->{'default'} = $env{'form.showrole'};
Line 261  sub domain_roles_select { Line 843  sub domain_roles_select {
             @roles = &construction_space_roles();              @roles = &construction_space_roles();
         } else {          } else {
             my $custom = 1;              my $custom = 1;
             @roles = &course_roles('domain',undef,$custom);              @roles = &course_roles('domain',undef,$custom,$roletype);
         }          }
         my $order = ['Any',@roles];          my $order = ['Any',@roles];
         $select_menus{$roletype}->{'order'} = $order;           $select_menus{$roletype}->{'order'} = $order; 
Line 271  sub domain_roles_select { Line 853  sub domain_roles_select {
                               &mt('Custom role');                                &mt('Custom role');
             } else {              } else {
                 $select_menus{$roletype}->{'select2'}->{$role} =                   $select_menus{$roletype}->{'select2'}->{$role} = 
                               &Apache::lonnet::plaintext($role);                                &Apache::lonnet::plaintext($role,$crstype);
             }              }
         }          }
         $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');          $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');
     }      }
     my $result = &Apache::loncommon::linked_select_forms      my $result = &Apache::loncommon::linked_select_forms
         ('studentform',('&nbsp;'x3).&mt('Role: '),$env{'form.roletype'},          ('studentform',('&nbsp;'x3).&mt('Role: '),$env{'form.roletype'},
          'roletype','showrole',\%select_menus,['domain','author','course']);           'roletype','showrole',\%select_menus,
            ['domain','author','course','community'],$onchangefirst,
            $onchangesecond);
     return $result;      return $result;
 }  }
   
Line 290  sub hidden_input { Line 874  sub hidden_input {
 }  }
   
 sub print_upload_manager_header {  sub print_upload_manager_header {
     my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_;      my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission,$crstype,
           $can_assign)=@_;
     my $javascript;      my $javascript;
     #      #
     if (! exists($env{'form.upfile_associate'})) {      if (! exists($env{'form.upfile_associate'})) {
Line 304  sub print_upload_manager_header { Line 889  sub print_upload_manager_header {
         }          }
     }      }
     if ($env{'form.upfile_associate'} eq 'reverse') {      if ($env{'form.upfile_associate'} eq 'reverse') {
         $javascript=&upload_manager_javascript_reverse_associate();          $javascript=&upload_manager_javascript_reverse_associate($can_assign);
     } else {      } else {
         $javascript=&upload_manager_javascript_forward_associate();          $javascript=&upload_manager_javascript_forward_associate($can_assign);
     }      }
     #      #
     # Deal with restored settings      # Deal with restored settings
Line 327  sub print_upload_manager_header { Line 912  sub print_upload_manager_header {
     my $javascript_validations =      my $javascript_validations =
         &javascript_validations('upload',$krbdefdom,$password_choice,undef,          &javascript_validations('upload',$krbdefdom,$password_choice,undef,
                                 $env{'request.role.domain'},$context,                                  $env{'request.role.domain'},$context,
                                 $groupslist);                                  $groupslist,$crstype);
     my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
     $r->print(&mt('Total number of records found in file: [_1]','<b>'.$distotal.'</b>').      $r->print(
               "<br />\n");          '<h3>'.&mt('Identify fields in uploaded list')."</h3>\n".
     $r->print('<div class="LC_left_float"><h3>'.          '<p class="LC_info">'.
               &mt('Identify fields in uploaded list')."</h3>\n");          &mt('Total number of records found in file: [_1]'
     $r->print(&mt('Enter as many fields as you can.<br /> The system will inform you and bring you back to this page, <br /> if the data selected are insufficient to add users.')."<br />\n");             ,'<b>'.$distotal.'</b>').
           "</p>\n"
       );
       if ($distotal == 0) {
           $r->print('<p class="LC_warning">'.&mt('None found').'</p>');
       }
       $r->print(
           '<p>'.
           &mt('Enter as many fields as you can.').'<br />'.
           &mt('The system will inform you and bring you back to this page,[_1]if the data selected are insufficient to add users.','<br />').
           "</p>\n"
       );
     $r->print(&hidden_input('action','upload').      $r->print(&hidden_input('action','upload').
               &hidden_input('state','got_file').                &hidden_input('state','got_file').
               &hidden_input('associate','').                &hidden_input('associate','').
Line 341  sub print_upload_manager_header { Line 937  sub print_upload_manager_header {
               &hidden_input('fileupload',$env{'form.fileupload'}).                &hidden_input('fileupload',$env{'form.fileupload'}).
               &hidden_input('upfiletype',$env{'form.upfiletype'}).                &hidden_input('upfiletype',$env{'form.upfiletype'}).
               &hidden_input('upfile_associate',$env{'form.upfile_associate'}));                &hidden_input('upfile_associate',$env{'form.upfile_associate'}));
     $r->print('<br /><label><input type="checkbox" name="noFirstLine"'.$checked.' />'.      $r->print(
               &mt('Ignore First Line').'</label><br />');          '<div class="LC_left_float">'.
     $r->print('<br /><input type="button" value="'.&mt('Reverse Association').'" '.          '<fieldset><legend>'.&mt('Functions').'</legend>'.
           '<label><input type="checkbox" name="noFirstLine"'.$checked.' />'.
                 &mt('Ignore First Line').'</label>'.
           ' <input type="button" value="'.&mt('Reverse Association').'" '.
               'name="Reverse Association" '.                'name="Reverse Association" '.
               'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');                'onclick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />'.
     $r->print("<br /><br />\n".          '</fieldset></div><br clear="all" />'
               '<script type="text/javascript" language="Javascript">'."\n".      );
               $javascript."\n".$javascript_validations.'</script>');      $r->print(
           '<script type="text/javascript" language="Javascript">'."\n".
           '// <![CDATA['."\n".
           $javascript."\n".$javascript_validations."\n".
           '// ]]>'."\n".
           '</script>'
       );
 }  }
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub javascript_validations {  sub javascript_validations {
     my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain,      my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain,
         $context,$groupslist)=@_;          $context,$groupslist,$crstype)=@_;
     my %param = (      my %param = (
                   kerb_def_dom => $krbdefdom,                    kerb_def_dom => $krbdefdom,
                   curr_authtype => $curr_authtype,                    curr_authtype => $curr_authtype,
Line 370  sub javascript_validations { Line 975  sub javascript_validations {
         $param{'curr_autharg'} = $curr_authfield;          $param{'curr_autharg'} = $curr_authfield;
     }      }
   
       my $showcredits;
       my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
       if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
           $showcredits = 1;
       }
   
     my ($setsection_call,$setsections_js);      my ($setsection_call,$setsections_js);
     my $finish = "  vf.submit();\n";      my $finish = "  vf.submit();\n";
     if ($mode eq 'upload') {      if ($mode eq 'upload') {
         if (($context eq 'course') || ($context eq 'domain')) {          if (($context eq 'course') || ($context eq 'domain')) {
             if ($context eq 'course') {              if ($context eq 'course') {
                 if ($env{'request.course.sec'} eq '') {                  if ($env{'request.course.sec'} eq '') {
                     $setsection_call = 'setSections(document.'.$param{'formname'}.');';                      $setsection_call = 'setSections(document.'.$param{'formname'}.",'$crstype'".');';
                     $setsections_js =                      $setsections_js =
                         &setsections_javascript($param{'formname'},$groupslist,                          &setsections_javascript($param{'formname'},$groupslist,
                                                 $mode);                                                  $mode,'',$crstype,$showcredits);
                 } else {                  } else {
                     $setsection_call = "'ok'";                      $setsection_call = "'ok'";
                 }                  }
             } elsif ($context eq 'domain') {              } elsif ($context eq 'domain') {
                 $setsection_call = 'setCourse()';                  $setsection_call = 'setCourse()';
                 $setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context);                  $setsections_js = &dc_setcourse_js($param{'formname'},$mode,
                                                      $context,$showcredits,$domain);
             }              }
             $finish = "  var checkSec = $setsection_call\n".              $finish = "  var checkSec = $setsection_call\n".
                       "  if (checkSec == 'ok') {\n".                        "  if (checkSec == 'ok') {\n".
Line 401  sub javascript_validations { Line 1013  sub javascript_validations {
          krb      => 'You need to specify the Kerberos domain.',           krb      => 'You need to specify the Kerberos domain.',
          ipass    => 'You need to specify the initial password.',           ipass    => 'You need to specify the initial password.',
          name     => 'The optional name field was not specified.',           name     => 'The optional name field was not specified.',
          snum     => 'The optional ID number field was not specified.',           snum     => 'The optional student/employee ID field was not specified.',
          section  => 'The optional section field was not specified.',           section  => 'The optional section field was not specified.',
          email    => 'The optional e-mail address field was not specified.',           email    => 'The optional e-mail address field was not specified.',
          role     => 'The optional role field was not specified.',           role     => 'The optional role field was not specified.',
          domain   => 'The optional domain field was not specified.',           domain   => 'The optional domain field was not specified.',
          continue => 'Continue adding users?',           continue => 'Continue adding users?',
          );           );
       if ($showcredits) {
           $alert{'credits'} = &mt('The optional credits field was not specified');
       }
     if (($mode eq 'upload') && ($context eq 'domain')) {      if (($mode eq 'upload') && ($context eq 'domain')) {
         $alert{'inststatus'} = &mt('The optional affiliation field was not specified');           $alert{'inststatus'} = &mt('The optional affiliation field was not specified'); 
     }      }
       &js_escape(\%alert);
     my $function_name = <<"END";      my $function_name = <<"END";
 $setsections_js  $setsections_js
   
 function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus) {  function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits) {
 END  END
     my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($domain);      my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($domain);
     my $auth_checks;      my $auth_checks;
Line 453  END Line 1069  END
 ";  ";
     } elsif ($mode eq 'modifycourse') {      } elsif ($mode eq 'modifycourse') {
         $auth_checks .= "          $auth_checks .= "
     if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') {      if ((current.argfield !== null) && (current.argfield !== undefined) && (current.argfield !== '') && (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '')) {
 ";  ";
     }      }
     if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {      if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
Line 471  END Line 1087  END
             return;              return;
         }          }
     }      }
   /* regexp here to check for non \d \. in credits */
 END  END
     } else {      } else {
           my ($numrules,$intargjs) =
               &Apache::loncommon::passwd_validation_js('vf.elements[current.argfield].value',$domain);
         $auth_checks .= (<<END);          $auth_checks .= (<<END);
     foundatype=1;      foundatype=1;
     if (current.argfield == null || current.argfield == '') {      if (current.argfield == null || current.argfield == '') {
           // The login radiobutton checked does not have an associated textbox
       } else if (vf.elements[current.argfield].value == '') {
         var alertmsg = '';          var alertmsg = '';
         switch (current.radiovalue) {          switch (current.radiovalue) {
             case 'krb':              case 'krb':
                 alertmsg = '$alert{'krb'}';                  alertmsg = '$alert{'krb'}';
                 break;                  break;
             case 'loc':              case 'int':
             case 'fsys':  
                 alertmsg = '$alert{'ipass'}';                  alertmsg = '$alert{'ipass'}';
                 break;                  break;
             case 'fsys':              case 'fsys':
                   alertmsg = '$alert{'ipass'}';
                   break;
               case 'loc':
                 alertmsg = '';                  alertmsg = '';
                 break;                  break;
               case 'lti':
             default:              default:
                 alertmsg = '';                  alertmsg = '';
         }          }
Line 495  END Line 1119  END
             alert(alertmsg);              alert(alertmsg);
             return;              return;
         }          }
       } else if (current.radiovalue == 'int') {
           if ($numrules > 0) {
   $intargjs
           }
     }      }
 END  END
     }      }
Line 522  END Line 1150  END
         if (message!='') {          if (message!='') {
             message+='\\n';              message+='\\n';
         }          }
           message+='$alert{'section'}';
     }      }
     if (foundemail==0) {      if (foundemail==0) {
         if (message!='') {          if (message!='') {
Line 542  END Line 1171  END
         message+='$alert{'domain'}';          message+='$alert{'domain'}';
     }      }
 END  END
           if ($showcredits) {
               $optional_checks .= <<END;
       if (foundcredits==0) {
           if (message!='') {
               message+='\\n';
           }
           message+='$alert{'credits'}';
       }
   END
           }
         if (($mode eq 'upload') && ($context eq 'domain')) {          if (($mode eq 'upload') && ($context eq 'domain')) {
             $optional_checks .= (<<END);              $optional_checks .= (<<END);
   
Line 572  END Line 1211  END
                  $section_checks.$authheader;                   $section_checks.$authheader;
     return $result;      return $result;
 }  }
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub upload_manager_javascript_forward_associate {  sub upload_manager_javascript_forward_associate {
       my ($can_assign) = @_;
       my ($auth_update,$numbuttons,$argreset);
       if (ref($can_assign) eq 'HASH') {
           if ($can_assign->{'krb4'} || $can_assign->{'krb5'}) {
               $argreset .= "      vf.krbarg.value='';\n";
               $numbuttons ++ ;
           }
           if ($can_assign->{'int'}) {
               $argreset .= "      vf.intarg.value='';\n";
               $numbuttons ++;
           }
           if ($can_assign->{'loc'}) {
               $argreset .= "      vf.locarg.value='';\n";
               $numbuttons ++;
           }
           if (!$can_assign->{'int'}) {
               my $warning = &mt('You may not specify an initial password for each user, as this is only available when new users use LON-CAPA internal authentication.')."\n".
                             &mt('Your current role does not have rights to create users with that authentication type.');
               &js_escape(\$warning);
               $auth_update = <<"END";
      // Currently the initial password field is only supported for internal auth
      // (see bug 6368).
      if (nw==9) {
          eval('vf.f'+tf+'.selectedIndex=0;')
          alert('$warning');
      }
   END
           } elsif ($numbuttons > 1) {
               $auth_update = <<"END";
      // If we set the password, make the password form below correspond to
      // the new value.
      if (nw==9) {
         changed_radio('int',document.studentform);
         set_auth_radio_buttons('int',document.studentform);
   $argreset
      }
   
   END
           }
       }
   
     return(<<ENDPICK);      return(<<ENDPICK);
 function verify(vf,sec_caller) {  function verify(vf,sec_caller) {
     var founduname=0;      var founduname=0;
Line 586  function verify(vf,sec_caller) { Line 1267  function verify(vf,sec_caller) {
     var foundrole=0;      var foundrole=0;
     var founddomain=0;      var founddomain=0;
     var foundinststatus=0;      var foundinststatus=0;
       var foundcredits=0;
     var tw;      var tw;
     for (i=0;i<=vf.nfields.value;i++) {      for (i=0;i<=vf.nfields.value;i++) {
         tw=eval('vf.f'+i+'.selectedIndex');          tw=eval('vf.f'+i+'.selectedIndex');
Line 598  function verify(vf,sec_caller) { Line 1280  function verify(vf,sec_caller) {
         if (tw==11) { foundrole=1; }          if (tw==11) { foundrole=1; }
         if (tw==12) { founddomain=1; }          if (tw==12) { founddomain=1; }
         if (tw==13) { foundinststatus=1; }          if (tw==13) { foundinststatus=1; }
           if (tw==14) { foundcredits=1; }
     }      }
     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus);      verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits);
 }  }
   
 //  //
Line 622  function verify(vf,sec_caller) { Line 1305  function verify(vf,sec_caller) {
 // 11 = role  // 11 = role
 // 12 = domain  // 12 = domain
 // 13 = inststatus  // 13 = inststatus
   // 14 = foundcredits 
   
 function flip(vf,tf) {  function flip(vf,tf) {
    var nw=eval('vf.f'+tf+'.selectedIndex');     var nw=eval('vf.f'+tf+'.selectedIndex');
Line 651  function flip(vf,tf) { Line 1335  function flip(vf,tf) {
          }           }
       }        }
    }     }
    // If we set the password, make the password form below correspond to     $auth_update
    // the new value.  
    if (nw==9) {  
        changed_radio('int',document.studentform);  
        set_auth_radio_buttons('int',document.studentform);  
        vf.intarg.value='';  
        vf.krbarg.value='';  
        vf.locarg.value='';  
    }  
 }  }
   
 function clearpwd(vf) {  function clearpwd(vf) {
Line 677  ENDPICK Line 1353  ENDPICK
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub upload_manager_javascript_reverse_associate {  sub upload_manager_javascript_reverse_associate {
       my ($can_assign) = @_;
       my ($auth_update,$numbuttons,$argreset);
       if (ref($can_assign) eq 'HASH') {
           if ($can_assign->{'krb4'} || $can_assign->{'krb5'}) {
               $argreset .= "      vf.krbarg.value='';\n";
               $numbuttons ++ ;
           }
           if ($can_assign->{'int'}) {
               $argreset .= "      vf.intarg.value='';\n";
               $numbuttons ++;
           }
           if ($can_assign->{'loc'}) {
               $argreset .= "      vf.locarg.value='';\n";
               $numbuttons ++;
           }
           if (!$can_assign->{'int'}) {
               my $warning = &mt('You may not specify an initial password, as this is only available when new users use LON-CAPA internal authentication.\n').
                             &mt('Your current role does not have rights to create users with that authentication type.');
               &js_escape(\$warning);
               $auth_update = <<"END";
      // Currently the initial password field is only supported for internal auth
      // (see bug 6368).
      if (tf==8 && nw!=0) {
          eval('vf.f'+tf+'.selectedIndex=0;')
          alert('$warning');
      }
   END
           } elsif ($numbuttons > 1) {
               $auth_update = <<"END";
      // initial password specified, pick internal authentication
      if (tf==8 && nw!=0) {
         changed_radio('int',document.studentform);
         set_auth_radio_buttons('int',document.studentform);
   $argreset
      }
   
   END
           }
       }
   
     return(<<ENDPICK);      return(<<ENDPICK);
 function verify(vf,sec_caller) {  function verify(vf,sec_caller) {
     var founduname=0;      var founduname=0;
Line 684  function verify(vf,sec_caller) { Line 1400  function verify(vf,sec_caller) {
     var foundname=0;      var foundname=0;
     var foundid=0;      var foundid=0;
     var foundsec=0;      var foundsec=0;
       var foundemail=0;
     var foundrole=0;      var foundrole=0;
     var founddomain=0;      var founddomain=0;
     var foundinststatus=0;      var foundinststatus=0;
       var foundcredits=0;
     var tw;      var tw;
     for (i=0;i<=vf.nfields.value;i++) {      for (i=0;i<=vf.nfields.value;i++) {
         tw=eval('vf.f'+i+'.selectedIndex');          tw=eval('vf.f'+i+'.selectedIndex');
Line 695  function verify(vf,sec_caller) { Line 1413  function verify(vf,sec_caller) {
         if (i==6 && tw!=0) { foundid=1; }          if (i==6 && tw!=0) { foundid=1; }
         if (i==7 && tw!=0) { foundsec=1; }          if (i==7 && tw!=0) { foundsec=1; }
         if (i==8 && tw!=0) { foundpwd=1; }          if (i==8 && tw!=0) { foundpwd=1; }
         if (i==9 && tw!=0) { foundrole=1; }          if (i==9 && tw!=0) { foundemail=1; }
         if (i==10 && tw!=0) { founddomain=1; }          if (i==10 && tw!=0) { foundrole=1; }
         if (i==13 && tw!=0) { foundinstatus=1; }          if (i==11 && tw!=0) { founddomain=1; }
           if (i==12 && tw!=0) { foundinstatus=1; }
           if (i==13 && tw!=0) { foundcredits=1; }
     }      }
     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundrole,founddomain,foundinststatus);      verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits);
 }  }
   
 function flip(vf,tf) {  function flip(vf,tf) {
Line 716  function flip(vf,tf) { Line 1436  function flip(vf,tf) {
    if ((tf>=2) && (tf<=5) && (nw!=0)) {     if ((tf>=2) && (tf<=5) && (nw!=0)) {
       eval('vf.f1.selectedIndex=0;')        eval('vf.f1.selectedIndex=0;')
    }     }
    // intial password specified, pick internal authentication     $auth_update
    if (tf==8 && nw!=0) {  
        changed_radio('int',document.studentform);  
        set_auth_radio_buttons('int',document.studentform);  
        vf.krbarg.value='';  
        vf.intarg.value='';  
        vf.locarg.value='';  
    }  
 }  }
   
 function clearpwd(vf) {  function clearpwd(vf) {
Line 738  ENDPICK Line 1451  ENDPICK
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub print_upload_manager_footer {  sub print_upload_manager_footer {
     my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission) = @_;      my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission,$crstype,
           $showcredits) = @_;
     my $form = 'document.studentform';      my $form = 'document.studentform';
     my $formname = 'studentform';      my $formname = 'studentform';
     my ($krbdef,$krbdefdom) =      my ($krbdef,$krbdefdom) =
Line 755  sub print_upload_manager_footer { Line 1469  sub print_upload_manager_footer {
     my $krbform = &Apache::loncommon::authform_kerberos(%param);      my $krbform = &Apache::loncommon::authform_kerberos(%param);
     my $intform = &Apache::loncommon::authform_internal(%param);      my $intform = &Apache::loncommon::authform_internal(%param);
     my $locform = &Apache::loncommon::authform_local(%param);      my $locform = &Apache::loncommon::authform_local(%param);
       my $ltiform = &Apache::loncommon::authform_lti(%param);
     my $date_table = &date_setting_table(undef,undef,$context,undef,      my $date_table = &date_setting_table(undef,undef,$context,undef,
                                          $formname,$permission);                                           $formname,$permission,$crstype);
   
     my $Str = "\n".'<div class="LC_left_float">';      my $Str = "\n".'<div class="LC_left_float">';
     $Str .= &hidden_input('nfields',$i);      $Str .= &hidden_input('nfields',$i);
     $Str .= &hidden_input('keyfields',$keyfields);      $Str .= &hidden_input('keyfields',$keyfields);
     $Str .= "<h3>".&mt('Login Type')."</h3>\n";  
       $Str .= '<h3>'.&mt('Options').'</h3>'
              .&Apache::lonhtmlcommon::start_pick_box();
   
       $Str .= &Apache::lonhtmlcommon::row_title(&mt('Login Type'));
     if ($context eq 'domain') {      if ($context eq 'domain') {
         $Str .= '<p>'.&mt('Change authentication for existing users in domain "[_1]" to these settings?',$defdom).'&nbsp;<span class="LC_nobreak"><label><input type="radio" name="changeauth" value="No" checked="checked" />'.&mt('No').'</label>&nbsp;&nbsp;<label><input type="radio" name="changeauth" value="Yes" />'.&mt('Yes').'</label></span></p>';           $Str .= '<p>'
                  .&mt('Change authentication for existing users in domain "[_1]" to these settings?'
                      ,$defdom)
                  .'&nbsp;<span class="LC_nobreak"><label>'
                  .'<input type="radio" name="changeauth" value="No" checked="checked" />'
                  .&mt('No').'</label>'
                  .'&nbsp;&nbsp;<label>'
                  .'<input type="radio" name="changeauth" value="Yes" />'
                  .&mt('Yes').'</label>'
                  .'</span></p>'; 
     } else {      } else {
         $Str .= "<p>\n".          $Str .= '<p class="LC_info">'."\n".
             &mt('Note: This will not take effect if the user already exists.').              &mt('This will not take effect if the user already exists.').
             &Apache::loncommon::help_open_topic('Auth_Options').              &Apache::loncommon::help_open_topic('Auth_Options').
             "</p>\n";              "</p>\n";
     }      }
     $Str .= &set_login($defdom,$krbform,$intform,$locform);      $Str .= &set_login($defdom,$krbform,$intform,$locform,$ltiform);
   
     my ($home_server_pick,$numlib) =      my ($home_server_pick,$numlib) =
         &Apache::loncommon::home_server_form_item($defdom,'lcserver',          &Apache::loncommon::home_server_form_item($defdom,'lcserver',
                                                   'default','hide');                                                    'default','hide');
     if ($numlib > 1) {      if ($numlib > 1) {
         $Str .= '<h3>'.&mt('LON-CAPA Home Server for New Users')."</h3>\n".          $Str .= &Apache::lonhtmlcommon::row_closure()
                 &mt('LON-CAPA domain: [_1] with home server: [_2]',$defdom,                 .&Apache::lonhtmlcommon::row_title(
                 $home_server_pick).'<br />';                      &mt('LON-CAPA Home Server for New Users'))
     } else {                 .&mt('LON-CAPA domain: [_1] with home server:','"'.$defdom.'"')
         $Str .= $home_server_pick;                 .$home_server_pick
     }                 .&Apache::lonhtmlcommon::row_closure();
     $Str .= '<h3>'.&mt('Default domain').'</h3>'."\n".      } else {
             &Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1);          $Str .= $home_server_pick.
     $Str .= '<h3>'.&mt('Starting and Ending Dates').                  &Apache::lonhtmlcommon::row_closure();
             "</h3>\n";  
     $Str .= "<p>\n".$date_table."</p>\n";  
     if ($context eq 'domain') {  
         $Str .= '<h3>'.&mt('Settings for assigning roles:').'</h3>'."\n".  
                 &mt('Pick the action to take on roles for these users:').'<br /><span class="LC_nobreak"><label><input type="radio" name="roleaction" value="norole" checked="checked" />&nbsp;'.&mt('No role changes').'</label>&nbsp;&nbsp;&nbsp;<label><input type="radio" name="roleaction" value="domain" />&nbsp;'.&mt('Add a domain role').'</label>&nbsp;&nbsp;&nbsp;<label><input type="radio" name="roleaction" value="course" />&nbsp;'.&mt('Add a course role').'</label></span>';  
     }      }
     if ($context eq 'author') {  
         $Str .= '<h3>'.&mt('Default role')."</h3>\n".      my ($trusted,$untrusted);
                 &mt('Choose the role to assign to users without a value specified in the uploaded file');      if ($context eq 'course') {
           ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom);
       } elsif ($context eq 'author') {
           ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('othcoau',$defdom);
       }
       $Str .= &Apache::lonhtmlcommon::row_title(&mt('Default domain'))
              .&Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1,undef,$trusted,$untrusted)
              .&Apache::lonhtmlcommon::row_closure();
   
       $Str .= &Apache::lonhtmlcommon::row_title(&mt('Starting and Ending Dates'))
              ."<p>\n".$date_table."</p>\n"
              .&Apache::lonhtmlcommon::row_closure();
   
       if ($context eq 'domain') {
           $Str .= &Apache::lonhtmlcommon::row_title(
                       &mt('Settings for assigning roles'))
                  .&mt('Pick the action to take on roles for these users:').'<br />'
                  .'<span class="LC_nobreak"><label>'
                  .'<input type="radio" name="roleaction" value="norole" checked="checked" />'
                  .'&nbsp;'.&mt('No role changes').'</label>'
                  .'&nbsp;&nbsp;&nbsp;<label>'
                  .'<input type="radio" name="roleaction" value="domain" />'
                  .'&nbsp;'.&mt('Add a domain role').'</label>'
                  .'&nbsp;&nbsp;&nbsp;<label>'
                  .'<input type="radio" name="roleaction" value="course" />'
                  .'&nbsp;'.&mt('Add a course/community role').'</label>'
                  .'</span>';
       } elsif ($context eq 'author') {
           $Str .= &Apache::lonhtmlcommon::row_title(
                       &mt('Default role'))
                  .&mt('Choose the role to assign to users without a value specified in the uploaded file.')
     } elsif ($context eq 'course') {      } elsif ($context eq 'course') {
         $Str .= '<h3>'.&mt('Default role and section')."</h3>\n".          if ($showcredits) {
                 &mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file');              $Str .= &Apache::lonhtmlcommon::row_title(
                       &mt('Default role, section and credits'))
                      .&mt('Choose the role and/or section(s) and/or credits to assign to users without values specified in the uploaded file.');
           } else { 
               $Str .= &Apache::lonhtmlcommon::row_title(
                       &mt('Default role and section'))
                      .&mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file.');
           }
     } else {      } else {
         $Str .= '<br /><br /><b>'.&mt('Default role and/or section(s)')."</b><br />\n".          $Str .= &Apache::lonhtmlcommon::row_title(
                 &mt('Role and/or section(s) for users without values specified in the uploaded file.');                      &mt('Default role and/or section(s)'))
                  .&mt('Role and/or section(s) for users without values specified in the uploaded file.');
     }      }
     $Str .= '<br />';  
     if (($context eq 'domain') || ($context eq 'author')) {      if (($context eq 'domain') || ($context eq 'author')) {
         my ($options,$cb_script,$coursepick) = &default_role_selector($context,1);          $Str .= '<br />';
           my ($options,$cb_script,$coursepick) = 
               &default_role_selector($context,1,'',$showcredits);
         if ($context eq 'domain') {          if ($context eq 'domain') {
             $Str .= '<span class="LC_role_level">'.&mt('Domain Level').'</span><br />'.$options.'<br /><br /><span class="LC_role_level">'.&mt('Course Level').'</span><br />'.$cb_script.$coursepick;              $Str .= '<p>'
                      .'<b>'.&mt('Domain Level').'</b><br />'
                      .$options
                      .'</p><p>'
                      .'<b>'.&mt('Course Level').'</b>'
                      .'</p>'
                      .$cb_script.$coursepick
                      .&Apache::lonhtmlcommon::row_closure();
         } elsif ($context eq 'author') {          } elsif ($context eq 'author') {
             $Str .= $options;              $Str .= $options
                      .&Apache::lonhtmlcommon::row_closure(1); # last row in pick_box
         }          }
     } else {      } else {
         my ($cnum,$cdom) = &get_course_identity();          my ($cnum,$cdom) = &get_course_identity();
         my $rowtitle = &mt('section');          my $rowtitle = &mt('section');
         my $secbox = &section_picker($cdom,$cnum,'Any',$rowtitle,          my $defaultcredits;
                                      $permission,$context,'upload');          if ($showcredits) {
         $Str .= $secbox."<h3>".&mt('Full Update')."</h3>\n".              $defaultcredits = &get_defaultcredits();
                 '<p><label><input type="checkbox" name="fullup" value="yes" />'.          }
                 ' '.&mt('Display students with current/future access who are not in the uploaded file.').'</label><br />'.&mt('Students selected from this list can be dropped.').'</p>'."\n";          my $secbox = &section_picker($cdom,$cnum,'Any',$rowtitle,$permission,
                                        $context,'upload',$crstype,$showcredits,
                                        $defaultcredits);
           $Str .= $secbox
                  .&Apache::lonhtmlcommon::row_closure();
           my %lt;
           if ($crstype eq 'Community') {
               %lt = &Apache::lonlocal::texthash (
                       disp => 'Display members with current/future access who are not in the uploaded file',
                       stus => 'Members selected from this list can be dropped.'
               );
           } else {
               %lt = &Apache::lonlocal::texthash (
                       disp => 'Display students with current/future access who are not in the uploaded file',
                       stus => 'Students selected from this list can be dropped.'
               );
           }
           $Str .= &Apache::lonhtmlcommon::row_title(&mt('Full Update'))
                  .'<label><input type="checkbox" name="fullup" value="yes" />'
                  .' '.$lt{'disp'}
                  .'</label><br />'
                  .$lt{'stus'}
                  .&Apache::lonhtmlcommon::row_closure();
     }      }
     if ($context eq 'course' || $context eq 'domain') {      if ($context eq 'course' || $context eq 'domain') {
         $Str .= &forceid_change($context);          $Str .= &Apache::lonhtmlcommon::row_title(&mt('Student/Employee ID'))
                  .&forceid_change($context)
                  .&Apache::lonhtmlcommon::row_closure(1); # last row in pick_box
     }      }
   
       $Str .= &Apache::lonhtmlcommon::end_pick_box();
     $Str .= '</div>';      $Str .= '</div>';
     $Str .= '<div class="LC_clear_float_footer">';  
       # Footer
       $Str .= '<div class="LC_clear_float_footer">'
              .'<hr />';
     if ($context eq 'course') {      if ($context eq 'course') {
         $Str .= '<div class="LC_info">'          $Str .= '<p class="LC_info">'
                .&mt('Note: For large courses, this operation may be time consuming.')                 .&mt('Note: This operation may be time consuming when adding several users.')
                .'</div>';                 .'</p>';
     }      }
     $Str .= '<input type="button"'      $Str .= '<p><input type="button"'
            .'onClick="javascript:verify(this.form,this.form.csec)" '             .' onclick="javascript:verify(this.form,this.form.csec)"'
            .'value="'.&mt('Update Users').'" />'."\n"             .' value="'.&mt('Update Users').'" />'
              .'</p>'."\n"
            .'</div>';             .'</div>';
     $r->print($Str);      $r->print($Str);
     return;      return;
 }  }
   
   sub get_defaultcredits {
       my ($cdom,$cnum) = @_;
        
       if ($cdom eq '' || $cnum eq '') {
           return unless ($env{'request.course.id'});
           $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       }
       return unless(($cdom =~ /^$match_domain$/) && ($cnum =~ /^$match_courseid$/)); 
       my ($defaultcredits,$domdefcredits);
       my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
       if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
           my $instcode = $env{'course.'.$cdom.'_'.$cnum.'.internal.coursecode'};
           if ($instcode) {
               $domdefcredits = $domdefaults{'officialcredits'};
           } elsif ($env{'course.'.$cdom.'_'.$cnum.'.internal.textbook'}) {
               $domdefcredits = $domdefaults{'textbookcredits'};
           } else {
               $domdefcredits = $domdefaults{'unofficialcredits'};
           }
       } else {
           return;
       }
   
       if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
           $defaultcredits = $env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'};
       } elsif (exists($env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'})) {
           $defaultcredits = $env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'};
       } else {
           my %crsinfo =
               &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1});
           $defaultcredits = $crsinfo{'internal.defaultcredits'};
       }
       if ($defaultcredits eq '') {
           $defaultcredits = $domdefcredits;
       }
       return $defaultcredits;
   }
   
 sub forceid_change {  sub forceid_change {
     my ($context) = @_;      my ($context) = @_;
     my $output =       my $output = 
         "<h3>".&mt('Student/Employee ID')."</h3>\n".          '<label><input type="checkbox" name="forceid" value="yes" />'
         "<p>\n".'<label><input type="checkbox" name="forceid" value="yes" />'.         .&mt('Force change of existing ID')
         &mt('Disable Student/Employee ID Safeguard and force change of conflicting IDs').         .'</label>'.&Apache::loncommon::help_open_topic('ForceIDChange')."\n";
         '</label><br />'."\n".  
         &mt('(only do if you know what you are doing.)')."\n";  
     if ($context eq 'domain') {      if ($context eq 'domain') {
         $output .= '<br /><label><input type="checkbox" name="recurseid"'.          $output .= 
                    ' value="yes" />'.               '<br />'
   &mt('Update Student/Employee ID in courses in which user is active/future student,[_1](if forcing change).','<br />').             .'<label><input type="checkbox" name="recurseid" value="yes" />'
                    '</label>'."\n";             .&mt("Update ID in user's course(s).").'</label>'."\n";
     }      }
     $output .= '</p>';  
     return $output;      return $output;
 }  }
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub print_upload_manager_form {  sub print_upload_manager_form {
     my ($r,$context,$permission) = @_;      my ($r,$context,$permission,$crstype,$showcredits) = @_;
     my $firstLine;      my $firstLine;
     my $datatoken;      my $datatoken;
     if (!$env{'form.datatoken'}) {      if (!$env{'form.datatoken'}) {
         $datatoken=&Apache::loncommon::upfile_store($r);          $datatoken=&Apache::loncommon::upfile_store($r);
     } else {      } else {
         $datatoken=$env{'form.datatoken'};          $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
         &Apache::loncommon::load_tmp_file($r);          if ($datatoken ne '') {
               &Apache::loncommon::load_tmp_file($r,$datatoken);
           }
       }
       if ($datatoken eq '') {
           $r->print('<p class="LC_error">'.&mt('Error').': '.
                     &mt('Invalid datatoken').'</p>');
           return 'missingdata';
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
     if($env{'form.noFirstLine'}){      if($env{'form.noFirstLine'}){
Line 888  sub print_upload_manager_form { Line 1733  sub print_upload_manager_form {
                                'domain_choice' => 'scalar',                                 'domain_choice' => 'scalar',
                                'inststatus_choice' => 'scalar',                                 'inststatus_choice' => 'scalar',
                              };                               };
     my $defdom = $env{'request.role.domain'};      if ($showcredits) {
           $col_setting_names->{'credits_choice'} = 'scalar';
       }
     if ($context eq 'course') {      if ($context eq 'course') {
         &Apache::loncommon::restore_course_settings('enrollment_upload',          &Apache::loncommon::restore_course_settings('enrollment_upload',
                                                     $col_setting_names);                                                      $col_setting_names);
Line 896  sub print_upload_manager_form { Line 1743  sub print_upload_manager_form {
         &Apache::loncommon::restore_settings($context,'user_upload',          &Apache::loncommon::restore_settings($context,'user_upload',
                                              $col_setting_names);                                               $col_setting_names);
     }      }
       my $defdom = $env{'request.role.domain'};
     #      #
     # Determine kerberos parameters as appropriate      # Determine kerberos parameters as appropriate
     my ($krbdef,$krbdefdom) =      my ($krbdef,$krbdefdom) =
         &Apache::loncommon::get_kerberos_defaults($defdom);          &Apache::loncommon::get_kerberos_defaults($defdom);
     #      #
       my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($defdom);
     &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context,      &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context,
                                  $permission);                                   $permission,$crstype,\%can_assign);
     my $i;      my $i;
     my $keyfields;      my $keyfields;
     if ($total>=0) {      if ($total>=0) {
Line 920  sub print_upload_manager_form { Line 1769  sub print_upload_manager_form {
              ['role',&mt('Role'),             $env{'form.role_choice'}],               ['role',&mt('Role'),             $env{'form.role_choice'}],
              ['domain',&mt('Domain'),         $env{'form.domain_choice'}],               ['domain',&mt('Domain'),         $env{'form.domain_choice'}],
              ['inststatus',&mt('Affiliation'), $env{'form.inststatus_choice'}]);               ['inststatus',&mt('Affiliation'), $env{'form.inststatus_choice'}]);
           if ($showcredits) {     
               push(@field,
                    ['credits',&mt('Student Credits'), $env{'form.credits_choice'}]);
           }
         if ($env{'form.upfile_associate'} eq 'reverse') {          if ($env{'form.upfile_associate'} eq 'reverse') {
             &Apache::loncommon::csv_print_samples($r,\@records);              &Apache::loncommon::csv_print_samples($r,\@records);
             $i=&Apache::loncommon::csv_print_select_table($r,\@records,              $i=&Apache::loncommon::csv_print_select_table($r,\@records,
Line 936  sub print_upload_manager_form { Line 1789  sub print_upload_manager_form {
             $keyfields=join(',',sort(keys(%sone)));              $keyfields=join(',',sort(keys(%sone)));
         }          }
     }      }
     $r->print('</div>');  
     &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,      &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
                                  $context,$permission);                                   $context,$permission,$crstype,$showcredits);
       return 'ok';
 }  }
   
 sub setup_date_selectors {  sub setup_date_selectors {
Line 1012  sub get_dates_from_form { Line 1865  sub get_dates_from_form {
 }  }
   
 sub date_setting_table {  sub date_setting_table {
     my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission) = @_;      my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission,$crstype) = @_;
     my $nolink;      my $nolink;
     if ($bulkaction) {      if ($bulkaction) {
         $nolink = 1;          $nolink = 1;
Line 1029  sub date_setting_table { Line 1882  sub date_setting_table {
             ($env{'form.action'} eq 'upload')) {              ($env{'form.action'} eq 'upload')) {
             if ($env{'request.course.sec'} eq '') {              if ($env{'request.course.sec'} eq '') {
                 $dateDefault = '<span class="LC_nobreak">'.                  $dateDefault = '<span class="LC_nobreak">'.
                     '<label><input type="checkbox" name="makedatesdefault" value="1" /> '.                      '<label><input type="checkbox" name="makedatesdefault" value="1" /> ';
                     &mt('make these dates the default access dates for future student enrollment').                  if ($crstype eq 'Community') {
                     '</label></span>';                      $dateDefault .= &mt("make these dates the default access dates for future community enrollment");
                   } else {
                       $dateDefault .= &mt("make these dates the default access dates for future course enrollment");
                   }
                   $dateDefault .= '</label></span>';
             }              }
         }          }
     }      }
Line 1060  sub date_setting_table { Line 1917  sub date_setting_table {
 }  }
   
 sub make_dates_default {  sub make_dates_default {
     my ($startdate,$enddate,$context) = @_;      my ($startdate,$enddate,$context,$crstype) = @_;
     my $result = '';      my $result = '';
     if ($context eq 'course') {      if ($context eq 'course') {
         my ($cnum,$cdom) = &get_course_identity();          my ($cnum,$cdom) = &get_course_identity();
Line 1068  sub make_dates_default { Line 1925  sub make_dates_default {
                 {'default_enrollment_start_date'=>$startdate,                  {'default_enrollment_start_date'=>$startdate,
                  'default_enrollment_end_date'  =>$enddate},$cdom,$cnum);                   'default_enrollment_end_date'  =>$enddate},$cdom,$cnum);
         if ($put_result eq 'ok') {          if ($put_result eq 'ok') {
             $result .= &mt('Set default start and end access dates for course.').              if ($crstype eq 'Community') {
                        '<br />'."\n";                  $result .= &mt('Set default start and end access dates for community.');
               } else {
                   $result .= &mt('Set default start and end access dates for course.');
               }
               $result .= '<br />'."\n";
             #              #
             # Refresh the course environment              # Refresh the course environment
             &Apache::lonnet::coursedescription($env{'request.course.id'},              &Apache::lonnet::coursedescription($env{'request.course.id'},
                                                {'freshen_cache' => 1});                                                 {'freshen_cache' => 1});
         } else {          } else {
             $result .= &mt('Unable to set default access dates for course.').":".$put_result.              if ($crstype eq 'Community') {
                        '<br />';                  $result .= &mt('Unable to set default access dates for community');
               } else {
                   $result .= &mt('Unable to set default access dates for course');
               }
               $result .= ':'.$put_result.'<br />';
         }          }
     }      }
     return $result;      return $result;
 }  }
   
 sub default_role_selector {  sub default_role_selector {
     my ($context,$checkpriv) = @_;      my ($context,$checkpriv,$crstype,$showcredits) = @_;
     my %customroles;      my %customroles;
     my ($options,$coursepick,$cb_jscript);      my ($options,$coursepick,$cb_jscript);
     if ($context ne 'author') {      if ($context ne 'author') {
         %customroles = &my_custom_roles();          %customroles = &my_custom_roles($crstype);
     }      }
   
     my %lt=&Apache::lonlocal::texthash(      my %lt=&Apache::lonlocal::texthash(
Line 1095  sub default_role_selector { Line 1960  sub default_role_selector {
                     'grs'  => "Section",                      'grs'  => "Section",
                     'exs'  => "Existing sections",                      'exs'  => "Existing sections",
                     'new'  => "New section",                      'new'  => "New section",
                       'crd'  => "Credits",
                   );                    );
     $options = '<select name="defaultrole">'."\n".      $options = '<select name="defaultrole">'."\n".
                ' <option value="">'.&mt('Please select').'</option>'."\n";                  ' <option value="">'.&mt('Please select').'</option>'."\n"; 
     if ($context eq 'course') {      if ($context eq 'course') {
         $options .= &default_course_roles($context,$checkpriv,%customroles);          $options .= &default_course_roles($context,$checkpriv,$crstype,%customroles);
     } elsif ($context eq 'author') {      } elsif ($context eq 'author') {
         my @roles = &construction_space_roles($checkpriv);          my @roles = &construction_space_roles($checkpriv);
         foreach my $role (@roles) {          foreach my $role (@roles) {
Line 1113  sub default_role_selector { Line 1979  sub default_role_selector {
            $options .= '  <option value="'.$role.'">'.$plrole.'</option>';             $options .= '  <option value="'.$role.'">'.$plrole.'</option>';
         }          }
         my $courseform = &Apache::loncommon::selectcourse_link          my $courseform = &Apache::loncommon::selectcourse_link
             ('studentform','dccourse','dcdomain','coursedesc',"$env{'request.role.domain'}",undef,'Course');              ('studentform','dccourse','dcdomain','coursedesc',"$env{'request.role.domain'}",undef,'Course/Community');
           my ($credit_elem,$creditsinput);
           if ($showcredits) {
               $credit_elem = 'credits';
               $creditsinput = '<td><input type="text" name="credits" value="" /></td>';
           }
         $cb_jscript =           $cb_jscript = 
             &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'currsec','studentform');              &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'currsec','studentform','courserole','Course/Community',$credit_elem);
         $coursepick = &Apache::loncommon::start_data_table().          $coursepick = &Apache::loncommon::start_data_table().
                       &Apache::loncommon::start_data_table_header_row().                        &Apache::loncommon::start_data_table_header_row().
                       '<th>'.$courseform.'</th><th>'.$lt{'rol'}.'</th>'.                        '<th>'.$courseform.'</th><th>'.$lt{'rol'}.'</th>'.
                       '<th>'.$lt{'grs'}.'</th>'.                        '<th>'.$lt{'grs'}.'</th>'.
                         '<th>'.$lt{'crd'}.'</th>'.
                       &Apache::loncommon::end_data_table_header_row().                        &Apache::loncommon::end_data_table_header_row().
                       &Apache::loncommon::start_data_table_row()."\n".                        &Apache::loncommon::start_data_table_row()."\n".
                       '<td><input type="text" name="coursedesc" value="" onFocus="this.blur();opencrsbrowser('."'studentform','dccourse','dcdomain','coursedesc',''".')" /></td>'."\n".                        '<td><input type="text" name="coursedesc" value="" onfocus="this.blur();opencrsbrowser('."'studentform','dccourse','dcdomain','coursedesc','','','','crstype'".')" /></td>'."\n".
                       '<td><select name="courserole">'."\n".                        '<td><select name="courserole">'."\n".
                       &default_course_roles($context,$checkpriv,%customroles)."\n".                        &default_course_roles($context,$checkpriv,'Course',%customroles)."\n".
                       '</select></td><td>'.                        '</select></td><td>'.
                       '<table class="LC_createuser">'.                        '<table class="LC_createuser">'.
                       '<tr class="LC_section_row"><td valign"top">'.                        '<tr class="LC_section_row"><td valign="top">'.
                       $lt{'exs'}.'<br /><select name="currsec">'.                        $lt{'exs'}.'<br /><select name="currsec">'.
                       ' <option value=""><--'.&mt('Pick course first').                        ' <option value="">&lt;--'.&mt('Pick course first').
                       '</select></td>'.                        '</select></td>'.
                       '<td>&nbsp;&nbsp;</td>'.                        '<td>&nbsp;&nbsp;</td>'.
                       '<td valign="top">'.$lt{'new'}.'<br />'.                        '<td valign="top">'.$lt{'new'}.'<br />'.
Line 1140  sub default_role_selector { Line 2012  sub default_role_selector {
                       $env{'request.role.domain'}.'" />'.                        $env{'request.role.domain'}.'" />'.
                       '<input type="hidden" name="dccourse" value="" />'.                        '<input type="hidden" name="dccourse" value="" />'.
                       '<input type="hidden" name="dcdomain" value="" />'.                        '<input type="hidden" name="dcdomain" value="" />'.
                       '</td></tr></table></td>'.                        '<input type="hidden" name="crstype" value="" />'.
                         '</td></tr></table></td>'.$creditsinput.
                       &Apache::loncommon::end_data_table_row().                        &Apache::loncommon::end_data_table_row().
                       &Apache::loncommon::end_data_table()."\n";                        &Apache::loncommon::end_data_table()."\n";
     }      }
Line 1149  sub default_role_selector { Line 2022  sub default_role_selector {
 }  }
   
 sub default_course_roles {  sub default_course_roles {
     my ($context,$checkpriv,%customroles) = @_;      my ($context,$checkpriv,$crstype,%customroles) = @_;
     my $output;      my $output;
     my $custom = 1;      my $custom = 1;
     my @roles = &course_roles($context,$checkpriv,$custom);      my @roles = &course_roles($context,$checkpriv,$custom,lc($crstype));
     foreach my $role (@roles) {      foreach my $role (@roles) {
         if ($role ne 'cr') {          if ($role ne 'cr') {
             my $plrole=&Apache::lonnet::plaintext($role);              my $plrole=&Apache::lonnet::plaintext($role,$crstype);
             $output .= '  <option value="'.$role.'">'.$plrole.'</option>';              $output .= '  <option value="'.$role.'">'.$plrole.'</option>';
         }          }
     }      }
Line 1179  sub construction_space_roles { Line 2052  sub construction_space_roles {
         foreach my $role (@allroles) {          foreach my $role (@allroles) {
             if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) {               if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) { 
                 push(@roles,$role);                   push(@roles,$role); 
               } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) {
                   my ($audom,$auname) = ($1,$2);
                   if (($role eq 'ca') || ($role eq 'aa')) {
                       if ((&Apache::lonnet::allowed('v'.$role,,$audom.'/'.$auname)) &&
                           ($env{"environment.internal.manager./$audom/$auname"})) {
                           push(@roles,$role);
                       }
                   }
             }              }
         }          }
         return @roles;          return @roles;
Line 1204  sub domain_roles { Line 2085  sub domain_roles {
 }  }
   
 sub course_roles {  sub course_roles {
     my ($context,$checkpriv,$custom) = @_;      my ($context,$checkpriv,$custom,$roletype) = @_;
     my @allroles = &roles_by_context('course',$custom);      my $crstype;
       if ($roletype eq 'community') {
           $crstype = 'Community' ;
       } else {
           $crstype = 'Course';
       }
       my @allroles = &roles_by_context('course',$custom,$crstype);
     my @roles;      my @roles;
     if ($context eq 'domain') {      if ($context eq 'domain') {
         @roles = @allroles;          @roles = @allroles;
Line 1216  sub course_roles { Line 2103  sub course_roles {
                     if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {                      if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
                         push(@roles,$role);                          push(@roles,$role);
                     } else {                      } else {
                         if ($role ne 'cc' && $env{'request.course.sec'} ne '') {                          if ((($role ne 'cc') && ($role ne 'co')) && ($env{'request.course.sec'} ne '')) {
                             if (&Apache::lonnet::allowed('c'.$role,                              if (&Apache::lonnet::allowed('c'.$role,
                                              $env{'request.course.id'}.'/'.                                               $env{'request.course.id'}.'/'.
                                              $env{'request.course.sec'})) {                                               $env{'request.course.sec'})) {
Line 1234  sub course_roles { Line 2121  sub course_roles {
 }  }
   
 sub curr_role_permissions {  sub curr_role_permissions {
     my ($context,$setting,$checkpriv) = @_;       my ($context,$setting,$checkpriv,$type) = @_; 
     my $custom = 1;      my $custom = 1;
     my @roles;      my @roles;
     if ($context eq 'author') {      if ($context eq 'author') {
         @roles = &construction_space_roles($checkpriv);          @roles = &construction_space_roles($checkpriv);
     } elsif ($context eq 'domain') {      } elsif ($context eq 'domain') {
         if ($setting eq 'course') {          if ($setting eq 'course') {
             @roles = &course_roles($context,$checkpriv,$custom);               @roles = &course_roles($context,$checkpriv,$custom,$type); 
         } else {          } else {
             @roles = &domain_roles($checkpriv);              @roles = &domain_roles($checkpriv);
         }          }
     } elsif ($context eq 'course') {      } elsif ($context eq 'course') {
         @roles = &course_roles($context,$checkpriv,$custom);          @roles = &course_roles($context,$checkpriv,$custom,$type);
     }      }
     return @roles;      return @roles;
 }  }
Line 1254  sub curr_role_permissions { Line 2141  sub curr_role_permissions {
 # ======================================================= Existing Custom Roles  # ======================================================= Existing Custom Roles
   
 sub my_custom_roles {  sub my_custom_roles {
       my ($crstype,$udom,$uname) = @_;
     my %returnhash=();      my %returnhash=();
     my %rolehash=&Apache::lonnet::dump('roles');      my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
     foreach my $key (keys %rolehash) {      my %rolehash=&Apache::lonnet::dump('roles',$udom,$uname);
       foreach my $key (keys(%rolehash)) {
         if ($key=~/^rolesdef\_(\w+)$/) {          if ($key=~/^rolesdef\_(\w+)$/) {
             $returnhash{$1}=$1;              my $role = $1;
               if ($crstype eq 'Community') {
                   next if ($rolehash{$key} =~ /bre\&S/); 
               }
               $returnhash{$role}=$role;
         }          }
     }      }
     return %returnhash;      return %returnhash;
Line 1266  sub my_custom_roles { Line 2159  sub my_custom_roles {
   
 sub print_userlist {  sub print_userlist {
     my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,      my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,
         $idlist,$idlist_titles) = @_;          $idlist,$idlist_titles,$showcredits) = @_;
     my $format = $env{'form.output'};      my $format = $env{'form.output'};
     if (! exists($env{'form.sortby'})) {      if (! exists($env{'form.sortby'})) {
         $env{'form.sortby'} = 'username';          $env{'form.sortby'} = 'username';
Line 1274  sub print_userlist { Line 2167  sub print_userlist {
     if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {      if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
         $env{'form.Status'} = 'Active';          $env{'form.Status'} = 'Active';
     }      }
       my $onchange = "javascript:updateCols('Status');";
     my $status_select = &Apache::lonhtmlcommon::StatusOptions      my $status_select = &Apache::lonhtmlcommon::StatusOptions
         ($env{'form.Status'});          ($env{'form.Status'},undef,undef,$onchange);
   
     if ($env{'form.showrole'} eq '') {      if ($env{'form.showrole'} eq '') {
         if ($context eq 'course') {          if ($context eq 'course') {
Line 1300  sub print_userlist { Line 2194  sub print_userlist {
         @statuses = ('future');          @statuses = ('future');
     }      }
   
 #    if ($context eq 'course') {   
 #        $r->print(&display_adv_courseroles());  
 #    }  
     #  
     # Interface output      # Interface output
     $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n".      $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n".
               '<input type="hidden" name="action" value="'.                '<input type="hidden" name="action" value="'.
               $env{'form.action'}.'" />');                $env{'form.action'}.'" />');
     $r->print("<p>\n");      $r->print('<div>'."\n");
     if ($env{'form.action'} ne 'modifystudent') {      if ($env{'form.action'} ne 'modifystudent') {
         my %lt=&Apache::lonlocal::texthash('csv' => "CSV",          my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
                                            'excel' => "Excel",                                             'excel' => "Excel",
                                            'html'  => 'HTML');                                             'html'  => 'HTML');
         my $output_selector = '<select size="1" name="output" >';          my $output_selector = '<select size="1" name="output" onchange="javascript:updateCols('."'output'".');" >';
         foreach my $outputformat ('html','csv','excel') {          foreach my $outputformat ('html','csv','excel') {
             my $option = '<option value="'.$outputformat.'" ';              my $option = '<option value="'.$outputformat.'"';
             if ($outputformat eq $env{'form.output'}) {              if ($outputformat eq $env{'form.output'}) {
                 $option .= 'selected ';                  $option .= ' selected="selected"';
             }              }
             $option .='>'.$lt{$outputformat}.'</option>';              $option .='>'.$lt{$outputformat}.'</option>';
             $output_selector .= "\n".$option;              $output_selector .= "\n".$option;
         }          }
         $output_selector .= '</select>';          $output_selector .= '</select>';
         $r->print('<label><span class="LC_nobreak">'          $r->print('<span class="LC_nobreak">'
                  .&mt('Output Format: [_1]',$output_selector)                   .&mt('Output Format: [_1]',$output_selector)
                  .'</span></label>'.('&nbsp;'x3));                   .'</span>'.('&nbsp;'x3));
     }      }
     $r->print('<label><span class="LC_nobreak">'      $r->print('<span class="LC_nobreak">'
              .&mt('User Status: [_1]',$status_select)               .&mt('User Status: [_1]',$status_select)
              .'</span></label>'.('&nbsp;'x3)."\n");               .'</span>'.('&nbsp;'x3)."\n");
     my $roleselected = '';      my $roleselected = '';
     if ($env{'form.showrole'} eq 'Any') {      if ($env{'form.showrole'} eq 'Any') {
        $roleselected = ' selected="selected" ';          $roleselected = ' selected="selected"'; 
     }      }
     my ($cnum,$cdom);      my ($cnum,$cdom);
     $r->print(&role_filter($context));      $r->print(&role_filter($context));
Line 1340  sub print_userlist { Line 2230  sub print_userlist {
         ($cnum,$cdom) = &get_course_identity();          ($cnum,$cdom) = &get_course_identity();
         $r->print(&section_group_filter($cnum,$cdom));          $r->print(&section_group_filter($cnum,$cdom));
     }      }
       $r->print('</div><div class="LC_left_float">'.
                 &column_checkboxes($context,$mode,$formname,$showcredits).
                 '</div>');
     if ($env{'form.phase'} eq '') {      if ($env{'form.phase'} eq '') {
         $r->print('<br /><br />'.&list_submit_button(&mt('Display List of Users')).          $r->print('<br clear="all" />'.
                   "\n</p>\n".                    &list_submit_button(&mt('Display List of Users'))."\n".
                   '<input type="hidden" name="phase" value="" /></form>');                    '<input type="hidden" name="phase" value="" /></form>');
         return;          return;
     }      }
     if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {      if (!(($context eq 'domain') && 
         $r->print('&nbsp;'.&list_submit_button(&mt('Update Display')).            (($env{'form.roletype'} eq 'course') || ($env{'form.roletype'} eq 'community')))) {
                   "\n</p>\n");          $r->print('<br clear="all" />'.
                     &list_submit_button(&mt('Update Display'))."\n");
       }
   
       my @cols = &infocolumns($context,$mode,$showcredits);  
       if (!@cols) {
            $r->print('<hr style="clear:both;" /><span class="LC_warning">'.
                      &mt('No user information selected for display.').'</span>'.
                      '<input type="hidden" name="phase" value="display" /></form>'."\n");
            return;
     }      }
     my ($indexhash,$keylist) = &make_keylist_array();      my ($indexhash,$keylist) = &make_keylist_array();
     my (%userlist,%userinfo);      my (%userlist,%userinfo,$clearcoursepick,$needauthorquota,$needauthorusage);
     if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {      if (($context eq 'domain') && 
           ($env{'form.roletype'} eq 'course') || 
           ($env{'form.roletype'} eq 'community')) {
           my ($crstype,$numcodes,$title,$warning);
           if ($env{'form.roletype'} eq 'course') {
               $crstype = 'Course';
               $numcodes = $totcodes;
               $title = &mt('Select Courses');
               $warning = &mt('Warning: data retrieval for multiple courses can take considerable time, as this operation is not currently optimized.');
           } elsif ($env{'form.roletype'} eq 'community') {
               $crstype = 'Community';
               $numcodes = 0;
               $title = &mt('Select Communities');
               $warning = &mt('Warning: data retrieval for multiple communities can take considerable time, as this operation is not currently optimized.');
           }
           my @standardnames = &Apache::loncommon::get_standard_codeitems();
         my $courseform =          my $courseform =
             &Apache::lonhtmlcommon::course_selection($formname,$totcodes,              &Apache::lonhtmlcommon::course_selection($formname,$numcodes,
                                          $codetitles,$idlist,$idlist_titles);                              $codetitles,$idlist,$idlist_titles,$crstype,
         $r->print('<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n".                              \@standardnames);
                   &Apache::lonhtmlcommon::start_pick_box()."\n".          $r->print('<div class="LC_left_float">'.
                   &Apache::lonhtmlcommon::row_title(&mt('Select Course(s)'),                    '<fieldset><legend>'.$title.'</legend>'."\n".
                                                     'LC_oddrow_value')."\n".  
                   $courseform."\n".                    $courseform."\n".
                   &Apache::lonhtmlcommon::row_closure(1).                    '</fieldset></div><br clear="all" />'.
                   &Apache::lonhtmlcommon::end_pick_box().'</p>'.                    '<p><input type="hidden" name="origroletype" value="'.$env{'form.roletype'}.'" />'.
                   '<p>'.&list_submit_button(&mt('Update Display')).                    &list_submit_button(&mt('Update Display')).
                   "\n".'</p><span class="LC_warning">'.&mt('Warning: data retrieval for multiple courses can take considerable time, as this operation is not currently optimized.').'</span>'."\n");                    "\n".'</p><span class="LC_warning">'.$warning.'</span>'."\n");
         if ($env{'form.coursepick'}) {          $clearcoursepick = 0;
             $r->print('<hr />'.&mt('Searching').' ...<br />&nbsp;<br />');          if (($env{'form.origroletype'} ne '') &&
               ($env{'form.origroletype'} ne $env{'form.roletype'})) {
               $clearcoursepick = 1;
           }
           if (($env{'form.coursepick'}) && (!$clearcoursepick)) {
               $r->print('<hr />'.&mt('Searching ...').'<br />&nbsp;<br />');
         }          }
     } else {      } else {
         $r->print('<hr />'.&mt('Searching').' ...<br />&nbsp;<br />');          $r->print('<hr style="clear:both;" /><div id="searching">'.&mt('Searching ...').'</div>');
     }      }
     $r->rflush();      $r->rflush();
     if ($context eq 'course') {      if ($context eq 'course') {
Line 1396  sub print_userlist { Line 2317  sub print_userlist {
     } else {      } else {
         my (%cstr_roles,%dom_roles);          my (%cstr_roles,%dom_roles);
         if ($context eq 'author') {          if ($context eq 'author') {
             # List co-authors and assistant co-authors  
             my @possroles = &roles_by_context($context);              my @possroles = &roles_by_context($context);
             %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,              my @allowedroles;
                                               \@statuses,\@possroles);              # List co-authors and assistant co-authors
             &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,              my ($auname,$audom);
                              \%cstr_roles,$permission);              if ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) {
                   ($audom,$auname) = ($1,$2);
                   foreach my $role (@possroles) {
                       if ((&Apache::lonnet::allowed('v'.$role,"$audom/$auname")) ||
                           (&Apache::lonnet::allowed('c'.$role,"$audom/$auname"))) {
                           push(@allowedroles,$role);
                       }
                   }
               } elsif ($env{'request.role'} =~ m{^au\./($match_domain)/}) {
                   if ($1 eq $env{'user.domain'}) {
                       $auname = $env{'user.name'};
                       $audom = $env{'user.domain'};
                   }
                   @allowedroles = @possroles;
               }
               if (($auname ne '') && ($audom ne '')) {
                   %cstr_roles = &Apache::lonnet::get_my_roles($auname,$audom,undef,
                                                               \@statuses,\@allowedroles);
                   &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
                                    \%cstr_roles,$permission);
               }
         } elsif ($context eq 'domain') {          } elsif ($context eq 'domain') {
             if ($env{'form.roletype'} eq 'domain') {              if ($env{'form.roletype'} eq 'domain') {
                   if (grep(/^authorusage$/,@cols)) {
                       $needauthorusage = 1;
                   }
                   if (grep(/^authorquota$/,@cols)) {
                       $needauthorquota = 1;
                   }
                 %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'});                  %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'});
                 foreach my $key (keys(%dom_roles)) {                  foreach my $key (keys(%dom_roles)) {
                     if (ref($dom_roles{$key}) eq 'HASH') {                      if (ref($dom_roles{$key}) eq 'HASH') {
Line 1438  sub print_userlist { Line 2384  sub print_userlist {
                         }                          }
                     }                      }
                 }                  }
             } elsif ($env{'form.roletype'} eq 'course') {              } elsif (($env{'form.roletype'} eq 'course') ||
                 if ($env{'form.coursepick'}) {                       ($env{'form.roletype'} eq 'community')) {
                   if (($env{'form.coursepick'}) && (!$clearcoursepick)) {
                     my %courses = &process_coursepick();                      my %courses = &process_coursepick();
                     my %allusers;                      my %allusers;
                     my $hidepriv = 1;                      my $hidepriv = 1;
Line 1450  sub print_userlist { Line 2397  sub print_userlist {
                         my (@roles,@sections,%access,%users,%userdata,                          my (@roles,@sections,%access,%users,%userdata,
                             %statushash);                              %statushash);
                         if ($env{'form.showrole'} eq 'Any') {                          if ($env{'form.showrole'} eq 'Any') {
                             @roles = &course_roles($context,undef,$custom);                              @roles = &course_roles($context,undef,$custom,
                                                      $env{'form.roletype'});
                         } else {                          } else {
                             @roles = ($env{'form.showrole'});                              @roles = ($env{'form.showrole'});
                         }                          }
Line 1487  sub print_userlist { Line 2435  sub print_userlist {
         }          }
     }      }
     if (keys(%userlist) == 0) {      if (keys(%userlist) == 0) {
           my $msg = '';
         if ($context eq 'author') {          if ($context eq 'author') {
             $r->print(&mt('There are no co-authors to display.')."\n");              $msg = &mt('There are no co-authors to display.');
         } elsif ($context eq 'domain') {          } elsif ($context eq 'domain') {
             if ($env{'form.roletype'} eq 'domain') {              if ($env{'form.roletype'} eq 'domain') {
                 $r->print(&mt('There are no users with domain roles to display.')."\n");                  $msg = &mt('There are no users with domain roles to display.');
             } elsif ($env{'form.roletype'} eq 'author') {              } elsif ($env{'form.roletype'} eq 'author') {
                 $r->print(&mt('There are no authors or co-authors to display.')."\n");                  $msg = &mt('There are no authors or co-authors to display.');
             } elsif ($env{'form.roletype'} eq 'course') {              } elsif ($env{'form.roletype'} eq 'course') {
                 $r->print(&mt('There are no course users to display')."\n");                   $msg = &mt('There are no course users to display');
               } elsif ($env{'form.roletype'} eq 'community') {
                   $msg = &mt('There are no community users to display');
             }              }
         } elsif ($context eq 'course') {          } elsif ($context eq 'course') {
             $r->print(&mt('There are no course users to display.')."\n");              $r->print(&mt('There are no course users to display.')."\n");
         }          }
           $r->print('<p class="LC_info">'.$msg.'</p>'."\n") if $msg;
     } else {      } else {
         # Print out the available choices          # Print out the available choices
         my $usercount;          my $usercount;
         if ($env{'form.action'} eq 'modifystudent') {          if ($env{'form.action'} eq 'modifystudent') {
             ($usercount) = &show_users_list($r,$context,'view',$permission,              ($usercount) = &show_users_list($r,$context,'view',$permission,
                                  $env{'form.Status'},\%userlist,$keylist);                                   $env{'form.Status'},\%userlist,$keylist,'',
                                    $showcredits);
         } else {          } else {
             ($usercount) = &show_users_list($r,$context,$env{'form.output'},              ($usercount) = &show_users_list($r,$context,$env{'form.output'},
                                $permission,$env{'form.Status'},\%userlist,$keylist);                                 $permission,$env{'form.Status'},\%userlist,
                                  $keylist,'',$showcredits,$needauthorquota,$needauthorusage);
         }          }
         if (!$usercount) {          if (!$usercount) {
             $r->print('<br /><span class="LC_warning">'              $r->print('<br /><span class="LC_info">'
                      .&mt('There are no users matching the search criteria.')                       .&mt('There are no users matching the search criteria.')
                      .'</span>'                       .'</span>'
             );               ); 
Line 1519  sub print_userlist { Line 2473  sub print_userlist {
     }      }
     $r->print('<input type="hidden" name="phase" value="'.      $r->print('<input type="hidden" name="phase" value="'.
               $env{'form.phase'}.'" /></form>');                $env{'form.phase'}.'" /></form>');
       return;
 }  }
   
 sub role_filter {  sub role_filter {
Line 1526  sub role_filter { Line 2481  sub role_filter {
     my $output;      my $output;
     my $roleselected = '';      my $roleselected = '';
     if ($env{'form.showrole'} eq 'Any') {      if ($env{'form.showrole'} eq 'Any') {
        $roleselected = ' selected="selected" ';         $roleselected = ' selected="selected"';
     }      }
     my ($role_select);      my ($role_select);
     if ($context eq 'domain') {      if ($context eq 'domain') {
         $role_select = &domain_roles_select();          $role_select = &domain_roles_select();
         $output = '<label><span class="LC_nobreak">'          $output = '<span class="LC_nobreak">'
                  .&mt('Role Type: [_1]',$role_select)                   .&mt('Role Type: [_1]',$role_select)
                  .'</span></label>';                   .'</span>';
     } else {      } else {
         $role_select = '<select name="showrole">'."\n".          $role_select = '<select name="showrole" onchange="javascript:updateCols('."'showrole'".');">'."\n".
                        '<option value="Any" '.$roleselected.'>'.                         '<option value="Any" '.$roleselected.'>'.
                        &mt('Any role').'</option>';                         &mt('Any role').'</option>';
         my @poss_roles = &curr_role_permissions($context);          my ($roletype,$crstype);
           if ($context eq 'course') {
               $crstype = &Apache::loncommon::course_type();
               if ($crstype eq 'Community') {
                   $roletype = 'community';
               } else {
                   $roletype = 'course';
               } 
           }
           my @poss_roles = &curr_role_permissions($context,'','',$roletype);
         foreach my $role (@poss_roles) {          foreach my $role (@poss_roles) {
             $roleselected = '';              $roleselected = '';
             if ($role eq $env{'form.showrole'}) {              if ($role eq $env{'form.showrole'}) {
                 $roleselected = ' selected="selected" ';                  $roleselected = ' selected="selected"';
             }              }
             my $plrole;              my $plrole;
             if ($role eq 'cr') {              if ($role eq 'cr') {
                 $plrole = &mt('Custom role');                  $plrole = &mt('Custom role');
             } else {              } else {
                 $plrole=&Apache::lonnet::plaintext($role);                  $plrole=&Apache::lonnet::plaintext($role,$crstype);
             }              }
             $role_select .= '<option value="'.$role.'"'.$roleselected.'>'.$plrole.'</option>';              $role_select .= '<option value="'.$role.'"'.$roleselected.'>'.$plrole.'</option>';
         }          }
         $role_select .= '</select>';          $role_select .= '</select>';
         $output = '<label><span class="LC_nobreak">'          $output = '<span class="LC_nobreak">'
                  .&mt('Role: [_1]',$role_select)                   .&mt('Role: [_1]',$role_select)
                  .'</span></label>';                   .'</span>';
     }      }
     return $output;      return $output;
 }  }
Line 1584  sub section_group_filter { Line 2548  sub section_group_filter {
             $env{'form.'.$name{$item}} = 'all';              $env{'form.'.$name{$item}} = 'all';
         }          }
         if ($item eq 'sec') {          if ($item eq 'sec') {
             if ($env{'form.showrole'} eq 'cc') {              if (($env{'form.showrole'} eq 'cc') || ($env{'form.showrole'} eq 'co')) {
                 $env{'form.'.$name{$item}} = 'none';                  $env{'form.'.$name{$item}} = 'none';
             }              }
             my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);              my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
Line 1595  sub section_group_filter { Line 2559  sub section_group_filter {
         }          }
         if (@options > 0) {          if (@options > 0) {
             my $currsel;              my $currsel;
             $markup = '<select name="'.$name{$item}.'" />'."\n";              $markup = '<select name="'.$name{$item}.'">'."\n";
             foreach my $option ('all','none',@options) {               foreach my $option ('all','none',@options) { 
                 $currsel = '';                  $currsel = '';
                 if ($env{'form.'.$name{$item}} eq $option) {                  if ($env{'form.'.$name{$item}} eq $option) {
                     $currsel = ' selected="selected" ';                      $currsel = ' selected="selected"';
                 }                  }
                 $markup .= ' <option value="'.$option.'"'.$currsel.'>';                  $markup .= ' <option value="'.$option.'"'.$currsel.'>';
                 if (($option eq 'all') || ($option eq 'none')) {                  if (($option eq 'all') || ($option eq 'none')) {
Line 1610  sub section_group_filter { Line 2574  sub section_group_filter {
                 $markup .= '</option>'."\n";                  $markup .= '</option>'."\n";
             }              }
             $markup .= '</select>'."\n";              $markup .= '</select>'."\n";
             $output .= ('&nbsp;'x3).'<label>'.$title{$item}.': '.$markup.'</label>';              $output .= ('&nbsp;'x3).'<span class="LC_nobreak">'
                         .'<label>'.$title{$item}.': '.$markup.'</label>'
                         .'</span> ';
         }          }
     }      }
     return $output;      return $output;
 }  }
   
   sub infocolumns {
       my ($context,$mode,$showcredits) = @_;
       my @cols;
       if (($mode eq 'pickauthor') || ($mode eq 'autoenroll')) {
           @cols = &get_cols_array($context,$mode,$showcredits);
       } else {
           my @posscols = &get_cols_array($context,$mode,$showcredits);
           if ($env{'form.phase'} ne '') {
               my @checkedcols = &Apache::loncommon::get_env_multiple('form.showcol');
               foreach my $col (@checkedcols) {
                   if (grep(/^$col$/,@posscols)) {
                       push(@cols,$col);
                   }
               }
           } else {
               @cols = @posscols;
           }
       }
       return @cols;
   }
   
   sub get_cols_array {
       my ($context,$mode,$showcredits) = @_;
       my @cols;
       if ($mode eq 'pickauthor') {
           @cols = ('username','fullname','status','email');
       } else {
           @cols = ('username','domain','id','fullname');
           if ($context eq 'course') {
               push(@cols,'section');
           }
           push(@cols,('start','end','role'));
           unless (($mode eq 'autoenroll') && ($env{'form.Status'} ne 'Any')) {
               push(@cols,'status');
           }
           if ($context eq 'course') {
               push(@cols,'groups');
           }
           push(@cols,'email');
           if (($context eq 'course') && ($mode ne 'autoenroll')) {
               if ($showcredits) {
                   push(@cols,'credits');
               }
               push(@cols,'lastlogin','clicker');
           }
           if (($context eq 'course') && ($mode ne 'autoenroll') &&
               ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) {
               push(@cols,'photo');
           }
           if ($context eq 'domain') {
               push (@cols,('authorusage','authorquota','extent'));
           }
       }
       return @cols;
   }
   
   sub column_checkboxes {
       my ($context,$mode,$formname,$showcredits) = @_;
       my @cols = &get_cols_array($context,$mode,$showcredits);
       my @showncols = &Apache::loncommon::get_env_multiple('form.showcol');
       my (%disabledchk,%unchecked);
       if ($env{'form.phase'} eq '') {
           $disabledchk{'status'} = 1;
           if ($context eq 'course') {
               $disabledchk{'role'} = 1;
               $unchecked{'photo'} = 1;
               $unchecked{'clicker'} = 1;
               if ($showcredits) {
                   $unchecked{'credits'} = 1;
               }
           } elsif ($context eq 'domain') { 
               $unchecked{'extent'} = 1; 
           }
           $unchecked{'start'} = 1;
           $unchecked{'end'} = 1;
       } else {
           if ($env{'form.Status'} ne 'Any') {
               $disabledchk{'status'} = 1;
           }
           if (($env{'form.showrole'} ne 'Any') && ($env{'form.showrole'} ne 'cr')) {
               $disabledchk{'role'} = 1;
           }
           if ($context eq 'domain') {
               if (($env{'form.roletype'} eq 'course') || 
                   ($env{'form.roletype'} eq 'community')) {
                   $disabledchk{'status'} = 1;
                   $disabledchk{'authorusage'} = 1;
                   $disabledchk{'authorquota'} = 1;
               } elsif ($env{'form.roletype'} eq 'domain') {
                   $disabledchk{'extent'} = 1; 
               }
           }
       }
       my $numposs = scalar(@cols);
       my $numinrow = 7;
       my %lt = &get_column_names($context);
       my $output = '<fieldset><legend>'.&mt('Information to show').'</legend>'."\n".'<span class="LC_nobreak">'.
                    '<input type="button" onclick="javascript:checkAll(document.'.$formname.'.showcol);" value="'.&mt('check all').'" />'.
                    ('&nbsp;'x3).
                    '<input type="button" onclick="javascript:uncheckAll(document.'.$formname.'.showcol);" value="'.&mt('uncheck all').'" />'.
                    '</span><table>';
       
       for (my $i=0; $i<$numposs; $i++) {
           my $rem = $i%($numinrow);
           if ($rem == 0) {
               if ($i > 0) {
                   $output .= '</tr>';
               }
               $output .= '<tr>';
           }
           my $checked;
           if ($env{'form.phase'} eq '') {
               $checked = ' checked="checked"';
               if ($unchecked{$cols[$i]}) { 
                  $checked = '';
               }
               if ($disabledchk{$cols[$i]}) {
                   $checked = ' disabled="disabled"';
               }
           } elsif (grep(/^\Q$cols[$i]\E$/,@showncols)) {
               $checked = ' checked="checked"';
           } elsif ($disabledchk{$cols[$i]}) {
               $checked = ' disabled="disabled"';
           }
           if ($i == $numposs-1) {
               my $colsleft = $numinrow-$rem;
               if ($colsleft > 1) {
                   $output .= '<td colspan="'.$colsleft.'">';
               } else {
                   $output .= '<td>';
               }
           } else {
               $output .= '<td>';
           }
           my $style;
           if ($cols[$i] eq 'extent') {
               if (($env{'form.roletype'} eq 'domain') || ($env{'form.roletype'} eq '')) {
                   $style = ' style="display: none;"';
               } 
           } elsif (($cols[$i] eq 'authorusage') || ($cols[$i] eq 'authorquota')) {
               if ($env{'form.roletype'} ne 'domain') {
                   $style = ' style="display: none;"';
               }
           }
           $output .= '<span id="show'.$cols[$i].'"'.$style.'><label>'.
                      '<input id="showcol'.$cols[$i].'" type="checkbox" name="showcol" value="'.$cols[$i].'"'.$checked.' /><span id="showcoltext'.$cols[$i].'">'.
                      $lt{$cols[$i]}.'</span>'.
                      '</label></span></td>';
       }
       $output .= '</tr></table></fieldset>';
       return $output;
   }
   
 sub list_submit_button {  sub list_submit_button {
     my ($text) = @_;      my ($text) = @_;
     return '<input type="button" name="updatedisplay" value="'.$text.'" onclick="javascript:display_update()" />';      return '<input type="button" name="updatedisplay" value="'.$text.'" onclick="javascript:display_update()" />';
 }  }
   
   sub get_column_names {
       my ($context) = @_;
       my %lt = &Apache::lonlocal::texthash(
           'username'   => "username",
           'domain'     => "domain",
           'id'         => 'ID',
           'fullname'   => "name",
           'section'    => "section",
           'groups'     => "active groups",
           'start'      => "start date",
           'end'        => "end date",
           'status'     => "status",
           'role'       => "role",
           'credits'    => "credits",
           'type'       => "enroll type/action",
           'email'      => "e-mail address",
           'photo'      => "photo",
           'lastlogin'  => "last login",
           'extent'     => "extent",
           'authorusage' => "disk usage (%)",
           'authorquota' => "disk quota (MB)",
           'ca'         => "check all",
           'ua'         => "uncheck all",
           'clicker'    => "clicker-ID",
       );
       if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
           $lt{'extent'} = &mt('course(s): description, section(s), status');
       } elsif ($context eq 'domain' && $env{'form.roletype'} eq 'community') {
           $lt{'extent'} = &mt('community(s): description, section(s), status');
       } elsif (($context eq 'author') || 
                ($context eq 'domain' && $env{'form.roletype'} eq 'author')) {
           $lt{'extent'} = &mt('author');
       }
       return %lt;
   }
   
 sub gather_userinfo {  sub gather_userinfo {
     my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_;      my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_;
     my $viewablesec;      my $viewablesec;
Line 1663  sub gather_userinfo { Line 2818  sub gather_userinfo {
                                            $indexhash,$uniqid,$userlist);                                             $indexhash,$uniqid,$userlist);
                     }                      }
                 }                  }
             } elsif ($env{'form.roletype'} eq 'course') {              } elsif (($env{'form.roletype'} eq 'course') || 
                        ($env{'form.roletype'} eq 'community')) {
                 ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =                  ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
                     split(/:/,$item);                      split(/:/,$item);
                 if (ref($rolehash->{$item}) eq 'HASH') {                  if (ref($rolehash->{$item}) eq 'HASH') {
Line 1713  sub gather_userinfo { Line 2869  sub gather_userinfo {
 sub build_user_record {  sub build_user_record {
     my ($context,$userdata,$userinfo,$indexhash,$record_key,$userlist) = @_;      my ($context,$userdata,$userinfo,$indexhash,$record_key,$userlist) = @_;
     next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1');      next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1');
     if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {      if (!(($context eq 'domain') && (($env{'form.roletype'} eq 'course')
                                && ($env{'form.roletype'} eq 'community')))) {
         &process_date_info($userdata);          &process_date_info($userdata);
     }      }
     my $username = $userdata->{'username'};      my $username = $userdata->{'username'};
Line 1736  sub build_user_record { Line 2893  sub build_user_record {
   
 sub courses_selector {  sub courses_selector {
     my ($cdom,$formname) = @_;      my ($cdom,$formname) = @_;
     my %coursecodes = ();  
     my %codes = ();      my %codes = ();
     my @codetitles = ();      my @codetitles = ();
     my %cat_titles = ();      my %cat_titles = ();
Line 1749  sub courses_selector { Line 2905  sub courses_selector {
     my $jscript = '';      my $jscript = '';
   
     my $totcodes = 0;      my $totcodes = 0;
     $totcodes =      my $instcats = &Apache::lonnet::get_dom_instcats($cdom);
         &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,      if (ref($instcats) eq 'HASH') {
                                                       $cdom,$totcodes);          if ((ref($instcats->{'codetitles'}) eq 'ARRAY') && (ref($instcats->{'codes'}) eq 'HASH') &&
     if ($totcodes > 0) {              (ref($instcats->{'cat_titles'}) eq 'HASH') && (ref($instcats->{'cat_order'}) eq 'HASH')) {
         $format_reply =              %codes = %{$instcats->{'codes'}};
              &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,              @codetitles = @{$instcats->{'codetitles'}};
                                 \%codes,\@codetitles,\%cat_titles,\%cat_order);              %cat_titles = %{$instcats->{'cat_titles'}};
         if ($format_reply eq 'ok') {              %cat_order = %{$instcats->{'cat_order'}};
               $totcodes = scalar(keys(%codes));
             my $numtypes = @codetitles;              my $numtypes = @codetitles;
             &Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);              &Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
             my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);              my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);
Line 1764  sub courses_selector { Line 2921  sub courses_selector {
             my $allidlist = $idlist{$codetitles[0]};              my $allidlist = $idlist{$codetitles[0]};
             $jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist);              $jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist);
             $jscript .= $scripttext;              $jscript .= $scripttext;
             $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,@codetitles);              $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,\@codetitles);
         }          }
     }      }
     my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);      my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
Line 1782  function setCourseCat(formname) { Line 2939  function setCourseCat(formname) {
     if (formname.Year.options[formname.Year.selectedIndex].value == -1) {      if (formname.Year.options[formname.Year.selectedIndex].value == -1) {
         return;          return;
     }      }
     courseSet('Year');      courseSet('$codetitles[0]');
     for (var j=0; j<formname.Semester.length; j++) {      for (var j=0; j<formname.Semester.length; j++) {
         if (formname.Semester.options[j].value == "$env{'form.Semester'}") {          if (formname.Semester.options[j].value == "$env{'form.Semester'}") {
             formname.Semester.options[j].selected = true;              formname.Semester.options[j].selected = true;
Line 1791  function setCourseCat(formname) { Line 2948  function setCourseCat(formname) {
     if (formname.Semester.options[formname.Semester.selectedIndex].value == -1) {      if (formname.Semester.options[formname.Semester.selectedIndex].value == -1) {
         return;          return;
     }      }
     courseSet('Semester');      courseSet('$codetitles[1]');
     for (var j=0; j<formname.Department.length; j++) {      for (var j=0; j<formname.Department.length; j++) {
         if (formname.Department.options[j].value == "$env{'form.Department'}") {            formname.Department.options[j].selected = true;          if (formname.Department.options[j].value == "$env{'form.Department'}") {
               formname.Department.options[j].selected = true;
         }          }
     }      }
     if (formname.Department.options[formname.Department.selectedIndex].value == -1) {      if (formname.Department.options[formname.Department.selectedIndex].value == -1) {
         return;          return;
     }      }
     courseSet('Department');      courseSet('$codetitles[2]');
     for (var j=0; j<formname.Number.length; j++) {      for (var j=0; j<formname.Number.length; j++) {
         if (formname.Number.options[j].value == "$env{'form.Number'}") {          if (formname.Number.options[j].value == "$env{'form.Number'}") {
             formname.Number.options[j].selected = true;              formname.Number.options[j].selected = true;
Line 1828  sub process_coursepick { Line 2986  sub process_coursepick {
     my $coursefilter = $env{'form.coursepick'};      my $coursefilter = $env{'form.coursepick'};
     my $cdom = $env{'request.role.domain'};      my $cdom = $env{'request.role.domain'};
     my %courses;      my %courses;
       my $crssrch = 'Course';
       if ($env{'form.roletype'} eq 'community') {
           $crssrch = 'Community';
       }
     if ($coursefilter eq 'all') {      if ($coursefilter eq 'all') {
         %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.',          %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.',
                                                  undef,undef,'Course');                                                   undef,undef,$crssrch);
     } elsif ($coursefilter eq 'category') {      } elsif ($coursefilter eq 'category') {
         my $instcode = &instcode_from_coursefilter();          my $instcode = &instcode_from_coursefilter();
         %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.',          %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.',
                                                  undef,undef,'Course');                                                   undef,undef,$crssrch);
     } elsif ($coursefilter eq 'specific') {      } elsif ($coursefilter eq 'specific') {
         if ($env{'form.coursetotal'} > 1) {          if ($env{'form.coursetotal'} > 1) {
             my @course_ids = split(/&&/,$env{'form.courselist'});              my @course_ids = split(/&&/,$env{'form.courselist'});
Line 1864  sub instcode_from_coursefilter { Line 3026  sub instcode_from_coursefilter {
     return $instcode;      return $instcode;
 }  }
   
 sub display_adv_courseroles {  
     my $output;  
     #  
     # List course personnel  
     my %coursepersonnel =   
        &Apache::lonnet::get_course_adv_roles($env{'request.course.id'});  
     #  
     $output = '<br />'.&Apache::loncommon::start_data_table();  
     foreach my $role (sort(keys(%coursepersonnel))) {  
         next if ($role =~ /^\s*$/);  
         $output .= &Apache::loncommon::start_data_table_row().  
                   '<td>'.$role.'</td><td>';  
         foreach my $user (split(',',$coursepersonnel{$role})) {  
             my ($puname,$pudom)=split(':',$user);  
             $output .= ' '.&Apache::loncommon::aboutmewrapper(  
                        &Apache::loncommon::plainname($puname,$pudom),  
                        $puname,$pudom);  
         }  
         $output .= '</td>'.&Apache::loncommon::end_data_table_row();  
     }  
     $output .= &Apache::loncommon::end_data_table();  
 }  
   
 sub make_keylist_array {  sub make_keylist_array {
     my ($index,$keylist);      my ($index,$keylist);
     $index->{'domain'} = &Apache::loncoursedata::CL_SDOM();      $index->{'domain'} = &Apache::loncoursedata::CL_SDOM();
Line 1905  sub make_keylist_array { Line 3044  sub make_keylist_array {
     $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();      $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();
     $index->{'photo'} = &Apache::loncoursedata::CL_PHOTO();      $index->{'photo'} = &Apache::loncoursedata::CL_PHOTO();
     $index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL();      $index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL();
       $index->{'credits'} = &Apache::loncoursedata::CL_CREDITS();
       $index->{'instsec'} = &Apache::loncoursedata::CL_INSTSEC();
       $index->{'authorquota'} = &Apache::loncoursedata::CL_AUTHORQUOTA();
       $index->{'authorusage'} = &Apache::loncoursedata::CL_AUTHORUSAGE();
     foreach my $key (keys(%{$index})) {      foreach my $key (keys(%{$index})) {
         $keylist->[$index->{$key}] = $key;          $keylist->[$index->{$key}] = $key;
     }      }
Line 1953  sub process_date_info { Line 3096  sub process_date_info {
 }  }
   
 sub show_users_list {  sub show_users_list {
     my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_;      my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname,
           $showcredits,$needauthorquota,$needauthorusage)=@_;
     if ($formname eq '') {      if ($formname eq '') {
         $formname = 'studentform';          $formname = 'studentform';
     }      }
       my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
     #      #
     # Variables for excel output      # Variables for excel output
     my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);      my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
Line 1968  sub show_users_list { Line 3113  sub show_users_list {
     my @sortable = ('username','domain','id','fullname','start','end','email','role');      my @sortable = ('username','domain','id','fullname','start','end','email','role');
     if ($context eq 'course') {      if ($context eq 'course') {
         push(@sortable,('section','groups','type'));          push(@sortable,('section','groups','type'));
           if ($showcredits) {
               push(@sortable,'credits');
           }
     } else {      } else {
         push(@sortable,'extent');          push(@sortable,'extent');
           if (($context eq 'domain') && ($env{'form.roletype'} eq 'domain') &&
               (($env{'form.showrole'} eq 'Any') || ($env{'form.showrole'} eq 'au'))) {
               push(@sortable,('authorusage','authorquota'));
           }
     }      }
     if ($mode eq 'pickauthor') {      if ($mode eq 'pickauthor') {
         @sortable = ('username','fullname','email','status');          @sortable = ('username','fullname','email','status');
     }      }
     if (!grep(/^\Q$sortby\E$/,@sortable)) {      my %is_sortable;
       map { $is_sortable{$_} = 1; } @sortable;
       unless ($is_sortable{$sortby}) {
         $sortby = 'username';          $sortby = 'username';
     }      }
     my $setting = $env{'form.roletype'};      my $setting = $env{'form.roletype'};
     my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers);      my ($cid,$cdom,$cnum,$classgroups,$crstype,$defaultcredits);
     if ($context eq 'course') {      if ($context eq 'course') {
         $cid = $env{'request.course.id'};          $cid = $env{'request.course.id'};
           $crstype = &Apache::loncommon::course_type();
         ($cnum,$cdom) = &get_course_identity($cid);          ($cnum,$cdom) = &get_course_identity($cid);
           $defaultcredits = $env{'course.'.$cid.'.internal.defaultcredits'};
         ($classgroups) = &Apache::loncoursedata::get_group_memberships(          ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                                      $userlist,$keylist,$cdom,$cnum);                                       $userlist,$keylist,$cdom,$cnum);
         if ($mode eq 'autoenroll') {          if ($mode eq 'autoenroll') {
             $env{'form.showrole'} = 'st';              $env{'form.showrole'} = 'st';
         } else {          } else {
             if (! exists($env{'form.displayphotos'})) {  
                 $env{'form.displayphotos'} = 'off';  
             }  
             $displayphotos = $env{'form.displayphotos'};  
             if (! exists($env{'form.displayclickers'})) {  
                 $env{'form.displayclickers'} = 'off';  
             }  
             $displayclickers = $env{'form.displayclickers'};  
             if ($env{'course.'.$cid.'.internal.showphoto'}) {              if ($env{'course.'.$cid.'.internal.showphoto'}) {
                 $r->print('                  $r->print('
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 function photowindow(photolink) {  function photowindow(photolink) {
     var title = "Photo_Viewer";      var title = "Photo_Viewer";
     var options = "scrollbars=1,resizable=1,menubar=0";      var options = "scrollbars=1,resizable=1,menubar=0";
Line 2005  function photowindow(photolink) { Line 3154  function photowindow(photolink) {
     stdeditbrowser = open(photolink,title,options,"1");      stdeditbrowser = open(photolink,title,options,"1");
     stdeditbrowser.focus();      stdeditbrowser.focus();
 }  }
   // ]]>
 </script>  </script>
                ');                 ');
             }              }
             $r->print(<<END);          }
 <input type="hidden" name="displayphotos" value="$displayphotos" />      } elsif ($context eq 'domain') {
 <input type="hidden" name="displayclickers" value="$displayclickers" />          if ($setting eq 'community') {
 END              $crstype = 'Community';
           } elsif ($setting eq 'course') {
               $crstype = 'Course';
         }          }
     }      }
     if ($mode ne 'autoenroll' && $mode ne 'pickauthor') {      if ($mode ne 'autoenroll' && $mode ne 'pickauthor') {
         my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();  
         my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode);          my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode);
         my $verify_action_js = &bulkaction_javascript($formname);          my $verify_action_js = &bulkaction_javascript($formname);
         $r->print(<<END);          $r->print(<<END);
   
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
 $check_uncheck_js  // <![CDATA[
   
 $verify_action_js  $verify_action_js
   
 function username_display_launch(username,domain) {  function username_display_launch(username,domain) {
     var target;      var target;
     for (var i=0; i<document.$formname.usernamelink.length; i++) {      if (!document.$formname.usernamelink.length) {
         if (document.$formname.usernamelink[i].checked) {          target = document.$formname.usernamelink.value;
             target = document.$formname.usernamelink[i].value;      } else {
           for (var i=0; i<document.$formname.usernamelink.length; i++) {
               if (document.$formname.usernamelink[i].checked) {
                  target = document.$formname.usernamelink[i].value;
               }
         }          }
     }      }
     if (target == 'modify') {      if ((target == 'modify') || (target == 'activity')) {
           var nextaction = 'singleuser';
           if (target == 'activity') {
               nextaction = 'accesslogs';
           }
         if (document.$formname.userwin.checked == true) {          if (document.$formname.userwin.checked == true) {
             var url = '/adm/createuser?srchterm='+username+'&srchdomain='+domain+'&phase=get_user_info&action=singleuser&srchin=dom&srchby=uname&srchtype=exact&popup=1';              var url = '/adm/createuser?srchterm='+username+'&srchdomain='+domain+'&phase=get_user_info&srchin=dom&srchby=uname&srchtype=exact&popup=1&action='+nextaction;
             var options = 'height=600,width=800,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no';              var options = 'height=600,width=800,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no';
             modifywin = window.open(url,'',options,1);              modifywin = window.open(url,'',options,1);
             modifywin.focus();              modifywin.focus();
Line 2043  function username_display_launch(usernam Line 3202  function username_display_launch(usernam
             document.$formname.srchterm.value=username;              document.$formname.srchterm.value=username;
             document.$formname.srchdomain.value=domain;              document.$formname.srchdomain.value=domain;
             document.$formname.phase.value='get_user_info';              document.$formname.phase.value='get_user_info';
             document.$formname.action.value = 'singleuser';              document.$formname.action.value = nextaction;
             document.$formname.submit();              document.$formname.submit();
         }          }
     }      }
Line 2058  function username_display_launch(usernam Line 3217  function username_display_launch(usernam
             document.location.href = '/adm/'+domain+'/'+username+'/aboutme';              document.location.href = '/adm/'+domain+'/'+username+'/aboutme';
         }          }
     }      }
       if (target == 'track') {
           if (document.$formname.userwin.checked == true) {
               var url = '/adm/trackstudent?selected_student='+username+':'+domain+'&only_body=1';
               var options = 'height=600,width=800,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no';
               var trackwin = window.open(url,'',options,1);
               trackwin.focus();
               return;
           } else {
               document.location.href = '/adm/trackstudent?selected_student='+username+':'+domain;
           }
       }
 }  }
   // ]]>
 </script>  </script>
 $date_sec_selector  $date_sec_selector
 <input type="hidden" name="state" value="$env{'form.state'}" />  <input type="hidden" name="state" value="$env{'form.state'}" />
Line 2067  END Line 3238  END
     $r->print(<<END);      $r->print(<<END);
 <input type="hidden" name="sortby" value="$sortby" />  <input type="hidden" name="sortby" value="$sortby" />
 END  END
       my @cols = &infocolumns($context,$mode,$showcredits);
     my %lt=&Apache::lonlocal::texthash(      my %coltxt = &get_column_names($context);
                        'username'   => "username",      my %acttxt = &Apache::lonlocal::texthash(
                        'domain'     => "domain",  
                        'id'         => 'ID',  
                        'fullname'   => "name",  
                        'section'    => "section",  
                        'groups'     => "active groups",  
                        'start'      => "start date",  
                        'end'        => "end date",  
                        'status'     => "status",  
                        'role'       => "role",  
                        'type'       => "enroll type/action",  
                        'email'      => "e-mail address",  
                        'photo'      => "photo",  
                        'extent'     => "extent",  
                        'pr'         => "Proceed",                         'pr'         => "Proceed",
                        'ca'         => "check all",  
                        'ua'         => "uncheck all",  
                        'ac'         => "Action to take for selected users",                         'ac'         => "Action to take for selected users",
                        'link'       => "Behavior of clickable username link for each user",                         'link'       => "Behavior of clickable username link for each user",
                        'aboutme'    => "Display a user's personal information page",                         'aboutme'    => "Display a user's personal information page",
                        'owin'       => "Open in a new window",                         'owin'       => "Open in a new window",
                        'modify'     => "Modify a user's information",                         'modify'     => "Modify a user's information",
                        'clicker'    => "Clicker-ID",                         'track'      => "View a user's recent activity",
                          'activity'   => "View a user's access log", 
                       );                        );
     if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {      my %lt = (%coltxt,%acttxt);
         $lt{'extent'} = &mt('Course(s): description, section(s), status');  
     } elsif ($context eq 'author') {  
         $lt{'extent'} = &mt('Author');   
     }  
     my @cols;  
     if ($mode eq 'pickauthor') {  
         @cols = ('username','fullname','status','email');  
     } else {  
         @cols = ('username','domain','id','fullname');  
         if ($context eq 'course') {  
             push(@cols,'section');  
         }  
         if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) {   
             push(@cols,('start','end'));  
         }  
         if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') {  
             push(@cols,'role');  
         }  
         if ($context eq 'domain' && ($env{'form.roletype'} eq 'author' ||  
                                     $env{'form.roletype'} eq 'course')) {  
             push (@cols,'extent');  
         }  
         if (($statusmode eq 'Any') &&   
             (!($context eq 'domain' && $env{'form.roletype'} eq 'course'))) {  
             push(@cols,'status');  
         }  
         if ($context eq 'course') {  
             push(@cols,'groups');  
         }  
         push(@cols,'email');  
     }  
   
     my $rolefilter = $env{'form.showrole'};      my $rolefilter = $env{'form.showrole'};
     if ($env{'form.showrole'} eq 'cr') {      if ($env{'form.showrole'} eq 'cr') {
         $rolefilter = &mt('custom');            $rolefilter = &mt('custom');  
     } elsif ($env{'form.showrole'} ne 'Any') {      } elsif ($env{'form.showrole'} ne 'Any') {
         $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'});          $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'},$crstype);
     }      }
     my $results_description;      my $results_description;
     if ($mode ne 'autoenroll') {      if ($mode ne 'autoenroll') {
         $results_description = &results_header_row($rolefilter,$statusmode,          $results_description = &results_header_row($rolefilter,$statusmode,
                                                    $context,$permission,$mode);                                                     $context,$permission,$mode,$crstype);
         $r->print('<b>'.$results_description.'</b><br /><br />');          $r->print('<b>'.$results_description.'</b><br clear="all" />');
     }      }
     my ($output,$actionselect,%canchange,%canchangesec);      my ($output,$actionselect,%canchange,%canchangesec);
     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {      if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
         if ($mode ne 'autoenroll' && $mode ne 'pickauthor') {          if ($mode ne 'autoenroll' && $mode ne 'pickauthor') {
             if ($permission->{'cusr'}) {              if ($permission->{'cusr'}) {
                 $actionselect = &select_actions($context,$setting,$statusmode,$formname);                  unless (($context eq 'domain') && 
                           (($setting eq 'course') || ($setting eq 'community'))) {
                       $actionselect = 
                           &select_actions($context,$setting,$statusmode,$formname);
                   }
             }              }
             $r->print(<<END);              $r->print(<<END);
 <input type="hidden" name="srchby"  value="uname" />  <input type="hidden" name="srchby"  value="uname" />
Line 2153  END Line 3282  END
 END  END
             if ($actionselect) {              if ($actionselect) {
                 $output .= <<"END";                  $output .= <<"END";
 <div class="LC_left_float"><fieldset><legend><b>$lt{'ac'}</b></legend>  <div class="LC_left_float"><fieldset><legend>$lt{'ac'}</legend>
 $actionselect  $actionselect
 <br/><br /><input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.$formname.actionlist)" /> &nbsp;  <br/><br /><input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.$formname.actionlist)" /> &nbsp;
 <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.$formname.actionlist)" /><br /><input type="button" value="$lt{'pr'}" onclick="javascript:verify_action('actionlist')" /></fieldset></div>  <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.$formname.actionlist)" /><br /><input type="button" value="$lt{'pr'}" onclick="javascript:verify_action('actionlist')" /></fieldset></div>
Line 2162  END Line 3291  END
                 if ($env{'form.showrole'} eq 'Any') {                  if ($env{'form.showrole'} eq 'Any') {
                     my $custom = 1;                      my $custom = 1;
                     if ($context eq 'domain') {                      if ($context eq 'domain') {
                         @allroles = &roles_by_context($setting,$custom);                          @allroles = &roles_by_context($setting,$custom,$crstype);
                     } else {                      } else {
                         @allroles = &roles_by_context($context,$custom);                          @allroles = &roles_by_context($context,$custom,$crstype);
                     }                      }
                 } else {                  } else {
                     @allroles = ($env{'form.showrole'});                      @allroles = ($env{'form.showrole'});
Line 2194  END Line 3323  END
                             if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {                              if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
                                 $canchangesec{$role} = $env{'request.course.sec'};                                  $canchangesec{$role} = $env{'request.course.sec'};
                             }                              }
                           } elsif ((($role eq 'co') && ($crstype eq 'Community')) ||
                                    (($role eq 'cc') && ($crstype eq 'Course'))) {
                               if (&is_courseowner($env{'request.course.id'},
                                                   $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) {
                                   $canchange{$role} = 1;
                               }
                         }                          }
                     }                      }
                 }                  }
             }              }
             $output .= '<div class="LC_left_float"><fieldset><legend><b>'.$lt{'link'}.'</b></legend>'.              $output .= '<div class="LC_left_float"><fieldset><legend>'.$lt{'link'}.'</legend>'.
                        '<table><tr>';                         '<table><tr>';
             my @linkdests = ('aboutme');              my @linkdests = ('aboutme');
             if ($permission->{'cusr'}) {              if ($permission->{'cusr'}) {
                 unshift (@linkdests,'modify');                  unshift (@linkdests,'modify');
             }              }
               if ($context eq 'course') {
                   if (&Apache::lonnet::allowed('vsa', $env{'request.course.id'}) ||
                       &Apache::lonnet::allowed('vsa', $env{'request.course.id'}.'/'.
                                                $env{'request.course.sec'})) {
                       push(@linkdests,'track');
                   }
               } elsif ($context eq 'domain') {
                   if (&Apache::lonnet::allowed('vac',$env{'request.role.domain'})) {
                       push(@linkdests,'activity');
                   }
               }
             $output .= '<td>';              $output .= '<td>';
             my $usernamelink = $env{'form.usernamelink'};              my $usernamelink = $env{'form.usernamelink'};
             if ($usernamelink eq '') {              if ($usernamelink eq '') {
Line 2220  END Line 3366  END
             if ($env{'form.userwin'}) {              if ($env{'form.userwin'}) {
                 $checkwin = ' checked="checked"';                  $checkwin = ' checked="checked"';
             }              }
             $output .= '</td><td valign="top"><span class="LC_nobreak"><input type="checkbox" name="userwin" value="1"'.$checkwin.' />'.$lt{'owin'}.'</span></td></tr></table></fieldset></div>';              $output .=
                   '</td><td valign="top"  style="border-left: 1px solid;">'
                  .'<span class="LC_nobreak"><label>'
                  .'<input type="checkbox" name="userwin" value="1"'.$checkwin.' />'.$lt{'owin'}
                  .'</label></span></td></tr></table></fieldset></div>';
         }          }
         $output .= "\n".'<div class="LC_clear_float_footer">&nbsp;</div>'."\n".          $output .= "\n".'<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n".
                   &Apache::loncommon::start_data_table().                    &Apache::loncommon::start_data_table().
                   &Apache::loncommon::start_data_table_header_row();                    &Apache::loncommon::start_data_table_header_row();
         if ($mode eq 'autoenroll') {          if ($mode eq 'autoenroll') {
Line 2230  END Line 3380  END
  <th><a href=\"javascript:document.$formname.sortby.value='type';document.$formname.submit();\">$lt{'type'}</a></th>   <th><a href=\"javascript:document.$formname.sortby.value='type';document.$formname.submit();\">$lt{'type'}</a></th>
             ";              ";
         } else {          } else {
             if ($mode eq 'pickauthor') {              $output .= "\n".'<th>&nbsp;</th>'."\n";
                 $output .= "\n".'<th>&nbsp;</th>'."\n";  
             } else {   
                 $output .= "\n".'<th>'.&mt('Count').'</th>'."\n";  
             }  
             if ($actionselect) {              if ($actionselect) {
                 $output .= '<th>'.&mt('Select').'</th>'."\n";                  $output .= '<th class="LC_nobreak" valign="top">'.&mt('Select').'</th>'."\n";
             }              }
         }          }
         foreach my $item (@cols) {          foreach my $item (@cols) {
             $output .= "<th><a href=\"javascript:document.$formname.sortby.value='$item';document.$formname.submit();\">$lt{$item}</a></th>\n";              $output .= '<th class="LC_nobreak" valign="top">';
         }              if ($is_sortable{$item}) {
         my %role_types = &role_type_names();                  $output .= "<a href=\"javascript:document.$formname.sortby.value='$item';document.$formname.submit();\" style=\"text-decoration:none;\">$lt{$item}<span class=\"LC_fontsize_small\"> &#9660;</span></a>";
         if ($context eq 'course' && $mode ne 'autoenroll') {              } else {
             if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {                  $output .= $lt{$item};
                 # Clicker display on or off?  
                 my %clicker_options = (  
                                         'on' => 'Show',  
                                         'off' => 'Hide',  
                                       );  
                 my $clickerchg = 'on';  
                 if ($displayclickers eq 'on') {  
                     $clickerchg = 'off';  
                 }  
                 $output .= '    <th>'."\n".'     '  
                         .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id'  
                             ,'<a href="javascript:document.'.$formname.'.displayclickers.value='  
                              ."'".$clickerchg."'".';document.'.$formname.'.submit();">'  
                             ,'</a>')  
                         ."\n".'    </th>'."\n";  
   
                 # Photo display on or off?  
                 if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {  
                     my %photo_options = &Apache::lonlocal::texthash(  
                                                             'on' => 'Show',  
                                                             'off' => 'Hide',  
                                                                 );  
                     my $photochg = 'on';  
                     if ($displayphotos eq 'on') {  
                         $photochg = 'off';  
                     }  
                     $output .= '    <th>'."\n".'     '.  
                 '<a href="javascript:document.'.$formname.'.displayphotos.value='.  
                       "'".$photochg."'".';document.'.$formname.'.submit();">'.  
                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".  
                       '    </th>'."\n";  
                 }  
             }              }
               $output .= "</th>\n";
         }          }
           my %role_types = &role_type_names();
         $output .= &Apache::loncommon::end_data_table_header_row();          $output .= &Apache::loncommon::end_data_table_header_row();
 # Done with the HTML header line  # Done with the HTML header line
     } elsif ($mode eq 'csv') {      } elsif ($mode eq 'csv') {
Line 2289  END Line 3405  END
                        time.'_'.rand(1000000000).'.csv';                         time.'_'.rand(1000000000).'.csv';
         unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {          unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
             $r->log_error("Couldn't open $CSVfilename for output $!");              $r->log_error("Couldn't open $CSVfilename for output $!");
             $r->print(&mt('Problems occurred in writing the CSV file. '              $r->print(
                          .'This error has been logged. '                  '<p class="LC_error">'
                          .'Please alert your LON-CAPA administrator.'));                 .&mt('Problems occurred in writing the CSV file.')
                  .' '.&mt('This error has been logged.')
                  .' '.&mt('Please alert your LON-CAPA administrator.')
                  .'</p>'
               );
             $CSVfile = undef;              $CSVfile = undef;
         }          }
         #          #
         push @cols,'clicker';  
         # Write headers and data to file          # Write headers and data to file
         print $CSVfile '"'.$results_description.'"'."\n";           print $CSVfile '"'.$results_description.'"'."\n"; 
         print $CSVfile '"'.join('","',map {          print $CSVfile '"'.join('","',map {
             &Apache::loncommon::csv_translate($lt{$_})              &Apache::loncommon::csv_translate($lt{$_})
             } (@cols))."\"\n";              } (@cols))."\"\n";
     } elsif ($mode eq 'excel') {      } elsif ($mode eq 'excel') {
         push @cols,'clicker';  
         # Create the excel spreadsheet          # Create the excel spreadsheet
         ($excel_workbook,$excel_filename,$format) =          ($excel_workbook,$excel_filename,$format) =
             &Apache::loncommon::create_workbook($r);              &Apache::loncommon::create_workbook($r);
Line 2338  END Line 3456  END
                                                 Future  => 'Future',                                                  Future  => 'Future',
                                                 Expired => 'Expired',                                                  Expired => 'Expired',
                                                );                                                 );
       # If this is for a single course get last course "log-in".
       my %crslogins;
       if ($context eq 'course') {
           %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum);
       }
     # Get groups, role, permanent e-mail so we can sort on them if      # Get groups, role, permanent e-mail so we can sort on them if
     # necessary.      # necessary.
     foreach my $user (keys(%{$userlist})) {      foreach my $user (keys(%{$userlist})) {
Line 2365  END Line 3488  END
                 }                  }
             } elsif ($env{'form.roletype'} eq 'author') {              } elsif ($env{'form.roletype'} eq 'author') {
                 ($uname,$udom,$role) = split(/:/,$user,-1);                  ($uname,$udom,$role) = split(/:/,$user,-1);
             } elsif ($env{'form.roletype'} eq 'course') {              } elsif (($env{'form.roletype'} eq 'course') || 
                        ($env{'form.roletype'} eq 'community')) {
                 ($uname,$udom,$role) = split(/:/,$user);                  ($uname,$udom,$role) = split(/:/,$user);
             }              }
         } else {          } else {
Line 2420  END Line 3544  END
                     }                      }
                 }                  }
                 if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {                  if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
                     if (($displayphotos eq 'on') && ($role eq 'st')) {                      if ((grep/^photo$/,@cols) && ($role eq 'st')) {
                         $userlist->{$user}->[$index{'photo'}] =                          $userlist->{$user}->[$index{'photo'}] =
                             &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg');                              &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg');
                         $userlist->{$user}->[$index{'thumbnail'}] =                          $userlist->{$user}->[$index{'thumbnail'}] =
Line 2428  END Line 3552  END
                                                                 'gif','thumbnail');                                                                  'gif','thumbnail');
                     }                      }
                 }                  }
                   if (($role eq 'st') && ($defaultcredits)) {
                       if ($userlist->{$user}->[$index{'credits'}] eq '') {
                           $userlist->{$user}->[$index{'credits'}] = $defaultcredits;
                       }
                   }
             }              }
         }          }
         my %emails   = &Apache::loncommon::getemails($uname,$udom);          my %emails   = &Apache::loncommon::getemails($uname,$udom);
         if ($emails{'permanentemail'} =~ /\S/) {          if ($emails{'permanentemail'} =~ /\S/) {
             $userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'};              $userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'};
         }          }
           if (($context eq 'domain') && ($env{'form.roletype'} eq 'domain') && 
               ($role eq 'au')) {
               my ($disk_quota,$current_disk_usage,$percent); 
               if (($needauthorusage) || ($needauthorquota)) {
                   $disk_quota = &Apache::loncommon::get_user_quota($uname,$udom,'author');
               }
               if ($needauthorusage) {
                   $current_disk_usage =
                       &Apache::lonnet::diskusage($udom,$uname,"$londocroot/priv/$udom/$uname");
                   if ($disk_quota == 0) {
                       $percent = 100.0;
                   } else {
                       $percent = $current_disk_usage/(10 * $disk_quota);
                   }
                   $userlist->{$user}->[$index{'authorusage'}] = sprintf("%.0f",$percent);
               }
               if ($needauthorquota) {
                   $userlist->{$user}->[$index{'authorquota'}] = sprintf("%.2f",$disk_quota);
               }
           }
         $usercount ++;          $usercount ++;
     }      }
     my $autocount = 0;      my $autocount = 0;
Line 2454  END Line 3603  END
     my $index  = $index{$sortby};      my $index  = $index{$sortby};
     my $second = $index{'username'};      my $second = $index{'username'};
     my $third  = $index{'domain'};      my $third  = $index{'domain'};
     my @sorted_users = sort {      my @sorted_users;
         lc($userlist->{$a}->[$index])  cmp lc($userlist->{$b}->[$index])      if (($sortby eq 'authorquota') || ($sortby eq 'authorusage')) {  
             ||          @sorted_users = sort {
         lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second])            ||              $userlist->{$b}->[$index] <=> $userlist->{$a}->[$index]           ||
         lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])              lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
         } (keys(%$userlist));              lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
               } (keys(%$userlist));
       } else {
           @sorted_users = sort {
               lc($userlist->{$a}->[$index]) cmp lc($userlist->{$b}->[$index])   ||
               lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
               lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
               } (keys(%$userlist));
       }
     my $rowcount = 0;      my $rowcount = 0;
       my $disabled;
       if ($mode eq 'autoenroll') {
           unless ($permission->{'cusr'}) {
               $disabled = ' disabled="disabled"';
           }
       }
     foreach my $user (@sorted_users) {      foreach my $user (@sorted_users) {
         my %in;          my %in;
         my $sdata = $userlist->{$user};          my $sdata = $userlist->{$user};
Line 2470  END Line 3633  END
         }          }
         my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];          my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
         if ($clickers!~/\w/) { $clickers='-'; }          if ($clickers!~/\w/) { $clickers='-'; }
         $in{'clicker'} = $clickers;           $in{'clicker'} = $clickers;
  my $role = $in{'role'};   my $role = $in{'role'};
         $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]);           $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype);
         if (! defined($in{'start'}) || $in{'start'} == 0) {          unless ($mode eq 'excel') {
             $in{'start'} = &mt('none');              if (! defined($in{'start'}) || $in{'start'} == 0) {
         } else {                  $in{'start'} = &mt('none');
             $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});              } else {
                   $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
               }
               if (! defined($in{'end'}) || $in{'end'} == 0) {
                   $in{'end'} = &mt('none');
               } else {
                   $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
               }
         }          }
         if (! defined($in{'end'}) || $in{'end'} == 0) {          if ($context eq 'course') {
             $in{'end'} = &mt('none');              my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role};
         } else {              if ($lastlogin ne '') {
             $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});                  $in{'lastlogin'} = &Apache::lonlocal::locallocaltime($lastlogin);
               }
         }          }
         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {          if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
             $r->print(&Apache::loncommon::start_data_table_row());              $r->print(&Apache::loncommon::start_data_table_row());
Line 2489  END Line 3660  END
             if ($mode eq 'autoenroll') {              if ($mode eq 'autoenroll') {
                 my $cellentry;                  my $cellentry;
                 if ($in{'type'} eq 'auto') {                  if ($in{'type'} eq 'auto') {
                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;Change</label>';                      $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$in{'username'}.':'.$in{'domain'}.'"'.$disabled.' />&nbsp;'.&mt('Change').'</label>';
                     $autocount ++;                      $autocount ++;
                 } else {                  } else {
                     $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><span class="LC_nobreak"><label><input type="checkbox" name="chgmanual" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;Change</label></span></td></tr><tr><td><span class="LC_nobreak">';                      $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><span class="LC_nobreak"><label><input type="checkbox" name="chgmanual" value="'.$in{'username'}.':'.$in{'domain'}.'"'.$disabled.' />&nbsp;'.&mt('Change').'</label></span></td></tr><tr><td><span class="LC_nobreak">';
                     $manualcount ++;                      $manualcount ++;
                     if ($in{'lockedtype'}) {                      if ($in{'lockedtype'}) {
                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;'.&mt('Unlock').'</label>';                          $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$in{'username'}.':'.$in{'domain'}.'"'.$disabled.' />&nbsp;'.&mt('Unlock').'</label>';
                         $unlockcount ++;                          $unlockcount ++;
                     } else {                      } else {
                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;'.&mt('Lock').'</label>';                          $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$in{'username'}.':'.$in{'domain'}.'"'.$disabled.' />&nbsp;'.&mt('Lock').'</label>';
                         $lockcount ++;                          $lockcount ++;
                     }                      }
                     $cellentry .= '</span></td></tr></table>';                      $cellentry .= '</span></td></tr></table>';
Line 2527  END Line 3698  END
                     if ($showcheckbox) {                      if ($showcheckbox) {
                         $checkval = $user;                           $checkval = $user; 
                         if ($context eq 'course') {                          if ($context eq 'course') {
                             if ($role eq 'st') {                              if (($role eq 'co' || $role eq 'cc') &&
                                 $checkval .= ':st';                                  ($user =~ /^\Q$env{'user.name'}:$env{'user.domain'}:$role\E/)) {
                             }                                  $showcheckbox = 0;
                             $checkval .= ':'.$in{'section'};                              } else {
                             if ($role eq 'st') {                                  if ($role eq 'st') {
                                 $checkval .= ':'.$in{'type'}.':'.                                      $checkval .= ':st';
                                              $in{'lockedtype'};                                  }
                                   $checkval .= ':'.$in{'section'};
                                   if ($role eq 'st') {
                                       $checkval .= ':'.$in{'type'}.':'.
                                                    $in{'lockedtype'}.':'.
                                                    $in{'credits'}.':'.
                                                    &escape($in{'instsec'});
                                   }
                                }
                           }
                           if ($showcheckbox) {
                               $r->print('<td><input type="checkbox" name="'.
                                         'actionlist" value="'.
                                         &HTML::Entities::encode($checkval,'&<>"').'" />');
                               foreach my $item ('start','end') {
                                   $r->print('<input type="hidden" name="'.
                                             &HTML::Entities::encode($checkval.'_'.$item,'&<>"').'"'.
                                             ' value="'.$sdata->[$index{$item}].'" />');
                             }                              }
                               $r->print('</td>');
                           } else {
                               $r->print('<td>&nbsp;</td>');
                         }                          }
                         $r->print('<td><input type="checkbox" name="'.  
                                   'actionlist" value="'.$checkval.'" /></td>');  
                     } else {                      } else {
                         $r->print('<td>&nbsp;</td>');                          $r->print('<td>&nbsp;</td>');
                     }                      }
Line 2548  END Line 3737  END
             foreach my $item (@cols) {              foreach my $item (@cols) {
                 if ($item eq 'username') {                  if ($item eq 'username') {
                     $r->print('<td>'.&print_username_link($mode,\%in).'</td>');                      $r->print('<td>'.&print_username_link($mode,\%in).'</td>');
                 } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) {  
                     $r->print('<td>'.$in{$item}.'<input type="hidden" name="'.$checkval.'_'.$item.'" value="'.$sdata->[$index{$item}].'" /></td>'."\n");  
                 } elsif ($item eq 'status') {                  } elsif ($item eq 'status') {
                     my $showitem = $in{$item};                      my $showitem = $in{$item};
                     if (defined($ltstatus{$in{$item}})) {                      if (defined($ltstatus{$in{$item}})) {
                         $showitem = $ltstatus{$in{$item}};                          $showitem = $ltstatus{$in{$item}};
                     }                      }
                     $r->print('<td>'.$showitem.'</td>'."\n");                      $r->print('<td>'.$showitem.'</td>'."\n");
                 } else {                  } elsif ($item eq 'photo') {
                     $r->print('<td>'.$in{$item}.'</td>'."\n");                       if (($context eq 'course') && ($mode ne 'autoenroll') && 
                 }                           ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) { 
             }                           if ($role eq 'st') {
             if (($context eq 'course') && ($mode ne 'autoenroll')) {                               $r->print('<td align="right"><a href="javascript:photowindow('."'".$in{'photo'}."'".')"><img src="'.$in{'thumbnail'}.'" border="1" alt="" /></a></td>');
                 if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {                           } else {
                     if ($displayclickers eq 'on') {                               $r->print('<td>&nbsp;</td>');
                         my $clickers =                           }
                        }
                   } elsif ($item eq 'clicker') {
                       if (($context eq 'course') && ($mode ne 'autoenroll')) {
                           if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
                               my $clickers =
                    (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];                     (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
                         if ($clickers!~/\w/) { $clickers='-'; }                              if ($clickers!~/\w/) { $clickers='-'; }
                         $r->print('<td>'.$clickers.'</td>');                              $r->print('<td>'.$clickers.'</td>');
                     } else {  
                         $r->print('    <td>&nbsp;</td>  ');  
                     }  
                     if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {  
                         if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') {  
                             $r->print('    <td align="right"><a href="javascript:photowindow('."'".$in{'photo'}."'".')"><img src="'.$in{'thumbnail'}.'" border="1" alt="" /></a></td>');  
                         } else {                          } else {
                             $r->print('    <td>&nbsp;</td>  ');                               $r->print('<td>&nbsp;</td>'."\n");
                         }                          } 
                     }                      }
                   } elsif (($item eq 'authorquota') || ($item eq 'authorusage')) {
                       $r->print('<td align="right">'.$in{$item}.'</td>'."\n");
                   } else {
                       $r->print('<td>'.$in{$item}.'</td>'."\n");
                 }                  }
             }              }
             $r->print(&Apache::loncommon::end_data_table_row());              $r->print(&Apache::loncommon::end_data_table_row());
         } elsif ($mode eq 'csv') {          } elsif ($mode eq 'csv') {
             next if (! defined($CSVfile));              next if (! defined($CSVfile));
             # no need to bother with $linkto              # no need to bother with $linkto
             if (! defined($in{'start'}) || $in{'start'} == 0) {  
                 $in{'start'} = &mt('none');  
             } else {  
                 $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});  
             }  
             if (! defined($in{'end'}) || $in{'end'} == 0) {  
                 $in{'end'} = &mt('none');  
             } else {  
                 $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});  
             }  
             my @line = ();              my @line = ();
             foreach my $item (@cols) {              foreach my $item (@cols) {
                 push @line,&Apache::loncommon::csv_translate($in{$item});                  push @line,&Apache::loncommon::csv_translate($in{$item});
Line 2602  END Line 3782  END
             my $col = 0;              my $col = 0;
             foreach my $item (@cols) {              foreach my $item (@cols) {
                 if ($item eq 'start' || $item eq 'end') {                  if ($item eq 'start' || $item eq 'end') {
                     if (defined($item) && $item != 0) {                      if ((defined($in{$item})) && ($in{$item} != 0)) {
                         $excel_sheet->write($row,$col++,                          $excel_sheet->write($row,$col++,
                             &Apache::lonstathelpers::calc_serial($in{item}),                              &Apache::lonstathelpers::calc_serial($in{$item}),
                                     $format->{'date'});                                      $format->{'date'});
                     } else {                      } else {
                         $excel_sheet->write($row,$col++,'none');                          $excel_sheet->write($row,$col++,'none');
Line 2620  END Line 3800  END
             $r->print(&Apache::loncommon::end_data_table().'<br />');              $r->print(&Apache::loncommon::end_data_table().'<br />');
     } elsif ($mode eq 'excel') {      } elsif ($mode eq 'excel') {
         $excel_workbook->close();          $excel_workbook->close();
  $r->print(&mt('[_1]Your Excel spreadsheet[_2] is ready for download.', '<p><a href="'.$excel_filename.'">','</a>')."</p>\n");   $r->print('<p>'.&mt('[_1]Your Excel spreadsheet[_2] is ready for download.', '<a href="'.$excel_filename.'">','</a>')."</p>\n");
     } elsif ($mode eq 'csv') {      } elsif ($mode eq 'csv') {
         close($CSVfile);          close($CSVfile);
  $r->print(&mt('[_1]Your CSV file[_2] is ready for download.', '<p><a href="'.$CSVfilename.'">','</a>')."</p>\n");   $r->print('<p>'.&mt('[_1]Your CSV file[_2] is ready for download.', '<a href="'.$CSVfilename.'">','</a>')."</p>\n");
         $r->rflush();          $r->rflush();
     }      }
     if ($mode eq 'autoenroll') {      if ($mode eq 'autoenroll') {
Line 2655  sub bulkaction_javascript { Line 3835  sub bulkaction_javascript {
     my $noaction = &mt("You need to select an action to take for the user(s) you have selected");       my $noaction = &mt("You need to select an action to take for the user(s) you have selected"); 
     my $singconfirm = &mt(' for a single user?');      my $singconfirm = &mt(' for a single user?');
     my $multconfirm = &mt(' for multiple users?');      my $multconfirm = &mt(' for multiple users?');
       &js_escape(\$alert);
       &js_escape(\$noaction);
       &js_escape(\$singconfirm);
       &js_escape(\$multconfirm);
     my $output = <<"ENDJS";      my $output = <<"ENDJS";
 function verify_action (field) {  function verify_action (field) {
     var numchecked = 0;      var numchecked = 0;
Line 2759  sub print_username_link { Line 3943  sub print_username_link {
         $output = $in->{'username'};          $output = $in->{'username'};
     } else {      } else {
         $output = '<a href="javascript:username_display_launch('.          $output = '<a href="javascript:username_display_launch('.
                   "'$in->{'username'}','$in->{'domain'}'".')" />'.                    "'$in->{'username'}','$in->{'domain'}'".')">'.
                   $in->{'username'}.'</a>';                    $in->{'username'}.'</a>';
     }      }
     return $output;      return $output;
Line 2770  sub role_type_names { Line 3954  sub role_type_names {
                          'domain' => 'Domain Roles',                           'domain' => 'Domain Roles',
                          'author' => 'Co-Author Roles',                           'author' => 'Co-Author Roles',
                          'course' => 'Course Roles',                           'course' => 'Course Roles',
                            'community' => 'Community Roles',
              );               );
     return %lt;      return %lt;
 }  }
Line 2784  sub select_actions { Line 3969  sub select_actions {
                 chgdates  => "Change starting/ending dates",                  chgdates  => "Change starting/ending dates",
                 chgsec   => "Change section associated with user roles",                  chgsec   => "Change section associated with user roles",
     );      );
       # FIXME Add an option to change credits for student roles.
     my ($output,$options,%choices);      my ($output,$options,%choices);
     # FIXME Disable actions for now for roletype=course in domain context      # FIXME Disable actions for now for roletype=course in domain context
     if ($context eq 'domain' && $setting eq 'course') {      if ($context eq 'domain' && $setting eq 'course') {
Line 2791  sub select_actions { Line 3977  sub select_actions {
     }      }
     if ($context eq 'course') {      if ($context eq 'course') {
         if ($env{'form.showrole'} ne 'Any') {          if ($env{'form.showrole'} ne 'Any') {
              if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},              my $showactions;
                                            $env{'request.course.id'})) {              if (&Apache::lonnet::allowed('c'.$env{'form.showrole'},
                  if ($env{'request.course.sec'} eq '') {                                            $env{'request.course.id'})) {
                      return;                  $showactions = 1;  
                  } else {              } elsif ($env{'request.course.sec'} ne '') {
                      if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {                  if (&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
                          return;                      $showactions = 1;
                      }                  }
                  }              }
               unless ($showactions) {
                   unless (&is_courseowner($env{'request.course.id'},
                                          $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) {
                       return; 
                   }
             }              }
         }          }
     }      }
Line 2859  sub select_actions { Line 4050  sub select_actions {
             }              }
         }          }
         if ($choices{'sections'}) {          if ($choices{'sections'}) {
             $output .= '<input type="hidden" name="retainsec" value= "" />'."\n".              $output .= '<input type="hidden" name="retainsec" value="" />'."\n".
                        '<input type="hidden" name="newsecs" value= "" />'."\n";                         '<input type="hidden" name="newsecs" value="" />'."\n";
         }          }
     }      }
     return $output;      return $output;
Line 2874  sub date_section_javascript { Line 4065  sub date_section_javascript {
         delete => "Check the boxes for any users for whom roles are to be deleted, and click 'Proceed'",          delete => "Check the boxes for any users for whom roles are to be deleted, and click 'Proceed'",
         none   => "Choose an action to take for selected users",          none   => "Choose an action to take for selected users",
     );        );  
     my $output = '      my $output = <<"ENDONE";
 <script type="text/javascript">'."\n";  <script type="text/javascript">
     $output .= <<"ENDONE";  // <![CDATA[
     function opendatebrowser(callingform,formname,calledby) {      function opendatebrowser(callingform,formname,calledby) {
         var bulkaction = callingform.bulkaction.options[callingform.bulkaction.selectedIndex].value;          var bulkaction = callingform.bulkaction.options[callingform.bulkaction.selectedIndex].value;
         var url = '/adm/createuser?';          var url = '/adm/createuser?';
Line 2899  ENDONE Line 4090  ENDONE
         stdeditbrowser = open(url,title,options,'1');          stdeditbrowser = open(url,title,options,'1');
         stdeditbrowser.focus();          stdeditbrowser.focus();
     }      }
   // ]]>
 </script>  </script>
 ENDTWO  ENDTWO
     return $output;      return $output;
 }  }
   
 sub date_section_selector {  sub date_section_selector {
     my ($context,$permission) = @_;      my ($context,$permission,$crstype,$showcredits) = @_;
     my $callingform = $env{'form.callingform'};      my $callingform = $env{'form.callingform'};
     my $formname = 'dateselect';        my $formname = 'dateselect';  
     my $groupslist = &get_groupslist();      my $groupslist = &get_groupslist();
     my $sec_js = &setsections_javascript($formname,$groupslist);      my $sec_js =
           &setsections_javascript($formname,$groupslist,undef,undef,$crstype,
                                   $showcredits);
     my $output = <<"END";      my $output = <<"END";
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
   
 $sec_js  $sec_js
   
Line 2929  END Line 4124  END
         } else {          } else {
             opener.document.$callingform.retainsec.value = formname.retainsec.value;              opener.document.$callingform.retainsec.value = formname.retainsec.value;
         }          }
         setSections(formname);          setSections(formname,'$crstype');
         if (seccheck == 'ok') {          if (seccheck == 'ok') {
             opener.document.$callingform.newsecs.value = formname.sections.value;              opener.document.$callingform.newsecs.value = formname.sections.value;
           } else {
               return;
         }          }
 END  END
     } else {      } else {
Line 2980  END Line 4177  END
   
 $verify_action_js  $verify_action_js
   
   // ]]>
 </script>  </script>
 ENDJS  ENDJS
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                  chac => 'Access dates to apply for selected users',                   chac => 'Access dates to apply for selected users',
                  chse => 'Changes in section affiliation to apply to selected users',                   chse => 'Changes in section affiliation to apply to selected users',
                  fors => 'For student roles changing the section, will result in a section switch as students may only be in one section of a course at a time.',                   fors => 'For student roles, changing the section will result in a section switch as students may only be in one section of a course at a time.',
                  forn => 'For a role in a course that is not a student role, a user may have roles in more than one section of a course at a time.',                   forn => 'For a course role that is not "student", users may have roles in more than one section at a time.',
                  reta => "Retain each user's current section affiliations?",                    reta => "Retain each user's current section affiliations?",
                  dnap => '(Does not apply to student roles).',                    dnap => '(Does not apply to student roles).',
             );              );
     my ($date_items,$headertext);      my ($date_items,$headertext);
     if ($env{'form.bulkaction'} eq 'chgsec') {      if ($env{'form.bulkaction'} eq 'chgsec') {
Line 3002  ENDJS Line 4200  ENDJS
         }          }
         $date_items = &date_setting_table($starttime,undef,$context,          $date_items = &date_setting_table($starttime,undef,$context,
                                           $env{'form.bulkaction'},$formname,                                            $env{'form.bulkaction'},$formname,
                                           $permission);                                            $permission,$crstype);
     }      }
     $output .= '<h3>'.$headertext.'</h3>'.      $output .= '<h3>'.$headertext.'</h3>'.
                '<form name="'.$formname.'" method="post">'."\n".                 '<form name="'.$formname.'" method="post" action="">'."\n".
                 $date_items;                  $date_items;
     if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') {      if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') {
         my ($cnum,$cdom) = &get_course_identity();          my ($cnum,$cdom) = &get_course_identity();
           if ($crstype eq 'Community') {
               $lt{'fors'} = &mt('For member roles, changing the section will result in a section switch, as members may only be in one section of a community at a time.');
               $lt{'forn'} = &mt('For a community role that is not "member", users may have roles in more than one section at a time.');
               $lt{'dnap'} = &mt('(Does not apply to member roles).'); 
           }
         my $info;          my $info;
         if ($env{'form.showrole'} eq 'st') {          if ($env{'form.showrole'} eq 'st') {
             $output .= '<p>'.$lt{'fors'}.'</p>';               $output .= '<p>'.$lt{'fors'}.'</p>'; 
Line 3034  ENDJS Line 4237  ENDJS
             $info = '<input type="hidden" name="retainsec" value="0" />';               $info = '<input type="hidden" name="retainsec" value="0" />'; 
         }          }
         my $rowtitle = &mt('New section to assign');          my $rowtitle = &mt('New section to assign');
         my $secbox = &section_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,$permission,$context);          my $secbox = &section_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,
                                        $permission,$context,'chgsec',$crstype);
         $output .= $info.$secbox;          $output .= $info.$secbox;
     }      }
     $output .= '<p>'.      $output .= '<p>'.
Line 3044  ENDJS Line 4248  ENDJS
 }  }
   
 sub section_picker {  sub section_picker {
     my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_;      my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode,$crstype,
           $showcredits,$credits) = @_;
     my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);      my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
     my $sections_select .= &course_sections(\%sections_count,$role);      my $sections_select .= &course_sections(\%sections_count,$role);
     my $secbox = '<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n";      my $secbox = '<div>'.&Apache::lonhtmlcommon::start_pick_box()."\n";
     if ($mode eq 'upload') {      if ($mode eq 'upload') {
         my ($options,$cb_script,$coursepick) =          my ($options,$cb_script,$coursepick) =
             &default_role_selector($context,1);              &default_role_selector($context,1,$crstype,$showcredits);
         $secbox .= &Apache::lonhtmlcommon::row_title(&mt('role'),'LC_oddrow_value').          $secbox .= &Apache::lonhtmlcommon::row_title(&mt('role'),'LC_oddrow_value').
                    $options. &Apache::lonhtmlcommon::row_closure(1)."\n";                     $options. &Apache::lonhtmlcommon::row_closure(1)."\n";
     }      }
Line 3060  sub section_picker { Line 4265  sub section_picker {
                    '<td align="center">'.&mt('Existing sections')."\n".                     '<td align="center">'.&mt('Existing sections')."\n".
                    '<br />'.$sections_select.'</td><td align="center">'.                     '<br />'.$sections_select.'</td><td align="center">'.
                    &mt('New section').'<br />'."\n".                     &mt('New section').'<br />'."\n".
                    '<input type="text" name="newsec" size="15" />'."\n".                     '<input type="text" name="newsec" size="15" value="" />'."\n".
                    '<input type="hidden" name="sections" value="" />'."\n".                     '<input type="hidden" name="sections" value="" />'."\n".
                    '</td></tr></table>'."\n";                     '</td></tr></table>'."\n";
     } else {      } else {
        $secbox .= '<input type="hidden" name="sections" value="'.          $secbox .= '<input type="hidden" name="sections" value="'.
                    $env{'request.course.sec'}.'" />'.                     $env{'request.course.sec'}.'" />'.
                    $env{'request.course.sec'};                     $env{'request.course.sec'};
     }      }
     $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n".      $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n";
                &Apache::lonhtmlcommon::end_pick_box().'</p>';      unless ($mode eq 'chgsec') {
           if ($showcredits) {
               $secbox .= 
                   &Apache::lonhtmlcommon::row_title(&mt('credits (students)'),
                                                     'LC_evenrow_value')."\n".
                   '<input type="text" name="credits" size="3" value="'.$credits.'" />'."\n".
                   &Apache::lonhtmlcommon::row_closure(1)."\n";
           }
       }
       $secbox .= &Apache::lonhtmlcommon::end_pick_box().'</div>';
     return $secbox;      return $secbox;
 }  }
   
 sub results_header_row {  sub results_header_row {
     my ($rolefilter,$statusmode,$context,$permission,$mode) = @_;      my ($rolefilter,$statusmode,$context,$permission,$mode,$crstype) = @_;
     my ($description,$showfilter);      my ($description,$showfilter);
     if ($rolefilter ne 'Any') {      if ($rolefilter ne 'Any') {
         $showfilter = $rolefilter;          $showfilter = $rolefilter;
     }      }
     if ($context eq 'course') {      if ($context eq 'course') {
         if ($mode eq 'csv' || $mode eq 'excel') {          if ($mode eq 'csv' || $mode eq 'excel') {
             $description = &mt('Course - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' ';              if ($crstype eq 'Community') {
                   $description = &mt('Community - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' ';
               } else {
                   $description = &mt('Course - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' ';
               }
         }          }
         if ($statusmode eq 'Expired') {          if ($statusmode eq 'Expired') {
             $description .= &mt('Users in course with expired [_1] roles',$showfilter);              if ($crstype eq 'Community') {
                   $description .= &mt('Users in community with expired [_1] roles',$showfilter);
               } else {
                   $description .= &mt('Users in course with expired [_1] roles',$showfilter);
               }
         } elsif ($statusmode eq 'Future') {          } elsif ($statusmode eq 'Future') {
             $description .= &mt('Users in course with future [_1] roles',$showfilter);              if ($crstype eq 'Community') {
                   $description .= &mt('Users in community with future [_1] roles',$showfilter);
               } else {
                   $description .= &mt('Users in course with future [_1] roles',$showfilter);
               }
         } elsif ($statusmode eq 'Active') {          } elsif ($statusmode eq 'Active') {
             $description .= &mt('Users in course with active [_1] roles',$showfilter);              if ($crstype eq 'Community') {
                   $description .= &mt('Users in community with active [_1] roles',$showfilter);
               } else {
                   $description .= &mt('Users in course with active [_1] roles',$showfilter);
               }
         } else {          } else {
             if ($rolefilter eq 'Any') {              if ($rolefilter eq 'Any') {
                 $description .= &mt('All users in course');                  if ($crstype eq 'Community') {
                       $description .= &mt('All users in community');
                   } else {
                       $description .= &mt('All users in course');
                   }
             } else {              } else {
                 $description .= &mt('All users in course with [_1] roles',$rolefilter);                  if ($crstype eq 'Community') {
                       $description .= &mt('All users in community with [_1] roles',$rolefilter);
                   } else {
                       $description .= &mt('All users in course with [_1] roles',$rolefilter);
                   }
             }              }
         }          }
         my $constraint;          my $constraint;
Line 3101  sub results_header_row { Line 4339  sub results_header_row {
         if ($viewablesec ne '') {          if ($viewablesec ne '') {
             if ($env{'form.showrole'} eq 'st') {              if ($env{'form.showrole'} eq 'st') {
                 $constraint = &mt('only users in section "[_1]"',$viewablesec);                  $constraint = &mt('only users in section "[_1]"',$viewablesec);
             } elsif ($env{'form.showrole'} ne 'cc') {              } elsif (($env{'form.showrole'} ne 'cc') && ($env{'form.showrole'} ne 'co')) {
                 $constraint = &mt('only users affiliated with no section or section "[_1]"',$viewablesec);                  $constraint = &mt('only users affiliated with no section or section "[_1]"',$viewablesec);
             }              }
             if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) {              if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) {
Line 3186  sub results_header_row { Line 4424  sub results_header_row {
                 if ($rolefilter eq 'Any') {                  if ($rolefilter eq 'Any') {
                     $description .= &mt('All users with co-author roles in domain',$showfilter);                      $description .= &mt('All users with co-author roles in domain',$showfilter);
                 } else {                  } else {
                     $description .= &mt('All co-authors in domain  with [_1] roles',$rolefilter);                      $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter);
                 }                  }
             }              }
         } elsif ($env{'form.roletype'} eq 'course') {          } elsif (($env{'form.roletype'} eq 'course') || 
                    ($env{'form.roletype'} eq 'community')) {
             my $coursefilter = $env{'form.coursepick'};              my $coursefilter = $env{'form.coursepick'};
             if ($coursefilter eq 'category') {              if ($env{'form.roletype'} eq 'course') {
                 my $instcode = &instcode_from_coursefilter();                  if ($coursefilter eq 'category') {
                 if ($instcode eq '.') {                      my $instcode = &instcode_from_coursefilter();
                       if ($instcode eq '.') {
                           $description .= &mt('All courses in domain').' - ';
                       } else {
                           $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - ';
                       }
                   } elsif ($coursefilter eq 'selected') {
                       $description .= &mt('Selected courses in domain').' - ';
                   } elsif ($coursefilter eq 'all') {
                     $description .= &mt('All courses in domain').' - ';                      $description .= &mt('All courses in domain').' - ';
                 } else {  
                     $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - ';  
                 }                  }
             } elsif ($coursefilter eq 'selected') {              } elsif ($env{'form.roletype'} eq 'community') {
                 $description .= &mt('Selected courses in domain').' - ';                  if ($coursefilter eq 'selected') {
             } elsif ($coursefilter eq 'all') {                      $description .= &mt('Selected communities in domain').' - ';
                 $description .= &mt('All courses in domain').' - ';                  } elsif ($coursefilter eq 'all') {
                       $description .= &mt('All communities in domain').' - ';
                   }
             }              }
             if ($statusmode eq 'Expired') {              if ($statusmode eq 'Expired') {
                 $description .= &mt('users with expired [_1] roles',$showfilter);                  $description .= &mt('users with expired [_1] roles',$showfilter);
Line 3238  sub viewable_section { Line 4485  sub viewable_section {
 #################################################  #################################################
 #################################################  #################################################
 sub show_drop_list {  sub show_drop_list {
     my ($r,$classlist,$nosort,$permission) = @_;      my ($r,$classlist,$nosort,$permission,$crstype) = @_;
     my $cid = $env{'request.course.id'};      my $cid = $env{'request.course.id'};
     my ($cnum,$cdom) = &get_course_identity($cid);      my ($cnum,$cdom) = &get_course_identity($cid);
     if (! exists($env{'form.sortby'})) {      if (! exists($env{'form.sortby'})) {
Line 3256  sub show_drop_list { Line 4503  sub show_drop_list {
 <input type="hidden" name="action" value="$action" />  <input type="hidden" name="action" value="$action" />
 <input type="hidden" name="state"  value="done" />  <input type="hidden" name="state"  value="done" />
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
   // <![CDATA[
 $check_uncheck_js  $check_uncheck_js
   // ]]>
 </script>  </script>
 <p>  
 <input type="hidden" name="phase" value="four" />  <input type="hidden" name="phase" value="four" />
 END  END
     my ($indexhash,$keylist) = &make_keylist_array();      my ($indexhash,$keylist) = &make_keylist_array();
Line 3282  END Line 4530  END
         }          }
     }      }
     if (!$studentcount) {      if (!$studentcount) {
         $r->print(&mt('There are no students to drop.'));         my $msg = '';
           if ($crstype eq 'Community') {
               $msg = &mt('There are no members to drop.');
           } else {
               $msg = &mt('There are no students to drop.');
           }
           $r->print('<p class="LC_info">'.$msg.'</p>');
         return;          return;
     }      }
     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(      my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                                               $classlist,$keylist,$cdom,$cnum);                                                $classlist,$keylist,$cdom,$cnum);
     my %lt=&Apache::lonlocal::texthash('usrn'   => "username",      my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                                        'dom'    => "domain",                                         'dom'    => "domain",
                                          'id'     => "ID",
                                        'sn'     => "student name",                                         'sn'     => "student name",
                                          'mn'     => "member name",
                                        'sec'    => "section",                                         'sec'    => "section",
                                        'start'  => "start date",                                         'start'  => "start date",
                                        'end'    => "end date",                                         'end'    => "end date",
                                        'groups' => "active groups",                                         'groups' => "active groups",
                                       );                                        );
       my $nametitle = $lt{'sn'};
       if ($crstype eq 'Community') {
           $nametitle = $lt{'mn'};
       }
     if ($nosort) {      if ($nosort) {
         $r->print(&Apache::loncommon::start_data_table().          $r->print(&Apache::loncommon::start_data_table().
                   &Apache::loncommon::start_data_table_header_row());                    &Apache::loncommon::start_data_table_header_row());
Line 3302  END Line 4562  END
     <th>&nbsp;</th>      <th>&nbsp;</th>
     <th>$lt{'usrn'}</th>      <th>$lt{'usrn'}</th>
     <th>$lt{'dom'}</th>      <th>$lt{'dom'}</th>
     <th>ID</th>      <th>$lt{'id'}</th>
     <th>$lt{'sn'}</th>      <th>$nametitle</th>
     <th>$lt{'sec'}</th>      <th>$lt{'sec'}</th>
     <th>$lt{'start'}</th>      <th>$lt{'start'}</th>
     <th>$lt{'end'}</th>      <th>$lt{'end'}</th>
Line 3316  END Line 4576  END
         $r->print(<<END);          $r->print(<<END);
     <th>&nbsp;</th>      <th>&nbsp;</th>
     <th>      <th>
        <a href="/adm/createuser?action=$action&sortby=username">$lt{'usrn'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=username">$lt{'usrn'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=domain">$lt{'dom'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=domain">$lt{'dom'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=id">ID</a>         <a href="/adm/createuser?action=$action&amp;sortby=id">$lt{'id'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=fullname">$lt{'sn'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=fullname">$nametitle</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=section">$lt{'sec'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=section">$lt{'sec'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=start">$lt{'start'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=start">$lt{'start'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=end">$lt{'end'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=end">$lt{'end'}</a>
     </th><th>      </th><th>
        <a href="/adm/createuser?action=$action&sortby=groups">$lt{'groups'}</a>         <a href="/adm/createuser?action=$action&amp;sortby=groups">$lt{'groups'}</a>
     </th>      </th>
 END  END
         $r->print(&Apache::loncommon::end_data_table_header_row());          $r->print(&Apache::loncommon::end_data_table_header_row());
Line 3392  END Line 4652  END
     $r->print(&Apache::loncommon::end_data_table().'<br />');      $r->print(&Apache::loncommon::end_data_table().'<br />');
     %lt=&Apache::lonlocal::texthash(      %lt=&Apache::lonlocal::texthash(
                        'dp'   => "Drop Students",                         'dp'   => "Drop Students",
                          'dm'   => "Drop Members",
                        'ca'   => "check all",                         'ca'   => "check all",
                        'ua'   => "uncheck all",                         'ua'   => "uncheck all",
                                        );                                         );
       my $btn = $lt{'dp'};
       if ($crstype eq 'Community') {
           $btn = $lt{'dm'}; 
       }
     $r->print(<<"END");      $r->print(<<"END");
 </p>  
 <p>  <p>
 <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)" /> &nbsp;  <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)" /> &nbsp;
 <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)" />  <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)" />
 </p>  </p>
 <p>  <p>
 <input type="submit" value="$lt{'dp'}" />  <input type="submit" value="$btn" />
 </p>  </p>
 END  END
     return;      return;
Line 3416  sub print_first_users_upload_form { Line 4680  sub print_first_users_upload_form {
     my $str;      my $str;
     $str  = '<input type="hidden" name="phase" value="two" />';      $str  = '<input type="hidden" name="phase" value="two" />';
     $str .= '<input type="hidden" name="action" value="upload" />';      $str .= '<input type="hidden" name="action" value="upload" />';
     $str .= '<input type="hidden"   name="state"  value="got_file" />';      $str .= '<input type="hidden" name="state"  value="got_file" />';
   
       $str .= &Apache::grades::checkforfile_js();
   
     $str .= '<h2>'.&mt('Upload a file containing information about users').'</h2>'."\n";      $str .= '<h2>'.&mt('Upload a file containing information about users').'</h2>'."\n";
     $str .= '<p class="LC_info">'  
            .&mt('Please upload an UTF8 encoded file to ensure a correct character encoding in your classlist.')      # Excel and CSV Help
            .'</p>'."\n";      $str .= '<div class="LC_columnSection">'
     $str .= &Apache::loncommon::upfile_select_html();             .&Apache::loncommon::help_open_topic("Course_Create_Class_List",
     $str .= '<p>';                  &mt("How do I create a users list from a spreadsheet"))
     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",             .' '.&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
                          &mt("How do I create a users list from a spreadsheet")).                  &mt("How do I create a CSV file from a spreadsheet"))
                              "<br />\n";             ."</div>\n";
     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",      $str .= &Apache::lonhtmlcommon::start_pick_box()
                            &mt("How do I create a CSV file from a spreadsheet"));             .&Apache::lonhtmlcommon::row_title(&mt('File'));
     $str .= "</p>\n";      if (&Apache::lonlocal::current_language() ne 'en') {
     $str .= "<p>\n";          if ($context eq 'course') { 
     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.              $str .= '<p class="LC_info">'."\n"
         &mt('Ignore First Line')."</label></p>\n";                     .&mt('Please upload an UTF8 encoded file to ensure a correct character encoding in your classlist.')."\n"
     $str .= '<input type="submit" name="fileupload" value="'.                     .'</p>'."\n";
         &mt('Next').'" />'."<br />\n";          }
     $str .= &Apache::loncommon::end_page();      }
       $str .= &Apache::loncommon::upfile_select_html()
              .&Apache::lonhtmlcommon::row_closure()
              .&Apache::lonhtmlcommon::row_title(
                   '<label for="noFirstLine">'
                  .&mt('Ignore First Line')
                  .'</label>')
              .'<input type="checkbox" name="noFirstLine" id="noFirstLine" />'
              .&Apache::lonhtmlcommon::row_closure(1)
              .&Apache::lonhtmlcommon::end_pick_box();
   
       $str .= '<p>'
              .'<input type="button" name="fileupload" value="'.&mt('Next').'"'
              .' onclick="javascript:checkUpload(this.form);" />'
              .'</p>';
   
     $r->print($str);      $r->print($str);
     return;      return;
 }  }
   
 # ================================================= Drop/Add from uploaded file  # ================================================= Drop/Add from uploaded file
 sub upfile_drop_add {  sub upfile_drop_add {
     my ($r,$context,$permission) = @_;      my ($r,$context,$permission,$showcredits) = @_;
     &Apache::loncommon::load_tmp_file($r);      my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
       if ($datatoken ne '') {
           &Apache::loncommon::load_tmp_file($r,$datatoken);
       }
     my @userdata=&Apache::loncommon::upfile_record_sep();      my @userdata=&Apache::loncommon::upfile_record_sep();
     if($env{'form.noFirstLine'}){shift(@userdata);}      if($env{'form.noFirstLine'}){shift(@userdata);}
     my @keyfields = split(/\,/,$env{'form.keyfields'});      my @keyfields = split(/\,/,$env{'form.keyfields'});
Line 3456  sub upfile_drop_add { Line 4741  sub upfile_drop_add {
             $fields{$env{'form.f'.$i}}=$keyfields[$i];              $fields{$env{'form.f'.$i}}=$keyfields[$i];
         }          }
     }      }
     if ($env{'form.fullup'} ne 'yes') {  
         $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n".  
                   '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />');  
     }  
     #      #
     # Store the field choices away      # Store the field choices away
     foreach my $field (qw/username names      my @storefields = qw/username names fname mname lname gen id 
                        fname mname lname gen id sec ipwd email role domain/) {                           sec ipwd email role domain inststatus/;
       if ($showcredits) {
           push (@storefields,'credits');
       }
       my %fieldstype; 
       foreach my $field (@storefields) {
         $env{'form.'.$field.'_choice'}=$fields{$field};          $env{'form.'.$field.'_choice'}=$fields{$field};
           $fieldstype{$field.'_choice'} = 'scalar';
       }
       &Apache::loncommon::store_course_settings('enrollment_upload',\%fieldstype);
       my ($cid,$crstype,$setting,$crsdom,$crsnum,$oldcrsuserdoms);
       if ($context eq 'domain') {
           $setting = $env{'form.roleaction'};
       }
       if ($env{'request.course.id'} ne '') {
           $cid = $env{'request.course.id'};
           $crstype = &Apache::loncommon::course_type();
           $crsdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           $crsnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       } elsif ($setting eq 'course') {
           if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) {
               $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'};
               $crstype = &Apache::loncommon::course_type($cid);
               $crsdom = $env{'form.dcdomain'};
               $crsnum = $env{'form.dccourse'};
               if (exists($env{'course.'.$cid.'.internal.userdomains'})) {
                   $oldcrsuserdoms = 1;
               }
               my %coursedesc = &Apache::lonnet::coursedescription($cid,{ one_time => 1 });
               $env{'course.'.$cid.'.internal.userdomains'} = $coursedesc{'internal.userdomains'};
           }
     }      }
     &Apache::loncommon::store_course_settings('enrollment_upload',  
                                               { 'username_choice' => 'scalar',  
                                                 'names_choice' => 'scalar',  
                                                 'fname_choice' => 'scalar',  
                                                 'mname_choice' => 'scalar',  
                                                 'lname_choice' => 'scalar',  
                                                 'gen_choice' => 'scalar',  
                                                 'id_choice' => 'scalar',  
                                                 'sec_choice' => 'scalar',  
                                                 'ipwd_choice' => 'scalar',  
                                                 'email_choice' => 'scalar',  
                                                 'role_choice'  => 'scalar',  
                                                 'domain_choice' => 'scalar',  
                                                 'inststatus_choice' => 'scalar'});  
     #  
     my ($startdate,$enddate) = &get_dates_from_form();      my ($startdate,$enddate) = &get_dates_from_form();
     if ($env{'form.makedatesdefault'}) {      if ($env{'form.makedatesdefault'}) {
         $r->print(&make_dates_default($startdate,$enddate,$context));          $r->print(&make_dates_default($startdate,$enddate,$context,$crstype));
     }      }
     # Determine domain and desired host (home server)      # Determine domain and desired host (home server)
     my $defdom=$env{'request.role.domain'};      my $defdom=$env{'request.role.domain'};
     my $domain;      my $domain;
     if ($env{'form.defaultdomain'} ne '') {      if ($env{'form.defaultdomain'} ne '') {
         $domain = $env{'form.defaultdomain'};          if (($context eq 'course') || ($setting eq 'course')) {
               if ($env{'form.defaultdomain'} eq $crsdom) {
                   $domain = $env{'form.defaultdomain'};
               } else {
                   if (&Apache::lonnet::will_trust('enroll',$crsdom,$env{'form.defaultdomain'})) {
                       $domain = $env{'form.defaultdomain'};
                   } else {
                       $r->print('<span class="LC_error">'.&mt('Error').': '.
                                 &mt('Enrollment of users not permitted for specified default domain: [_1].',
                                     &Apache::lonnet::domain($env{'form.defaultdomain'},'description')).'</span>');
                       return 'untrusted';
                   }
               }
           } elsif ($context eq 'author') {
               if ($env{'form.defaultdomain'} eq $defdom) {
                   $domain = $env{'form.defaultdomain'}; 
               } else {
                   if ((&Apache::lonnet::will_trust('othcoau',$defdom,$env{'form.defaultdomain'})) &&
                       (&Apache::lonnet::will_trust('coaurem',$env{'form.defaultdomain'},$defdom))) {
                       $domain = $env{'form.defaultdomain'};
                   } else {
                       $r->print('<span class="LC_error">'.&mt('Error').': '.
                                 &mt('Addition of users not permitted for specified default domain: [_1].',
                                     &Apache::lonnet::domain($env{'form.defaultdomain'},'description')).'</span>');
                       return 'untrusted';
                   }
               }
           } elsif (($context eq 'domain') && ($setting eq 'domain')) {
               if ($env{'form.defaultdomain'} eq $defdom) {
                   $domain = $env{'form.defaultdomain'};
               } else {
                   if (&Apache::lonnet::will_trust('domroles',$defdom,$env{'form.defaultdomain'})) {
                       $domain = $env{'form.defaultdomain'};
                   } else {
                       $r->print('<span class="LC_error">'.&mt('Error').': '.
                                 &mt('Addition of users not permitted for specified default domain: [_1].',
                                     &Apache::lonnet::domain($env{'form.defaultdomain'},'description')).'</span>');
                       return 'untrusted';
                   }
               }
           }
     } else {      } else {
         $domain = $defdom;          $domain = $defdom;
     }      }
Line 3499  sub upfile_drop_add { Line 4834  sub upfile_drop_add {
     } else {      } else {
         my %home_servers = &Apache::lonnet::get_servers($defdom,'library');          my %home_servers = &Apache::lonnet::get_servers($defdom,'library');
         if (! exists($home_servers{$desiredhost})) {          if (! exists($home_servers{$desiredhost})) {
             $r->print('<span class="LC_error">'.&mt('Error').              $r->print('<p class="LC_error">'.&mt('Error').': '.
                       &mt('Invalid home server specified').'</span>');                        &mt('Invalid home server specified').'</p>');
             $r->print(&Apache::loncommon::end_page());              return 'invalidhome';
             return;  
         }          }
     }      }
     # Determine authentication mechanism      # Determine authentication mechanism
Line 3512  sub upfile_drop_add { Line 4846  sub upfile_drop_add {
     }      }
     my $amode  = '';      my $amode  = '';
     my $genpwd = '';      my $genpwd = '';
       my @genpwdfail;
     if ($env{'form.login'} eq 'krb') {      if ($env{'form.login'} eq 'krb') {
         $amode='krb';          $amode='krb';
         $amode.=$env{'form.krbver'};          $amode.=$env{'form.krbver'};
Line 3520  sub upfile_drop_add { Line 4855  sub upfile_drop_add {
         $amode='internal';          $amode='internal';
         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {          if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
             $genpwd=$env{'form.intarg'};              $genpwd=$env{'form.intarg'};
               @genpwdfail =
                   &Apache::loncommon::check_passwd_rules($domain,$genpwd);
         }          }
     } elsif ($env{'form.login'} eq 'loc') {      } elsif ($env{'form.login'} eq 'loc') {
         $amode='localauth';          $amode='localauth';
         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {          if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
             $genpwd=$env{'form.locarg'};              $genpwd=$env{'form.locarg'};
         }          }
       } elsif ($env{'form.login'} eq 'lti') {
           $amode='lti';
     }      }
     if ($amode =~ /^krb/) {      if ($amode =~ /^krb/) {
         if (! defined($genpwd) || $genpwd eq '') {          if (! defined($genpwd) || $genpwd eq '') {
Line 3535  sub upfile_drop_add { Line 4874  sub upfile_drop_add {
             $amode = ''; # This causes the loop below to be skipped              $amode = ''; # This causes the loop below to be skipped
         }          }
     }      }
     my ($cid,$defaultsec,$defaultrole,$setting);      my ($defaultsec,$defaultrole,$defaultcredits,$commoncredits);
     if ($context eq 'domain') {      if ($context eq 'domain') {
         $setting = $env{'form.roleaction'};  
         if ($setting eq 'domain') {          if ($setting eq 'domain') {
             $defaultrole = $env{'form.defaultrole'};              $defaultrole = $env{'form.defaultrole'};
         } elsif ($setting eq 'course') {          } elsif ($setting eq 'course') {
             $defaultrole = $env{'form.courserole'};              $defaultrole = $env{'form.courserole'};
             $defaultsec = $env{'form.sections'};              $defaultsec = $env{'form.sections'};
         }                if ($showcredits) {
                   $commoncredits = $env{'form.credits'};
                   if ($crstype ne 'Community') {
                       my %coursehash=&Apache::lonnet::coursedescription($cid);
                       $defaultcredits = $coursehash{'internal.defaultcredits'};
                   }
               }
           }
     } elsif ($context eq 'author') {      } elsif ($context eq 'author') {
         $defaultrole = $env{'form.defaultrole'};          $defaultrole = $env{'form.defaultrole'};
     } elsif ($context eq 'course') {      } elsif ($context eq 'course') {
         $defaultrole = $env{'form.defaultrole'};          $defaultrole = $env{'form.defaultrole'};
         $defaultsec = $env{'form.sections'};          $defaultsec = $env{'form.sections'};
     }          if ($showcredits) {
     if ($env{'request.course.id'} ne '') {              $commoncredits = $env{'form.credits'};
         $cid = $env{'request.course.id'};              $defaultcredits = $env{'course.'.$cid.'.internal.defaultcredits'};
     } elsif ($setting eq 'course') {  
         if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) {  
             $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'};  
         }          }
     }      }
     # Check to see if user information can be changed      # Check to see if user information can be changed
Line 3569  sub upfile_drop_add { Line 4911  sub upfile_drop_add {
     }      }
     my (%userlist,%modifiable_fields,@poss_roles);      my (%userlist,%modifiable_fields,@poss_roles);
     my $secidx = &Apache::loncoursedata::CL_SECTION();      my $secidx = &Apache::loncoursedata::CL_SECTION();
     my @courseroles = &roles_by_context('course',1);      my @courseroles = &roles_by_context('course',1,$crstype);
     if (!&Apache::lonnet::allowed('mau',$domain)) {      if (!&Apache::lonnet::allowed('mau',$domain)) {
         if ($context eq 'course' || $context eq 'author') {          if ($context eq 'course' || $context eq 'author') {
             @poss_roles =  &curr_role_permissions($context);              @poss_roles =  &curr_role_permissions($context,'','',$crstype);
             my @statuses = ('active','future');              my @statuses = ('active','future');
             my ($indexhash,$keylist) = &make_keylist_array();              my ($indexhash,$keylist) = &make_keylist_array();
             my %info;              my %info;
Line 3595  sub upfile_drop_add { Line 4937  sub upfile_drop_add {
                                                   \@statuses,\@poss_roles);                                                    \@statuses,\@poss_roles);
                 &gather_userinfo($context,'view',\%userlist,$indexhash,\%info,                  &gather_userinfo($context,'view',\%userlist,$indexhash,\%info,
                              \%cstr_roles,$permission);                               \%cstr_roles,$permission);
   
             }              }
         }          }
     }      }
       if ($datatoken eq '') {
           $r->print('<p class="LC_error">'.&mt('Error').': '.
                     &mt('Invalid datatoken').'</p>');
           return 'missingdata';
       }
     if ( $domain eq &LONCAPA::clean_domain($domain)      if ( $domain eq &LONCAPA::clean_domain($domain)
         && ($amode ne '')) {          && ($amode ne '')) {
         #######################################          #######################################
Line 3612  sub upfile_drop_add { Line 4958  sub upfile_drop_add {
             $r->print('<h3>'.&mt('Adding/Modifying Users')."</h3>\n<p>\n");              $r->print('<h3>'.&mt('Adding/Modifying Users')."</h3>\n<p>\n");
         }          }
         $r->rflush;          $r->rflush;
           my (%got_role_approvals,%got_instdoms,%process_by,%instdoms,
               %pending,%reject,%notifydc,%status,%unauthorized,%currqueued);
   
         my %counts = (          my %counts = (
                        user => 0,                         user => 0,
Line 3657  sub upfile_drop_add { Line 5005  sub upfile_drop_add {
                 $r->print($groupwarn.'<br />');                  $r->print($groupwarn.'<br />');
             }              }
         }          }
         my (%curr_rules,%got_rules,%alerts);          my (%curr_rules,%got_rules,%alerts,%cancreate);
         my %customroles = &my_custom_roles();          my %customroles = &my_custom_roles($crstype);
         my @permitted_roles = &roles_on_upload($context,$setting,%customroles);           my @permitted_roles = 
               &roles_on_upload($context,$setting,$crstype,%customroles);
           my %longtypes = &Apache::lonlocal::texthash(
                               official   => 'Institutional',
                               unofficial => 'Non-institutional',
                           );
           my $newuserdom = $env{'request.role.domain'};
           map { $cancreate{$_} = &can_create_user($newuserdom,$context,$_); } keys(%longtypes);
         # Get new users list          # Get new users list
           my (%existinguser,%userinfo,%disallow,%rulematch,%inst_results,%alerts,%checkuname,
               %showpasswdrules,$haspasswdmap);
           my $counter = -1;
           my (%willtrust,%trustchecked);
         foreach my $line (@userdata) {          foreach my $line (@userdata) {
               $counter ++;
             my @secs;              my @secs;
             my %entries=&Apache::loncommon::record_sep($line);              my %entries=&Apache::loncommon::record_sep($line);
             # Determine user name              # Determine user name
               $entries{$fields{'username'}} =~ s/^\s+|\s+$//g;
             unless (($entries{$fields{'username'}} eq '') ||              unless (($entries{$fields{'username'}} eq '') ||
                     (!defined($entries{$fields{'username'}}))) {                      (!defined($entries{$fields{'username'}}))) {
                 my ($fname, $mname, $lname,$gen) = ('','','','');                  my ($fname, $mname, $lname,$gen) = ('','','','');
Line 3685  sub upfile_drop_add { Line 5046  sub upfile_drop_add {
                         $gen=$entries{$fields{'gen'}};                          $gen=$entries{$fields{'gen'}};
                     }                      }
                 }                  }
   
                 if ($entries{$fields{'username'}}                  if ($entries{$fields{'username'}}
                     ne &LONCAPA::clean_username($entries{$fields{'username'}})) {                      ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
                     $r->print('<br />'.                      my $nowhitespace;
       &mt('[_1]: Unacceptable username for user [_2] [_3] [_4] [_5]',                      if ($entries{$fields{'username'}} =~ /\s/) {
           '<b>'.$entries{$fields{'username'}}.'</b>',$fname,$mname,$lname,$gen));                          $nowhitespace = ' - '.&mt('usernames may not contain spaces.');
                       }
                       $disallow{$counter} =
                           &mt('Unacceptable username [_1] for user [_2] [_3] [_4] [_5]',
                               '"<b>'.$entries{$fields{'username'}}.'</b>"',
                               $fname,$mname,$lname,$gen).$nowhitespace;
                     next;                      next;
                 } else {                  } else {
                       $entries{$fields{'domain'}} =~ s/^\s+|\s+$//g;
                     if ($entries{$fields{'domain'}}                       if ($entries{$fields{'domain'}} 
                         ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) {                          ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) {
                         $r->print('<br />'. '<b>'.$entries{$fields{'domain'}}.                          $disallow{$counter} =
                                   '</b>: '.&mt('Unacceptable domain for user [_2] [_3] [_4] [_5]',$fname,$mname,$lname,$gen));                              &mt('Unacceptable domain [_1] for user [_2] [_3] [_4] [_5]',
                                   '"<b>'.$entries{$fields{'domain'}}.'</b>"',
                                   $fname,$mname,$lname,$gen);
                         next;                          next;
                       } elsif ($entries{$fields{'domain'}} ne $domain) {
                           my $possdom = $entries{$fields{'domain'}};
                           if ($context eq 'course' || $setting eq 'course') {
                               unless ($trustchecked{$possdom}) {
                                   $willtrust{$possdom} = &Apache::lonnet::will_trust('enroll',$domain,$possdom);
                                   $trustchecked{$possdom} = 1;
                               }
                           } elsif ($context eq 'author') {
                               unless ($trustchecked{$possdom}) {
                                   $willtrust{$possdom} = &Apache::lonnet::will_trust('othcoau',$domain,$possdom);
                               }
                               if ($willtrust{$possdom}) {
                                   $willtrust{$possdom} = &Apache::lonnet::will_trust('coaurem',$possdom,$domain); 
                               }
                           }
                           unless ($willtrust{$possdom}) {
                               $disallow{$counter} =
                                   &mt('Unacceptable domain [_1] for user [_2] [_3] [_4] [_5]',
                                       '"<b>'.$possdom.'</b>"',
                                       $fname,$mname,$lname,$gen);
                               next;
                           }
                     }                      }
                     my $username = $entries{$fields{'username'}};                      my $username = $entries{$fields{'username'}};
                     my $userdomain = $entries{$fields{'domain'}};                      my $userdomain = $entries{$fields{'domain'}};
Line 3708  sub upfile_drop_add { Line 5100  sub upfile_drop_add {
                             $entries{$fields{'sec'}} =~ s/\W//g;                              $entries{$fields{'sec'}} =~ s/\W//g;
                             my $item = $entries{$fields{'sec'}};                              my $item = $entries{$fields{'sec'}};
                             if ($item eq "none" || $item eq 'all') {                              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;                                  next;
                             } elsif (exists($curr_groups{$item})) {                              } 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;                                  next;
                             } else {                              } else {
                                 push(@secs,$item);                                  push(@secs,$item);
Line 3723  sub upfile_drop_add { Line 5120  sub upfile_drop_add {
                         if (ref($userlist{$username.':'.$userdomain}) eq 'ARRAY') {                          if (ref($userlist{$username.':'.$userdomain}) eq 'ARRAY') {
                             my $currsec = $userlist{$username.':'.$userdomain}[$secidx];                              my $currsec = $userlist{$username.':'.$userdomain}[$secidx];
                             if ($currsec ne $env{'request.course.sec'}) {                              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 '') {                                  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 {                                  } 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;                                  next;
                             }                              }
                         }                          }
Line 3750  sub upfile_drop_add { Line 5154  sub upfile_drop_add {
                     # determine email address                      # determine email address
                     my $email='';                      my $email='';
                     if (defined($fields{'email'})) {                      if (defined($fields{'email'})) {
                           $entries{$fields{'email'}} =~ s/^\s+|\s+$//g;
                         if (defined($entries{$fields{'email'}})) {                          if (defined($entries{$fields{'email'}})) {
                             $email=$entries{$fields{'email'}};                              $email=$entries{$fields{'email'}};
                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }                              unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
Line 3763  sub upfile_drop_add { Line 5168  sub upfile_drop_add {
                         }                          }
                     }                      }
                     # determine user password                      # determine user password
                     my $password = $genpwd;                      my $password;
                       my $passwdfromfile;
                     if (defined($fields{'ipwd'})) {                      if (defined($fields{'ipwd'})) {
                         if ($entries{$fields{'ipwd'}}) {                          if ($entries{$fields{'ipwd'}}) {
                             $password=$entries{$fields{'ipwd'}};                              $password=$entries{$fields{'ipwd'}};
                               $passwdfromfile = 1;
                               if ($env{'form.login'} eq 'int') {
                                   my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
                                   if (($uhome eq 'no_host') || ($changeauth)) {
                                       my @brokepwdrules =
                                           &Apache::loncommon::check_passwd_rules($domain,$password);
                                       if (@brokepwdrules) {
                                           $disallow{$counter} = &mt('[_1]: Password included in file for this user did not meet requirements.',
                                                                     '<b>'.$username.'</b>');
                                           map { $showpasswdrules{$_} = 1; } @brokepwdrules;
                                           next;
                                       }
                                   }
                               }
                           }
                       }
                       unless ($passwdfromfile) {
                           if ($env{'form.login'} eq 'int') {
                               if (@genpwdfail) {
                                   my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
                                   if (($uhome eq 'no_host') || ($changeauth)) {
                                       $disallow{$counter} = &mt('[_1]: No specific password in file for this user; default password did not meet requirements',
                                                                 '<b>'.$username.'</b>');
                                       unless ($haspasswdmap) {
                                           map { $showpasswdrules{$_} = 1; } @genpwdfail;
                                           $haspasswdmap = 1;
                                       }
                                   }
                                   next;
                               }
                         }                          }
                           $password = $genpwd;
                     }                      }
                     # determine user role                      # determine user role
                     my $role = '';                      my $role = '';
Line 3781  sub upfile_drop_add { Line 5218  sub upfile_drop_add {
                             }                              }
                             if ($role eq '') {                              if ($role eq '') {
                                 my $rolestr = join(', ',@permitted_roles);                                  my $rolestr = join(', ',@permitted_roles);
                                 $r->print('<br />'                                  $disallow{$counter} =
                                          .&mt('[_1]: You do not have permission to add the requested role [_2] for the user.'                                      &mt('[_1]: You do not have permission to add the requested role [_2] for the user.'
                                              ,'<b>'.$entries{$fields{'username'}}.'</b>'                                          ,'<b>'.$entries{$fields{'username'}}.'</b>'
                                              ,$entries{$fields{'role'}})                                          ,$entries{$fields{'role'}})
                                          .'<br />'                                          .'<br />'
                                          .&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n"                                          .&mt('Allowable role(s) is/are: [_1].',$rolestr);
                                 );  
                                 next;                                  next;
                             }                              }
                         }                          }
Line 3796  sub upfile_drop_add { Line 5232  sub upfile_drop_add {
                         $role = $defaultrole;                          $role = $defaultrole;
                     }                      }
                     # Clean up whitespace                      # Clean up whitespace
                     foreach (\$id,\$fname,\$mname,\$lname,\$gen) {                      foreach (\$id,\$fname,\$mname,\$lname,\$gen,\$inststatus) {
                         $$_ =~ s/(\s+$|^\s+)//g;                          $$_ =~ s/(\s+$|^\s+)//g;
                     }                      }
                       my $credits;
                       if ($showcredits) {
                           if (($role eq 'st') && ($crstype ne 'Community')) {
                               $credits = $entries{$fields{'credits'}};
                               if ($credits ne '') {
                                   $credits =~ s/[^\d\.]//g;
                               }
                               if ($credits eq '') {
                                   $credits = $commoncredits;
                               }
                               if ($credits eq $defaultcredits) {
                                   undef($credits);
                               }
                           }
                       }
                     # check against rules                      # check against rules
                     my $checkid = 0;                      my $checkid = 0;
                     my $newuser = 0;                      my $newuser = 0;
                     my (%rulematch,%inst_results,%idinst_results);  
                     my $uhome=&Apache::lonnet::homeserver($username,$userdomain);                      my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
                     if ($uhome eq 'no_host') {                      if ($uhome eq 'no_host') {
                         next if ($userdomain ne $domain);                          if ($userdomain ne $newuserdom) {
                         $checkid = 1;                              if ($context eq 'course') {
                         $newuser = 1;                                  $disallow{$counter} =
                         my $checkhash;                                      &mt('[_1]: The domain specified ([_2]) is different to that of the course.',
                         my $checks = { 'username' => 1 };                                         '<b>'.$username.'</b>',$userdomain);
                         $checkhash->{$username.':'.$domain} = { 'newuser' => 1, };                              } elsif ($context eq 'author') {
                         &Apache::loncommon::user_rule_check($checkhash,$checks,                                  $disallow{$counter} =
                             \%alerts,\%rulematch,\%inst_results,\%curr_rules,                                      &mt('[_1]: The domain specified ([_2]) is different to that of the author.',
                             \%got_rules);                                          '<b>'.$username.'</b>',$userdomain); 
                         if (ref($alerts{'username'}) eq 'HASH') {                              } else {
                             if (ref($alerts{'username'}{$domain}) eq 'HASH') {                                  $disallow{$counter} =
                                 next if ($alerts{'username'}{$domain}{$username});                                      &mt('[_1]: The domain specified ([_2]) is different to that of your current role.',
                                           '<b>'.$username.'</b>',$userdomain);
                               }
                               $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 ne '') || ($env{'form.login'} eq 'loc') || ($env{'form.login'} eq 'lti')) {
                                   $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;
                           $checkuname{$username.':'.$newuserdom} = { 'newuser' => $newuser, 'id' => $id };
                     } else {                      } else {
                         if ($context eq 'course' || $context eq 'author') {                          if ($context eq 'course' || $context eq 'author') {
                             if ($userdomain eq $domain ) {                              if ($userdomain eq $domain ) {
Line 3851  sub upfile_drop_add { Line 5315  sub upfile_drop_add {
                                 }                                  }
                             }                              }
                         }                          }
                           if ($id) {
                               $existinguser{$userdomain}{$username} = $id;
                           }
                       }
                       $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 %checkids;
               if ((keys(%existinguser)) || (keys(%checkuname))) {
                   $r->print(&mt('Please be patient -- checking for institutional data ...'));
                   $r->rflush();
                   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 (keys(%checkids)) {
                                   &Apache::loncommon::user_rule_check(\%checkids,{ 'id' => 1 },
                                                                       \%alerts,\%rulematch,
                                                                       \%inst_results,\%curr_rules,
                                                                       \%got_rules);
                               }
                           }
                     }                      }
                     if ($id ne '') {                  }
                         if (!$newuser) {                  if (keys(%checkuname)) {
                             my %idhash = &Apache::lonnet::idrget($userdomain,($username));                      &Apache::loncommon::user_rule_check(\%checkuname,{ 'username' => 1, 'id' => 1, },
                             if ($idhash{$username} ne $id) {                                                          \%alerts,\%rulematch,\%inst_results,
                                 $checkid = 1;                                                          \%curr_rules,\%got_rules);
                   }
                   $r->print(' '.&mt('done').'<br /><br />');
                   $r->rflush();
               }
               my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,$total);
               $r->print('<ul>');
               for (my $i=0; $i<=$counter; $i++) {
                   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;
                                   }
                               }
                           }
                           if (ref($inst_results{$user}) eq 'HASH') {
                               if ($inst_results{$user}{'firstname'} ne '') {
                                   $fname = $inst_results{$user}{'firstname'};
                               }
                               if ($inst_results{$user}{'middlename'} ne '') {
                                   $mname = $inst_results{$user}{'middlename'};
                               }
                               if ($inst_results{$user}{'lasttname'} ne '') {
                                   $lname = $inst_results{$user}{'lastname'};
                               }
                               if ($inst_results{$user}{'permanentemail'} ne '') {
                                   $email = $inst_results{$user}{'permanentemail'};
                               }
                               if ($inst_results{$user}{'id'} ne '') {
                                   $id = $inst_results{$user}{'id'};
                                   $checkid = 0;
                               }
                               if (ref($inst_results{$user}{'inststatus'}) eq 'ARRAY') {
                                   $inststatus = join(':',@{$inst_results{$user}{'inststatus'}});
                               }
                           }
                           if (($checkid) && ($id ne '')) {
                               if (ref($alerts{'id'}) eq 'HASH') {
                                   if (ref($alerts{'id'}{$userdomain}) eq 'HASH') {
                                       if ($alerts{'id'}{$userdomain}{$username}) {
                                           $r->print('<li>'.
                                                     &mt('[_1]: has a student/employee ID matching the format at your institution, but the ID is not found by your directory service.',
                                                     '<b>'.$username.'</b>').'<br />'.
                                                     &mt('Consequently, the user was not created.').'</li>');
                                           next;
                                       }
                                   }
                             }                              }
                         }                          }
                         if ($checkid) {                          my $usertype = 'unofficial';
                             my $checkhash;                          if (ref($rulematch{$user}) eq 'HASH') {
                             my $checks = { 'id' => 1 };                              if ($rulematch{$user}{'username'}) {
                             $checkhash->{$username.':'.$userdomain} = { 'newuser' => $newuser,                                  $usertype = 'official';
                                                                     'id'  => $id };                              }
                             &Apache::loncommon::user_rule_check($checkhash,$checks,                          }
                                 \%alerts,\%rulematch,\%idinst_results,\%curr_rules,                          unless ($cancreate{$usertype}) {
                                 \%got_rules);                              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;
                           }
                       } elsif ($id ne '') {
                           if (exists($checkids{$user})) {
                               $checkid = 1; 
                             if (ref($alerts{'id'}) eq 'HASH') {                              if (ref($alerts{'id'}) eq 'HASH') {
                                 if (ref($alerts{'id'}{$userdomain}) eq 'HASH') {                                  if (ref($alerts{'id'}{$userdomain}) eq 'HASH') {
                                     next if ($alerts{'id'}{$userdomain}{$id});                                      if ($alerts{'id'}{$userdomain}{$username}) {
                                           $r->print('<li>'.
                                                     &mt('[_1]: has a student/employee ID matching the format at your institution, but the ID is not found by your directory service.',
                                                     '<b>'.$username.'</b>').'<br />'.
                                                     &mt('Consequently, the ID was not changed.').'</li>');
                                           $id = '';
                                       }
                                 }                                  }
                             }                              }
                         }                          }
                     }                      }
                     if ($password || $env{'form.login'} eq 'loc') {                      my $multiple = 0;
                         my $multiple = 0;                      my ($userresult,$authresult,$roleresult,$idresult);
                         my ($userresult,$authresult,$roleresult,$idresult);                      my (%userres,%authres,%roleres,%idres);
                         my (%userres,%authres,%roleres,%idres);                      my $singlesec = '';
                         my $singlesec = '';                      if ($role eq 'st') {
                         if ($role eq 'st') {                          if (($context eq 'domain') && ($changeauth eq 'Yes') && (!$newuser)) {
                             my $sec;                              if ((&Apache::lonnet::allowed('mau',$userdomain)) &&
                                   (&Apache::lonnet::homeserver($username,$userdomain) ne 'no_host')) {
                                   if ((($amode =~ /^krb4|krb5|internal$/) && $password ne '') ||
                                        ($amode eq 'localauth')) {
                                       $authresult =
                                           &Apache::lonnet::modifyuserauth($userdomain,$username,$amode,$password);
                                   }
                               }
                           }
                           my $sec;
                           if (ref($userinfo{$i}{'sections'}) eq 'ARRAY') {
                             if (@secs > 0) {                              if (@secs > 0) {
                                 $sec = $secs[0];                                  $sec = $secs[0];
                             }                              }
                             &modifystudent($userdomain,$username,$cid,$sec,                          }
                                            $desiredhost,$context);                          if ($userdomain ne $env{'request.role.domain'}) {
                             $roleresult =                              my $item = "/$crsdom/$crsnum" ;
                                 &Apache::lonnet::modifystudent                              if ($sec ne '') {
                                     ($userdomain,$username,$id,$amode,$password,                                  $item .= "/$sec";
                                      $fname,$mname,$lname,$gen,$sec,$enddate,                              }
                                      $startdate,$env{'form.forceid'},                              $item .= '_st';
                                      $desiredhost,$email,'manual','',$cid,                              next if (&restricted_dom($context,$item,$userdomain,$username,$role,$startdate,
                                      '',$context,$inststatus);                                                       $enddate,$crsdom,$crsnum,$sec,$credits,\%process_by,
                             $userresult = $roleresult;                                                       \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject,
                         } else {                                                       \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued));
                             if ($role ne '') {                           }
                                 if ($context eq 'course' || $setting eq 'course') {                          &modifystudent($userdomain,$username,$cid,$sec,
                                     if ($customroles{$role}) {                                         $desiredhost,$context);
                                         $role = 'cr_'.$env{'user.domain'}.'_'.                          $roleresult =
                                                 $env{'user.name'}.'_'.$role;                              &Apache::lonnet::modifystudent
                                     }                                  ($userdomain,$username,$id,$amode,$password,
                                     if ($role ne 'cc') {                                    $fname,$mname,$lname,$gen,$sec,$enddate,
                                         if (@secs > 1) {                                   $startdate,$env{'form.forceid'},
                                             $multiple = 1;                                   $desiredhost,$email,'manual','',$cid,
                                             foreach my $sec (@secs) {                                   '',$context,$inststatus,$credits);
                                                 ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) =                          $userresult = $roleresult;
                                                 &modifyuserrole($context,$setting,                      } else {
                                                     $changeauth,$cid,$userdomain,$username,                          my $possrole;
                                                     $id,$amode,$password,$fname,                          if ($role ne '') {
                                                     $mname,$lname,$gen,$sec,                              if ($context eq 'course' || $setting eq 'course') {
                                                     $env{'form.forceid'},$desiredhost,                                  if ($customroles{$role}) {
                                                     $email,$role,$enddate,                                      $role = 'cr_'.$env{'user.domain'}.'_'.
                                                     $startdate,$checkid,$inststatus);                                              $env{'user.name'}.'_'.$role;
                                   }
                                   $possrole = $role;
                                   if ($possrole =~ /^cr_/) {
                                       $possrole =~ s{_}{/}g;
                                   }
                                   if (($role ne 'cc') && ($role ne 'co')) {
                                      if (@secs > 1) {
                                           $multiple = 1;
                                           my $prefix = "/$crsdom/$crsnum";
                                           foreach my $sec (@secs) {
                                               if ($userdomain ne $env{'request.role.domain'}) {
                                                   my $item = $prefix;
                                                   if ($sec ne '') {
                                                       $item .= "/$sec";
                                                   }
                                                   $item .= '_'.$possrole;
                                                   next if (&restricted_dom($context,$item,$userdomain,$username,$possrole,
                                                                            $startdate,$enddate,$crsdom,$crsnum,$sec,
                                                                            $credits,\%process_by,\%instdoms,\%got_role_approvals,
                                                                            \%got_instdoms,\%reject,\%pending,\%notifydc,
                                                                            \%status,\%unauthorized,\%currqueued));
                                             }                                              }
                                         } elsif (@secs > 0) {                                              ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) =
                                             $singlesec = $secs[0];                                              &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];
                                     }                                      }
                                 }                                  }
                               } else {
                                   $possrole = $role;
                             }                              }
                             if (!$multiple) {                          }
                                 ($userresult,$authresult,$roleresult,$idresult) =                           if (!$multiple) {
                                     &modifyuserrole($context,$setting,                              if (($userdomain ne $env{'request.role.domain'}) && ($role ne '')) {
                                                     $changeauth,$cid,$userdomain,$username,                                   my $item = "/$crsdom/$crsnum";
                                                     $id,$amode,$password,$fname,                                  if ($singlesec ne '') {
                                                     $mname,$lname,$gen,$singlesec,                                      $item .= "/$singlesec";
                                                     $env{'form.forceid'},$desiredhost,                                  }
                                                     $email,$role,$enddate,$startdate,                                  $item .= '_'.$possrole;
                                                     $checkid,$inststatus);                                  next if (&restricted_dom($context,$item,$userdomain,$username,$possrole,$startdate,$enddate,
                                                            $crsdom,$crsnum,$singlesec,$credits,\%process_by,\%instdoms,
                                                            \%got_role_approvals,\%got_instdoms,\%reject,\%pending,\%notifydc,
                                                            \%status,\%unauthorized,\%currqueued));
                             }                              }
                               ($userresult,$authresult,$roleresult,$idresult) = 
                                   &modifyuserrole($context,$setting,
                                                   $changeauth,$cid,$userdomain,$username, 
                                                   $id,$amode,$password,$fname,
                                                   $mname,$lname,$gen,$singlesec,
                                                   $env{'form.forceid'},$desiredhost,
                                                   $email,$role,$enddate,$startdate,
                                                   $checkid,$inststatus);
                         }                          }
                         if ($multiple) {                      }
                             foreach my $sec (sort(keys(%userres))) {                      if ($multiple) {
                                 $flushc =                          foreach my $sec (sort(keys(%userres))) {
                               $flushc =
                                 &user_change_result($r,$userres{$sec},$authres{$sec},                                  &user_change_result($r,$userres{$sec},$authres{$sec},
                                                     $roleres{$sec},$idres{$sec},\%counts,$flushc,                                                      $roleres{$sec},$idres{$sec},\%counts,$flushc,
                                                     $username,$userdomain,\%userchg);                                                      $username,$userdomain,\%userchg);
   
                             }  
                         } else {  
                             $flushc =   
                                 &user_change_result($r,$userresult,$authresult,  
                                                     $roleresult,$idresult,\%counts,$flushc,  
                                                     $username,$userdomain,\%userchg);  
                         }                          }
                     } else {                      } else {
                         if ($context eq 'course') {                          $flushc = 
                             $r->print('<br />'.                               &user_change_result($r,$userresult,$authresult,
       &mt('[_1]: Unable to enroll. No password specified.','<b>'.$username.'</b>')                                                  $roleresult,$idresult,\%counts,$flushc,
                                      );                                                  $username,$userdomain,\%userchg);
                         } elsif ($context eq 'author') {                      }
                             $r->print('<br />'.                  }
       &mt('[_1]: Unable to add co-author. No password specified.','<b>'.$username.'</b>')                  &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last user');
                                      );              } # end of loop
                         } else {              $r->print('</ul>');
                             $r->print('<br />'.              &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
       &mt('[_1]: Unable to add user. No password specified.','<b>'.$username.'</b>')              if (($context eq 'domain') && ($setting eq 'course')) {
                                      );                  unless ($oldcrsuserdoms) {
                         }                      if (exists($env{'course.'.$cid.'.internal.userdomains'})) {
                           delete($env{'course.'.$cid.'.internal.userdomains'});
                     }                      }
                 }                  }
             }              }
         } # end of foreach (@userdata)          }
         # Flush the course logs so reverse user roles immediately updated          # Flush the course logs so reverse user roles immediately updated
         &Apache::lonnet::flushcourselogs();          $r->register_cleanup(\&Apache::lonnet::flushcourselogs);
         $r->print("</p>\n<p>\n".&mt('Processed [quant,_1,user].',$counts{'user'}).          $r->print("</p>\n<p>\n".&mt('Processed [quant,_1,user].',$counts{'user'}).
                   "</p>\n");                    "</p>\n");
         if ($counts{'role'} > 0) {          if ($counts{'role'} > 0) {
             $r->print("<p>\n".              $r->print("<p>\n".
                       &mt('Roles added for [quant,_1,user].',$counts{'role'}).' '.&mt('If a user is currently logged-in to LON-CAPA, any new roles which are active will be available when the user next logs in.')."</p>\n");                        &mt('Roles added for [quant,_1,user].',$counts{'role'}).' '.
                         &mt('If a user is currently logged-in to LON-CAPA, any new roles which are active will be available when the user next logs in.').
                         "</p>\n");
         } else {          } else {
             $r->print('<p>'.&mt('No roles added').'</p>');              $r->print('<p>'.&mt('No roles added').'</p>');
         }          }
Line 3979  sub upfile_drop_add { Line 5626  sub upfile_drop_add {
                           $counts{'auth'})."</p>\n");                            $counts{'auth'})."</p>\n");
         }          }
         $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules));          $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules));
           $r->print(&passwdrule_alerts($domain,\%showpasswdrules));
           if ((keys(%reject)) || (keys(%unauthorized))) {
               $r->print(&print_roles_rejected($context,\%reject,\%unauthorized));
           }
           if ((keys(%pending)) || (keys(%currqueued))) {
               $r->print(&print_roles_queued($context,\%pending,\%notifydc,\%currqueued));
           }
         #####################################          #####################################
         # Display list of students to drop  #          # Display list of students to drop  #
         #####################################          #####################################
Line 3987  sub upfile_drop_add { Line 5641  sub upfile_drop_add {
             #  Get current classlist              #  Get current classlist
             my $classlist = &Apache::loncoursedata::get_classlist();              my $classlist = &Apache::loncoursedata::get_classlist();
             if (! defined($classlist)) {              if (! defined($classlist)) {
                 $r->print('<form name="studentform" method="post" action="/adm/createuser" />'.                  $r->print('<p class="LC_info">'.
                           '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'.  
                           &mt('There are no students with current/future access to the course.').                            &mt('There are no students with current/future access to the course.').
                           '</form>'."\n");                            '</p>'."\n");
             } elsif (ref($classlist) eq 'HASH') {              } elsif (ref($classlist) eq 'HASH') {
                 # Remove the students we just added from the list of students.                  # Remove the students we just added from the list of students.
                 foreach my $line (@userdata) {                  foreach my $line (@userdata) {
Line 4006  sub upfile_drop_add { Line 5659  sub upfile_drop_add {
             }              }
         }          }
     } # end of unless      } # end of unless
     if ($env{'form.fullup'} ne 'yes') {      return 'ok';
         $r->print('</form>');  
     }  
 }  }
   
 sub print_namespacing_alerts {  sub print_namespacing_alerts {
Line 4051  sub print_namespacing_alerts { Line 5702  sub print_namespacing_alerts {
     }      }
 }  }
   
   sub passwdrule_alerts {
       my ($domain,$passwdrules) = @_;
       my $warning;
       if (ref($passwdrules) eq 'HASH') {
           my %showrules = %{$passwdrules};
           if (keys(%showrules)) {
               my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
               $warning = '<b>'.&mt('Password requirement(s) unmet for one or more users:').'</b><ul>';
               if ($showrules{'min'}) {
                   my $min = $passwdconf{'min'};
                   if ($min eq '') {
                       $min = $Apache::lonnet::passwdmin;
                   }
                   $warning .= '<li>'.&mt('minimum [quant,_1,character]',$min).'</li>';
               }
               if ($showrules{'max'}) {
                   $warning .= '<li>'.&mt('maximum [quant,_1,character]',$passwdconf{'max'}).'</li>';
               }
               if ($showrules{'uc'}) {
                   $warning .= '<li>'.&mt('contain at least one upper case letter').'</li>';
               }
               if ($showrules{'lc'}) {
                   $warning .= '<li>'.&mt('contain at least one lower case letter').'</li>';
               }
               if ($showrules{'num'}) {
                   $warning .= '<li>'.&mt('contain at least one number').'</li>';
               }
               if ($showrules{'spec'}) {
                   $warning .= '<li>'.&mt('contain at least one non-alphanumeric').'</li>';
               }
               $warning .= '</ul>';
           }
       }
       return $warning;
   }
   
 sub user_change_result {  sub user_change_result {
     my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,      my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
         $username,$userdomain,$userchg) = @_;          $username,$userdomain,$userchg) = @_;
     my $okresult = 0;      my $okresult = 0;
       my @status;
     if ($userresult ne 'ok') {      if ($userresult ne 'ok') {
         if ($userresult =~ /^error:(.+)$/) {          if ($userresult =~ /^error:(.+)$/) {
             my $error = $1;              my $error = $1;
             $r->print('<br />'.              push(@status,
                   &mt('[_1]: Unable to add/modify: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));                   &mt('[_1]: Unable to add/modify: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         }          }
     } else {      } else {
         $counts->{'user'} ++;          $counts->{'user'} ++;
Line 4068  sub user_change_result { Line 5756  sub user_change_result {
     if ($authresult ne 'ok') {      if ($authresult ne 'ok') {
         if ($authresult =~ /^error:(.+)$/) {          if ($authresult =~ /^error:(.+)$/) {
             my $error = $1;              my $error = $1;
             $r->print('<br />'.              push(@status, 
                   &mt('[_1]: Unable to modify authentication: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));                   &mt('[_1]: Unable to modify authentication: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         }           } 
     } else {      } else {
         $counts->{'auth'} ++;          $counts->{'auth'} ++;
Line 4078  sub user_change_result { Line 5766  sub user_change_result {
     if ($roleresult ne 'ok') {      if ($roleresult ne 'ok') {
         if ($roleresult =~ /^error:(.+)$/) {          if ($roleresult =~ /^error:(.+)$/) {
             my $error = $1;              my $error = $1;
             $r->print('<br />'.              push(@status,
                   &mt('[_1]: Unable to add role: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));                   &mt('[_1]: Unable to add role: [_2]','<b>'.$username.':'.$userdomain.'</b>',$error));
         }          }
     } else {      } else {
         $counts->{'role'} ++;          $counts->{'role'} ++;
Line 4088  sub user_change_result { Line 5776  sub user_change_result {
     if ($okresult) {      if ($okresult) {
         $flushc++;          $flushc++;
         $userchg->{$username.':'.$userdomain}=1;          $userchg->{$username.':'.$userdomain}=1;
         $r->print('. ');  
         if ($flushc>15) {          if ($flushc>15) {
             $r->rflush;              $r->rflush;
             $flushc=0;              $flushc=0;
         }          }
     }      }
     if ($idresult) {      if ($idresult) {
         $r->print($idresult);          push(@status,$idresult);
       }
       if (@status) {
           $r->print('<li>'.join('<br />',@status).'</li>');
     }      }
     return $flushc;      return $flushc;
 }  }
   
 # ========================================================= Menu Phase Two Drop  # ========================================================= Menu Phase Two Drop
 sub print_drop_menu {  sub print_drop_menu {
     my ($r,$context,$permission) = @_;      my ($r,$context,$permission,$crstype) = @_;
     $r->print('<h3>'.&mt("Drop Students").'</h3>'."\n".      my $heading;
               '<form name="studentform" method="post">'."\n");      if ($crstype eq 'Community') {
           $heading = &mt("Drop Members");
       } else {
           $heading = &mt("Drop Students");
       }
       $r->print('<h3>'.$heading.'</h3>'."\n".
                 '<form name="studentform" method="post" action="">'."\n");
     my $classlist = &Apache::loncoursedata::get_classlist();      my $classlist = &Apache::loncoursedata::get_classlist();
     if (! defined($classlist)) {      if (! defined($classlist)) {
         $r->print(&mt('There are no students currently enrolled.')."\n");          my $msg = '';
           if ($crstype eq 'Community') {
               $msg = &mt('There are no members currently enrolled.');
           } else {
               $msg = &mt('There are no students currently enrolled.');
           }
           $r->print('<p class="LC_info">'.$msg."</p>\n");
     } else {      } else {
         &show_drop_list($r,$classlist,'nosort',$permission);          &show_drop_list($r,$classlist,'nosort',$permission,$crstype);
     }      }
     $r->print('</form>'. &Apache::loncommon::end_page());      $r->print('</form>');
     return;      return;
 }  }
   
 # ================================================================== Phase four  # ================================================================== Phase four
   
 sub update_user_list {  sub update_user_list {
     my ($r,$context,$setting,$choice) = @_;      my ($r,$context,$setting,$choice,$crstype) = @_;
     my $now = time;      my $now = time;
     my $count=0;      my $count=0;
     my @changelist;      if ($context eq 'course') {
           $crstype = &Apache::loncommon::course_type();
       }
       my (@changelist,%got_role_approvals,%got_instdoms,%process_by,%instdoms,
           %pending,%reject,%notifydc,%status,%unauthorized,%currqueued);
     if ($choice eq 'drop') {      if ($choice eq 'drop') {
         @changelist = &Apache::loncommon::get_env_multiple('form.droplist');          @changelist = &Apache::loncommon::get_env_multiple('form.droplist');
     } else {      } else {
Line 4132  sub update_user_list { Line 5838  sub update_user_list {
                                    'reenable' => 'Re-enabled',                                     'reenable' => 'Re-enabled',
                                    'activate' => 'Activated',                                     'activate' => 'Activated',
                                    'chgdates' => 'Changed Access Dates for',                                     'chgdates' => 'Changed Access Dates for',
                                    'chgsec'   => 'Changed section for',                                     'chgsec'   => 'Changed section(s) for',
                                    'drop'     => 'Dropped',                                     'drop'     => 'Dropped',
                                  },                                   },
                         error => {'revoke'    => 'revoking',                          error => {'revoke'    => 'revoking',
Line 4149  sub update_user_list { Line 5855  sub update_user_list {
         ($startdate,$enddate) = &get_dates_from_form();          ($startdate,$enddate) = &get_dates_from_form();
     }      }
     foreach my $item (@changelist) {      foreach my $item (@changelist) {
         my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections,          my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,
             $scopestem);              @sections,$scopestem,$singlesec,$showsecs,$warn_singlesec,
               $nothingtodo,$keepnosection,$credits,$instsec,$cdom,$cnum);
         if ($choice eq 'drop') {          if ($choice eq 'drop') {
             ($uname,$udom,$sec) = split(/:/,$item,-1);              ($uname,$udom,$sec) = split(/:/,$item,-1);
             $role = 'st';              $role = 'st';
Line 4163  sub update_user_list { Line 5870  sub update_user_list {
                 $scope = $scopestem.'/'.$sec;                  $scope = $scopestem.'/'.$sec;
             }              }
         } elsif ($context eq 'course') {          } elsif ($context eq 'course') {
             ($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1);              ($uname,$udom,$role,$sec,$type,$locktype,$credits,$instsec) =
                   split(/\:/,$item,8);
               $instsec = &unescape($instsec);
             $cid = $env{'request.course.id'};              $cid = $env{'request.course.id'};
               $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
             $scopestem = '/'.$cid;              $scopestem = '/'.$cid;
             $scopestem =~s/\_/\//g;              $scopestem =~s/\_/\//g;
             if ($sec eq '') {              if ($sec eq '') {
Line 4175  sub update_user_list { Line 5886  sub update_user_list {
         } elsif ($context eq 'author') {          } elsif ($context eq 'author') {
             ($uname,$udom,$role) = split(/\:/,$item,-1);              ($uname,$udom,$role) = split(/\:/,$item,-1);
             $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};              $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
               $cdom = $env{'user.domain'};
               $cnum = $env{'user.name'};
         } elsif ($context eq 'domain') {          } elsif ($context eq 'domain') {
             if ($setting eq 'domain') {              if ($setting eq 'domain') {
                 ($role,$uname,$udom) = split(/\:/,$item,-1);                  ($role,$uname,$udom) = split(/\:/,$item,-1);
                 $scope = '/'.$env{'request.role.domain'}.'/';                  $scope = '/'.$env{'request.role.domain'}.'/';
                   $cdom = $env{'request.role.domain'};
             } elsif ($setting eq 'author') {               } elsif ($setting eq 'author') { 
                 ($uname,$udom,$role,$scope) = split(/\:/,$item);                  ($uname,$udom,$role,$scope) = split(/\:/,$item);
                   (undef,$cdom,$cnum) = split(/\//,$scope);
             } elsif ($setting eq 'course') {              } elsif ($setting eq 'course') {
                 ($uname,$udom,$role,$cid,$sec,$type,$locktype) =                   ($uname,$udom,$role,$cid,$sec,$type,$locktype,$credits,$instsec) = 
                     split(/\:/,$item);                      split(/\:/,$item,9);
                   ($cdom,$cnum) = split('_',$cid);
                   $instsec = &unescape($instsec);
                 $scope = '/'.$cid;                  $scope = '/'.$cid;
                 $scope =~s/\_/\//g;                  $scope =~s/\_/\//g;
                 if ($sec ne '') {                  if ($sec ne '') {
Line 4191  sub update_user_list { Line 5908  sub update_user_list {
                 }                  }
             }              }
         }          }
         my $plrole = &Apache::lonnet::plaintext($role);          my $plrole = &Apache::lonnet::plaintext($role,$crstype);
         my $start = $env{'form.'.$item.'_start'};          my $start = $env{'form.'.$item.'_start'};
         my $end = $env{'form.'.$item.'_end'};          my $end = $env{'form.'.$item.'_end'};
         if ($choice eq 'drop') {          if ($choice eq 'drop') {
Line 4205  sub update_user_list { Line 5922  sub update_user_list {
             $end = $now;               $end = $now; 
             if ($role eq 'st') {              if ($role eq 'st') {
                 $result =                   $result = 
                     &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);                      &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
             } else {              } else {
                 $result =                   $result = 
                     &Apache::lonnet::revokerole($udom,$uname,$scope,$role,                      &Apache::lonnet::revokerole($udom,$uname,$scope,$role,
Line 4213  sub update_user_list { Line 5930  sub update_user_list {
             }              }
         } elsif ($choice eq 'delete') {          } elsif ($choice eq 'delete') {
             if ($role eq 'st') {              if ($role eq 'st') {
                 &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context);                  &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
             }              }
             $result =              $result =
                 &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,                  &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,
Line 4224  sub update_user_list { Line 5941  sub update_user_list {
                 $start = $startdate;                   $start = $startdate; 
                 $end = $enddate;                  $end = $enddate;
             }              }
               my $id = $scope.'_'.$role;
             if ($choice eq 'reenable') {              if ($choice eq 'reenable') {
                   next if (&restricted_dom($context,$id,$udom,$uname,$role,$now,$end,$cdom,$cnum,
                                            $sec,$credits,\%process_by,\%instdoms,\%got_role_approvals,
                                            \%got_instdoms,\%reject,\%pending,\%notifydc,
                                            \%status,\%unauthorized,\%currqueued));
                 if ($role eq 'st') {                  if ($role eq 'st') {
                     $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);                      $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
                 } else {                  } else {
                     $result =                       $result = 
                         &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,                          &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                                     $now,'','',$context);                                                      $now,'','',$context);
                 }                  }
             } elsif ($choice eq 'activate') {              } elsif ($choice eq 'activate') {
                   next if (&restricted_dom($context,$id,$udom,$uname,$role,$now,$end,$cdom,$cnum,
                                            $sec,$credits,\%process_by,\%instdoms,\%got_role_approvals,
                                            \%got_instdoms,\%reject,\%pending,\%notifydc,
                                            \%status,\%unauthorized,\%currqueued));
                 if ($role eq 'st') {                  if ($role eq 'st') {
                     $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);                      $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
                 } else {                  } else {
                     $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,                      $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                             $now,'','',$context);                                              $now,'','',$context);
                 }                  }
             } elsif ($choice eq 'chgdates') {              } elsif ($choice eq 'chgdates') {
                   next if (&restricted_dom($context,$id,$udom,$uname,$role,$start,$end,$cdom,$cnum,
                                            $sec,$credits,\%process_by,\%instdoms,\%got_role_approvals,
                                            \%got_instdoms,\%reject,\%pending,\%notifydc,
                                            \%status,\%unauthorized,\%currqueued));
                 if ($role eq 'st') {                  if ($role eq 'st') {
                     $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);                      $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
                 } else {                  } else {
                     $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,                      $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                                 $start,'','',$context);                                                  $start,'','',$context);
                 }                  }
             } elsif ($choice eq 'chgsec') {              } elsif ($choice eq 'chgsec') {
                 my (@newsecs,$revresult,$nochg,@retained);                  my (@newsecs,$revresult,$nochg,@retained);
                 if ($role ne 'cc') {                  if (($role ne 'cc') && ($role ne 'co')) {
                     @newsecs = split(/,/,$env{'form.newsecs'});                      my @secs = sort(split(/,/,$env{'form.newsecs'}));
                       if (@secs) {
                           my %curr_groups = &Apache::longroup::coursegroups();
                           foreach my $sec (@secs) {
                               next if (($sec =~ /\W/) || ($sec eq 'none') ||
                               (exists($curr_groups{$sec})));
                               push(@newsecs,$sec);
                           }
                       }
                 }                  }
                 # remove existing section if not to be retained.                     # remove existing section if not to be retained.   
                 if (!$env{'form.retainsec'}) {                  if (!$env{'form.retainsec'} || ($role eq 'st')) {
                     if ($sec eq '') {                      if ($sec eq '') {
                         if (@newsecs == 0) {                          if (@newsecs == 0) {
                             $result = &mt('No change in section assignment (none)');                              $result = 'ok';
                             $nochg = 1;                              $nochg = 1;
                               $nothingtodo = 1;
                         } else {                          } else {
                             $revresult =                              $revresult =
                                 &Apache::lonnet::revokerole($udom,$uname,                                  &Apache::lonnet::revokerole($udom,$uname,
Line 4283  sub update_user_list { Line 6022  sub update_user_list {
                 } else {                  } else {
                     if ($sec eq '') {                      if ($sec eq '') {
                         $nochg = 1;                          $nochg = 1;
                     } else {                           $keepnosection = 1;
                       } else {
                         push(@retained,$sec);                          push(@retained,$sec);
                     }                      }
                 }                  }
                 # add new sections                  # add new sections
                   my (@diffs,@shownew);
                   if (@retained) {
                       @diffs = &Apache::loncommon::compare_arrays(\@retained,\@newsecs);
                   } else {
                       @diffs = @newsecs;
                   }
                 if (@newsecs == 0) {                  if (@newsecs == 0) {
                     if (!$nochg) {                      if ($nochg) {
                           $result = 'ok';
                           $nothingtodo = 1;
                       } else {
                         if ($role eq 'st') {                          if ($role eq 'st') {
                             $result =                               $result = 
                                 &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context);                                  &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
                         } else {                          } else {
                             my $newscope = $scopestem;                              my $newscope = $scopestem;
                             $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context);                              $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context);
                         }                          }
                     }                      }
                       $showsecs = &mt('No section');
                   } elsif (@diffs == 0) {
                       $result = 'ok';
                       $nothingtodo = 1;
                 } else {                  } else {
                     foreach my $newsec (@newsecs) {                       foreach my $newsec (@newsecs) {
                         if (!grep(/^\Q$newsec\E$/,@retained)) {                          if (!grep(/^\Q$newsec\E$/,@retained)) {
                             if ($role eq 'st') {                              if ($role eq 'st') {
                                 $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context);                                  $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
                                   if (@newsecs > 1) {
                                       my $showsingle; 
                                       if ($newsec eq '') {
                                           $showsingle = &mt('No section');
                                       } else {
                                           $showsingle = $newsec;
                                       }
                                       if ($crstype eq 'Community') {
                                           $warn_singlesec = &mt('Although more than one section was indicated, a role was only added for the first section - [_1], as each community member may only be in one section at a time.','<i>'.$showsingle.'</i>');
                                       } else { 
                                           $warn_singlesec = &mt('Although more than one section was indicated, a role was only added for the first section - [_1], as each student may only be in one section of a course at a time.','<i>'.$showsingle.'</i>');
                                       }
                                       $showsecs = $showsingle; 
                                       last;
                                   } else {
                                       if ($newsec eq '') {
                                           $showsecs = &mt('No section');
                                       } else {
                                           $showsecs = $newsec;
                                       }
                                   }
                             } else {                              } else {
                                 my $newscope = $scopestem;                                  my $newscope = $scopestem;
                                 if ($newsec ne '') {                                  if ($newsec ne '') {
                                    $newscope .= '/'.$newsec;                                     $newscope .= '/'.$newsec;
                                      push(@shownew,$newsec); 
                                 }                                  }
                                 $result = &Apache::lonnet::assignrole($udom,$uname,                                  $result = &Apache::lonnet::assignrole($udom,$uname,
                                                         $newscope,$role,$end,$start);                                                          $newscope,$role,$end,$start);
                                   
                             }                              }
                         }                          }
                     }                      }
                 }                  }
                   unless ($role eq 'st') {
                       unless ($showsecs) {
                           my @tolist = sort(@shownew,@retained);
                           if ($keepnosection) {
                               push(@tolist,&mt('No section'));
                           }
                           $showsecs = join(', ',@tolist);
                       }
                   }
             }              }
         }          }
         my $extent = $scope;          my $extent = $scope;
Line 4324  sub update_user_list { Line 6109  sub update_user_list {
             }              }
         }          }
         if ($result eq 'ok' || $result eq 'ok:') {          if ($result eq 'ok' || $result eq 'ok:') {
             $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]",              my $dates;
                           $plrole,$extent,$uname.':'.$udom).'<br />');              if (($choice eq 'chgsec') || ($choice eq 'chgdates')) {
             $count++;                  $dates = &dates_feedback($start,$end,$now);
               }
               if ($choice eq 'chgsec') {
                   if ($nothingtodo) {
                       $r->print(&mt("Section assignment for role of '[_1]' in [_2] for '[_3]' unchanged.",$plrole,$extent,'<i>'.
                             &Apache::loncommon::plainname($uname,$udom).
                             '</i>').' ');
                       if ($sec eq '') {
                           $r->print(&mt('[_1]No section[_2] - [_3]','<b>','</b>',$dates));
                       } else {
                           $r->print(&mt('Section(s): [_1] - [_2]',
                                         '<b>'.$showsecs.'</b>',$dates));
                       }
                       $r->print('<br />');
                   } else {
                       $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]' to [_4] - [_5]",$plrole,$extent,
                           '<i>'.&Apache::loncommon::plainname($uname,$udom).'</i>',
                           '<b>'.$showsecs.'</b>',$dates).'<br />');
                      $count ++;
                  }
                  if ($warn_singlesec) {
                      $r->print('<div class="LC_warning">'.$warn_singlesec.'</div>');
                  }
               } elsif ($choice eq 'chgdates') {
                   $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]' - [_4]",$plrole,$extent, 
                         '<i>'.&Apache::loncommon::plainname($uname,$udom).'</i>',
                         $dates).'<br />');
                  $count ++;
               } else {
                   $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]'.",$plrole,$extent,
                         '<i>'.&Apache::loncommon::plainname($uname,$udom).'</i>').
                             '<br />');
                   $count ++;
               }
         } else {          } else {
             $r->print(              $r->print(
                 &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].",                  &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for '[_3]': [_4].",
                     $plrole,$extent,$uname.':'.$udom,$result).'<br />');                      $plrole,$extent,
                       '<i>'.&Apache::loncommon::plainname($uname,$udom).'</i>',
                       $result).'<br />');
         }          }
     }      }
     $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n");      $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n");
Line 4346  sub update_user_list { Line 6166  sub update_user_list {
             }              }
         }          }
     }      }
     $r->print('<p><b>'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,no users].",$count).'</b></p>');      $r->print('<p><b>'.&mt("$result_text{'ok'}{$choice} [quant,_1,user role,user roles,no user roles].",$count).'</b></p>');
     if ($count > 0) {      if ($count > 0) {
         if ($choice eq 'revoke' || $choice eq 'drop') {          if ($choice eq 'revoke' || $choice eq 'drop') {
             $r->print('<p>'.&mt('Re-enabling will re-activate data for the role.').'</p>');              $r->print('<p>'.&mt('Re-enabling will re-activate data for the role.').'</p>');
         }          }
         # Flush the course logs so reverse user roles immediately updated          # Flush the course logs so reverse user roles immediately updated
         &Apache::lonnet::flushcourselogs();          $r->register_cleanup(\&Apache::lonnet::flushcourselogs);
     }      }
     if ($env{'form.makedatesdefault'}) {      if ($env{'form.makedatesdefault'}) {
         if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {          if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
             $r->print(&make_dates_default($startdate,$enddate,$context));              $r->print(&make_dates_default($startdate,$enddate,$context,$crstype));
         }          }
     }      }
       if ((keys(%reject)) || (keys(%unauthorized))) {
           $r->print(&print_roles_rejected($context,\%reject,\%unauthorized));
       }
       if ((keys(%pending)) || (keys(%currqueued))) {
           $r->print(&print_roles_queued($context,\%pending,\%notifydc,\%currqueued));
       }
     my $linktext = &mt('Display User Lists');      my $linktext = &mt('Display User Lists');
     if ($choice eq 'drop') {      if ($choice eq 'drop') {
         $linktext = &mt('Display current class roster');          $linktext = &mt('Display current class roster');
     }      }
     $r->print('<a href="javascript:document.studentform.submit()">'.$linktext.'</a></form>'."\n");      $r->print(
           &Apache::lonhtmlcommon::actionbox(
               ['<a href="javascript:document.studentform.submit()">'.$linktext.'</a>'])
          .'</form>'."\n");
   }
   
   sub dates_feedback {
       my ($start,$end,$now) = @_;
       my $dates;
       if ($start < $now) {
           if ($end == 0) {
               $dates = &mt('role(s) active now; no end date');
           } elsif ($end > $now) {
               $dates = &mt('role(s) active now; ends [_1].',&Apache::lonlocal::locallocaltime($end));
           } else {
               $dates = &mt('role(s) expired: [_1].',&Apache::lonlocal::locallocaltime($end));
           }
        } else {
           if ($end == 0 || $end > $now) {
               $dates = &mt('future role(s); starts: [_1].',&Apache::lonlocal::locallocaltime($start));
           } else {
               $dates = &mt('role(s) expired: [_1].',&Apache::lonlocal::locallocaltime($end));
           }
       }
       return $dates;
 }  }
   
 sub classlist_drop {  sub classlist_drop {
Line 4389  sub active_student_roles { Line 6239  sub active_student_roles {
   
 sub section_check_js {  sub section_check_js {
     my $groupslist= &get_groupslist();      my $groupslist= &get_groupslist();
       my %js_lt = &Apache::lonlocal::texthash(
           mayn   => 'may not be used as the name for a section, as it is a reserved word.',
           plch   => 'Please choose a different section name.',
           mnot   => 'may not be used as a section name, as it is the name of a course group.',
           secn   => 'Section names and group names must be distinct. Please choose a different section name.',
       );
       &js_escape(\%js_lt);
     return <<"END";      return <<"END";
 function validate(caller) {  function validate(caller) {
     var groups = new Array($groupslist);      var groups = new Array($groupslist);
     var secname = caller.value;      var secname = caller.value;
     if ((secname == 'all') || (secname == 'none')) {      if ((secname == 'all') || (secname == 'none')) {
         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");          alert("'"+secname+"' $js_lt{'mayn'}\\n$js_lt{'plch'}");
         return 'error';          return 'error';
     }      }
     if (secname != '') {      if (secname != '') {
         for (var k=0; k<groups.length; k++) {          for (var k=0; k<groups.length; k++) {
             if (secname == groups[k]) {              if (secname == groups[k]) {
                 alert("'"+secname+"' may not be used as the name for a section, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name.");                  alert("'"+secname+"' $js_lt{'mnot'}\\n$js_lt{'secn'}");
                 return 'error';                  return 'error';
             }              }
         }          }
Line 4411  END Line 6268  END
 }  }
   
 sub set_login {  sub set_login {
     my ($dom,$authformkrb,$authformint,$authformloc) = @_;      my ($dom,$authformkrb,$authformint,$authformloc,$authformlti) = @_;
     my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);      my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
     my $response;      my $response;
     my ($authnum,%can_assign) =      my ($authnum,%can_assign) =
Line 4433  sub set_login { Line 6290  sub set_login {
                          '<td>'.$authformloc.'</td>'.                           '<td>'.$authformloc.'</td>'.
                          &Apache::loncommon::end_data_table_row()."\n";                           &Apache::loncommon::end_data_table_row()."\n";
         }          }
           if ($can_assign{'lti'}) {
               $response .= &Apache::loncommon::start_data_table_row().
                            '<td>'.$authformlti.'</td>'.
                            &Apache::loncommon::end_data_table_row()."\n";
           }
         $response .= &Apache::loncommon::end_data_table();          $response .= &Apache::loncommon::end_data_table();
     }      }
     return $response;      return $response;
 }  }
   
 sub course_sections {  sub course_sections {
     my ($sections_count,$role,$current_sec) = @_;      my ($sections_count,$role,$current_sec,$disabled) = @_;
     my $output = '';      my $output = '';
     my @sections = (sort {$a <=> $b} keys %{$sections_count});      my @sections = (sort {$a <=> $b} keys(%{$sections_count}));
     my $numsec = scalar(@sections);      my $numsec = scalar(@sections);
     my $is_selected = ' selected="selected" ';      my $is_selected = ' selected="selected"';
     if ($numsec <= 1) {      if ($numsec <= 1) {
         $output = '<select name="currsec_'.$role.'" >'."\n".          $output = '<select name="currsec_'.$role.'"'.$disabled.'>'."\n".
                   '  <option value="">'.&mt('Select').'</option>'."\n";                    '  <option value="">'.&mt('Select').'</option>'."\n";
         if ($current_sec eq 'none') {          if ($current_sec eq 'none') {
             $output .=                     $output .=       
Line 4468  sub course_sections { Line 6330  sub course_sections {
         my $multiple = 4;          my $multiple = 4;
         if (scalar(@sections) < 4) { $multiple = scalar(@sections); }          if (scalar(@sections) < 4) { $multiple = scalar(@sections); }
         if ($role eq 'st') {          if ($role eq 'st') {
             $output .= '>'."\n".              $output .= $disabled.'>'."\n".
                        '  <option value="">'.&mt('Select').'</option>'."\n";                         '  <option value="">'.&mt('Select').'</option>'."\n";
             if ($current_sec eq 'none') {              if ($current_sec eq 'none') {
                 $output .=                   $output .= 
Line 4478  sub course_sections { Line 6340  sub course_sections {
                        '  <option value="">'.&mt('No section')."</option>\n";                         '  <option value="">'.&mt('No section')."</option>\n";
             }              }
         } else {          } else {
             $output .= 'multiple="multiple" size="'.$multiple.'">'."\n";              $output .= 'multiple="multiple" size="'.$multiple.'"'.$disabled.'>'."\n";
         }          }
         foreach my $sec (@sections) {          foreach my $sec (@sections) {
             if ($current_sec eq $sec) {              if ($current_sec eq $sec) {
Line 4503  sub get_groupslist { Line 6365  sub get_groupslist {
 }  }
   
 sub setsections_javascript {  sub setsections_javascript {
     my ($formname,$groupslist,$mode,$checkauth) = @_;      my ($formname,$groupslist,$mode,$checkauth,$crstype,$showcredits) = @_;
     my ($checkincluded,$finish,$rolecode,$setsection_js);      my ($checkincluded,$finish,$rolecode,$setsection_js);
     if ($mode eq 'upload') {      if ($mode eq 'upload') {
         $checkincluded = 'formname.name == "'.$formname.'"';          $checkincluded = 'formname.name == "'.$formname.'"';
         $finish = "return 'ok';";          $finish = "return 'ok';";
         $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n";          $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n";
     } elsif ($formname eq 'cu') {      } elsif ($formname eq 'cu') {
         $checkincluded = 'formname.elements[i-1].checked == true';          if (($crstype eq 'Course') && ($showcredits)) {
               $checkincluded = "((role == 'st') && (formname.elements[i-2].checked == true)) || ((role != 'st') && (formname.elements[i-1].checked == true))";
           } else {
               $checkincluded = 'formname.elements[i-1].checked == true';
           }
         if ($checkauth) {          if ($checkauth) {
             $finish = "var authcheck = auth_check();\n".              $finish = "var authcheck = auth_check();\n".
                       "   if (authcheck == 'ok') {\n".                        "   if (authcheck == 'ok') {\n".
Line 4521  sub setsections_javascript { Line 6387  sub setsections_javascript {
         }          }
         $rolecode = "var match = str.split('_');          $rolecode = "var match = str.split('_');
                 var role = match[3];\n";                  var role = match[3];\n";
     } elsif ($formname eq 'enrollstudent') {      } elsif (($formname eq 'enrollstudent') || ($formname eq 'selfenroll')) {
         $checkincluded = 'formname.name == "'.$formname.'"';          $checkincluded = 'formname.name == "'.$formname.'"';
         if ($checkauth) {          if ($checkauth) {
             $finish = "var authcheck = auth_check();\n".              $finish = "var authcheck = auth_check();\n".
Line 4542  sub setsections_javascript { Line 6408  sub setsections_javascript {
     }      }
     my %alerts = &Apache::lonlocal::texthash(      my %alerts = &Apache::lonlocal::texthash(
                     secd => 'Section designations do not apply to Course Coordinator roles.',                      secd => 'Section designations do not apply to Course Coordinator roles.',
                       sedn => 'Section designations do not apply to Coordinator roles.',
                     accr => 'A course coordinator role will be added with access to all sections.',                      accr => 'A course coordinator role will be added with access to all sections.',
                       acor => 'A coordinator role will be added with access to all sections',
                     inea => 'In each course, each user may only have one student role at a time.',                      inea => 'In each course, each user may only have one student role at a time.',
                     youh => 'You had selected ',                      inco => 'In each community, each user may only have one member role at a time.',
                       youh => 'You had selected',
                     secs => 'sections.',                      secs => 'sections.',
                     plmo => 'Please modify your selections so they include no more than one section.',                      plmo => 'Please modify your selections so they include no more than one section.',
                     mayn => 'may not be used as the name for a section, as it is a reserved word.',                      mayn => 'may not be used as the name for a section, as it is a reserved word.',
                     plch => 'Please choose a different section name.',                      plch => 'Please choose a different section name.',
                     mnot => 'may not be used as a section name, as it is the name of a course group.',                      mnot => 'may not be used as a section name, as it is the name of a course group.',
                     secn => 'Section names and group names must be distinct. Please choose a different section name.',                      secn => 'Section names and group names must be distinct. Please choose a different section name.',
                  );                                      nonw => 'Section names may only contain letters or numbers.',
                    );
       &js_escape(\%alerts);
     $setsection_js .= <<"ENDSECCODE";      $setsection_js .= <<"ENDSECCODE";
   
 function setSections(formname) {  function setSections(formname,crstype) {
     var re1 = /^currsec_/;      var re1 = /^currsec_/;
       var re2 =/\\W/;
       var trimleading = /^\\s+/;
       var trimtrailing = /\\s+\$/;
     var groups = new Array($groupslist);      var groups = new Array($groupslist);
     for (var i=0;i<formname.elements.length;i++) {      for (var i=0;i<formname.elements.length;i++) {
         var str = formname.elements[i].name;          var str = formname.elements[i].name;
           if (typeof(str) === "undefined") {
               continue;
           }
         var checkcurr = str.match(re1);          var checkcurr = str.match(re1);
         if (checkcurr != null) {          if (checkcurr != null) {
               var num = i;
               $rolecode
             if ($checkincluded) {              if ($checkincluded) {
                 $rolecode                  if (role == 'cc' || role == 'co') {
                 if (role == 'cc') {                      if (role == 'cc') {
                     alert("$alerts{'secd'}\\n$alerts{'accr'}");                          alert("$alerts{'secd'}\\n$alerts{'accr'}");
                 }                      } else {
                 else {                          alert("$alerts{'sedn'}\\n$alerts{'acor'}");
                       }
                   } else {
                     var sections = '';                      var sections = '';
                     var numsec = 0;                      var numsec = 0;
                     var sections;                      var fromexisting = new Array();
                     for (var j=0; j<formname.elements[i].length; j++) {                      for (var j=0; j<formname.elements[num].length; j++) {
                         if (formname.elements[i].options[j].selected == true ) {                          if (formname.elements[num].options[j].selected == true ) {
                             if (formname.elements[i].options[j].value != "") {                              var addsec = formname.elements[num].options[j].value;
                               if ((addsec != "") && (addsec != null)) {
                                   fromexisting.push(addsec);
                                 if (numsec == 0) {                                  if (numsec == 0) {
                                     if (formname.elements[i].options[j].value != "") {                                      sections = addsec;
                                         sections = formname.elements[i].options[j].value;                                  } else {
                                         numsec ++;                                      sections = sections + "," +  addsec;
                                     }  
                                 }  
                                 else {  
                                     sections = sections + "," +  formname.elements[i].options[j].value  
                                     numsec ++;  
                                 }                                  }
                                   numsec ++;
                             }                              }
                         }                          }
                     }                      }
                     if (numsec > 0) {                      var newsecs = formname.elements[num+1].value;
                         if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) {                      var validsecs = new Array();
                             sections = sections + "," +  formname.elements[i+1].value;                      var validsecstr = '';
                         }                      var badsecs = new Array();
                     }  
                     else {  
                         sections = formname.elements[i+1].value;  
                     }  
                     var newsecs = formname.elements[i+1].value;  
                     var numsplit;  
                     if (newsecs != null && newsecs != "") {                      if (newsecs != null && newsecs != "") {
                         numsplit = newsecs.split(/,/g);                          var numsplit;
                         numsec = numsec + numsplit.length;                          if (newsecs.indexOf(',') == -1) {
                               numsplit = new Array(newsecs);
                           } else {
                               numsplit = newsecs.split(/,/g);
                           }
                           for (var m=0; m<numsplit.length; m++) {
                               var newsec = numsplit[m];
                               newsec = newsec.replace(trimleading,'');
                               newsec = newsec.replace(trimtrailing,'');
                               if (re2.test(newsec) == true) {
                                   badsecs.push(newsec);
                               } else {
                                   if (newsec != '') {
                                       var isnew = 1;
                                       if (fromexisting != null) {
                                           for (var n=0; n<fromexisting.length; n++) {
                                               if (newsec == fromexisting[n]) {
                                                   isnew = 0;
                                               }
                                           }
                                       }
                                       if (isnew == 1) {
                                           validsecs.push(newsec);
                                       }
                                   }
                               }
                           }
                           if (badsecs.length > 0) {
                               alert("$alerts{'nonw'}\\n$alerts{'plch'}");
                               return;
                           }
                           numsec = numsec + validsecs.length;
                     }                      }
   
                     if ((role == 'st') && (numsec > 1)) {                      if ((role == 'st') && (numsec > 1)) {
                         alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}")                          if (crstype == 'Community') {
                               alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}");
                           } else {
                               alert("$alerts{'inco'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}");
                           }
                         return;                          return;
                     }                      } else {
                     else {                          if (validsecs != null) {
                         if (numsplit != null) {                              for (var j=0; j<validsecs.length; j++) {
                             for (var j=0; j<numsplit.length; j++) {                                  if (validsecstr == '' || validsecstr == null) {
                                 if ((numsplit[j] == 'all') ||                                      validsecstr = validsecs[j];
                                     (numsplit[j] == 'none')) {                                  } else {
                                     alert("'"+numsplit[j]+"' $alerts{'mayn'}\\n$alerts{'plch'}");                                      validsecstr += ','+validsecs[j];
                                   }
                                   if ((validsecs[j] == 'all') ||
                                       (validsecs[j] == 'none')) {
                                       alert("'"+validsecs[j]+"' $alerts{'mayn'}\\n$alerts{'plch'}");
                                     return;                                      return;
                                 }                                  }
                                 for (var k=0; k<groups.length; k++) {                                  for (var k=0; k<groups.length; k++) {
                                     if (numsplit[j] == groups[k]) {                                      if (validsecs[j] == groups[k]) {
                                         alert("'"+numsplit[j]+"' $alerts{'mnot'}\\n$alerts{'secn'}");                                          alert("'"+validsecs[j]+"' $alerts{'mnot'}\\n$alerts{'secn'}");
                                         return;                                          return;
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                         formname.elements[i+2].value = sections;  
                     }                      }
                       if ((validsecstr != '') && (validsecstr != null)) {
                           if ((sections == '') || (sections == null)) {
                               sections = validsecstr;
                           } else {
                               sections = sections + "," + validsecstr;
                           }
                       }
                       formname.elements[num+2].value = sections;
                 }                  }
             }              }
         }          }
Line 4639  sub can_create_user { Line 6557  sub can_create_user {
     my $cancreate = 1;      my $cancreate = 1;
     if (&Apache::lonnet::allowed('mau',$dom)) {      if (&Apache::lonnet::allowed('mau',$dom)) {
         return $cancreate;          return $cancreate;
       } elsif ($context eq 'domain') {
           $cancreate = 0;
           return $cancreate;
     }      }
     if (ref($domconf{'usercreation'}) eq 'HASH') {      if (ref($domconf{'usercreation'}) eq 'HASH') {
         if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') {          if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') {
             if ($context eq 'course' || $context eq 'author') {              if ($context eq 'course' || $context eq 'author' || $context eq 'requestcrs') {
                 my $creation = $domconf{'usercreation'}{'cancreate'}{$context};                  my $creation = $domconf{'usercreation'}{'cancreate'}{$context};
                 if ($creation eq 'none') {                  if ($creation eq 'none') {
                     $cancreate = 0;                      $cancreate = 0;
Line 4718  sub can_modify_userinfo { Line 6639  sub can_modify_userinfo {
     return %canmodify;      return %canmodify;
 }  }
   
   sub can_change_internalpass {
       my ($uname,$udom,$crstype,$permission) = @_;
       my $canchange;
       if (&Apache::lonnet::allowed('mau',$udom)) {
           $canchange = 1;
       } elsif ((ref($permission) eq 'HASH') && ($permission->{'mip'}) &&
                ($udom eq $env{'request.role.domain'})) {
           unless ($env{'course.'.$env{'request.course.id'}.'.internal.nopasswdchg'}) {
               my ($cnum,$cdom) = &get_course_identity();
               if ((&Apache::lonnet::is_course_owner($cdom,$cnum)) && ($udom eq $env{'user.domain'})) {
                   my @userstatuses = ('default');
                   my %userenv = &Apache::lonnet::userenvironment($udom,$uname,'inststatus');
                   if ($userenv{'inststatus'} ne '') {
                       @userstatuses =  split(/:/,$userenv{'inststatus'});
                   }
                   my $noupdate = 1;
                   my %passwdconf = &Apache::lonnet::get_passwdconf($cdom);
                   if (ref($passwdconf{'crsownerchg'}) eq 'HASH') {
                       if (ref($passwdconf{'crsownerchg'}{'for'}) eq 'ARRAY') {
                           foreach my $status (@userstatuses) {
                               if (grep(/^\Q$status\E$/,@{$passwdconf{'crsownerchg'}{'for'}})) {
                                   undef($noupdate);
                                   last;
                               }
                           }
                       }
                   }
                   if ($noupdate) {
                       return;
                   }
                   my %owned = &Apache::lonnet::courseiddump($cdom,'.',1,'.',
                                                             $env{'user.name'}.':'.$env{'user.domain'},
                                                             undef,undef,undef,'.');
                   my %roleshash = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',
                                                                 ['active','future']);
                   foreach my $key (keys(%roleshash)) {
                       my ($name,$domain,$role) = split(/:/,$key);
                       if ($role eq 'st') {
                           next if (($name eq $cnum) && ($domain eq $cdom));
                           if ($owned{$domain.'_'.$name}) {
                               if (ref($owned{$domain.'_'.$name}) eq 'HASH') {
                                   if ($owned{$domain.'_'.$name}{'nopasswdchg'}) {
                                       $noupdate = 1;
                                       last;
                                   }
                               }
                           } else {
                               $noupdate = 1;
                               last;
                           }
                       } else {
                           $noupdate = 1;
                           last;
                       }
                   }
                   unless ($noupdate) {
                       $canchange = 1;
                   }
               }
           }
       }
       return $canchange;
   }
   
 sub check_usertype {  sub check_usertype {
     my ($dom,$uname,$rules) = @_;      my ($dom,$uname,$rules,$curr_rules,$got_rules) = @_;
     my $usertype;      my $usertype;
     if (ref($rules) eq 'HASH') {      if ((ref($got_rules) eq 'HASH') && (ref($curr_rules) eq 'HASH')) {
         my @user_rules = keys(%{$rules});          if (!$got_rules->{$dom}) {
         if (@user_rules > 0) {              my %domconfig = &Apache::lonnet::get_dom('configuration',
             my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules);                                                ['usercreation'],$dom);
             if (keys(%rule_check) > 0) {              if (ref($domconfig{'usercreation'}) eq 'HASH') {
                 $usertype = 'unofficial';                  foreach my $item ('username','id') {
                 foreach my $item (keys(%rule_check)) {                      if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
                     if ($rule_check{$item}) {                          $curr_rules->{$dom}{$item} =
                         $usertype = 'official';                                  $domconfig{'usercreation'}{$item.'_rule'};
                         last;                      }
                   }
               }
               $got_rules->{$dom} = 1;
           }
           if (ref($rules) eq 'HASH') {
               my @user_rules;
               if (ref($curr_rules->{$dom}{'username'}) eq 'ARRAY') {
                   foreach my $rule (keys(%{$rules})) {
                       if (grep(/^\Q$rule\E/,@{$curr_rules->{$dom}{'username'}})) {
                           push(@user_rules,$rule);
                       }
                   } 
               }
               if (@user_rules > 0) {
                   my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules);
                   if (keys(%rule_check) > 0) {
                       $usertype = 'unofficial';
                       foreach my $item (keys(%rule_check)) {
                           if ($rule_check{$item}) {
                               $usertype = 'official';
                               last;
                           }
                     }                      }
                 }                  }
             }              }
Line 4740  sub check_usertype { Line 6747  sub check_usertype {
 }  }
   
 sub roles_by_context {  sub roles_by_context {
     my ($context,$custom) = @_;      my ($context,$custom,$crstype) = @_;
     my @allroles;      my @allroles;
     if ($context eq 'course') {      if ($context eq 'course') {
         @allroles = ('st','ad','ta','ep','in','cc');          @allroles = ('st');
           if ($env{'request.role'} =~ m{^dc\./}) {
               push(@allroles,'ad');
           }
           push(@allroles,('ta','ep','in'));
           if ($crstype eq 'Community') {
               push(@allroles,'co');
           } else {
               push(@allroles,'cc');
           }
         if ($custom) {          if ($custom) {
             push(@allroles,'cr');              push(@allroles,'cr');
         }          }
     } elsif ($context eq 'author') {      } elsif ($context eq 'author') {
         @allroles = ('ca','aa');          @allroles = ('ca','aa');
     } elsif ($context eq 'domain') {      } elsif ($context eq 'domain') {
         @allroles = ('li','dg','sc','au','dc');          @allroles = ('li','ad','dg','dh','da','sc','au','dc');
     }      }
     return @allroles;      return @allroles;
 }  }
   
 sub get_permission {  sub get_permission {
     my ($context,$roles) = @_;      my ($context,$crstype) = @_;
     my %permission;      my %permission;
     if ($context eq 'course') {      if ($context eq 'course') {
         my $custom = 1;          my $custom = 1;
         my @allroles = &roles_by_context($context,$custom);          my @allroles = &roles_by_context($context,$custom,$crstype);
         foreach my $role (@allroles) {          foreach my $role (@allroles) {
             if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {              if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
                 $permission{'cusr'} = 1;                  $permission{'cusr'} = 1;
Line 4792  sub get_permission { Line 6808  sub get_permission {
         if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {          if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
             $permission{'grp_manage'} = 1;              $permission{'grp_manage'} = 1;
         }          }
           if ($permission{'cusr'}) {
               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
               my %coursehash = (
                   'internal.selfenrollmgrdc' => $env{'course.'.$env{'request.course.id'}.'.internal.selfenrollmgrdc'},
                   'internal.selfenrollmgrcc' => $env{'course.'.$env{'request.course.id'}.'.internal.selfenrollmgrcc'},
                   'internal.coursecode'      => $env{'course.'.$env{'request.course.id'}.'.internal.coursecode'},
                   'internal.textbook'        =>$env{'course.'.$env{'request.course.id'}.'.internal.textbook'},
               );
               my ($managed_by_cc,$managed_by_dc) = &selfenrollment_administration($cdom,$cnum,$crstype,\%coursehash);
               if (ref($managed_by_cc) eq 'ARRAY') {
                   if (@{$managed_by_cc}) {
                       $permission{'selfenrolladmin'} = 1;
                   }
               }
               unless ($permission{'selfenrolladmin'}) {
                   $permission{'selfenrollview'} = 1;
               }
           }
           if ($env{'request.course.id'}) {
               my $user;
               if (($env{'user.name'} ne '') && ($env{'user.domain'} ne '')) {
                   $user = $env{'user.name'}.':'.$env{'user.domain'};
               }
               if (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.courseowner'} eq
                                     $user)) {
                   $permission{'owner'} = 1;
                   if (&Apache::lonnet::allowed('mip',$env{'request.course.id'})) {
                       $permission{'mip'} = 1;
                   }
               } elsif (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.co-owners'} ne '')) {
                   if (grep(/^\Q$user\E$/,split(/,/,$env{'course.'.$env{'request.course.id'}.'.internal.co-owners'}))) {
                       $permission{'co-owner'} = 1;
                   }
               }
           }
     } elsif ($context eq 'author') {      } elsif ($context eq 'author') {
         $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'});          my $audom = $env{'request.role.domain'};
         $permission{'view'} = $permission{'cusr'};          my $auname = $env{'user.name'};
           if ((&Apache::lonnet::allowed('cca',"$audom/$auname")) ||
               (&Apache::lonnet::allowed('caa',"$audom/$auname"))) {
               $permission{'author'} = 1;
               $permission{'cusr'} = 1;
               $permission{'view'} = 1;
           }
       } elsif ($context eq 'coauthor') {
           my ($audom,$auname) = ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$});
           if ((&Apache::lonnet::allowed('vca',"$audom/$auname")) ||
               (&Apache::lonnet::allowed('vaa',"$audom/$auname"))) {
               if ($env{"environment.internal.manager./$audom/$auname"}) {
                   $permission{'cusr'} = 1;
                   $permission{'view'} = 1;
               }
           }
     } else {      } else {
         my @allroles = &roles_by_context($context);          my @allroles = &roles_by_context($context);
         foreach my $role (@allroles) {          foreach my $role (@allroles) {
Line 4811  sub get_permission { Line 6878  sub get_permission {
         if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {          if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {
             $permission{'custom'} = 1;              $permission{'custom'} = 1;
         }          }
         $permission{'view'} = $permission{'cusr'};          if (&Apache::lonnet::allowed('vac',$env{'request.role.domain'})) {
               $permission{'activity'} = 1;
           }
           if (&Apache::lonnet::allowed('vur',$env{'request.role.domain'})) {
               $permission{'view'} = 1;
           }
           if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
               $permission{'owner'} = 1;
           }
     }      }
     my $allowed = 0;      my $allowed = 0;
     foreach my $perm (values(%permission)) {      foreach my $key (keys(%permission)) {
         if ($perm) { $allowed=1; last; }          next if (($key eq 'owner') || ($key eq 'co-owner') || ($key eq 'author'));
           if ($permission{$key}) { $allowed=1; last; }
     }      }
     return (\%permission,$allowed);      return (\%permission,$allowed);
 }  }
Line 4828  sub authorpriv { Line 6904  sub authorpriv {
          || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; }    return 1;           || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; }    return 1;
 }  }
   
   sub coauthorpriv {
       my ($auname,$audom)=@_;
       my $uname = $env{'user.name'};
       my $udom = $env{'user.domain'};
       if (((&Apache::lonnet::allowed('vca',"$udom/$uname")) ||
            (&Apache::lonnet::allowed('vaa',"$udom/$uname"))) &&
            ($env{"environment.internal.manager./$audom/$auname"})) {
           return 1;
       }
       return '';
   }
   
 sub roles_on_upload {  sub roles_on_upload {
     my ($context,$setting,%customroles) = @_;      my ($context,$setting,$crstype,%customroles) = @_;
     my (@possible_roles,@permitted_roles);      my (@possible_roles,@permitted_roles);
     @possible_roles = &curr_role_permissions($context,$setting,1);      @possible_roles = &curr_role_permissions($context,$setting,1,$crstype);
     foreach my $role (@possible_roles) {      foreach my $role (@possible_roles) {
         if ($role eq 'cr') {          if ($role eq 'cr') {
             push(@permitted_roles,keys(%customroles));              push(@permitted_roles,keys(%customroles));
Line 4864  sub get_course_identity { Line 6952  sub get_course_identity {
 }  }
   
 sub dc_setcourse_js {  sub dc_setcourse_js {
     my ($formname,$mode,$context) = @_;      my ($formname,$mode,$context,$showcredits,$domain) = @_;
     my ($dc_setcourse_code,$authen_check);      my ($dc_setcourse_code,$authen_check);
     my $cctext = &Apache::lonnet::plaintext('cc');      my $cctext = &Apache::lonnet::plaintext('cc');
       my $cotext = &Apache::lonnet::plaintext('co');
     my %alerts = &sectioncheck_alerts();      my %alerts = &sectioncheck_alerts();
     my $role = 'role';      my $role = 'role';
     if ($mode eq 'upload') {      if ($mode eq 'upload') {
         $role = 'courserole';          $role = 'courserole';
     } else {      } else {
         $authen_check = &verify_authen($formname,$context);          $authen_check = &verify_authen($formname,$context,$domain);
     }      }
     $dc_setcourse_code = (<<"SCRIPTTOP");      $dc_setcourse_code = (<<"SCRIPTTOP");
 $authen_check  $authen_check
Line 4913  function setCourse() { Line 7002  function setCourse() {
             numsections = numsections + newsecs.length;              numsections = numsections + newsecs.length;
         }          }
         if ((userrole == 'st') && (numsections > 1)) {          if ((userrole == 'st') && (numsections > 1)) {
             alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")              if (document.$formname.crstype.value == 'Community') {
                   alert("$alerts{'inco'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")
               } else {
                   alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")
               }
             return;              return;
         }          }
         for (var j=0; j<newsecs.length; j++) {          for (var j=0; j<newsecs.length; j++) {
Line 4925  function setCourse() { Line 7018  function setCourse() {
                 var groups = document.$formname.groups.value.split(/,/g);                  var groups = document.$formname.groups.value.split(/,/g);
                 for (var k=0; k<groups.length; k++) {                  for (var k=0; k<groups.length; k++) {
                     if (newsecs[j] == groups[k]) {                      if (newsecs[j] == groups[k]) {
                         alert("'"+newsecs[j]+"' $alerts{'mayt'}.\\n$alerts{'secn'}. $alerts{'plsc'}.");                          if (document.$formname.crstype.value == 'Community') {
                               alert("'"+newsecs[j]+"' $alerts{'mayc'}.\\n$alerts{'secn'}. $alerts{'plsc'}.");
                           } else {
                               alert("'"+newsecs[j]+"' $alerts{'mayt'}.\\n$alerts{'secn'}. $alerts{'plsc'}.");
                           }
                         return;                          return;
                     }                      }
                 }                  }
Line 4935  function setCourse() { Line 7032  function setCourse() {
             alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}.");              alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}.");
             section = "";              section = "";
         }          }
           if ((userrole == 'co') && (numsections > 0)) {
               alert("$alerts{'secd'} $cotext $alerts{'role'}.\\n$alerts{'accr'}.");
               section = "";
           }
 SCRIPTTOP  SCRIPTTOP
     if ($mode ne 'upload') {      if ($mode ne 'upload') {
         $dc_setcourse_code .= (<<"ENDSCRIPT");          $dc_setcourse_code .= (<<"SCRIPTMID");
         var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole          var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole
         var numcourse = getIndex(document.$formname.dccourse);          var numcourse = getIndex(document.$formname.dccourse);
         if (numcourse == "-1") {          if (numcourse == "-1") {
             alert("$alerts{'thwa'}");              if (document.$formname.type == 'Community') {
                   alert("$alerts{'thwc'}");
               } else {
                   alert("$alerts{'thwa'}");
               }
             return;              return;
         }          }
         else {          else {
Line 4959  SCRIPTTOP Line 7064  SCRIPTTOP
             if (numend != "-1") {              if (numend != "-1") {
                 document.$formname.elements[numend].name = "end"+coursename                  document.$formname.elements[numend].name = "end"+coursename
             }              }
   SCRIPTMID
           if ($showcredits) {
               $dc_setcourse_code .= <<ENDCRED;
               var numcredits = getIndex(document.$formname.credits);
               if (numcredits != "-1") {
                   document.$formname.elements[numcredits].name = "credits"+coursename;
               }
   ENDCRED
           }
           $dc_setcourse_code .= <<ENDSCRIPT; 
         }          }
     }      }
     var authcheck = auth_check();      var authcheck = auth_check();
Line 4990  ENDSCRIPT Line 7105  ENDSCRIPT
 }  }
   
 sub verify_authen {  sub verify_authen {
     my ($formname,$context) = @_;      my ($formname,$context,$domain) = @_;
     my %alerts = &authcheck_alerts();      my %alerts = &authcheck_alerts();
     my $finish = "return 'ok';";      my $finish = "return 'ok';";
     if ($context eq 'author') {      if ($context eq 'author') {
         $finish = "document.$formname.submit();";          $finish = "document.$formname.submit();";
     }      }
       my ($numrules,$intargjs) =
           &Apache::loncommon::passwd_validation_js('argpicked',$domain);
     my $outcome = <<"ENDSCRIPT";      my $outcome = <<"ENDSCRIPT";
   
 function auth_check() {  function auth_check() {
Line 5029  function auth_check() { Line 7146  function auth_check() {
                 break;                  break;
             case 'int':              case 'int':
                 alertmsg = '$alerts{'ipass'}';                  alertmsg = '$alerts{'ipass'}';
                   break;
             case 'fsys':              case 'fsys':
                 alertmsg = '$alerts{'ipass'}';                  alertmsg = '$alerts{'ipass'}';
                 break;                  break;
Line 5042  function auth_check() { Line 7160  function auth_check() {
             alert(alertmsg);              alert(alertmsg);
             return;              return;
         }          }
       } else if (logintype == 'int') {
           var numrules = $numrules;
           if (numrules > 0) {
   $intargjs
           }
     }      }
     $finish      $finish
 }  }
Line 5050  ENDSCRIPT Line 7173  ENDSCRIPT
   
 sub sectioncheck_alerts {  sub sectioncheck_alerts {
     my %alerts = &Apache::lonlocal::texthash(      my %alerts = &Apache::lonlocal::texthash(
                     curd => 'You must select a course in the current domain',                      curd => 'You must select a course or community in the current domain',
                     inea => 'In each course, each user may only have one student role at a time',                      inea => 'In each course, each user may only have one student role at a time',
                       inco => 'In each community, each user may only have one member role at a time', 
                     youh => 'You had selected',                      youh => 'You had selected',
                     sect => 'sections',                      sect => 'sections',
                     plsm => 'Please modify your selections so they include no more than one section',                      plsm => 'Please modify your selections so they include no more than one section',
                     mayn => 'may not be used as the name for a section, as it is a reserved word',                      mayn => 'may not be used as the name for a section, as it is a reserved word',
                     plsc => 'Please choose a different section name',                      plsc => 'Please choose a different section name',
                     mayt => 'may not be used as the name for a section, as it is the name of a course group',                      mayt => 'may not be used as the name for a section, as it is the name of a course group',
                       mayc => 'may not be used as the name for a section, as it is the name of a community group',
                     secn => 'Section names and group names must be distinct',                      secn => 'Section names and group names must be distinct',
                     secd => 'Section designations do not apply to ',                      secd => 'Section designations do not apply to ',
                     role => 'roles',                      role => 'roles',
                     accr => 'role will be added with access to all sections',                      accr => 'role will be added with access to all sections',
                     thwa => 'There was a problem with your course selection'                      thwa => 'There was a problem with your course selection',
                       thwc => 'There was a problem with your community selection',
                  );                   );
       &js_escape(\%alerts);
     return %alerts;      return %alerts;
 }  }
   
Line 5074  sub authcheck_alerts { Line 7201  sub authcheck_alerts {
                     krb    => 'You need to specify the Kerberos domain.',                      krb    => 'You need to specify the Kerberos domain.',
                     ipass  => 'You need to specify the initial password.',                      ipass  => 'You need to specify the initial password.',
         );          );
       &js_escape(\%alerts);
     return %alerts;      return %alerts;
 }  }
   
   sub is_courseowner {
       my ($thiscourse,$courseowner) = @_;
       if ($courseowner eq '') {
           if ($env{'request.course.id'} eq $thiscourse) {
               $courseowner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
           }
       }
       if ($courseowner ne '') {
           if ($courseowner eq $env{'user.name'}.':'.$env{'user.domain'}) {
               return 1;
           }
       }
       return;
   }
   
   sub get_selfenroll_titles {
       my @row = ('types','registered','enroll_dates','access_dates','section',
                  'approval','limit');
       my %lt = &Apache::lonlocal::texthash (
                   types        => 'Users allowed to self-enroll',
                   registered   => 'Registration status (official courses)' ,
                   enroll_dates => 'Dates self-enrollment available',
                   access_dates => 'Access dates for self-enrolling users',
                   section      => "Self-enrolling users' section",
                   approval     => 'Processing of requests',
                   limit        => 'Enrollment limit',
                );
       return (\@row,\%lt);
   }
   
   sub selfenroll_default_descs {
       my %desc = (
                    types => {
                               dom => &mt('Course domain'),
                               all => &mt('Any domain'),
                               ''  => &mt('None'),
                             },
                    limit => {
                               none         => &mt('No limit'),
                               allstudents  => &mt('Limit by total students'),
                               selfenrolled => &mt('Limit by total self-enrolled'),
                             },
                    approval => {
                                   '0' => &mt('Processed automatically'),
                                   '1' => &mt('Queued for approval'),
                                   '2' => &mt('Queued, pending validation'),
                                },
                    registered => {
                                    0 => 'No registration required',
                                    1 => 'Registered students only',
                                  },
                  );
       return %desc;
   }
   
   sub selfenroll_validation_types {
       my @items = ('url','fields','button','markup');
       my %names =  &Apache::lonlocal::texthash (
               url      => 'Web address of validation server/script',
               fields   => 'Form fields to send to validator',
               button   => 'Text for validation button',
               markup   => 'Validation description (HTML)',
       );
       my @fields = ('username','domain','uniquecode','course','coursetype','description');
       return (\@items,\%names,\@fields);
   }
   
   sub get_extended_type {
       my ($cdom,$cnum,$crstype,$current) = @_;
       my $type = 'unofficial';
       my %settings;
       if (ref($current) eq 'HASH') {
           %settings = %{$current};
       } else {
           %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.textbook'],$cdom,$cnum);
       }
       if ($crstype eq 'Community') {
           $type = 'community';
       } elsif ($crstype eq 'Placement') {
           $type = 'placement';
       } elsif ($settings{'internal.coursecode'}) {
           $type = 'official';
       } elsif ($settings{'internal.textbook'}) {
           $type = 'textbook';
       }
       return $type;
   }
   
   sub selfenrollment_administration {
       my ($cdom,$cnum,$crstype,$coursehash) = @_;
       my %settings;
       if (ref($coursehash) eq 'HASH') {
           %settings = %{$coursehash};
       } else {
           %settings = &Apache::lonnet::get('environment',
                           ['internal.selfenrollmgrdc','internal.selfenrollmgrcc',
                            'internal.coursecode','internal.textbook'],$cdom,$cnum);
       }
       my ($possconfigs) = &get_selfenroll_titles(); 
       my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
       my $selfenrolltype = &get_extended_type($cdom,$cnum,$crstype,\%settings);
   
       my (@in_course,@in_domain); 
       if ($settings{'internal.selfenrollmgrcc'} ne '') {
           @in_course = split(/,/,$settings{'internal.selfenrollmgrcc'}); 
           my @diffs = &Apache::loncommon::compare_arrays($possconfigs,\@in_course);
           unless (@diffs) {
               return (\@in_course,\@in_domain);
           }
       }
       if ($settings{'internal.selfenrollmgrdc'} ne '') {
           @in_domain = split(/,/,$settings{'internal.selfenrollmgrdc'});
           my @diffs = &Apache::loncommon::compare_arrays(\@in_domain,$possconfigs);
           unless (@diffs) {
               return (\@in_course,\@in_domain);
           }
       }
       my @combined = @in_course;
       push(@combined,@in_domain);
       my @diffs = &Apache::loncommon::compare_arrays(\@combined,$possconfigs); 
       unless (@diffs) {
           return (\@in_course,\@in_domain);
       }
       if ($domdefaults{$selfenrolltype.'selfenrolladmdc'} eq '') {
           push(@in_course,@diffs);
       } else {
           my @defaultdc = split(/,/,$domdefaults{$selfenrolltype.'selfenrolladmdc'});
           foreach my $item (@diffs) {
               if (grep(/^\Q$item\E$/,@defaultdc)) {
                   push(@in_domain,$item);
               } else {
                   push(@in_course,$item);
               }
           }
       }
       return (\@in_course,\@in_domain);
   }
   
   sub custom_role_header {
       my ($context,$crstype,$templaterolerefs,$prefix) = @_;
       my %lt = &Apache::lonlocal::texthash(
                    sele => 'Select a Template',
       );
       my ($context_code,$button_code);
       if ($context eq 'domain') {
           $context_code = &custom_coursetype_switch($crstype,$prefix);
       }
       if (ref($templaterolerefs) eq 'ARRAY') {
           foreach my $role (@{$templaterolerefs}) {
               my $display = 'inline';
               if (($context eq 'domain') && ($role eq 'co')) {
                   $display = 'none';
               }
               $button_code .= &make_button_code($role,$crstype,$display,$prefix).' ';
           }
       }
       return <<"END";
   <div class="LC_left_float">
   <fieldset>
   <legend>$lt{'sele'}</legend>
   $button_code
   </fieldset></div>
   $context_code
   <br clear="all" />
   END
   }
   
   sub custom_coursetype_switch {
       my ($crstype,$prefix) = @_;
       my ($checkedcourse,$checkedcommunity);
       if ($crstype eq 'Community') {
           $checkedcommunity = ' checked="checked"';
       } else {
           $checkedcourse = ' checked="checked"';
       }
       my %lt = &Apache::lonlocal::texthash(
           cont => 'Context',
           cour => 'Course',
           comm => 'Community',
       );
       return <<"END";
   <div class="LC_left_float">
   <fieldset>
   <legend>$lt{'cont'}</legend>
   <label>
   <input type="radio" name="${prefix}_custrolecrstype" value="Course"$checkedcourse onclick="javascript:customSwitchType('$prefix');" />
   $lt{'cour'}
   </label>&nbsp;&nbsp;
   <label>
   <input type="radio" name="${prefix}_custrolecrstype" value="Community"$checkedcommunity onclick="javascript:customSwitchType('$prefix');" />
   $lt{'comm'}
   </label>
   </fieldset>
   </div>
   END
   }
   
   sub custom_role_table {
       my ($crstype,$full,$levels,$levelscurrent,$prefix,$add_class,$id) = @_;
       return unless ((ref($full) eq 'HASH') && (ref($levels) eq 'HASH') &&
                      (ref($levelscurrent) eq 'HASH'));
       my %lt=&Apache::lonlocal::texthash (
                       'prv'  => "Privilege",
                       'crl'  => "Course Level",
                       'dml'  => "Domain Level",
                       'ssl'  => "System Level");
       my %cr = (
                  course => '_c',
                  domain => '_d',
                  system => '_s',
                );
   
       my $output=&Apache::loncommon::start_data_table($add_class,$id).
                  &Apache::loncommon::start_data_table_header_row().
                  '<th>'.$lt{'prv'}.'</th><th>'.$lt{'crl'}.'</th><th>'.$lt{'dml'}.
                  '</th><th>'.$lt{'ssl'}.'</th>'.
                  &Apache::loncommon::end_data_table_header_row();
       foreach my $priv (sort(keys(%{$full}))) {
           my $privtext = &Apache::lonnet::plaintext($priv,$crstype);
           $output .= &Apache::loncommon::start_data_table_row().
                     '<td><span id="'.$prefix.$priv.'">'.$privtext.'</span></td>';
           foreach my $type ('course','domain','system') {
               if (($type eq 'system') && ($priv eq 'bre') && ($crstype eq 'Community')) {
                   $output .= '<td>&nbsp;</td>';
               } else {
                   $output .= '<td>'.
                     ($levels->{$type}{$priv}?'<input type="checkbox" id="'.$prefix.$priv.$cr{$type}.'"'.
                     ' name="'.$prefix.$priv.$cr{$type}.'"'.
                     ($levelscurrent->{$type}{$priv}?' checked="checked"':'').' />':'&nbsp;').
                     '</td>';
               }
           }
           $output .= &Apache::loncommon::end_data_table_row();
       }
       $output .= &Apache::loncommon::end_data_table();
       return $output;
   }
   
   sub custom_role_privs {
       my ($privs,$full,$levels,$levelscurrent)= @_;
       return unless ((ref($privs) eq 'HASH') && (ref($full) eq 'HASH') &&
                      (ref($levels) eq 'HASH') && (ref($levelscurrent) eq 'HASH'));
       my %cr = (
                  course => 'cr:c',
                  domain => 'cr:d',
                  system => 'cr:s',
                );
       foreach my $type ('course','domain','system') {
           foreach my $item (split(/\:/,$Apache::lonnet::pr{$cr{$type}})) {
               my ($priv,$restrict)=split(/\&/,$item);
               if (!$restrict) { $restrict='F'; }
               $levels->{$type}->{$priv}=$restrict;
               if ($privs->{$type}=~/\:$priv/) {
                   $levelscurrent->{$type}->{$priv}=1;
               }
               $full->{$priv}=1;
           }
       }
       return;
   }
   
   sub custom_template_roles {
       my ($context,$crstype) = @_;
       my @template_roles = ("in","ta","ep");
       if (($context eq 'domain') || ($context eq 'domprefs')) {
           push(@template_roles,"ad");
       }
       push(@template_roles,"st");
       if ($context eq 'domain') {
           unshift(@template_roles,('co','cc'));
       } else {
           if ($crstype eq 'Community') {
               unshift(@template_roles,'co');
           } else {
               unshift(@template_roles,'cc');
           }
       }
       return @template_roles;
   }
   
   sub custom_roledefs_js {
       my ($context,$crstype,$formname,$full,$templaterolesref,$jsback) = @_;
       my $button_code = "\n";
       my $head_script = "\n";
       my (%roletitlestr,$rolenamestr);
       my %role_titles = (
                           Course    => [],
                           Community => [],
                         );
       $head_script .= '<script type="text/javascript">'."\n"
                      .'// <![CDATA['."\n";
       if (ref($templaterolesref) eq 'ARRAY') {
           if ($context eq 'domain') {
               $rolenamestr = join("','",@{$templaterolesref});
           }
           foreach my $role (@{$templaterolesref}) {
               $head_script .= &make_script_template($role,$crstype,$formname);
               if ($context eq 'domain') {
                   foreach my $type ('Course','Community') {
                       push(@{$role_titles{$type}},&Apache::lonnet::plaintext($role,$type));
                   }
               }
           }
       }
       if ($context eq 'domain') {
           foreach my $type ('Course','Community') {
               $roletitlestr{$type} = join("','",@{$role_titles{$type}});
           }
           my %pt = (
               Community => {
                              cst => &mt('Grant/revoke role of Member'),
                              mdc => &mt('Edit community contents'),
                              pch => &mt('Post discussion on community resources'),
                              pfo => &mt('Print for other users and entire community'),
                            },
               Course    => {
                              cst => &mt('Grant/revoke role of Student'),
                              mdc => &mt('Edit course contents'),
                              pch => &mt('Post discussion on course resources'),
                              pfo => &mt('Print for other users and entire course'),
                            },
           );
           $head_script .= <<"ENDJS";
   function customSwitchType(prefix) {
       var privnames = new Array('cst','mdc','pch','pfo');
       var privtxtcrs = new Array('$pt{Course}{cst}','$pt{Course}{mdc}','$pt{Course}{pch}','$pt{Course}{pfo}');
       var privtxtcom = new Array('$pt{Community}{cst}','$pt{Community}{mdc}','$pt{Community}{pch}','$pt{Community}{pfo}');
       var rolenames = new Array('$rolenamestr');
       var rolescrs = new Array('$roletitlestr{Course}');
       var rolescom = new Array('$roletitlestr{Community}');
       var radio = prefix+'_custrolecrstype';
       if (document.$formname.elements[radio].length > 1) {
           for (var i=0; i<document.$formname.elements[radio].length; i++) {
               if (document.$formname.elements[radio][i].checked) {
                   if ((document.getElementById(prefix+'bre_s')) && (document.getElementById(prefix+'bro_s'))) {
                       if (document.$formname.elements[radio][i].value == 'Community') {
                           if (document.getElementById(prefix+'bre_s').checked) {
                               document.getElementById(prefix+'bro_s').checked = true;
                               document.getElementById(prefix+'bre_s').checked = false;
   
                           }
                           document.getElementById(prefix+'bre_s').style.visibility = 'hidden';
                       } else {
                           document.getElementById(prefix+'bre_s').style.visibility = 'visible';
                           if (document.getElementById(prefix+'bro_s').checked) {
                               document.getElementById(prefix+'bre_s').checked = true;
                               document.getElementById(prefix+'bro_s').checked = false;
                           }
                       }
                   }
                   for (var j=0; j<privnames.length; j++) {
                       if (document.getElementById(prefix+privnames[j])) {
                           if (document.getElementById(prefix+privnames[j])) {
                               if (document.$formname.elements[radio][i].value == 'Course') {
                                   document.getElementById(prefix+privnames[j]).innerHTML = privtxtcrs[j];
                               } else {
                                   document.getElementById(prefix+privnames[j]).innerHTML = privtxtcom[j];
                               }
                           }
                       }
                   }
                   for (var j=0; j<rolenames.length; j++) {
                       if (document.getElementById(prefix+rolenames[j])) {
                           if (document.getElementById(prefix+rolenames[j])) {
                               if (document.$formname.elements[radio][i].value == 'Course') {
                                   document.getElementById(prefix+rolenames[j]).value = rolescrs[j];
                                   if (rolenames[j] == 'cc') {
                                       document.getElementById(prefix+rolenames[j]).style.display = 'inline';
                                   }
                                   if (rolenames[j] == 'co') {
                                       document.getElementById(prefix+rolenames[j]).style.display = 'none';
                                   }
                               } else {
                                   document.getElementById(prefix+rolenames[j]).value = rolescom[j];
                                   if (rolenames[j] == 'cc') {
                                       document.getElementById(prefix+rolenames[j]).style.display = 'none';
                                   }
                                   if (rolenames[j] == 'co') {
                                       document.getElementById(prefix+rolenames[j]).style.display = 'inline';
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
       return;
   }
   ENDJS
       }
       $head_script .= "\n".$jsback."\n"
                      .'// ]]>'."\n"
                      .'</script>'."\n";
       return $head_script;
   }
   
   # --------------------------------------------------------
   sub make_script_template {
       my ($role,$crstype,$formname) = @_;
       my $return_script = 'function set_'.$role.'(prefix) {'."\n";
       my (%full_by_level,%role_priv);
       foreach my $level ('c','d','s') {
           foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:'.$level})) {
               next if (($level eq 's') && ($crstype eq 'Community') && ($item eq 'bre&S'));
               my ($priv,$restrict)=split(/\&/,$item);
               $full_by_level{$level}{$priv}=1;
           }
           $role_priv{$level} = {};
           my @temp = split(/:/,$Apache::lonnet::pr{$role.':'.$level});
           foreach my $priv (@temp) {
               my ($priv_item, $dummy) = split(/\&/,$priv);
               $role_priv{$level}{$priv_item} = 1;
           }
       }
       my %to_check = (
                         c => ['c','d','s'],
                         d => ['d','s'],
                         s => ['s'],
                      );
       foreach my $level ('c','d','s') {
           if (ref($full_by_level{$level}) eq 'HASH') {
               foreach my $priv (keys(%{$full_by_level{$level}})) {
                   my $value = 'false';
                   if (ref($to_check{$level}) eq 'ARRAY') {
                       foreach my $lett (@{$to_check{$level}}) {
                           if (exists($role_priv{$lett}{$priv})) {
                               $value = 'true';
                               last;
                           }
                       }
                       $return_script .= "document.$formname.elements[prefix+'".$priv."_".$level."'].checked = $value;\n";
                   }
               }
           }
       }
       $return_script .= '}'."\n";
       return ($return_script);
   }
   # ----------------------------------------------------------
   sub make_button_code {
       my ($role,$crstype,$display,$prefix) = @_;
       my $label = &Apache::lonnet::plaintext($role,$crstype);
       my $button_code = '<input type="button" onclick="set_'.$role."('$prefix'".')" '.
                         'id="'.$prefix.$role.'" value="'.$label.'" '.
                         'style="display:'.$display.'" />';
       return ($button_code);
   }
   
   sub custom_role_update {
       my ($rolename,$prefix) = @_;
   # ------------------------------------------------------- What can be assigned?
       my %privs = (
                         c => '',
                         d => '',
                         s => '',
                       );
       foreach my $level (keys(%privs)) {
           foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:'.$level})) {
               my ($priv,$restrict)=split(/\&/,$item);
               if (!$restrict) { $restrict=''; }
               if ($env{'form.'.$prefix.$priv.'_'.$level}) {
                   $privs{$level} .=':'.$item;
               }
           }
       }
       return %privs;
   }
   
   sub adhoc_status_types {
       my ($cdom,$context,$role,$selectedref,$othertitle,$usertypes,$types,$disabled) = @_;
       my $output = &Apache::loncommon::start_data_table();
       my $numinrow = 3;
       my $rem;
       if (ref($types) eq 'ARRAY') {
           for (my $i=0; $i<@{$types}; $i++) {
               if (defined($usertypes->{$types->[$i]})) {
                   my $rem = $i%($numinrow);
                   if ($rem == 0) {
                       if ($i > 0) {
                           $output .= &Apache::loncommon::end_data_table_row();
                       }
                       $output .= &Apache::loncommon::start_data_table_row();
                   }
                   my $check;
                   if (ref($selectedref) eq 'ARRAY') {
                       if (grep(/^\Q$types->[$i]\E$/,@{$selectedref})) {
                           $check = ' checked="checked"';
                       }
                   }
                   $output .= '<td>'.
                              '<span class="LC_nobreak"><label>'.
                              '<input type="checkbox" name="'.$context.$role.'_status" '.
                              'value="'.$types->[$i].'"'.$check.$disabled.' />'.
                              $usertypes->{$types->[$i]}.'</label></span></td>';
               }
           }
           $rem = @{$types}%($numinrow);
       }
       my $colsleft = $numinrow - $rem;
       if (($rem == 0) && (@{$types} > 0)) {
           $output .= &Apache::loncommon::start_data_table_row();
       }
       if ($colsleft > 1) {
           $output .= '<td colspan="'.$colsleft.'">';
       } else {
           $output .= '<td>';
       }
       my $defcheck;
       if (ref($selectedref) eq 'ARRAY') {
           if (grep(/^default$/,@{$selectedref})) {
               $defcheck = ' checked="checked"';
           }
       }
       $output .= '<span class="LC_nobreak"><label>'.
                  '<input type="checkbox" name="'.$context.$role.'_status"'.
                  'value="default"'.$defcheck.$disabled.' />'.
                  $othertitle.'</label></span></td>'.
                  &Apache::loncommon::end_data_table_row().
                  &Apache::loncommon::end_data_table();
       return $output;
   }
   
   sub adhoc_staff {
       my ($access,$context,$role,$selectedref,$adhocref,$disabled) = @_;
       my $output;
       if (ref($adhocref) eq 'HASH') {
           my %by_fullname;
           my $numinrow = 4;
           my $rem;
           my @personnel = keys(%{$adhocref});
           if (@personnel) {
               foreach my $person (@personnel) {
                   my ($uname,$udom) = split(/:/,$person);
                   my $fullname = &Apache::loncommon::plainname($uname,$udom,'lastname');
                   $by_fullname{$fullname} = $person;
               }
               my @sorted = sort(keys(%by_fullname));
               my $count = scalar(@sorted);
               $output = &Apache::loncommon::start_data_table();
               for (my $i=0; $i<$count; $i++) {
                   my $rem = $i%($numinrow);
                   if ($rem == 0) {
                       if ($i > 0) {
                           $output .= &Apache::loncommon::end_data_table_row();
                       }
                       $output .= &Apache::loncommon::start_data_table_row();
                   }
                   my $check;
                   my $user = $by_fullname{$sorted[$i]};
                   if (ref($selectedref) eq 'ARRAY') {
                       if (grep(/^\Q$user\E$/,@{$selectedref})) {
                           $check = ' checked="checked"';
                       }
                   }
                   if ($i == $count-1) {
                       my $colsleft = $numinrow - $rem;
                       if ($colsleft > 1) {
                           $output .= '<td colspan="'.$colsleft.'">';
                       } else {
                           $output .= '<td>';
                       }
                   } else {
                       $output .= '<td>';
                   }
                   $output .= '<span class="LC_nobreak"><label>'.
                              '<input type="checkbox" name="'.$context.$role.'_staff_'.$access.'" '.
                              'value="'.$user.'"'.$check.$disabled.' />'.$sorted[$i].
                              '</label></span></td>';
                   if ($i == $count-1) {
                       $output .= &Apache::loncommon::end_data_table_row();
                   }
               }
               $output .= &Apache::loncommon::end_data_table();
           }
       }
       return $output;
   }
   
   
 1;  1;
   

Removed from v.1.90  
changed lines
  Added in v.1.218


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.