Diff for /loncom/interface/lonuserutils.pm between versions 1.1 and 1.53

version 1.1, 2007/10/22 22:16:38 version 1.53, 2008/05/09 17:55:25
Line 35  use Apache::lonnet; Line 35  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
 use Apache::lonlocal;  use Apache::lonlocal;
 use LONCAPA();  use Apache::longroup;
   use LONCAPA qw(:DEFAULT :match);
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 # Drop student from all sections of a course, except optional $csec  # Drop student from all sections of a course, except optional $csec
 sub modifystudent {  sub modifystudent {
     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;      my ($udom,$unam,$courseid,$csec,$desiredhost,$context)=@_;
     # if $csec is undefined, drop the student from all the courses matching      # if $csec is undefined, drop the student from all the courses matching
     # this one.  If $csec is defined, drop them from all other sections of      # this one.  If $csec is defined, drop them from all other sections of
     # this course and add them to section $csec      # this course and add them to section $csec
     my $cdom = $env{'course.'.$courseid.'.domain'};      my ($cnum,$cdom) = &get_course_identity($courseid);
     my $cnum = $env{'course.'.$courseid.'.num'};  
     my %roles = &Apache::lonnet::dump('roles',$udom,$unam);      my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
     my ($tmp) = keys(%roles);      my ($tmp) = keys(%roles);
     # Bail out if we were unable to get the students roles      # Bail out if we were unable to get the students roles
Line 68  sub modifystudent { Line 68  sub modifystudent {
                     my $reply=&Apache::lonnet::modifystudent                      my $reply=&Apache::lonnet::modifystudent
                         # dom  name  id mode pass     f     m     l     g                          # dom  name  id mode pass     f     m     l     g
                         ($udom,$unam,'',  '',  '',undef,undef,undef,undef,                          ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
                          $section,time,undef,undef,$desiredhost);                           $section,time,undef,undef,$desiredhost,'','manual',
                            '',$courseid,'',$context);
                     $result .= $reply.':';                      $result .= $reply.':';
                 }                  }
             }              }
         }          }
     }      }
     if ($result eq '') {      if ($result eq '') {
         $result = 'Unable to find section for this student';          $result = &mt('Unable to find section for this student');
     } else {      } else {
         $result =~ s/(ok:)+/ok/g;          $result =~ s/(ok:)+/ok/g;
     }      }
Line 85  sub modifystudent { Line 86  sub modifystudent {
 sub modifyuserrole {  sub modifyuserrole {
     my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass,      my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass,
         $first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role,          $first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role,
         $end,$start) = @_;          $end,$start,$checkid) = @_;
     my ($scope,$userresult,$authresult,$roleresult);      my ($scope,$userresult,$authresult,$roleresult,$idresult);
     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' && $sec ne '') {
             $scope .='/'.$sec;              $scope .='/'.$sec;
         }          }
     } elsif ($setting eq 'domain') {      } elsif ($context eq 'domain') {
         $scope = '/'.$env{'request.role.domain'}.'/';          $scope = '/'.$env{'request.role.domain'}.'/';
     } elsif ($setting eq 'construction_space') {      } elsif ($context eq 'author') {
         $scope =  '/'.$env{'user.domain'}.'/'.$env{'user.name'};          $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);
         if ($uhome ne 'no_host') {          if ($uhome ne 'no_host') {
             if (($changeauth) && (&Apache::lonnet::allowed('mau',$udom))) {              if (($changeauth eq 'Yes') && (&Apache::lonnet::allowed('mau',$udom))) {
                 if ((($umode =~ /^krb4|krb5|internal$/) && $upass ne '') ||                  if ((($umode =~ /^krb4|krb5|internal$/) && $upass ne '') ||
                     ($umode eq 'localauth')) {                      ($umode eq 'localauth')) {
                     $authresult = &Apache::lonnet::modifyuserauth($udom,$uname,$umode,$upass);                      $authresult = &Apache::lonnet::modifyuserauth($udom,$uname,$umode,$upass);
                 }                  }
             }              }
               if (($forceid) && (&Apache::lonnet::allowed('mau',$udom)) &&
                   ($env{'form.recurseid'}) && ($checkid)) {
                   my %userupdate = (
                                     lastname   => $last,
                                     middlename => $middle,
                                     firstname  => $first,
                                     generation => $gene,
                                     id         => $uid,
                                    );
                   $idresult = &propagate_id_change($uname,$udom,\%userupdate);
               }
         }          }
     }      }
     $userresult =      $userresult =
Line 114  sub modifyuserrole { Line 126  sub modifyuserrole {
                                     $middle,$last,$gene,$forceid,$desiredhome,                                      $middle,$last,$gene,$forceid,$desiredhome,
                                     $email,$role,$start,$end);                                      $email,$role,$start,$end);
     if ($userresult eq 'ok') {      if ($userresult eq 'ok') {
         if ($role ne '') {           if ($role ne '') {
               $role =~ s/_/\//g;
             $roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope,              $roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope,
                                                       $role,$end,$start);                                                        $role,$end,$start,'',
                                                         '',$context);
         }          }
     }      }
     return ($userresult,$authresult,$roleresult);      return ($userresult,$authresult,$roleresult,$idresult);
 }  }
   
   sub propagate_id_change {
       my ($uname,$udom,$user) = @_;
       my (@types,@roles);
       @types = ('active','future');
       @roles = ('st');
       my $idresult;
       my %roleshash = &Apache::lonnet::get_my_roles($uname,
                           $udom,'userroles',\@types,\@roles);
       my %args = (
                   one_time => 1,
                  );
       foreach my $item (keys(%roleshash)) {
           my ($cnum,$cdom,$role) = split(/:/,$item,-1);
           my ($start,$end) = split(/:/,$roleshash{$item});
           if (&Apache::lonnet::is_course($cdom,$cnum)) {
               my $result = &update_classlist($cdom,$cnum,$udom,$uname,$user);
               my %coursehash = 
                   &Apache::lonnet::coursedescription($cdom.'_'.$cnum,\%args);
               my $cdesc = $coursehash{'description'};
               if ($cdesc eq '') { 
                   $cdesc = $cdom.'_'.$cnum;
               }
               if ($result eq 'ok') {
                   $idresult .= &mt('Classlist update for "[_1]" in "[_2]".',$uname.':'.$udom,$cdesc).'<br />'."\n";
               } else {
                   $idresult .= &mt('Error: "[_1]" during classlist update for "[_2]" in "[_3]".',$result,$uname.':'.$udom,$cdesc).'<br />'."\n";
               }
           }
       }
       return $idresult;
   }
   
   sub update_classlist {
       my ($cdom,$cnum,$udom,$uname,$user) = @_;
       my ($uid,$classlistentry);
       my $fullname =
           &Apache::lonnet::format_name($user->{'firstname'},$user->{'middlename'},
                                        $user->{'lastname'},$user->{'generation'},
                                        'lastname');
       my %classhash = &Apache::lonnet::get('classlist',[$uname.':'.$udom],
                                            $cdom,$cnum);
       my @classinfo = split(/:/,$classhash{$uname.':'.$udom});
       my $ididx=&Apache::loncoursedata::CL_ID() - 2;
       my $nameidx=&Apache::loncoursedata::CL_FULLNAME() - 2;
       for (my $i=0; $i<@classinfo; $i++) {
           if ($i == $ididx) {
               if (defined($user->{'id'})) {
                   $classlistentry .= $user->{'id'}.':';
               } else {
                   $classlistentry .= $classinfo[$i].':';
               }
           } elsif ($i == $nameidx) {
               $classlistentry .= $fullname.':';
           } else {
               $classlistentry .= $classinfo[$i].':';
           }
       }
       $classlistentry =~ s/:$//;
       my $reply=&Apache::lonnet::cput('classlist',
                                       {"$uname:$udom" => $classlistentry},
                                       $cdom,$cnum);
       if (($reply eq 'ok') || ($reply eq 'delayed')) {
           return 'ok';
       } else {
           return 'error: '.$reply;
       }
   }
   
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 # build a domain and server selection form  # build a role type and role selection form
 sub domain_form {  sub domain_roles_select {
     my ($defdom) = @_;      # Set up the role type and role selection boxes when in 
     # Set up domain and server selection forms      # domain context   
       #
       # Role types
       my @roletypes = ('domain','author','course');
       my %lt = &role_type_names();
     #      #
     # Get the domains  
     my @domains = &Apache::lonnet::all_domains();  
     # 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
     my %select_menus;      my %select_menus;
     foreach my $dom (@domains) {      if ($env{'form.roletype'} eq '') {
           $env{'form.roletype'} = 'domain';
       }
       foreach my $roletype (@roletypes) {
         # set up the text for this domain          # set up the text for this domain
         $select_menus{$dom}->{'text'}= $dom;          $select_menus{$roletype}->{'text'}= $lt{$roletype};
         # 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
         $select_menus{$dom}->{'default'}= 'default';          if ($env{'form.roletype'} ne '') {
         $select_menus{$dom}->{'select2'}->{'default'} = 'default';              $select_menus{$roletype}->{'default'} = $env{'form.showrole'};
           } else { 
               $select_menus{$roletype}->{'default'} = 'Any';
           }
         # Now build up the other items in the second menu          # Now build up the other items in the second menu
         my %servers = &Apache::lonnet::get_servers($dom,'library');          my @roles;
         foreach my $server (keys(%servers)) {          if ($roletype eq 'domain') {
             $select_menus{$dom}->{'select2'}->{$server}              @roles = &domain_roles();
                                             = "$server $servers{$server}";          } elsif ($roletype eq 'author') {
               @roles = &construction_space_roles();
           } else {
               my $custom = 1;
               @roles = &course_roles('domain',undef,$custom);
         }          }
           my $order = ['Any',@roles];
           $select_menus{$roletype}->{'order'} = $order; 
           foreach my $role (@roles) {
               if ($role eq 'cr') {
                   $select_menus{$roletype}->{'select2'}->{$role} =
                                 &mt('Custom role');
               } else {
                   $select_menus{$roletype}->{'select2'}->{$role} = 
                                 &Apache::lonnet::plaintext($role);
               }
           }
           $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');
     }      }
     my $result  = &Apache::loncommon::linked_select_forms      my $result = &Apache::loncommon::linked_select_forms
         ('studentform',' with home server ',$defdom,          ('studentform',('&nbsp;'x3).&mt('Role: '),$env{'form.roletype'},
          'lcdomain','lcserver',\%select_menus);           'roletype','showrole',\%select_menus,['domain','author','course']);
     return $result;      return $result;
 }  }
   
Line 161  sub hidden_input { Line 268  sub hidden_input {
 }  }
   
 sub print_upload_manager_header {  sub print_upload_manager_header {
     my ($r,$datatoken,$distotal,$krbdefdom,$context)=@_;      my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_;
     my $javascript;      my $javascript;
     #      #
     if (! exists($env{'form.upfile_associate'})) {      if (! exists($env{'form.upfile_associate'})) {
Line 191  sub print_upload_manager_header { Line 298  sub print_upload_manager_header {
         $password_choice = 'int';          $password_choice = 'int';
     }      }
     #      #
       my $groupslist;
       if ($context eq 'course') {
           $groupslist = &get_groupslist();
       }
     my $javascript_validations =      my $javascript_validations =
         &javascript_validations('auth',$krbdefdom,$password_choice,undef,          &javascript_validations('upload',$krbdefdom,$password_choice,undef,
                                 $env{'request.role.domain'});                                  $env{'request.role.domain'},$context,
                                   $groupslist);
     my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');
     $r->print(&mt('Total number of records found in file: <b>[_1]</b>.',$distotal).      $r->print(&mt('Total number of records found in file: <b>[_1]</b>.',$distotal).
               "<br />\n");                "<br />\n");
Line 220  sub print_upload_manager_header { Line 332  sub print_upload_manager_header {
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub javascript_validations {  sub javascript_validations {
     my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain)=@_;      my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain,
     my $authheader;          $context,$groupslist)=@_;
     if ($mode eq 'auth') {      my %param = (
         my %param = ( formname => 'studentform',  
                       kerb_def_dom => $krbdefdom,  
                       curr_authtype => $curr_authtype);  
         $authheader = &Apache::loncommon::authform_header(%param);  
     } elsif ($mode eq 'createcourse') {  
         my %param = ( formname => 'ccrs',  
                       kerb_def_dom => $krbdefdom,  
                       curr_authtype => $curr_authtype );  
         $authheader = &Apache::loncommon::authform_header(%param);  
     } elsif ($mode eq 'modifycourse') {  
         my %param = ( formname => 'cmod',  
                   kerb_def_dom => $krbdefdom,                    kerb_def_dom => $krbdefdom,
                   mode => 'modifycourse',  
                   curr_authtype => $curr_authtype,                    curr_authtype => $curr_authtype,
                   curr_autharg => $curr_authfield );                  );
         $authheader = &Apache::loncommon::authform_header(%param);      if ($mode eq 'upload') {
           $param{'formname'} = 'studentform';
       } elsif ($mode eq 'createcourse') {
           $param{'formname'} = 'ccrs';
       } elsif ($mode eq 'modifycourse') {
           $param{'formname'} = 'cmod';
           $param{'mode'} = 'modifycourse',
           $param{'curr_autharg'} = $curr_authfield;
     }      }
   
       my ($setsection_call,$setsections_js);
       my $finish = "  vf.submit();\n";
       if ($mode eq 'upload') {
           if (($context eq 'course') || ($context eq 'domain')) {
               if ($context eq 'course') {
                   if ($env{'request.course.sec'} eq '') {
                       $setsection_call = 'setSections(document.'.$param{'formname'}.');';
                       $setsections_js =
                           &setsections_javascript($param{'formname'},$groupslist,
                                                   $mode);
                   } else {
                       $setsection_call = "'ok'";
                   }
               } elsif ($context eq 'domain') {
                   $setsection_call = 'setCourse()';
                   $setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context);
               }
               $finish = "  var checkSec = $setsection_call\n".
                         "  if (checkSec == 'ok') {\n".
                         "      vf.submit();\n".
                         "   }\n";
           }
       }
       my $authheader = &Apache::loncommon::authform_header(%param);
   
     my %alert = &Apache::lonlocal::texthash      my %alert = &Apache::lonlocal::texthash
         (username => 'You need to specify the username field.',          (username => 'You need to specify the username field.',
          authen   => 'You must choose an authentication type.',           authen   => 'You must choose an authentication type.',
Line 253  sub javascript_validations { Line 385  sub javascript_validations {
          role     => 'The optional role field was not specified.',           role     => 'The optional role field was not specified.',
          continue => 'Continue adding users?',           continue => 'Continue adding users?',
          );           );
       my $function_name = <<"END";
   $setsections_js
   
 #    my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();  
     my $function_name =(<<END);  
 function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {  function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
 END  END
     my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($domain);      my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($domain);
Line 319  END Line 451  END
     foundatype=1;      foundatype=1;
     if (current.argfield == null || current.argfield == '') {      if (current.argfield == null || current.argfield == '') {
         var alertmsg = '';          var alertmsg = '';
         switch (current.value) {          switch (current.radiovalue) {
             case 'krb':              case 'krb':
                 alertmsg = '$alert{'krb'}';                  alertmsg = '$alert{'krb'}';
                 break;                  break;
Line 375  END Line 507  END
         message+= '\\n$alert{'continue'}';          message+= '\\n$alert{'continue'}';
         if (confirm(message)) {          if (confirm(message)) {
             vf.state.value='enrolling';              vf.state.value='enrolling';
             vf.submit();              $finish
         }          }
     } else {      } else {
         vf.state.value='enrolling';          vf.state.value='enrolling';
         vf.submit();          $finish
     }      }
 }  }
 END  END
     }      }
     my $result = $function_name;      my $result = $function_name.$auth_checks.$optional_checks."\n".
     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {                   $section_checks.$authheader;
         $result .= $auth_checks;  
     }  
     $result .= $optional_checks."\n".$section_checks;  
     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {  
         $result .= $authheader;  
     }  
     return $result;      return $result;
 }  }
 ###############################################################  ###############################################################
Line 550  ENDPICK Line 676  ENDPICK
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub print_upload_manager_footer {  sub print_upload_manager_footer {
     my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context)=@_;      my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission) = @_;
     my $formname;      my $form = 'document.studentform';
     if ($context eq 'course') {      my $formname = 'studentform';
         $formname = 'document.studentform';  
     } elsif ($context eq 'construction_space') {  
         $formname = 'document.studentform';  
     } elsif ($context eq 'domain') {  
         $formname = 'document.studentform';  
     }  
     my ($krbdef,$krbdefdom) =      my ($krbdef,$krbdefdom) =
         &Apache::loncommon::get_kerberos_defaults($defdom);          &Apache::loncommon::get_kerberos_defaults($defdom);
     my %param = ( formname => $formname,      my %param = ( formname => $form,
                   kerb_def_dom => $krbdefdom,                    kerb_def_dom => $krbdefdom,
                   kerb_def_auth => $krbdef                    kerb_def_auth => $krbdef
                   );                    );
Line 573  sub print_upload_manager_footer { Line 693  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 $date_table = &date_setting_table(undef,undef,$context);      my $date_table = &date_setting_table(undef,undef,$context,undef,
                                            $formname,$permission);
     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);
Line 605  sub print_upload_manager_footer { Line 725  sub print_upload_manager_footer {
         $Str .= '<h3>'.&mt('Settings for assigning roles:').'</h3>'."\n".          $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>';                  &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 'construction_space') {      if ($context eq 'author') {
         $Str .= '<h3>'.&mt('Default role')."</h3>\n".          $Str .= '<h3>'.&mt('Default role')."</h3>\n".
                 &mt('Choose the role to assign to users without one specified in the uploaded file');                  &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".          $Str .= '<h3>'.&mt('Default role and section')."</h3>\n".
                 &mt('Choose the role and/or section to assign to users without one specified in the uploaded file');                  &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')."</b><br />\n".          $Str .= '<br /><br /><b>'.&mt('Default role and/or section(s)')."</b><br />\n".
                 &mt('Role and/or section for users without one in the uploaded file.');                  &mt('Role and/or section(s) for users without values specified in the uploaded file.');
     }      }
     $Str .= '<br /><br />';      $Str .= '<br />';
     my ($options,$cb_script,$coursepick) = &default_role_selector($context);      if (($context eq 'domain') || ($context eq 'author')) {
     if ($context eq 'domain') {          my ($options,$cb_script,$coursepick) = &default_role_selector($context,1);
         $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;          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;
           } elsif ($context eq 'author') {
               $Str .= $options;
           }
     } else {      } else {
         $Str .= $options;          my ($cnum,$cdom) = &get_course_identity();
           my $rowtitle = &mt('section');
           my $secbox = &section_picker($cdom,$cnum,'Any',$rowtitle,
                                        $permission,$context,'upload');
           $Str .= $secbox."<h3>".&mt('Full Update')."</h3>\n".
                   '<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";
       }
       if ($context eq 'course' || $context eq 'domain') {
           $Str .= &forceid_change($context);
     }      }
     if ($context eq 'course') {  
         $Str .= "<h3>".&mt('Full Update')."</h3>\n".  
                 '<label><input type="checkbox" name="fullup" value="yes">'.  
                 ' '.&mt('Full update (also print list of users not enrolled anymore)').  
                 "</label></p>\n";  
     }  
     $Str .= "<h3>".&mt('ID/Student Number')."</h3>\n";  
     $Str .= "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">';  
     $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '.  
                 'of Conflicting IDs').  
                 '</label><br />'."\n".  
                 &mt('(only do if you know what you are doing.)')."</p><p>\n";  
     $Str .= '</div><div class="LC_clear_float_footer"><br /><input type="button"'.      $Str .= '</div><div class="LC_clear_float_footer"><br /><input type="button"'.
               'onClick="javascript:verify(this.form,this.form.csec)" '.                'onClick="javascript:verify(this.form,this.form.csec)" '.
         'value="Update Users" />'."<br />\n";          'value="Update Users" />'."<br />\n";
Line 646  sub print_upload_manager_footer { Line 767  sub print_upload_manager_footer {
     return;      return;
 }  }
   
   sub forceid_change {
       my ($context) = @_;
       my $output = 
           "<h3>".&mt('ID/Student Number')."</h3>\n".
           "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">'.
           &mt('Disable ID/Student Number Safeguard and Force Change '.
           'of Conflicting IDs').'</label><br />'."\n".
           &mt('(only do if you know what you are doing.)')."\n";
       if ($context eq 'domain') {
           $output .= '<br /><label><input type="checkbox" name="recurseid"'.
                      ' value="yes">'. 
     &mt('Update ID/Student Number in courses in which user is Active/Future student,<br />(if forcing change).').
                      '</label>'."\n";
       }
       $output .= '</p>';
       return $output;
   }
   
 ###############################################################  ###############################################################
 ###############################################################  ###############################################################
 sub print_upload_manager_form {  sub print_upload_manager_form {
     my ($r,$context) = @_;      my ($r,$context,$permission) = @_;
     my $firstLine;      my $firstLine;
     my $datatoken;      my $datatoken;
     if (!$env{'form.datatoken'}) {      if (!$env{'form.datatoken'}) {
Line 693  sub print_upload_manager_form { Line 832  sub print_upload_manager_form {
     my ($krbdef,$krbdefdom) =      my ($krbdef,$krbdefdom) =
         &Apache::loncommon::get_kerberos_defaults($defdom);          &Apache::loncommon::get_kerberos_defaults($defdom);
     #      #
     &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context);      &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context,
                                    $permission);
     my $i;      my $i;
     my $keyfields;      my $keyfields;
     if ($total>=0) {      if ($total>=0) {
Line 727  sub print_upload_manager_form { Line 867  sub print_upload_manager_form {
     }      }
     $r->print('</div>');      $r->print('</div>');
     &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,      &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
                                  $context);                                   $context,$permission);
 }  }
   
 sub setup_date_selectors {  sub setup_date_selectors {
     my ($starttime,$endtime,$mode) = @_;      my ($starttime,$endtime,$mode,$nolink,$formname) = @_;
       if ($formname eq '') {
           $formname = 'studentform';
       }
     if (! defined($starttime)) {      if (! defined($starttime)) {
         $starttime = time;          $starttime = time;
         unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {          unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
Line 752  sub setup_date_selectors { Line 895  sub setup_date_selectors {
             }              }
         }          }
     }      }
     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',  
                                                             'startdate',      my $startdateform = 
                                                             $starttime);          &Apache::lonhtmlcommon::date_setter($formname,'startdate',$starttime,
     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',              undef,undef,undef,undef,undef,undef,undef,$nolink);
                                                           'enddate',  
                                                           $endtime);      my $enddateform = 
           &Apache::lonhtmlcommon::date_setter($formname,'enddate',$endtime,
               undef,undef,undef,undef,undef,undef,undef,$nolink);
   
     if ($mode eq 'create_enrolldates') {      if ($mode eq 'create_enrolldates') {
         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',          $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                                                             'startenroll',                                                              'startenroll',
Line 788  sub get_dates_from_form { Line 934  sub get_dates_from_form {
 }  }
   
 sub date_setting_table {  sub date_setting_table {
     my ($starttime,$endtime,$mode) = @_;      my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission) = @_;
     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);      my $nolink;
       if ($bulkaction) {
           $nolink = 1;
       }
       my ($startform,$endform) = 
           &setup_date_selectors($starttime,$endtime,$mode,$nolink,$formname);
     my $dateDefault;      my $dateDefault;
     if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {      if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
         $dateDefault = '&nbsp;';          $dateDefault = '&nbsp;';
     } elsif ($mode ne 'construction_space' && $mode ne 'domain') {      } elsif ($mode ne 'author' && $mode ne 'domain') {
         $dateDefault = '<nobr>'.          if (($bulkaction eq 'reenable') || 
         '<label><input type="checkbox" name="makedatesdefault" /> '.              ($bulkaction eq 'activate') || 
         &mt('make these dates the default for future enrollment').              ($bulkaction eq 'chgdates') ||
         '</label></nobr>';              ($env{'form.action'} eq 'upload')) {
               if ($env{'request.course.sec'} eq '') {
                   $dateDefault = '<span class="LC_nobreak">'.
                       '<label><input type="checkbox" name="makedatesdefault" value="1" /> '.
                       &mt('make these dates the default access dates for future student enrollment').
                       '</label></span>';
               }
           }
     }      }
     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"';      my $perpetual = '<span class="LC_nobreak"><label><input type="checkbox" name="no_end_date"';
     if (defined($endtime) && $endtime == 0) {      if (defined($endtime) && $endtime == 0) {
         $perpetual .= ' checked';          $perpetual .= ' checked';
     }      }
     $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>';      $perpetual.= ' /> '.&mt('no ending date').'</label></span>';
     if ($mode eq 'create_enrolldates') {      if ($mode eq 'create_enrolldates') {
         $perpetual = '&nbsp;';          $perpetual = '&nbsp;';
     }      }
     my $result = &Apache::lonhtmlcommon::start_pick_box()."\n".      my $result = &Apache::lonhtmlcommon::start_pick_box()."\n";
                  &Apache::lonhtmlcommon::row_title(&mt('Starting Date'),      $result .= &Apache::lonhtmlcommon::row_title(&mt('Starting Date'),
                                                    'LC_oddrow_value')."\n".                                                       'LC_oddrow_value')."\n".
                  $startform."\n".                 $startform."\n".
                  &Apache::lonhtmlcommon::row_closure(1).                 &Apache::lonhtmlcommon::row_closure(1).
                  &Apache::lonhtmlcommon::row_title(&mt('Ending Date'),                 &Apache::lonhtmlcommon::row_title(&mt('Ending Date'), 
                                                    'LC_oddrow_value')."\n".                                                       'LC_oddrow_value')."\n".
                  $endform.'&nbsp;'.$perpetual.                 $endform.'&nbsp;'.$perpetual.
                  &Apache::lonhtmlcommon::row_closure(1).                 &Apache::lonhtmlcommon::row_closure(1).
                  &Apache::lonhtmlcommon::end_pick_box().'<br />';                 &Apache::lonhtmlcommon::end_pick_box();
     if ($dateDefault) {      if ($dateDefault) {
         $result .=  $dateDefault.'<br />'."\n";          $result .=  $dateDefault.'<br />'."\n";
     }      }
Line 827  sub make_dates_default { Line 985  sub make_dates_default {
     my ($startdate,$enddate,$context) = @_;      my ($startdate,$enddate,$context) = @_;
     my $result = '';      my $result = '';
     if ($context eq 'course') {      if ($context eq 'course') {
         my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};          my ($cnum,$cdom) = &get_course_identity();
         my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};  
         my $put_result = &Apache::lonnet::put('environment',          my $put_result = &Apache::lonnet::put('environment',
                 {'default_enrollment_start_date'=>$startdate,                  {'default_enrollment_start_date'=>$startdate,
                  'default_enrollment_end_date'  =>$enddate},$dom,$crs);                   'default_enrollment_end_date'  =>$enddate},$cdom,$cnum);
         if ($put_result eq 'ok') {          if ($put_result eq 'ok') {
             $result .= "Set default start and end dates for course<br />";              $result .= &mt('Set default start and end access dates for course.').
                          '<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 dates for course').":".$put_result.              $result .= &mt('Unable to set default access dates for course.').":".$put_result.
                        '<br />';                         '<br />';
         }          }
     }      }
Line 847  sub make_dates_default { Line 1005  sub make_dates_default {
 }  }
   
 sub default_role_selector {  sub default_role_selector {
     my ($context) = @_;      my ($context,$checkpriv) = @_;
     my %customroles;      my %customroles;
     my ($options,$coursepick,$cb_jscript);      my ($options,$coursepick,$cb_jscript);
     if ($context ne 'construction_space') {      if ($context ne 'author') {
         %customroles = &my_custom_roles();          %customroles = &my_custom_roles();
     }      }
   
Line 863  sub default_role_selector { Line 1021  sub default_role_selector {
     $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,%customroles);          $options .= &default_course_roles($context,$checkpriv,%customroles);
     } elsif ($context eq 'construction_space') {      } elsif ($context eq 'author') {
         my @roles = &construction_space_roles();          my @roles = &construction_space_roles($checkpriv);
         foreach my $role (@roles) {          foreach my $role (@roles) {
            my $plrole=&Apache::lonnet::plaintext($role);             my $plrole=&Apache::lonnet::plaintext($role);
            $options .= '  <option value="'.$role.'">'.$plrole.'</option>'."\n";             $options .= '  <option value="'.$role.'">'.$plrole.'</option>'."\n";
         }          }
     } elsif ($context eq 'domain') {      } elsif ($context eq 'domain') {
         my @roles = &domain_roles();          my @roles = &domain_roles($checkpriv);
         foreach my $role (@roles) {          foreach my $role (@roles) {
            my $plrole=&Apache::lonnet::plaintext($role);             my $plrole=&Apache::lonnet::plaintext($role);
            $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','defaultcourse','defaultdomain','defaultdesc',"$env{'request.role.domain'}",undef,'Course');              ('studentform','dccourse','dcdomain','coursedesc',"$env{'request.role.domain'}",undef,'Course');
         $cb_jscript =           $cb_jscript = 
             &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'defaultsec','studentform');              &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'currsec','studentform');
         $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>'.
                       &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="defaultdesc" value="" onFocus="this.blur();opencrsbrowser('."'studentform','defcourse','defdomain','coursedesc',''".')" /></td>'."\n".                        '<td><input type="text" name="coursedesc" value="" onFocus="this.blur();opencrsbrowser('."'studentform','dccourse','dcdomain','coursedesc',''".')" /></td>'."\n".
                       '<td><select name="courserole">'."\n".                        '<td><select name="courserole">'."\n".
                       &default_course_roles($context,%customroles)."\n".                        &default_course_roles($context,$checkpriv,%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="defaultsec">'.                        $lt{'exs'}.'<br /><select name="currsec">'.
                       ' <option value=""><--'.&mt('Pick course first').                        ' <option value=""><--'.&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 />'.
                       '<input type="text" name="newsec" value="" size="5" />'.                        '<input type="text" name="newsec" value="" size="5" />'.
                       '<input type="hidden" name="groups" value="" /></td>'.                        '<input type="hidden" name="groups" value="" />'.
                       '</tr></table></td>'.                        '<input type="hidden" name="sections" value="" />'.
                         '<input type="hidden" name="origdom" value="'.
                         $env{'request.role.domain'}.'" />'.
                         '<input type="hidden" name="dccourse" value="" />'.
                         '<input type="hidden" name="dcdomain" value="" />'.
                         '</td></tr></table></td>'.
                       &Apache::loncommon::end_data_table_row().                        &Apache::loncommon::end_data_table_row().
                       &Apache::loncommon::end_data_table()."\n".                        &Apache::loncommon::end_data_table()."\n";
                       '<input type="hidden" name="defaultcourse" value="" />'.  
                       '<input type="hidden" name="defaultdomain" value="" />';  
     }      }
     $options .= '</select>';      $options .= '</select>';
     return ($options,$cb_jscript,$coursepick);      return ($options,$cb_jscript,$coursepick);
 }  }
   
 sub default_course_roles {  sub default_course_roles {
     my ($context,%customroles) = @_;      my ($context,$checkpriv,%customroles) = @_;
     my $output;      my $output;
     my @roles = &course_roles($context);      my $custom = 1;
       my @roles = &course_roles($context,$checkpriv,$custom);
     foreach my $role (@roles) {      foreach my $role (@roles) {
         my $plrole=&Apache::lonnet::plaintext($role);          if ($role ne 'cr') {
         $output .= '  <option value="'.$role.'">'.$plrole.'</option>';              my $plrole=&Apache::lonnet::plaintext($role);
               $output .= '  <option value="'.$role.'">'.$plrole.'</option>';
           }
     }      }
     if (keys(%customroles) > 0) {      if (keys(%customroles) > 0) {
         foreach my $cust (sort(keys(%customroles))) {          if (grep(/^cr$/,@roles)) {
             my $custrole='cr_cr_'.$env{'user.domain'}.              foreach my $cust (sort(keys(%customroles))) {
                 '_'.$env{'user.name'}.'_'.$cust;                  my $custrole='cr_'.$env{'user.domain'}.
             $output .= '  <option value="'.$custrole.'">'.$cust.'</option>';                               '_'.$env{'user.name'}.'_'.$cust;
                   $output .= '  <option value="'.$custrole.'">'.$cust.'</option>';
               }
         }          }
     }      }
     return $output;      return $output;
 }  }
   
 sub construction_space_roles {  sub construction_space_roles {
     my @allroles = ('ca','aa');      my ($checkpriv) = @_;
       my @allroles = &roles_by_context('author');
     my @roles;      my @roles;
     foreach my $role (@allroles) {      if ($checkpriv) {
         if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) {           foreach my $role (@allroles) {
             push(@roles,$role);               if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) { 
                   push(@roles,$role); 
               }
         }          }
           return @roles;
       } else {
           return @allroles;
     }      }
     return @roles;  
 }  }
   
 sub domain_roles {  sub domain_roles {
     my @allroles = ('dc','li','dg','au','sc');      my ($checkpriv) = @_;
       my @allroles = &roles_by_context('domain');
     my @roles;      my @roles;
     foreach my $role (@allroles) {      if ($checkpriv) {
         if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {          foreach my $role (@allroles) {
             push(@roles,$role);              if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
                   push(@roles,$role);
               }
         }          }
           return @roles;
       } else {
           return @allroles;
     }      }
     return @roles;  
 }  }
   
 sub course_roles {  sub course_roles {
     my ($context) = @_;      my ($context,$checkpriv,$custom) = @_;
     my @allroles = ('st','ta','ep','in','cc');      my @allroles = &roles_by_context('course',$custom);
     my @roles;      my @roles;
     if ($context eq 'domain') {      if ($context eq 'domain') {
         @roles = @allroles;          @roles = @allroles;
     } elsif ($context eq 'course') {      } elsif ($context eq 'course') {
         if ($env{'request.course.id'}) {          if ($env{'request.course.id'}) {
             foreach my $role (@allroles) {              if ($checkpriv) { 
                 if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {                  foreach my $role (@allroles) {
                     push(@roles,$role);                        if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
                 } else {                          push(@roles,$role);
                     if ($role ne 'cc' && $env{'request.course.section'} ne '') {                      } else {
                         if (!&Apache::lonnet::allowed('c'.$role,                          if ($role ne 'cc' && $env{'request.course.sec'} ne '') {
                                          $env{'request.course.id'}.'/'.                              if (&Apache::lonnet::allowed('c'.$role,
                                          $env{'request.course.section'})) {                                               $env{'request.course.id'}.'/'.
                             push(@roles,$role);                                               $env{'request.course.sec'})) {
                                   push(@roles,$role);
                               }
                         }                          }
                     }                      }
                 }                  }
               } else {
                   @roles = @allroles;
             }              }
         }          }
     }      }
Line 976  sub course_roles { Line 1156  sub course_roles {
 }  }
   
 sub curr_role_permissions {  sub curr_role_permissions {
     my ($context,$setting) = @_;       my ($context,$setting,$checkpriv) = @_; 
       my $custom = 1;
     my @roles;      my @roles;
     if ($context eq 'construction_space') {      if ($context eq 'author') {
         @roles = &construction_space_roles();          @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);               @roles = &course_roles($context,$checkpriv,$custom); 
         } else {          } else {
             @roles = &domain_roles();              @roles = &domain_roles($checkpriv);
         }          }
     } elsif ($context eq 'course') {      } elsif ($context eq 'course') {
         @roles = &course_roles($context);          @roles = &course_roles($context,$checkpriv,$custom);
     }      }
     return @roles;      return @roles;
 }  }
Line 1005  sub my_custom_roles { Line 1186  sub my_custom_roles {
     return %returnhash;      return %returnhash;
 }  }
   
 sub print_html_classlist {  sub print_userlist {
     my ($r,$mode,$permission,$context) = @_;      my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,
           $idlist,$idlist_titles) = @_;
       my $format = $env{'form.output'};
     if (! exists($env{'form.sortby'})) {      if (! exists($env{'form.sortby'})) {
         $env{'form.sortby'} = 'username';          $env{'form.sortby'} = 'username';
     }      }
     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 $status_select = &Apache::lonhtmlcommon::StatusOptions      my $status_select = &Apache::lonhtmlcommon::StatusOptions
         ($env{'form.status'});          ($env{'form.Status'});
   
       if ($env{'form.showrole'} eq '') {
           if ($context eq 'course') {
               $env{'form.showrole'} = 'st';
           } else {
               $env{'form.showrole'} = 'Any';            
           }
       }
     if (! defined($env{'form.output'}) ||      if (! defined($env{'form.output'}) ||
         $env{'form.output'} !~ /^(csv|excel|html)$/ ) {          $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
         $env{'form.output'} = 'html';          $env{'form.output'} = 'html';
     }      }
   
     if ($context eq 'course') {       my @statuses;
         my $cid =$env{'request.course.id'};      if ($env{'form.Status'} eq 'Any') {
         my $cdom=$env{'course.'.$cid.'.domain'};          @statuses = ('previous','active','future');
         my $cnum=$env{'course.'.$cid.'.num'};      } elsif ($env{'form.Status'} eq 'Expired') {
         #          @statuses = ('previous');
         # List course personnel      } elsif ($env{'form.Status'} eq 'Active') {
         my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);          @statuses = ('active');
         #      } elsif ($env{'form.Status'} eq 'Future') {
           @statuses = ('future');
         $r->print('<br />'.&Apache::loncommon::start_data_table());  
         foreach my $role (sort keys %coursepersonnel) {  
             next if ($role =~ /^\s*$/);  
             $r->print(&Apache::loncommon::start_data_table_row().  
                       '<td>'.$role.'</td><td>');  
             foreach my $user (split(',',$coursepersonnel{$role})) {  
                 my ($puname,$pudom)=split(':',$user);  
                 $r->print(' '.&Apache::loncommon::aboutmewrapper(  
                           &Apache::loncommon::plainname($puname,$pudom),  
                           $puname,$pudom));  
             }  
             $r->print('</td>'.&Apache::loncommon::end_data_table_row());  
         }  
         $r->print(&Apache::loncommon::end_data_table());  
     }      }
   
   #    if ($context eq 'course') { 
   #        $r->print(&display_adv_courseroles());
   #    }
     #      #
     # Interface output      # Interface output
     $r->print('<input type="hidden" name="action" value="'.      $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n".
                 '<input type="hidden" name="action" value="'.
               $env{'form.action'}.'" />');                $env{'form.action'}.'" />');
     $r->print("<p>\n");      $r->print("<p>\n");
     if ($env{'form.action'} ne 'modifystudent') {      if ($env{'form.action'} ne 'modifystudent') {
Line 1066  sub print_html_classlist { Line 1247  sub print_html_classlist {
         $output_selector .= '</select>';          $output_selector .= '</select>';
         $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.('&nbsp;'x3));          $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.('&nbsp;'x3));
     }      }
     $r->print('<label>'.&mt('Student Status: [_1]',$status_select)."</label>\n");      $r->print('<label>'.&mt('User Status: [_1]',$status_select).'</label>'.('&nbsp;'x3)."\n");
     $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.      my $roleselected = '';
               "\n</p>\n");      if ($env{'form.showrole'} eq 'Any') {
          $roleselected = ' selected="selected" '; 
       }
       my ($cnum,$cdom);
       $r->print(&role_filter($context));
     if ($context eq 'course') {      if ($context eq 'course') {
         #          ($cnum,$cdom) = &get_course_identity();
         # Print the classlist          $r->print(&section_group_filter($cnum,$cdom));
         $r->print('<h2>'.&mt('Current Class List').'</h2>');      }
         my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();      if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {
           $r->print('&nbsp;'.&list_submit_button(&mt('Update Display')).
         if (exists($permission->{'view_section'})) {                    "\n</p>\n");
             my $sec = &Apache::loncoursedata::CL_SECTION();      }
             foreach my $student (keys(%{$classlist})) {      my ($indexhash,$keylist) = &make_keylist_array();
                 if ($classlist->{$student}[$sec] ne $permission->{'view_section'}) {      my (%userlist,%userinfo);
                     delete($classlist->{$student});      if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
           my $courseform =
               &Apache::lonhtmlcommon::course_selection($formname,$totcodes,
                                            $codetitles,$idlist,$idlist_titles);
           $r->print('<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n".
                     &Apache::lonhtmlcommon::start_pick_box()."\n".
                     &Apache::lonhtmlcommon::row_title(&mt('Select Course(s)'),
                                                       'LC_oddrow_value')."\n".
                     $courseform."\n".
                     &Apache::lonhtmlcommon::row_closure(1).
                     &Apache::lonhtmlcommon::end_pick_box().'</p>'.
                     '<p>'.&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");
           if ($env{'form.coursepick'}) {
               $r->print('<hr />'.&mt('Searching').' ...<br />&nbsp;<br />');
           }
       } else {
           $r->print('<hr />'.&mt('Searching').' ...<br />&nbsp;<br />');
       }
       $r->rflush();
       if ($context eq 'course') {
           if (($env{'form.showrole'} eq 'st') || ($env{'form.showrole'} eq 'Any')) { 
               my $classlist = &Apache::loncoursedata::get_classlist();
               %userlist = %{$classlist};
           }
           if ($env{'form.showrole'} ne 'st') {
               my $showroles;
               if ($env{'form.showrole'} ne 'Any') {
                   $showroles = [$env{'form.showrole'}];
               } else {
                   $showroles = undef;
               }
               my $withsec = 1;
               my $hidepriv = 1;
               my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,
                                 \@statuses,$showroles,undef,$withsec,$hidepriv);
               &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
                                \%advrolehash,$permission);
           }
       } else {
           my (%cstr_roles,%dom_roles);
           if ($context eq 'author') {
               # List co-authors and assistant co-authors
               my @possroles = &roles_by_context($context);
               %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
                                                 \@statuses,\@possroles);
               &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
                                \%cstr_roles,$permission);
           } elsif ($context eq 'domain') {
               if ($env{'form.roletype'} eq 'domain') {
                   %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'});
                   foreach my $key (keys(%dom_roles)) {
                       if (ref($dom_roles{$key}) eq 'HASH') {
                           &gather_userinfo($context,$format,\%userlist,$indexhash,
                                            \%userinfo,$dom_roles{$key},$permission);
                       }
                   }
               } elsif ($env{'form.roletype'} eq 'author') {
                   my %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'},['au']);
                   my %coauthors;
                   foreach my $key (keys(%dom_roles)) {
                       if (ref($dom_roles{$key}) eq 'HASH') {
                           if ($env{'form.showrole'} eq 'au') {
                               &gather_userinfo($context,$format,\%userlist,$indexhash,
                                                \%userinfo,$dom_roles{$key},$permission);
                           } else {
                               my @possroles;
                               if ($env{'form.showrole'} eq 'Any') {
                                   @possroles = &roles_by_context('author');
                               } else {
                                   @possroles = ($env{'form.showrole'}); 
                               }
                               foreach my $author (sort(keys(%{$dom_roles{$key}}))) {
                                   my ($role,$authorname,$authordom) = split(/:/,$author,-1);
                                   my $extent = '/'.$authordom.'/'.$authorname;
                                   %{$coauthors{$extent}} =
                                       &Apache::lonnet::get_my_roles($authorname,
                                          $authordom,undef,\@statuses,\@possroles);
                               }
                               &gather_userinfo($context,$format,\%userlist,
                                        $indexhash,\%userinfo,\%coauthors,$permission);
                           }
                       }
                   }
               } elsif ($env{'form.roletype'} eq 'course') {
                   if ($env{'form.coursepick'}) {
                       my %courses = &process_coursepick();
                       my %allusers;
                       my $hidepriv = 1;
                       foreach my $cid (keys(%courses)) {
                           my ($cnum,$cdom,$cdesc) = &get_course_identity($cid);
                           next if ($cnum eq '' || $cdom eq '');
                           my $custom = 1;
                           my (@roles,@sections,%access,%users,%userdata,
                               %statushash);
                           if ($env{'form.showrole'} eq 'Any') {
                               @roles = &course_roles($context,undef,$custom);
                           } else {
                               @roles = ($env{'form.showrole'});
                           }
                           foreach my $role (@roles) {
                               %{$users{$role}} = ();
                           }
                           foreach my $type (@statuses) {
                               $access{$type} = $type;
                           }
                           &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users,\%userdata,\%statushash,$hidepriv);
                           foreach my $user (keys(%userdata)) {
                               next if (ref($userinfo{$user}) eq 'HASH');
                               foreach my $item ('fullname','id') {
                                   $userinfo{$user}{$item} = $userdata{$user}[$indexhash->{$item}];
                               }
                           }
                           foreach my $role (keys(%users)) {
                               foreach my $user (keys(%{$users{$role}})) {
                                   my $uniqid = $user.':'.$role;
                                   $allusers{$uniqid}{$cid} = { desc => $cdesc,
                                                                secs  => $statushash{$user}{$role},
                                                              };
                               }
                           }
                       }
                       &gather_userinfo($context,$format,\%userlist,$indexhash,
                                        \%userinfo,\%allusers,$permission);
                   } else {
                       $r->print('<input type="hidden" name="phase" value="'.
                                 $env{'form.phase'}.'" /></form>');
                       return;
                 }                  }
             }              }
         }          }
       }
         if (! defined($classlist)) {      if (keys(%userlist) == 0) {
             $r->print(&mt('There are no students currently enrolled.')."\n");          if ($context eq 'author') {
               $r->print(&mt('There are no co-authors to display.')."\n");
           } elsif ($context eq 'domain') {
               if ($env{'form.roletype'} eq 'domain') {
                   $r->print(&mt('There are no users with domain roles to display.')."\n");
               } elsif ($env{'form.roletype'} eq 'author') {
                   $r->print(&mt('There are no authors or co-authors to display.')."\n");
               } elsif ($env{'form.roletype'} eq 'course') {
                   $r->print(&mt('There are no course users to display')."\n"); 
               }
           } elsif ($context eq 'course') {
               $r->print(&mt('There are no course users to display.')."\n");
           }
       } else {
           # Print out the available choices
           my $usercount;
           if ($env{'form.action'} eq 'modifystudent') {
               ($usercount) = &show_users_list($r,$context,'view',$permission,
                                    $env{'form.Status'},\%userlist,$keylist);
         } else {          } else {
             # Print out the available choices              ($usercount) = &show_users_list($r,$context,$env{'form.output'},
             if ($env{'form.action'} eq 'modifystudent') {                                 $permission,$env{'form.Status'},\%userlist,$keylist);
                 &show_users_list($r,$context,'view','modify',          }
                                  $env{'form.Status'},$classlist,$keylist);          if (!$usercount) {
             } else {              $r->print('<br />'.&mt('There are no users matching the search criteria.')); 
                 &show_users_list($r,$context,$env{'form.output'},'aboutme',          }
                                  $env{'form.Status'},$classlist,$keylist);      }
             }      $r->print('<input type="hidden" name="phase" value="'.
         }                $env{'form.phase'}.'" /></form>');
     } elsif ($context eq 'construction_space') {  }
         # List co-authors and assistant co-authors  
         my @statuses;  sub role_filter {
         if ($env{'form.status'} eq 'Any') {      my ($context) = @_;
             @statuses = ('previous','active','future');      my $output;
         } elsif ($env{'form.status'} eq 'Expired') {      my $roleselected = '';
             @statuses = ('previous');      if ($env{'form.showrole'} eq 'Any') {
         } elsif ($env{'form.status'} eq 'Active') {         $roleselected = ' selected="selected" ';
             @statuses = ('active');      }
         } elsif ($env{'form.status'} eq 'Future') {      my ($role_select);
             @statuses = ('future');      if ($context eq 'domain') {
         }          $role_select = &domain_roles_select();
         my @possroles = ('ca','aa');          $output = '<label>'.&mt('Role Type: [_1]',$role_select).'</label>';
         my %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,      } else {
                                           \@statuses,\@possroles);          $role_select = '<select name="showrole">'."\n".
         if (keys(%cstr_roles) == 0) {                         '<option value="Any" '.$roleselected.'>'.
              $r->print(&mt('There are no authors or co-authors.')."\n");                         &mt('Any role').'</option>';
         } else {          my @poss_roles = &curr_role_permissions($context);
             # Print out the available choices          foreach my $role (@poss_roles) {
             if ($env{'form.action'} eq 'modifystudent') {              $roleselected = '';
                 &show_users_list($r,$context,'view','modify',              if ($role eq $env{'form.showrole'}) {
                                  $env{'form.Status'},\%cstr_roles);                  $roleselected = ' selected="selected" ';
               }
               my $plrole;
               if ($role eq 'cr') {
                   $plrole = &mt('Custom role');
             } else {              } else {
                 &show_users_list($r,$context,$env{'form.output'},'aboutme',                  $plrole=&Apache::lonnet::plaintext($role);
                                  $env{'form.Status'},\%cstr_roles);              }
               $role_select .= '<option value="'.$role.'"'.$roleselected.'>'.$plrole.'</option>';
           }
           $role_select .= '</select>';
           $output = '<label>'.&mt('Role: [_1]',$role_select).'</label>';
       }
       return $output;
   }
   
   sub section_group_filter {
       my ($cnum,$cdom) = @_;
       my @filters;
       if ($env{'request.course.sec'} eq '') {
           @filters = ('sec');
       }
       push(@filters,'grp');
       my %name = (
                    sec => 'secfilter',
                    grp => 'grpfilter',
                  );
       my %title = &Apache::lonlocal::texthash (
                                                 sec  => 'Section(s)',
                                                 grp  => 'Group(s)',
                                                 all  => 'all',
                                                 none => 'none',
                                               );
       my $output;
       foreach my $item (@filters) {
           my ($markup,@options); 
           if ($env{'form.'.$name{$item}} eq '') {
               $env{'form.'.$name{$item}} = 'all';
           }
           if ($item eq 'sec') {
               if ($env{'form.showrole'} eq 'cc') {
                   $env{'form.'.$name{$item}} = 'none';
             }              }
               my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
               @options = sort(keys(%sections_count));
           } elsif ($item eq 'grp') {
               my %curr_groups = &Apache::longroup::coursegroups();
               @options = sort(keys(%curr_groups));
           }
           if (@options > 0) {
               my $currsel;
               $markup = '<select name="'.$name{$item}.'" />'."\n";
               foreach my $option ('all','none',@options) { 
                   $currsel = '';
                   if ($env{'form.'.$name{$item}} eq $option) {
                       $currsel = ' selected="selected" ';
                   }
                   $markup .= ' <option value="'.$option.'"'.$currsel.'>';
                   if (($option eq 'all') || ($option eq 'none')) {
                       $markup .= $title{$option};
                   } else {
                       $markup .= $option;
                   }   
                   $markup .= '</option>'."\n";
               }
               $markup .= '</select>'."\n";
               $output .= ('&nbsp;'x3).'<label>'.$title{$item}.': '.$markup.'</label>';
         }          }
       }
       return $output;
   }
   
   sub list_submit_button {
       my ($text) = @_;
       return '<input type="button" name="updatedisplay" value="'.$text.'" onclick="javascript:display_update()" />';
   }
   
   sub gather_userinfo {
       my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_;
       my $viewablesec;
       if ($context eq 'course') {
           $viewablesec = &viewable_section($permission);
       }
       foreach my $item (keys(%{$rolehash})) {
           my %userdata;
           if ($context eq 'author') { 
               ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
                   split(/:/,$item);
               ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item});
               &build_user_record($context,\%userdata,$userinfo,$indexhash,
                                  $item,$userlist);
           } elsif ($context eq 'course') {
               ($userdata{'username'},$userdata{'domain'},$userdata{'role'},
                $userdata{'section'}) = split(/:/,$item,-1);
               ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item});
               if (($viewablesec ne '') && ($userdata{'section'} ne '')) {
                   next if ($viewablesec ne $userdata{'section'});
               }
               &build_user_record($context,\%userdata,$userinfo,$indexhash,
                                  $item,$userlist);
           } elsif ($context eq 'domain') {
               if ($env{'form.roletype'} eq 'domain') {
                   ($userdata{'role'},$userdata{'username'},$userdata{'domain'}) =
                       split(/:/,$item);
                   ($userdata{'end'},$userdata{'start'})=split(/:/,$rolehash->{$item});
                   &build_user_record($context,\%userdata,$userinfo,$indexhash,
                                      $item,$userlist);
               } elsif ($env{'form.roletype'} eq 'author') {
                   if (ref($rolehash->{$item}) eq 'HASH') {
                       $userdata{'extent'} = $item;
                       foreach my $key (keys(%{$rolehash->{$item}})) {
                           ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =  split(/:/,$key);
                           ($userdata{'start'},$userdata{'end'}) = 
                               split(/:/,$rolehash->{$item}{$key});
                           my $uniqid = $key.':'.$item;
                           &build_user_record($context,\%userdata,$userinfo,
                                              $indexhash,$uniqid,$userlist);
                       }
                   }
               } elsif ($env{'form.roletype'} eq 'course') {
                   ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
                       split(/:/,$item);
                   if (ref($rolehash->{$item}) eq 'HASH') {
                       my $numcids = keys(%{$rolehash->{$item}});
                       foreach my $cid (sort(keys(%{$rolehash->{$item}}))) {
                           if (ref($rolehash->{$item}{$cid}) eq 'HASH') {
                               my $spanstart = '';
                               my $spanend = '; ';
                               my $space = ', ';
                               if ($format eq 'html' || $format eq 'view') {
                                   $spanstart = '<span class="LC_nobreak">';
                                   # FIXME: actions on courses disabled for now
   #                                if ($permission->{'cusr'}) {
   #                                    if ($numcids > 1) {
   #                                        $spanstart .= '<input type="radio" name="'.$item.'" value="'.$cid.'" />&nbsp;';
   #                                    } else {
   #                                        $spanstart .= '<input type="hidden" name="'.$item.'" value="'.$cid.'" />&nbsp;';
   #                                    }
   #                                }
                                   $spanend = '</span><br />';
                                   $space = ',&nbsp;';
                               }
                               $userdata{'extent'} .= $spanstart.
                                       $rolehash->{$item}{$cid}{'desc'}.$space;
                               if (ref($rolehash->{$item}{$cid}{'secs'}) eq 'HASH') { 
                                   foreach my $sec (sort(keys(%{$rolehash->{$item}{$cid}{'secs'}}))) {
                                       if (($env{'form.Status'} eq 'Any') ||
                                           ($env{'form.Status'} eq $rolehash->{$item}{$cid}{'secs'}{$sec})) {
                                           $userdata{'extent'} .= $sec.$space.$rolehash->{$item}{$cid}{'secs'}{$sec}.$spanend;
                                           $userdata{'status'} = $rolehash->{$item}{$cid}{'secs'}{$sec};
                                       }
                                   }
                               }
                           }
                       }
                   }
                   if ($userdata{'status'} ne '') {
                       &build_user_record($context,\%userdata,$userinfo,
                                          $indexhash,$item,$userlist);
                   }
               }
           }
       }
       return;
   }
   
   sub build_user_record {
       my ($context,$userdata,$userinfo,$indexhash,$record_key,$userlist) = @_;
       next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1');
       if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {
           &process_date_info($userdata);
       }
       my $username = $userdata->{'username'};
       my $domain = $userdata->{'domain'};
       if (ref($userinfo->{$username.':'.$domain}) eq 'HASH') {
           $userdata->{'fullname'} = $userinfo->{$username.':'.$domain}{'fullname'};
           $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
     } else {      } else {
           &aggregate_user_info($domain,$username,$userinfo);
           $userdata->{'fullname'} = $userinfo->{$username.':'.$domain}{'fullname'};
           $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
       }
       foreach my $key (keys(%{$indexhash})) {
           if (defined($userdata->{$key})) {
               $userlist->{$record_key}[$indexhash->{$key}] = $userdata->{$key};
           }
       }
       return;
   }
   
   sub courses_selector {
       my ($cdom,$formname) = @_;
       my %coursecodes = ();
       my %codes = ();
       my @codetitles = ();
       my %cat_titles = ();
       my %cat_order = ();
       my %idlist = ();
       my %idnums = ();
       my %idlist_titles = ();
       my $caller = 'global';
       my $format_reply;
       my $jscript = '';
   
       my $totcodes = 0;
       $totcodes =
           &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,
                                                         $cdom,$totcodes);
       if ($totcodes > 0) {
           $format_reply =
                &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,
                                   \%codes,\@codetitles,\%cat_titles,\%cat_order);
           if ($format_reply eq 'ok') {
               my $numtypes = @codetitles;
               &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 $longtitles_str = join('","',@{$longtitles});
               my $allidlist = $idlist{$codetitles[0]};
               $jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist);
               $jscript .= $scripttext;
               $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,@codetitles);
           }
       }
       my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
   
       my %elements = (
                        Year => 'selectbox',
                        coursepick => 'radio',
                        coursetotal => 'text',
                        courselist => 'text',
                      );
       $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements);
       if ($env{'form.coursepick'} eq 'category') {
           $jscript .= qq|
   function setCourseCat(formname) {
       if (formname.Year.options[formname.Year.selectedIndex].value == -1) {
           return;
       }
       courseSet('Year');
       for (var j=0; j<formname.Semester.length; j++) {
           if (formname.Semester.options[j].value == "$env{'form.Semester'}") {
               formname.Semester.options[j].selected = true;
           }
     }      }
       if (formname.Semester.options[formname.Semester.selectedIndex].value == -1) {
           return;
       }
       courseSet('Semester');
       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[formname.Department.selectedIndex].value == -1) {
           return;
       }
       courseSet('Department');
       for (var j=0; j<formname.Number.length; j++) {
           if (formname.Number.options[j].value == "$env{'form.Number'}") {
               formname.Number.options[j].selected = true;
           }
       }
   }
   |;
       }
       return ($cb_jscript,$jscript,$totcodes,\@codetitles,\%idlist,
               \%idlist_titles);
   }
   
   sub course_selector_loadcode {
       my ($formname) = @_;
       my $loadcode;
       if ($env{'form.coursepick'} ne '') {
           $loadcode = 'javascript:setFormElements(document.'.$formname.')';
           if ($env{'form.coursepick'} eq 'category') {
               $loadcode .= ';javascript:setCourseCat(document.'.$formname.')';
           }
       }
       return $loadcode;
   }
   
   sub process_coursepick {
       my $coursefilter = $env{'form.coursepick'};
       my $cdom = $env{'request.role.domain'};
       my %courses;
       if ($coursefilter eq 'all') {
           %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.',
                                                    undef,undef,'Course');
       } elsif ($coursefilter eq 'category') {
           my $instcode = &instcode_from_coursefilter();
           %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.',
                                                    undef,undef,'Course');
       } elsif ($coursefilter eq 'specific') {
           if ($env{'form.coursetotal'} > 1) {
               my @course_ids = split(/&&/,$env{'form.courselist'});
               foreach my $cid (@course_ids) {
                   $courses{$cid} = '';
               }
           } else {
               $courses{$env{'form.courselist'}} = '';
           }
       }
       return %courses;
   }
   
   sub instcode_from_coursefilter {
       my $instcode = '';
       my @cats = ('Semester','Year','Department','Number');
       foreach my $category (@cats) {
           if (defined($env{'form.'.$category})) {
               unless ($env{'form.'.$category} eq '-1') {
                   $instcode .= $env{'form.'.$category};
              }
           }
       }
       if ($instcode eq '') {
           $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 {
       my ($index,$keylist);
       $index->{'domain'} = &Apache::loncoursedata::CL_SDOM();
       $index->{'username'} = &Apache::loncoursedata::CL_SNAME();
       $index->{'end'} = &Apache::loncoursedata::CL_END();
       $index->{'start'} = &Apache::loncoursedata::CL_START();
       $index->{'id'} = &Apache::loncoursedata::CL_ID();
       $index->{'section'} = &Apache::loncoursedata::CL_SECTION();
       $index->{'fullname'} = &Apache::loncoursedata::CL_FULLNAME();
       $index->{'status'} = &Apache::loncoursedata::CL_STATUS();
       $index->{'type'} = &Apache::loncoursedata::CL_TYPE();
       $index->{'lockedtype'} = &Apache::loncoursedata::CL_LOCKEDTYPE();
       $index->{'groups'} = &Apache::loncoursedata::CL_GROUP();
       $index->{'email'} = &Apache::loncoursedata::CL_PERMANENTEMAIL();
       $index->{'role'} = &Apache::loncoursedata::CL_ROLE();
       $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();
       $index->{'photo'} = &Apache::loncoursedata::CL_PHOTO();
       $index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL();
       foreach my $key (keys(%{$index})) {
           $keylist->[$index->{$key}] = $key;
       }
       return ($index,$keylist);
   }
   
   sub aggregate_user_info {
       my ($udom,$uname,$userinfo) = @_;
       my %info=&Apache::lonnet::get('environment',
                                     ['firstname','middlename',
                                      'lastname','generation','id'],
                                      $udom,$uname);
       my ($tmp) = keys(%info);
       my ($fullname,$id);
       if ($tmp =~/^(con_lost|error|no_such_host)/i) {
           $fullname = 'not available';
           $id = 'not available';
           &Apache::lonnet::logthis('unable to retrieve environment '.
                                    'for '.$uname.':'.$udom);
       } else {
           $fullname = &Apache::lonnet::format_name(@info{qw/firstname middlename lastname generation/},'lastname');
           $id = $info{'id'};
       }
       $userinfo->{$uname.':'.$udom} = { 
                                         fullname => $fullname,
                                         id       => $id,
                                       };
       return;
   }
   
   sub process_date_info {
       my ($userdata) = @_;
       my $now = time;
       $userdata->{'status'} = 'Active';
       if ($userdata->{'start'} > 0) {
           if ($now < $userdata->{'start'}) {
               $userdata->{'status'} = 'Future';
           }
       }
       if ($userdata->{'end'} > 0) {
           if ($now > $userdata->{'end'}) {
               $userdata->{'status'} = 'Expired';
           }
       }
       return;
 }  }
   
 sub show_users_list {  sub show_users_list {
     my ($r,$context,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;      my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist)=@_;
     #      #
     # 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 1139  sub show_users_list { Line 1865  sub show_users_list {
     my ($CSVfile,$CSVfilename);      my ($CSVfile,$CSVfilename);
     #      #
     my $sortby = $env{'form.sortby'};      my $sortby = $env{'form.sortby'};
     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) {      my @sortable = ('username','domain','id','fullname','start','end','email','role');
       if ($context eq 'course') {
           push(@sortable,('section','groups','type'));
       } else {
           push(@sortable,'extent');
       }
       if (!grep(/^\Q$sortby\E$/,@sortable)) {
         $sortby = 'username';          $sortby = 'username';
     }      }
     my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers)=@_;      my $setting = $env{'form.roletype'};
       my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers);
     if ($context eq 'course') {      if ($context eq 'course') {
         $cid=$env{'request.course.id'};          $cid = $env{'request.course.id'};
         $cdom = $env{'course.'.$cid.'.domain'};          ($cnum,$cdom) = &get_course_identity($cid);
         $cnum = $env{'course.'.$cid.'.num'};          ($classgroups) = &Apache::loncoursedata::get_group_memberships(
         $classgroups = &Apache::loncoursedata::get_group_memberships(                                       $userlist,$keylist,$cdom,$cnum);
                                      $classlist,$keylist,$cdom,$cnum);          if ($mode eq 'autoenroll') {
         if (! exists($env{'form.displayphotos'})) {              $env{'form.showrole'} = 'st';
             $env{'form.displayphotos'} = 'off';          } else {
         }              if (! exists($env{'form.displayphotos'})) {
         $displayphotos = $env{'form.displayphotos'};                  $env{'form.displayphotos'} = 'off';
         if (! exists($env{'form.displayclickers'})) {              }
             $env{'form.displayclickers'} = 'off';              $displayphotos = $env{'form.displayphotos'};
         }              if (! exists($env{'form.displayclickers'})) {
         $displayclickers = $env{'form.displayclickers'};                  $env{'form.displayclickers'} = 'off';
         if ($env{'course.'.$cid.'.internal.showphoto'}) {              }
             $r->print('              $displayclickers = $env{'form.displayclickers'};
               if ($env{'course.'.$cid.'.internal.showphoto'}) {
                   $r->print('
 <script type="text/javascript">  <script type="text/javascript">
 function photowindow(photolink) {  function photowindow(photolink) {
     var title = "Photo_Viewer";      var title = "Photo_Viewer";
Line 1168  function photowindow(photolink) { Line 1903  function photowindow(photolink) {
     stdeditbrowser.focus();      stdeditbrowser.focus();
 }  }
 </script>  </script>
            ');                 ');
         }              }
         $r->print(<<END);              $r->print(<<END);
 <input type="hidden" name="displayphotos" value="$displayphotos" />  <input type="hidden" name="displayphotos" value="$displayphotos" />
 <input type="hidden" name="displayclickers" value="$displayclickers" />  <input type="hidden" name="displayclickers" value="$displayclickers" />
 END  END
           }
     }      }
     unless ($mode eq 'autoenroll') {      if ($mode ne 'autoenroll') {
           my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
           my $alert = &mt("You must select at least one user by checking a user's 'Select' checkbox");
           my $singconfirm = &mt(' for a single user?');
           my $multconfirm = &mt(' for multiple users?');
           my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode);
           my %lt = &Apache::lonlocal::texthash( 
                 acwi => 'Access will be set to start immediately',
                 asyo => 'as you did not select an end date in the pop-up window',
                 accw => 'Access will be set to continue indefinitely',
                 asyd => 'as you did not select an end date in the pop-up window',
                 sewi => "Sections will be switched to 'No section'",
                 ayes => "as you either selected the 'No section' option",
                 oryo => 'or you did not select a section in the pop-up window',
                 arol => 'A role with no section will be added',
                 swbs => 'Sections will be switched to:',
                 rwba => 'Roles will be added for section(s):',
           );
         $r->print(<<END);          $r->print(<<END);
   
   <script type="text/javascript" language="Javascript">
   $check_uncheck_js
   
   function verify_action (field) {
       var numchecked = 0;
       var singconf = '$singconfirm';
       var multconf = '$multconfirm';
       if (field.length > 0) {
           for (i = 0; i < field.length; i++) {
               if (field[i].checked == true) {
                  numchecked ++;
               }
           }
       } else {
           if (field.checked == true) {
               numchecked ++;
           }
       }
       if (numchecked == 0) {
           alert("$alert");
       } 
       else {
           var message = document.studentform.bulkaction[document.studentform.bulkaction.selectedIndex].text;
           var choice = document.studentform.bulkaction[document.studentform.bulkaction.selectedIndex].value;
           if (numchecked == 1) { 
               message += singconf;
           } 
           else {
               message += multconf; 
           }
           if (choice == 'chgdates' || choice == 'reenable' || choice == 'activate') {
               var datemsg = '';
               if ((document.studentform.startdate_month.value == '') && 
                   (document.studentform.startdate_day.value  == '') &&
                   (document.studentform.startdate_year.value == '')) {
                   datemsg = "\\n$lt{'acwi'},\\n$lt{'asyo'}.\\n";
               }
               if ((document.studentform.enddate_month.value == '') &&
                   (document.studentform.enddate_day.value  == '') &&
                   (document.studentform.enddate_year.value == '')) {
                   datemsg += "\\n$lt{'accw'},\\n$lt{'asyd'}.\\n";
               }
               if (datemsg != '') {
                   message += "\\n"+datemsg;
               }
           }
           if (choice == 'chgsec') {
               var rolefilter = document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value;
               var retained =  document.studentform.retainsec.value;
               var secshow = document.studentform.newsecs.value;
               if (secshow == '') {
                   if (rolefilter == 'st' || retained == 0 || retained == "") {
                       message += "\\n\\n$lt{'sewi'},\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n"; 
                   } else {
                       message += "\\n\\n$lt{'arol'}\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n";
                   }
               } else {
                   if (rolefilter == 'st' || retained == 0 || retained == "") {
                       message += "\\n\\n$lt{'swbs'} "+secshow+".\\n";
                   } else {
                       message += "\\n\\n$lt{'rwba'} "+secshow+".\\n";
                   }
               }
           }
           if (confirm(message)) {
               document.studentform.phase.value = 'bulkchange';
               document.studentform.submit();
           }
       }
   }
   
   function username_display_launch(username,domain) {
       var target;
       for (var i=0; i<document.studentform.usernamelink.length; i++) {
           if (document.studentform.usernamelink[i].checked) {
               target = document.studentform.usernamelink[i].value;
           }
       }
       if (target == 'modify') {
           if (document.studentform.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 options = 'height=600,width=800,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no';
               modifywin = window.open(url,'',options,1);
               modifywin.focus();
               return;
           } else {
               document.studentform.srchterm.value=username;
               document.studentform.srchdomain.value=domain;
               document.studentform.phase.value='get_user_info';
               document.studentform.action.value = 'singleuser';
               document.studentform.submit();
           }
       }
       if (target == 'aboutme') {
           if (document.studentform.userwin.checked == true) {
               var url = '/adm/'+domain+'/'+username+'/aboutme?popup=1';
               var options = 'height=600,width=800,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no';
               aboutmewin = window.open(url,'',options,1);
               aboutmewin.focus();
               return;
           } else {
               document.location.href = '/adm/'+domain+'/'+username+'/aboutme';
           }
       }
   }
   </script>
   $date_sec_selector
 <input type="hidden" name="state" value="$env{'form.state'}" />  <input type="hidden" name="state" value="$env{'form.state'}" />
 END  END
     }      }
Line 1194  END Line 2055  END
                        'start'      => "start date",                         'start'      => "start date",
                        'end'        => "end date",                         'end'        => "end date",
                        'status'     => "status",                         'status'     => "status",
                          'role'       => "role",
                        'type'       => "enroll type/action",                         'type'       => "enroll type/action",
                        'email'      => "email address",                         'email'      => "email address",
                        'clicker'    => "clicker id",                         'clicker'    => "clicker id",
                        'photo'      => "photo",                         'photo'      => "photo",
                          'extent'     => "extent",
                          'go'         => "go",
                          'pr'         => "Proceed",
                          'ca'         => "check all",
                          'ua'         => "uncheck all",
                          'ac'         => "Action to take for selected users",
                          'link'       => "Behavior of username links",
                          'aboutme'    => "Display a user's personal page",
                          'owin'       => "Open in a new window",
                          'modify'     => "Modify a user's information",
                       );                        );
       if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
           $lt{'extent'} = &mt('Course(s): description, section(s), status');
       } elsif ($context eq 'author') {
           $lt{'extent'} = &mt('Author'); 
       }
     my @cols = ('username','domain','id','fullname');      my @cols = ('username','domain','id','fullname');
     if ($context eq 'course') {      if ($context eq 'course') {
         push(@cols,'section');          push(@cols,'section');
     }      }
     push(@cols,('start','end'));      if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) { 
     if ($statusmode eq 'Any') {          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');          push(@cols,'status');
     }      }
     if ($context eq 'course') {      if ($context eq 'course') {
Line 1212  END Line 2099  END
     }      }
     push(@cols,'email');      push(@cols,'email');
   
     if ($mode eq 'html' || $mode eq 'view') {      my $rolefilter = $env{'form.showrole'};
         if ($linkto eq 'aboutme') {      if ($env{'form.showrole'} eq 'cr') {
             $r->print(&mt("Select a user name to view the user's personal page."));          $rolefilter = &mt('custom');  
         } elsif ($linkto eq 'modify') {      } elsif ($env{'form.showrole'} ne 'Any') {
             $r->print(&mt("Select a user name to modify the user's information"));          $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'});
         }      }
         $r->print(<<END);      my $results_description;
 <input type="hidden" name="sname"  value="" />      if ($mode ne 'autoenroll') {
 <input type="hidden" name="sdom"   value="" />          $results_description = &results_header_row($rolefilter,$statusmode,
                                                      $context,$permission,$mode);
           $r->print('<b>'.$results_description.'</b><br />');
       }
       my ($output,$actionselect,%canchange,%canchangesec);
       if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
           if ($mode ne 'autoenroll') {
               if ($permission->{'cusr'}) {
                   $actionselect = &select_actions($context,$setting,$statusmode);
               }
               $r->print(<<END);
   <input type="hidden" name="srchby"  value="uname" />
   <input type="hidden" name="srchin"   value="dom" />
   <input type="hidden" name="srchtype" value="exact" />
   <input type="hidden" name="srchterm" value="" />
   <input type="hidden" name="srchdomain" value="" /> 
 END  END
               $output = '<p>';
         $r->print("\n<p>\n".              my @linkdests = ('aboutme');
               if ($permission->{'cusr'}) {
                   unshift (@linkdests,'modify');
               }
               $output .= '<span class="LC_nobreak">'.$lt{'link'}.':&nbsp;';
               my $usernamelink = $env{'form.usernamelink'};
               if ($usernamelink eq '') {
                   $usernamelink = 'aboutme';
               }
               foreach my $item (@linkdests) {
                   my $checkedstr = '';
                   if ($item eq $usernamelink) {
                       $checkedstr = ' checked="checked" ';
                   }
                   $output .= '<label><input type="radio" name="usernamelink" value="'.$item.'"'.$checkedstr.'>&nbsp;'.$lt{$item}.'</label>&nbsp;&nbsp;';
               }
               my $checkwin;
               if ($env{'form.userwin'}) { 
                   $checkwin = 'checked = "checked"'; 
               }
               $output .= '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="userwin" value="1" $checkwin />'.$lt{'owin'}.'</span><br />';
               if ($actionselect) {
                   $output .= <<"END";
   $lt{'ac'}:&nbsp;$actionselect <input type="button" value="$lt{'go'}" onclick="javascript:opendatebrowser(this.form,'studentform','go')" /></p>
   <p><input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.actionlist)" /> &nbsp;
   <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.actionlist)" /><br /><br /><input type="button" value="$lt{'pr'}" onclick="javascript:verify_action(document.studentform.actionlist)" />
   END
                   my @allroles;
                   if ($env{'form.showrole'} eq 'Any') {
                       my $custom = 1;
                       if ($context eq 'domain') {
                           @allroles = &roles_by_context($setting,$custom);
                       } else {
                           @allroles = &roles_by_context($context,$custom);
                       }
                   } else {
                       @allroles = ($env{'form.showrole'});
                   }
                   foreach my $role (@allroles) {
                       if ($context eq 'domain') {
                           if ($setting eq 'domain') {
                               if (&Apache::lonnet::allowed('c'.$role,
                                       $env{'request.role.domain'})) {
                                   $canchange{$role} = 1;
                               }
                           } elsif ($setting eq 'author') {
                               if (&Apache::lonnet::allowed('c'.$role,
                                       $env{'request.role.domain'})) {
                                   $canchange{$role} = 1;
                               }
                           }
                       } elsif ($context eq 'author') {
                           if (&Apache::lonnet::allowed('c'.$role,
                               $env{'user.domain'}.'/'.$env{'user.name'})) {
                               $canchange{$role} = 1;
                           }
                       } elsif ($context eq 'course') {
                           if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
                               $canchange{$role} = 1;
                           } elsif ($env{'request.course.sec'} ne '') {
                               if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
                                   $canchangesec{$role} = $env{'request.course.sec'};
                               }
                           }
                       }
                   }
               }
           }
           $output .= "\n<p>\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') {
             $r->print("              $output .= "
  <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>   <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
             ");              ";
         } else {          } else {
             $r->print("              $output .= "\n".'<th>'.&mt('Count').'</th>'."\n";
 <th>Count</th>              if ($actionselect) {
             ");                  $output .= '<th>'.&mt('Select').'</th>'."\n";
               }
         }          }
         foreach my $item (@cols) {          foreach my $item (@cols) {
             $r->print('<th><a href="javascript:document.studentform.sortby.value='.$item.';document.studentform.submit();">'.$lt{$item}.'</a></th>'."\n");              $output .= "<th><a href=\"javascript:document.studentform.sortby.value='$item';document.studentform.submit();\">$lt{$item}</a></th>\n";
         }          }
         if ($context eq 'course') {          my %role_types = &role_type_names();
             # Clicker display on or off?          if ($context eq 'course' && $mode ne 'autoenroll') {
             my %clicker_options = &Apache::lonlocal::texthash(              if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
                                                         'on' => 'Show',                  # Clicker display on or off?
                                                         'off' => 'Hide',                  my %clicker_options = &Apache::lonlocal::texthash(
                                                        );                                                              'on' => 'Show',
             my $clickerchg = 'on';                                                              'off' => 'Hide',
             if ($displayclickers eq 'on') {                                                             );
                 $clickerchg = 'off';                  my $clickerchg = 'on';
             }                  if ($displayclickers eq 'on') {
             $r->print('    <th>'."\n".'     '.                      $clickerchg = 'off';
                 '<a href="javascript:document.studentform.displayclickers.value='.                  }
                   $output .= '    <th>'."\n".'     '.
                       '<a href="javascript:document.studentform.displayclickers.value='.
                       "'".$clickerchg."'".';document.studentform.submit();">'.                        "'".$clickerchg."'".';document.studentform.submit();">'.
                       $clicker_options{$clickerchg}.'</a>&nbsp;'.$lt{'clicker'}."\n".                        $clicker_options{$clickerchg}.'</a>&nbsp;'.$lt{'clicker'}."\n".
                       '    </th>'."\n");                        '    </th>'."\n";
   
             # Photo display on or off?                  # Photo display on or off?
             if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {                  if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
                 my %photo_options = &Apache::lonlocal::texthash(                      my %photo_options = &Apache::lonlocal::texthash(
                                                         'on' => 'Show',                                                              'on' => 'Show',
                                                         'off' => 'Hide',                                                              'off' => 'Hide',
                                                             );                                                                  );
                 my $photochg = 'on';                      my $photochg = 'on';
                 if ($displayphotos eq 'on') {                      if ($displayphotos eq 'on') {
                     $photochg = 'off';                          $photochg = 'off';
                 }                      }
                 $r->print('    <th>'."\n".'     '.                      $output .= '    <th>'."\n".'     '.
             '<a href="javascript:document.studentform.displayphotos.value='.                  '<a href="javascript:document.studentform.displayphotos.value='.
                       "'".$photochg."'".';document.studentform.submit();">'.                        "'".$photochg."'".';document.studentform.submit();">'.
                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".                        $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                       '    </th>'."\n");                        '    </th>'."\n";
                   }
             }              }
             $r->print(&Apache::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') {
         #          #
         # Open a file          # Open a file
         $CSVfilename = '/prtspool/'.          $CSVfilename = '/prtspool/'.
             $env{'user.name'}.'_'.$env{'user.domain'}.'_'.                         $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
             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("Problems occured in writing the csv file.  ".              $r->print("Problems occured in writing the csv file.  ".
Line 1289  END Line 2262  END
         }          }
         #          #
         # Write headers and data to file          # Write headers and data to file
         if($statusmode eq 'Expired') {          print $CSVfile '"'.$results_description.'"'."\n"; 
             print $CSVfile '"'.&mt('Users with expired roles').'"'."\n";        }  
         if($statusmode eq 'Future') {  
             print $CSVfile '"'.&mt('Users with future roles').'"'."\n";  
         }  
         print $CSVfile '"'.join('","',map {          print $CSVfile '"'.join('","',map {
             &Apache::loncommon::csv_translate($lt{$_})              &Apache::loncommon::csv_translate($lt{$_})
             } (@cols)).'"'."\n";              } (@cols)).'"'."\n";
Line 1303  END Line 2272  END
             &Apache::loncommon::create_workbook($r);              &Apache::loncommon::create_workbook($r);
         return if (! defined($excel_workbook));          return if (! defined($excel_workbook));
         $excel_sheet = $excel_workbook->addworksheet('userlist');          $excel_sheet = $excel_workbook->addworksheet('userlist');
         #          $excel_sheet->write($row++,0,$results_description,$format->{'h2'});
         my $description;  
         if ($context eq 'course') {  
             $description = &mt('Class List for ').  
                 $env{'course.'.$env{'request.course.id'}.'.description'};  
         } elsif ($context eq 'construction_space') {  
             $description = &mt('List of co-authors for construction space for [_1]',  
                            &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}));  
         } else {  
             $description = &mt('List of users for domain: [_1]',&Apache::lonnet::domain($env{'request.role.domain'},'description'));  
         }  
         $excel_sheet->write($row++,0,$description,$format->{'h1'});  
         #          #
         my @colnames = map {$lt{$_}} (@cols);          my @colnames = map {$lt{$_}} (@cols);
         $excel_sheet->write($row++,0,\@colnames,$format->{'bold'});          $excel_sheet->write($row++,0,\@colnames,$format->{'bold'});
     }      }
   
 # Done with header lines in all formats  # Done with header lines in all formats
   
     #  
     # Sort the users  
     my %index;      my %index;
     my $i;      my $i;
     foreach (@$keylist) {      foreach my $idx (@$keylist) {
         $index{$_} = $i++;          $index{$idx} = $i++;
       }
       my $usercount = 0;
       my ($secfilter,$grpfilter);
       if ($context eq 'course') {
           $secfilter = $env{'form.secfilter'};
           $grpfilter = $env{'form.grpfilter'};
           if ($secfilter eq '') {
               $secfilter = 'all';
           }
           if ($grpfilter eq '') {
               $grpfilter = 'all';
           }
       }
       # Get groups, role, permanent e-mail so we can sort on them if
       # necessary.
       foreach my $user (keys(%{$userlist})) {
           if ($user eq '' ) {
               delete($userlist->{$user});
               next;
           }
           if ($context eq 'domain' &&  $user eq $env{'request.role.domain'}.'-domainconfig:'.$env{'request.role.domain'}) {
               delete($userlist->{$user});
               next;
           }
           my ($uname,$udom,$role,$groups,$email);
           if (($statusmode ne 'Any') && 
                    ($userlist->{$user}->[$index{'status'}] ne $statusmode)) {
               delete($userlist->{$user});
               next;
           }
           if ($context eq 'domain') {
               if ($env{'form.roletype'} eq 'domain') {
                   ($role,$uname,$udom) = split(/:/,$user);
                   if (($uname eq $env{'request.role.domain'}.'-domainconfig') &&
                       ($udom eq $env{'request.role.domain'})) {
                       delete($userlist->{$user});
                       next;
                   }
               } elsif ($env{'form.roletype'} eq 'author') {
                   ($uname,$udom,$role) = split(/:/,$user,-1);
               } elsif ($env{'form.roletype'} eq 'course') {
                   ($uname,$udom,$role) = split(/:/,$user);
               }
           } else {
               ($uname,$udom,$role) = split(/:/,$user,-1);
               if (($context eq 'course') && $role eq '') {
                   $role = 'st';
               }
           }
           $userlist->{$user}->[$index{'role'}] = $role;
           if (($env{'form.showrole'} ne 'Any') && (!($env{'form.showrole'}  eq 'cr' && $role =~ /^cr\//)) && ($role ne $env{'form.showrole'})) {
               delete($userlist->{$user});
               next;
           }
           if ($context eq 'course') {
               my @ac_groups;
               if (ref($classgroups) eq 'HASH') {
                   $groups = $classgroups->{$user};
               }
               if (ref($groups->{'active'}) eq 'HASH') {
                   @ac_groups = keys(%{$groups->{'active'}});
                   $userlist->{$user}->[$index{'groups'}] = join(', ',@ac_groups);
               }
               if ($mode ne 'autoenroll') {
                   my $section = $userlist->{$user}->[$index{'section'}];
                   if (($env{'request.course.sec'} ne '') && 
                       ($section ne $env{'request.course.sec'})) {
                       if ($role eq 'st') {
                           delete($userlist->{$user});
                           next;
                       }
                   }
                   if ($secfilter eq 'none') {
                       if ($section ne '') {
                           delete($userlist->{$user});
                           next;
                       }
                   } elsif ($secfilter ne 'all') {
                       if ($section ne $secfilter) {
                           delete($userlist->{$user});
                           next;
                       }
                   }
                   if ($grpfilter eq 'none') {
                       if (@ac_groups > 0) {
                           delete($userlist->{$user});
                           next;
                       }
                   } elsif ($grpfilter ne 'all') {
                       if (!grep(/^\Q$grpfilter\E$/,@ac_groups)) {
                           delete($userlist->{$user});
                           next;
                       }
                   }
                   if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
                       if (($displayphotos eq 'on') && ($role eq 'st')) {
                           $userlist->{$user}->[$index{'photo'}] =
                               &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg');
                           $userlist->{$user}->[$index{'thumbnail'}] =
                               &Apache::lonnet::retrievestudentphoto($udom,$uname,
                                                                   'gif','thumbnail');
                       }
                   }
               }
           }
           my %emails   = &Apache::loncommon::getemails($uname,$udom);
           if ($emails{'permanentemail'} =~ /\S/) {
               $userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'};
           }
           $usercount ++;
       }
       my $autocount = 0;
       my $manualcount = 0;
       my $lockcount = 0;
       my $unlockcount = 0;
       if ($usercount) {
           $r->print($output);
       } else {
           if ($mode eq 'autoenroll') {
               return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
           } else {
               return;
           }
     }      }
     $index{'groups'} = scalar(@$keylist);      #
       # Sort the users
     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_Students = sort {      my @sorted_users = sort {
         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])          lc($userlist->{$a}->[$index])  cmp lc($userlist->{$b}->[$index])
             ||              ||
         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])            ||          lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second])            ||
         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])          lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
         } (keys(%$classlist));          } (keys(%$userlist));
     my $studentcount = 0;      my $rowcount = 0;
     my $autocount = 0;      foreach my $user (@sorted_users) {
     my $manualcount = 0;          my %in;
     my $unlockcount = 0;          my $sdata = $userlist->{$user};
     my $lockcount = 0;          $rowcount ++; 
     foreach my $student (@Sorted_Students) {          foreach my $item (@{$keylist}) {
         my $sdata = $classlist->{$student};              $in{$item} = $sdata->[$index{$item}];
         my $groups = $classgroups->{$student};          }
         my $username = $sdata->[$index{'username'}];          my $role = $in{'role'};
         my $domain   = $sdata->[$index{'domain'}];          $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]); 
         my $section  = $sdata->[$index{'section'}];          if (! defined($in{'start'}) || $in{'start'} == 0) {
         my $active_groups;              $in{'start'} = &mt('none');
         if (ref($groups->{active}) eq 'HASH') {          } else {
             $active_groups = join(', ',keys(%{$groups->{'active'}}));              $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
         }          }
         my $name     = $sdata->[$index{'fullname'}];          if (! defined($in{'end'}) || $in{'end'} == 0) {
         my $id       = $sdata->[$index{'id'}];              $in{'end'} = &mt('none');
         my $status   = $sdata->[$index{'status'}];  
         next if (($statusmode ne 'Any') && ($status ne $statusmode));  
         my $start    = $sdata->[$index{'start'}];  
         my $end      = $sdata->[$index{'end'}];  
         if (! defined($start) || $start == 0) {  
             $start = &mt('none');  
         } else {          } else {
             $start = &Apache::lonlocal::locallocaltime($start);              $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
         }          }
         if (! defined($end) || $end == 0) {          if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
             $end = &mt('none');              $r->print(&Apache::loncommon::start_data_table_row());
               my $checkval;
               if ($mode eq 'autoenroll') {
                   my $cellentry;
                   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>';
                       $autocount ++;
                   } else {
                       $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><nobr><label><input type="checkbox" name="chgmanual" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;Change</label></nobr></td></tr><tr><td><nobr>';
                       $manualcount ++;
                       if ($in{'lockedtype'}) {
                           $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;'.&mt('Unlock').'</label>';
                           $unlockcount ++;
                       } else {
                           $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" />&nbsp;'.&mt('Lock').'</label>';
                           $lockcount ++;
                       }
                       $cellentry .= '</nobr></td></tr></table>';
                   }
                   $r->print("<td>$cellentry</td>\n");
               } else {
                   $r->print("<td>$rowcount</td>\n");
                   if ($actionselect) {
                       my $showcheckbox;
                       if ($role =~ /^cr\//) {
                           $showcheckbox = $canchange{'cr'};
                       } else {
                           $showcheckbox = $canchange{$role};
                       }
                       if (!$showcheckbox) {
                           if ($context eq 'course') {
                               if ($canchangesec{$role} ne '') {
                                   if ($canchangesec{$role} eq $in{'section'}) {
                                       $showcheckbox = 1;
                                   }
                               }
                           }
                       }
                       if ($showcheckbox) {
                           $checkval = $user; 
                           if ($context eq 'course') {
                               if ($role eq 'st') {
                                   $checkval .= ':st';
                               }
                               $checkval .= ':'.$in{'section'};
                               if ($role eq 'st') {
                                   $checkval .= ':'.$in{'type'}.':'.
                                                $in{'lockedtype'};
                               }
                           }
                           $r->print('<td><input type="checkbox" name="'.
                                     'actionlist" value="'.$checkval.'"></td>');
                       } else {
                           $r->print('<td>&nbsp;</td>');
                       }
                   }
               }
               foreach my $item (@cols) {
                   if ($item eq 'username') {
                       $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");
                   } else {
                       $r->print('<td>'.$in{$item}.'</td>'."\n");
                   }
               }
               if (($context eq 'course') && ($mode ne 'autoenroll')) {
                   if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
                       if ($displayclickers eq 'on') {
                           my $clickers =
                      (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
                           if ($clickers!~/\w/) { $clickers='-'; }
                           $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"></a></td>');
                           } else {
                               $r->print('    <td>&nbsp;</td>  ');
                           }
                       }
                   }
               }
               $r->print(&Apache::loncommon::end_data_table_row());
           } elsif ($mode eq 'csv') {
               next if (! defined($CSVfile));
               # 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 = ();
               foreach my $item (@cols) {
                   push @line,&Apache::loncommon::csv_translate($in{$item});
               }
               print $CSVfile '"'.join('","',@line).'"'."\n";
           } elsif ($mode eq 'excel') {
               my $col = 0;
               foreach my $item (@cols) {
                   if ($item eq 'start' || $item eq 'end') {
                       if (defined($item) && $item != 0) {
                           $excel_sheet->write($row,$col++,
                               &Apache::lonstathelpers::calc_serial($in{item}),
                                       $format->{'date'});
                       } else {
                           $excel_sheet->write($row,$col++,'none');
                       }
                   } else {
                       $excel_sheet->write($row,$col++,$in{$item});
                   }
               }
               $row++;
           }
       }
       if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
               $r->print(&Apache::loncommon::end_data_table().'<br />');
       } elsif ($mode eq 'excel') {
           $excel_workbook->close();
           $r->print('<p><a href="'.$excel_filename.'">'.
                     &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
       } elsif ($mode eq 'csv') {
           close($CSVfile);
           $r->print('<a href="'.$CSVfilename.'">'.
                     &mt('Your CSV file').'</a> is ready for download.'.
                     "\n");
           $r->rflush();
       }
       if ($mode eq 'autoenroll') {
           return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
       } else {
           return ($usercount);
       }
   }
   
   sub print_username_link {
       my ($mode,$in) = @_;
       my $output;
       if ($mode eq 'autoenroll') {
           $output = $in->{'username'};
       } else {
           $output = '<a href="javascript:username_display_launch('.
                     "'$in->{'username'}','$in->{'domain'}'".')" />'.
                     $in->{'username'}.'</a>';
       }
       return $output;
   }
   
   sub role_type_names {
       my %lt = &Apache::lonlocal::texthash (
                            'domain' => 'Domain Roles',
                            'author' => 'Co-Author Roles',
                            'course' => 'Course Roles',
                );
       return %lt;
   }
   
   sub select_actions {
       my ($context,$setting,$statusmode) = @_;
       my %lt = &Apache::lonlocal::texthash(
                   revoke   => "Revoke user roles",
                   delete   => "Delete user roles",
                   reenable => "Re-enable expired user roles",
                   activate => "Make future user roles active now",
                   chgdates  => "Change starting/ending dates",
                   chgsec   => "Change section associated with user roles",
       );
       my ($output,$options,%choices);
       # FIXME Disable actions for now for roletype=course in domain context
       if ($context eq 'domain' && $setting eq 'course') {
           return;
       }
       if ($context eq 'course') {
           if ($env{'form.showrole'} ne 'Any') {
                if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},
                                              $env{'request.course.id'})) {
                    if ($env{'request.course.sec'} eq '') {
                        return;
                    } else {
                        if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
                            return;
                        }
                    }
               }
           }
       }
       if ($statusmode eq 'Any') {
           $options .= '
   <option value="chgdates">'.$lt{'chgdates'}.'</option>';
           $choices{'dates'} = 1;
       } else {
           if ($statusmode eq 'Future') {
               $options .= '
   <option value="activate">'.$lt{'activate'}.'</option>';
               $choices{'dates'} = 1;
           } elsif ($statusmode eq 'Expired') {
               $options .= '
   <option value="reenable">'.$lt{'reenable'}.'</option>';
               $choices{'dates'} = 1;
           }
           if ($statusmode eq 'Active' || $statusmode eq 'Future') {
               $options .= '
   <option value="chgdates">'.$lt{'chgdates'}.'</option>
   <option value="revoke">'.$lt{'revoke'}.'</option>';
               $choices{'dates'} = 1;
           }
       }
       if ($context eq 'domain') {
           $options .= '
   <option value="delete">'.$lt{'delete'}.'</option>';
       }
       if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) {
           if (($statusmode ne 'Expired') && ($env{'request.course.sec'} eq '')) {
               $options .= '
   <option value="chgsec">'.$lt{'chgsec'}.'</option>';
               $choices{'sections'} = 1;
           }
       }
       if ($options) {
           $output = '<select name="bulkaction" onchange="javascript:opendatebrowser(this.form,'."'studentform','change'".')" />'."\n".
                     '<option value="" selected="selected">'.
                     &mt('Please select').'</option>'."\n".$options."\n".'</select>';
           if ($choices{'dates'}) {
               $output .= 
                   '<input type="hidden" name="startdate_month" value="" />'."\n".
                   '<input type="hidden" name="startdate_day" value="" />'."\n".
                   '<input type="hidden" name="startdate_year" value="" />'."\n".
                   '<input type="hidden" name="startdate_hour" value="" />'."\n".
                   '<input type="hidden" name="startdate_minute" value="" />'."\n".
                   '<input type="hidden" name="startdate_second" value="" />'."\n".
                   '<input type="hidden" name="enddate_month" value="" />'."\n".
                   '<input type="hidden" name="enddate_day" value="" />'."\n".
                   '<input type="hidden" name="enddate_year" value="" />'."\n".
                   '<input type="hidden" name="enddate_hour" value="" />'."\n".
                   '<input type="hidden" name="enddate_minute" value="" />'."\n".
                   '<input type="hidden" name="enddate_second" value="" />'."\n";
               if ($context eq 'course') {
                   $output .= '<input type="hidden" name="makedatesdefault" value="" />'."\n";
               }
           }
           if ($choices{'sections'}) {
               $output .= '<input type="hidden" name="retainsec" value= "" />'."\n".
                          '<input type="hidden" name="newsecs" value= "" />'."\n";
           }
       }
       return $output;
   }
   
   sub date_section_javascript {
       my ($context,$setting) = @_;
       my $title = 'Date_And_Section_Selector';
       my %nopopup = &Apache::lonlocal::texthash (
           revoke => "Check the boxes for any users for whom roles are to be revoked, 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",
       );  
       my $output = '
   <script type="text/javascript">'."\n";
       $output .= <<"ENDONE";
       function opendatebrowser(callingform,formname,calledby) {
           var bulkaction = callingform.bulkaction.options[callingform.bulkaction.selectedIndex].value;
           if (bulkaction == 'revoke' || bulkaction == 'delete' || bulkaction == '') {
               if (calledby == 'go') {
                   if (bulkaction == 'revoke') {
                       alert("$nopopup{'revoke'}");
                   }
                   if (bulkaction == 'delete') {
                       alert("$nopopup{'delete'}"); 
                   }
                   if (bulkaction == '') {
                       alert("$nopopup{'none'}");
                   }
               }
               return;
           }
           var url = '/adm/createuser?';
           var type = '';
           var showrole = callingform.showrole.options[callingform.showrole.selectedIndex].value;
   ENDONE
       if ($context eq 'domain') {
           $output .= '
           type = callingform.roletype.options[callingform.roletype.selectedIndex].value;
   ';
       }
       my $width= '700';
       my $height = '400';
       $output .= <<"ENDTWO";
           url += 'action=dateselect&callingform=' + formname + 
                  '&roletype='+type+'&showrole='+showrole +'&bulkaction='+bulkaction;
           var title = '$title';
           var options = 'scrollbars=1,resizable=1,menubar=0';
           options += ',width=$width,height=$height';
           stdeditbrowser = open(url,title,options,'1');
           stdeditbrowser.focus();
       }
   </script>
   ENDTWO
       return $output;
   }
   
   sub date_section_selector {
       my ($context,$permission) = @_;
       my $callingform = $env{'form.callingform'};
       my $formname = 'dateselect';  
       my $groupslist = &get_groupslist();
       my $sec_js = &setsections_javascript($formname,$groupslist);
       my $output = <<"END";
   <script type="text/javascript">
   
   $sec_js
   
   function saveselections(formname) {
   
   END
       if ($env{'form.bulkaction'} eq 'chgsec') {
           $output .= <<"END";
           if (formname.retainsec.length > 1) {  
               for (var i=0; i<formname.retainsec.length; i++) {
                   if (formname.retainsec[i].checked == true) {
                       opener.document.$callingform.retainsec.value = formname.retainsec[i].value;
                   }
               }
         } else {          } else {
             $end = &Apache::lonlocal::locallocaltime($end);              opener.document.$callingform.retainsec.value = formname.retainsec.value;
         }          }
         my $status   = $sdata->[$index{'status'}];          setSections(formname);
         next if ($status ne 'Active');          if (seccheck == 'ok') {
         #              opener.document.$callingform.newsecs.value = formname.sections.value;
         $r->print(&Apache::loncommon::start_data_table_row());              window.close();
         $r->print(<<"END");          }
     <td><input type="checkbox" name="droplist" value="$student"></td>          return;
     <td>$username</td>  
     <td>$domain</td>  
     <td>$id</td>  
     <td>$name</td>  
     <td>$start</td>  
     <td>$end</td>  
 END  END
         $r->print(&Apache::loncommon::end_data_table_row());      } else {
     }          if ($context eq 'course') {
     $r->print(&Apache::loncommon::end_data_table().'<br />');              if (($env{'form.bulkaction'} eq 'reenable') || 
     %lt=&Apache::lonlocal::texthash(                  ($env{'form.bulkaction'} eq 'activate') || 
                        'dp'   => "Expire User Roles",                  ($env{'form.bulkaction'} eq 'chgdates')) {
                        'ca'   => "check all",                  if ($env{'request.course.sec'} eq '') {
                        'ua'   => "uncheck all",                      $output .= <<"END";
                                        );   
     $r->print(<<"END");          if (formname.makedatesdefault.checked == true) {
 </p><p>              opener.document.$callingform.makedatesdefault.value = 1;
 <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)">          else {
 <p><input type=submit value="$lt{'dp'}"></p>              opener.document.$callingform.makedatesdefault.value = 0;
           }
   
 END  END
     return;                  }
               }
           }
           $output .= <<"END";
       opener.document.$callingform.startdate_month.value =  formname.startdate_month.options[formname.startdate_month.selectedIndex].value;
       opener.document.$callingform.startdate_day.value =  formname.startdate_day.value;
       opener.document.$callingform.startdate_year.value = formname.startdate_year.value;
       opener.document.$callingform.startdate_hour.value =  formname.startdate_hour.options[formname.startdate_hour.selectedIndex].value;
       opener.document.$callingform.startdate_minute.value =  formname.startdate_minute.value;
       opener.document.$callingform.startdate_second.value = formname.startdate_second.value;
       opener.document.$callingform.enddate_month.value =  formname.enddate_month.options[formname.enddate_month.selectedIndex].value;
       opener.document.$callingform.enddate_day.value =  formname.enddate_day.value;
       opener.document.$callingform.enddate_year.value = formname.enddate_year.value;
       opener.document.$callingform.enddate_hour.value =  formname.enddate_hour.options[formname.enddate_hour.selectedIndex].value;
       opener.document.$callingform.enddate_minute.value =  formname.enddate_minute.value;
       opener.document.$callingform.enddate_second.value = formname.enddate_second.value;
       window.close();
   END
       }
       $output .= '
   }
   </script>
   ';
       my %lt = &Apache::lonlocal::texthash (
                    chac => 'Access dates to apply for 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.',
                    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.',
                    reta => "Retain each user's current section affiliations?", 
                    dnap => '(Does not apply to student roles).', 
               );
       my ($date_items,$headertext);
       if ($env{'form.bulkaction'} eq 'chgsec') {
           $headertext = $lt{'chse'};
       } else {
           $headertext = $lt{'chac'};
           my $starttime;
           if (($env{'form.bulkaction'} eq 'activate') || 
               ($env{'form.bulkaction'} eq 'reenable')) {
               $starttime = time;
           }
           $date_items = &date_setting_table($starttime,undef,$context,
                                             $env{'form.bulkaction'},$formname,
                                             $permission);
       }
       $output .= '<h3>'.$headertext.'</h3>'.
                  '<form name="'.$formname.'" method="post">'."\n".
                   $date_items;
       if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') {
           my ($cnum,$cdom) = &get_course_identity();
           my $info;
           if ($env{'form.showrole'} eq 'st') {
               $output .= '<p>'.$lt{'fors'}.'</p>'; 
           } elsif ($env{'form.showrole'} eq 'Any') {
               $output .= '<p>'.$lt{'fors'}.'</p>'.
                          '<p>'.$lt{'forn'}.'&nbsp;';
               $info = $lt{'reta'};
           } else {
               $output .= '<p>'.$lt{'forn'}.'&nbsp;';
               $info = $lt{'reta'};
           }
           if ($info) {
               $info .= '<span class="LC_nobreak">'.
                        '<label><input type="radio" name="retainsec" value="1" '.
                        'checked="checked" />'.&mt('Yes').'</label>&nbsp;&nbsp;'.
                        '<label><input type="radio" name="retainsec" value="0" />'.
                        &mt('No').'</label></span>';
               if ($env{'form.showrole'} eq 'Any') {
                   $info .= '<br />'.$lt{'dnap'};
               }
               $info .= '</p>';
           } else {
               $info = '<input type="hidden" name="retainsec" value="0" />'; 
           }
           my $rowtitle = &mt('New section to assign');
           my $secbox = &section_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,$permission,$context);
           $output .= $info.$secbox;
       }
       $output .= '<p>'.
   &mt('Use "Save" to update the main window with your selections.').'<br /><br />'.
   '<input type="button" name="dateselection" value="'.&mt('Save').'" onclick="javascript:saveselections(this.form)" /></p>'."\n".
   '</form>';
       return $output;
 }  }
   
   sub section_picker {
       my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_;
       my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
       my $sections_select .= &course_sections(\%sections_count,$role);
       my $secbox = '<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n";
       if ($mode eq 'upload') {
           my ($options,$cb_script,$coursepick) =
               &default_role_selector($context,1);
           $secbox .= &Apache::lonhtmlcommon::row_title('role','LC_oddrow_value').
                      $options. &Apache::lonhtmlcommon::row_closure(1)."\n";
       }
       $secbox .= &Apache::lonhtmlcommon::row_title($rowtitle,'LC_oddrow_value')."\n";
       if ($env{'request.course.sec'} eq '') {
           $secbox .= '<table class="LC_createuser"><tr class="LC_section_row">'."\n".
                      '<td align="center">'.&mt('Existing sections')."\n".
                      '<br />'.$sections_select.'</td><td align="center">'.
                      &mt('New section').'<br />'."\n".
                      '<input type="text" name="newsec" size="15" />'."\n".
                      '<input type="hidden" name="sections" value="" />'."\n".
                      '</td></tr></table>'."\n";
       } else {
          $secbox .= '<input type="hidden" name="sections" value="'.
                      $env{'request.course.sec'}.'" />'.
                      $env{'request.course.sec'};
       }
       $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n".
                  &Apache::lonhtmlcommon::end_pick_box().'</p>';
       return $secbox;
   }
   
   sub results_header_row {
       my ($rolefilter,$statusmode,$context,$permission,$mode) = @_;
       my ($description,$showfilter);
       if ($rolefilter ne 'Any') {
           $showfilter = $rolefilter;
       }
       if ($context eq 'course') {
           if ($mode eq 'csv' || $mode eq 'excel') {
               $description = &mt('Course - ').$env{'course.'.$env{'request.course.id'}.'.description'}.': ';
           }
           if ($statusmode eq 'Expired') {
               $description .= &mt('Users in course with expired [_1] roles',$showfilter);
           } elsif ($statusmode eq 'Future') {
               $description .= &mt('Users in course with future [_1] roles',$showfilter);
           } elsif ($statusmode eq 'Active') {
               $description .= &mt('Users in course with active [_1] roles',$showfilter);
           } else {
               if ($rolefilter eq 'Any') {
                   $description .= &mt('All users in course');
               } else {
                   $description .= &mt('All users in course with [_1] roles',$rolefilter);
               }
           }
           my $constraint;
           my $viewablesec = &viewable_section($permission);
           if ($viewablesec ne '') {
               if ($env{'form.showrole'} eq 'st') {
                   $constraint = &mt('only users in section "[_1]"',$viewablesec);
               } elsif ($env{'form.showrole'} ne 'cc') {
                   $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'} eq 'none') {
                       $constraint .= &mt(' and not in any group');
                   } else {
                       $constraint .= &mt(' and members of group: "[_1]"',$env{'form.grpfilter'});
                   }
               }
           } else {
               if (($env{'form.secfilter'} ne 'all') && ($env{'form.secfilter'} ne '')) {
                   if ($env{'form.secfilter'} eq 'none') {
                       $constraint = &mt('only users affiliated with no section');
                   } else {
                       $constraint = &mt('only users affiliated with section "[_1]"',$env{'form.secfilter'});
                   }
               }
               if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) {
                   if ($env{'form.grpfilter'} eq 'none') {
                       if ($constraint eq '') {
                           $constraint = &mt('only users not in any group');
                       } else {
                           $constraint .= &mt(' and also not in any group'); 
                       }
                   } else {
                       if ($constraint eq '') {
                           $constraint = &mt('only members of group: "[_1]"',$env{'form.grpfilter'});
                       } else {
                           $constraint .= &mt(' and also members of group: "[_1]"'.$env{'form.grpfilter'});
                       }
                   }
               }
           }
           if ($constraint ne '') {
               $description .= ' ('.$constraint.')';
           } 
       } elsif ($context eq 'author') {
           $description = 
               &mt('Author space for <span class="LC_cusr_emph">[_1]</span>',
           &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'})).':&nbsp;&nbsp;';
           if ($statusmode eq 'Expired') {
               $description .= &mt('Co-authors with expired [_1] roles',$showfilter);
           } elsif ($statusmode eq 'Future') {
               $description .= &mt('Co-authors with future [_1] roles',$showfilter);
           } elsif ($statusmode eq 'Active') {
               $description .= &mt('Co-authors with active [_1] roles',$showfilter);
           } else {
               if ($rolefilter eq 'Any') {
                   $description .= &mt('All co-authors');
               } else {
                   $description .= &mt('All co-authors with [_1] roles',$rolefilter);
               }
           }
       } elsif ($context eq 'domain') {
           my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description');
           $description = &mt('Domain - ').$domdesc.': ';
           if ($env{'form.roletype'} eq 'domain') {
               if ($statusmode eq 'Expired') {
                   $description .= &mt('Users in domain with expired [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Future') {
                   $description .= &mt('Users in domain with future [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Active') {
                   $description .= &mt('Users in domain with active [_1] roles',$showfilter);
               } else {
                   if ($rolefilter eq 'Any') {
                       $description .= &mt('All users in domain');
                   } else {
                       $description .= &mt('All users in domain with [_1] roles',$rolefilter);
                   }
               }
           } elsif ($env{'form.roletype'} eq 'author') {
               if ($statusmode eq 'Expired') {
                   $description .= &mt('Co-authors in domain with expired [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Future') {
                   $description .= &mt('Co-authors in domain with future [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Active') {
                  $description .= &mt('Co-authors in domain with active [_1] roles',$showfilter);
               } else {
                   if ($rolefilter eq 'Any') {
                       $description .= &mt('All users with co-author roles in domain',$showfilter);
                   } else {
                       $description .= &mt('All co-authors in domain  with [_1] roles',$rolefilter);
                   }
               }
           } elsif ($env{'form.roletype'} eq 'course') {
               my $coursefilter = $env{'form.coursepick'};
               if ($coursefilter eq 'category') {
                   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').' - ';
               }
               if ($statusmode eq 'Expired') {
                   $description .= &mt('users with expired [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Future') {
                   $description .= &mt('users with future [_1] roles',$showfilter);
               } elsif ($statusmode eq 'Active') {
                   $description .= &mt('users with active [_1] roles',$showfilter);
               } else {
                   if ($rolefilter eq 'Any') {
                       $description .= &mt('all users');
                   } else {
                       $description .= &mt('users with [_1] roles',$rolefilter);
                   }
               }
           }
       }
       return $description;
   }
   
   sub viewable_section {
       my ($permission) = @_;
       my $viewablesec;
       if (ref($permission) eq 'HASH') {
           if (exists($permission->{'view_section'})) {
               $viewablesec = $permission->{'view_section'};
           } elsif (exists($permission->{'cusr_section'})) {
               $viewablesec = $permission->{'cusr_section'};
           }
       }
       return $viewablesec;
   }
   
       
 #################################################  #################################################
 #################################################  #################################################
 sub show_drop_list {  sub show_drop_list {
     my ($r,$classlist,$keylist,$nosort)=@_;      my ($r,$classlist,$nosort,$permission) = @_;
     my $cid=$env{'request.course.id'};      my $cid = $env{'request.course.id'};
       my ($cnum,$cdom) = &get_course_identity($cid);
     if (! exists($env{'form.sortby'})) {      if (! exists($env{'form.sortby'})) {
         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},          &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                 ['sortby']);                                                  ['sortby']);
Line 1413  sub show_drop_list { Line 3082  sub show_drop_list {
     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {      if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
         $sortby = 'username';          $sortby = 'username';
     }      }
     my $cdom = $env{'course.'.$cid.'.domain'};  
     my $cnum = $env{'course.'.$cid,'.num'};  
     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(  
                                               $classlist,$keylist,$cdom,$cnum);  
     #  
     my $action = "drop";      my $action = "drop";
       my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
     $r->print(<<END);      $r->print(<<END);
 <input type="hidden" name="sortby" value="$sortby" />  <input type="hidden" name="sortby" value="$sortby" />
 <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>  <script type="text/javascript" language="Javascript">
 function checkAll(field) {  $check_uncheck_js
     for (i = 0; i < field.length; i++)  
         field[i].checked = true ;  
 }  
   
 function uncheckAll(field) {  
     for (i = 0; i < field.length; i++)  
         field[i].checked = false ;  
 }  
 </script>  </script>
 <p>  <p>
 <input type="hidden" name="phase" value="four">  <input type="hidden" name="phase" value="four">
 END  END
       my ($indexhash,$keylist) = &make_keylist_array();
 my %lt=&Apache::lonlocal::texthash('usrn'   => "username",      my $studentcount = 0;
                                    'dom'    => "domain",      if (ref($classlist) eq 'HASH') {
                                    'sn'     => "student name",          foreach my $student (keys(%{$classlist})) {
                                    'sec'    => "section",              my $sdata = $classlist->{$student}; 
                                    'start'  => "start date",              my $status = $sdata->[$indexhash->{'status'}];
                                    'end'    => "end date",              my $section = $sdata->[$indexhash->{'section'}];
                                    'groups' => "active groups",              if ($status ne 'Active') {
                                    );                  delete($classlist->{$student});
                   next;
               }
               if ($env{'request.course.sec'} ne '') {
                   if ($section ne $env{'request.course.sec'}) {
                       delete($classlist->{$student});
                       next;
                   }
               }
               $studentcount ++;
           }
       }
       if (!$studentcount) {
           $r->print(&mt('There are no students to drop.'));
           return;
       }
       my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                                                 $classlist,$keylist,$cdom,$cnum);
       my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                                          'dom'    => "domain",
                                          'sn'     => "student name",
                                          'sec'    => "section",
                                          'start'  => "start date",
                                          'end'    => "end date",
                                          'groups' => "active groups",
                                         );
     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());
         $r->print(<<END);          $r->print(<<END);
 <tr>  
     <th>&nbsp;</th>      <th>&nbsp;</th>
     <th>$lt{'usrn'}</th>      <th>$lt{'usrn'}</th>
     <th>$lt{'dom'}</th>      <th>$lt{'dom'}</th>
Line 1459  my %lt=&Apache::lonlocal::texthash('usrn Line 3141  my %lt=&Apache::lonlocal::texthash('usrn
     <th>$lt{'start'}</th>      <th>$lt{'start'}</th>
     <th>$lt{'end'}</th>      <th>$lt{'end'}</th>
     <th>$lt{'groups'}</th>      <th>$lt{'groups'}</th>
 </tr>  
 END  END
           $r->print(&Apache::loncommon::end_data_table_header_row());
     } else  {      } else  {
         $r->print(&Apache::loncommon::start_data_table());          $r->print(&Apache::loncommon::start_data_table().
                     &Apache::loncommon::start_data_table_header_row());
         $r->print(<<END);          $r->print(<<END);
 <tr><th>&nbsp;</th>      <th>&nbsp;</th>
     <th>      <th>
        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>         <a href="/adm/createuser?action=$action&sortby=username">$lt{'usrn'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>         <a href="/adm/createuser?action=$action&sortby=domain">$lt{'dom'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>         <a href="/adm/createuser?action=$action&sortby=id">ID</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>         <a href="/adm/createuser?action=$action&sortby=fullname">$lt{'sn'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>         <a href="/adm/createuser?action=$action&sortby=section">$lt{'sec'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>         <a href="/adm/createuser?action=$action&sortby=start">$lt{'start'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>         <a href="/adm/createuser?action=$action&sortby=end">$lt{'end'}</a>
     </th><th>      </th><th>
        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>         <a href="/adm/createuser?action=$action&sortby=groups">$lt{'groups'}</a>
     </th>      </th>
 </tr>  
 END  END
           $r->print(&Apache::loncommon::end_data_table_header_row());
     }      }
     #      #
     # Sort the students      # Sort the students
     my %index;      my $index  = $indexhash->{$sortby};
     my $i;      my $second = $indexhash->{'username'};
     foreach (@$keylist) {      my $third  = $indexhash->{'domain'};
         $index{$_} = $i++;  
     }  
     $index{'groups'} = scalar(@$keylist);  
     my $index  = $index{$sortby};  
     my $second = $index{'username'};  
     my $third  = $index{'domain'};  
     my @Sorted_Students = sort {      my @Sorted_Students = sort {
         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])          lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
             ||              ||
         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])          lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
             ||              ||
         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])          lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
         } (keys(%$classlist));          } (keys(%{$classlist}));
     foreach my $student (@Sorted_Students) {      foreach my $student (@Sorted_Students) {
         my $error;          my $error;
         my $sdata = $classlist->{$student};          my $sdata = $classlist->{$student};
         my $username = $sdata->[$index{'username'}];          my $username = $sdata->[$indexhash->{'username'}];
         my $domain   = $sdata->[$index{'domain'}];          my $domain   = $sdata->[$indexhash->{'domain'}];
         my $section  = $sdata->[$index{'section'}];          my $section  = $sdata->[$indexhash->{'section'}];
         my $name     = $sdata->[$index{'fullname'}];          my $name     = $sdata->[$indexhash->{'fullname'}];
         my $id       = $sdata->[$index{'id'}];          my $id       = $sdata->[$indexhash->{'id'}];
         my $start    = $sdata->[$index{'start'}];          my $start    = $sdata->[$indexhash->{'start'}];
         my $end      = $sdata->[$index{'end'}];          my $end      = $sdata->[$indexhash->{'end'}];
         my $groups = $classgroups->{$student};          my $groups = $classgroups->{$student};
         my $active_groups;          my $active_groups;
         if (ref($groups->{active}) eq 'HASH') {          if (ref($groups->{active}) eq 'HASH') {
Line 1529  END Line 3205  END
         } else {          } else {
             $end = &Apache::lonlocal::locallocaltime($end);              $end = &Apache::lonlocal::locallocaltime($end);
         }          }
         my $status   = $sdata->[$index{'status'}];          my $studentkey = $student.':'.$section;
         next if ($status ne 'Active');          my $startitem = '<input type="hidden" name="'.$studentkey.'_start" value="'.$sdata->[$indexhash->{'start'}].'" />';
         #          #
         $r->print(&Apache::loncommon::start_data_table_row());          $r->print(&Apache::loncommon::start_data_table_row());
         $r->print(<<"END");          $r->print(<<"END");
     <td><input type="checkbox" name="droplist" value="$student"></td>      <td><input type="checkbox" name="droplist" value="$studentkey"></td>
     <td>$username</td>      <td>$username</td>
     <td>$domain</td>      <td>$domain</td>
     <td>$id</td>      <td>$id</td>
     <td>$name</td>      <td>$name</td>
     <td>$section</td>      <td>$section</td>
     <td>$start</td>      <td>$start $startitem</td>
     <td>$end</td>      <td>$end</td>
     <td>$active_groups</td>      <td>$active_groups</td>
 END  END
Line 1548  END Line 3224  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'   => "Expire Users' Roles",                         'dp'   => "Drop Students",
                        'ca'   => "check all",                         'ca'   => "check all",
                        'ua'   => "uncheck all",                         'ua'   => "uncheck all",
                                        );                                         );
Line 1561  END Line 3237  END
     return;      return;
 }  }
   
   
   
 #  #
 # Print out the initial form to get the file containing a list of users  # Print out the initial form to get the file containing a list of users
 #  #
Line 1572  sub print_first_users_upload_form { Line 3246  sub print_first_users_upload_form {
     $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 .= "<h3>".&mt('Upload a list of users')."</h3>\n";      $str .= "<h3>".&mt('Upload a file containing information about users')."</h3>\n";
     $str .= &Apache::loncommon::upfile_select_html();      $str .= &Apache::loncommon::upfile_select_html();
     $str .= "<p>\n";      $str .= "<p>\n";
     $str .= '<input type="submit" name="fileupload" value="'.      $str .= '<input type="submit" name="fileupload" value="'.
         &mt('Upload users list').'">'."\n";          &mt('Upload file of users').'">'."\n";
     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.      $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
         &mt('Ignore First Line')."</label></p>\n";          &mt('Ignore First Line')."</label></p>\n";
     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",      $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
Line 1592  sub print_first_users_upload_form { Line 3266  sub print_first_users_upload_form {
   
 # ================================================= Drop/Add from uploaded file  # ================================================= Drop/Add from uploaded file
 sub upfile_drop_add {  sub upfile_drop_add {
     my ($r,$context) = @_;      my ($r,$context,$permission) = @_;
     &Apache::loncommon::load_tmp_file($r);      &Apache::loncommon::load_tmp_file($r);
     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);}
Line 1607  sub upfile_drop_add { Line 3281  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      foreach my $field (qw/username names
Line 1628  sub upfile_drop_add { Line 3306  sub upfile_drop_add {
     #      #
     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));          $r->print(&make_dates_default($startdate,$enddate,$context));
     }      }
     # Determine domain and desired host (home server)      # Determine domain and desired host (home server)
     my $domain=$env{'request.role.domain'};      my $domain=$env{'request.role.domain'};
Line 1681  sub upfile_drop_add { Line 3359  sub upfile_drop_add {
             $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'};
         }            }  
     } elsif ($context eq 'construction_space') {      } elsif ($context eq 'author') {
         $defaultrole = $env{'form.defaultrole'};          $defaultrole = $env{'form.defaultrole'};
     }      } elsif ($context eq 'course') {
     if ($context eq 'domain' && $setting eq 'course') {           $defaultrole = $env{'form.defaultrole'};
         if ($env{'form.newsec'} ne '') {          $defaultsec = $env{'form.sections'};
             $defaultsec = $env{'form.newsec'};  
         } elsif ($env{'form.defaultsec'} ne '') {  
             $defaultsec = $env{'form.defaultsec'}  
         }  
     }      }
     if ($env{'request.course.id'} ne '') {      if ($env{'request.course.id'} ne '') {
         $cid = $env{'request.course.id'};          $cid = $env{'request.course.id'};
     } elsif ($env{'form.defaultdomain'} ne '' && $env{'form.defaultcourse'} ne '') {      } elsif ($setting eq 'course') {
         $cid = $env{'form.defaultdomain'}.'_'.          if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) {
                $env{'form.defaultcourse'};              $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'};
           }
       }
       # Check to see if user information can be changed
       my @userinfo = ('firstname','middlename','lastname','generation',
                       'permanentemail','id');
       my %canmodify;
       if (&Apache::lonnet::allowed('mau',$domain)) {
           foreach my $field (@userinfo) {
               $canmodify{$field} = 1;
           }
       }
       my (%userlist,%modifiable_fields,@poss_roles);
       my $secidx = &Apache::loncoursedata::CL_SECTION();
       my @courseroles = &roles_by_context('course',1);
       if (!&Apache::lonnet::allowed('mau',$domain)) {
           if ($context eq 'course' || $context eq 'author') {
               @poss_roles =  &curr_role_permissions($context);
               my @statuses = ('active','future');
               my ($indexhash,$keylist) = &make_keylist_array();
               my %info;
               foreach my $role (@poss_roles) {
                   %{$modifiable_fields{$role}} = &can_modify_userinfo($context,$domain,
                                                           \@userinfo,[$role]);
               }
               if ($context eq 'course') {
                   my ($cnum,$cdom) = &get_course_identity();
                   my $roster = &Apache::loncoursedata::get_classlist();
                   %userlist = %{$roster};
                   my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,
                                                            \@statuses,\@poss_roles);
                   &gather_userinfo($context,'view',\%userlist,$indexhash,\%info,
                                   \%advrolehash,$permission);
               } elsif ($context eq 'author') {
                   my %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
                                                     \@statuses,\@poss_roles);
                   &gather_userinfo($context,'view',\%userlist,$indexhash,\%info,
                                \%cstr_roles,$permission);
   
               }
           }
     }      }
     if ( $domain eq &LONCAPA::clean_domain($domain)      if ( $domain eq &LONCAPA::clean_domain($domain)
         && ($amode ne '')) {          && ($amode ne '')) {
Line 1705  sub upfile_drop_add { Line 3420  sub upfile_drop_add {
         #######################################          #######################################
         if ($context eq 'course') {          if ($context eq 'course') {
             $r->print('<h3>'.&mt('Enrolling Users')."</h3>\n<p>\n");              $r->print('<h3>'.&mt('Enrolling Users')."</h3>\n<p>\n");
         } elsif ($context eq 'construction_space') {          } elsif ($context eq 'author') {
             $r->print('<h3>'.&mt('Updating Co-authors')."</h3>\n<p>\n");              $r->print('<h3>'.&mt('Updating Co-authors')."</h3>\n<p>\n");
         } else {          } else {
             $r->print('<h3>'.&mt('Adding/Modifying Users')."</h3>\n<p>\n");              $r->print('<h3>'.&mt('Adding/Modifying Users')."</h3>\n<p>\n");
Line 1717  sub upfile_drop_add { Line 3432  sub upfile_drop_add {
                      );                       );
         my $flushc=0;          my $flushc=0;
         my %student=();          my %student=();
         my %curr_groups;          my (%curr_groups,@sections,@cleansec,$defaultwarn,$groupwarn);
         my %userchg;          my %userchg;
         if ($context eq 'course') {          if ($context eq 'course' || $setting eq 'course') {
             # Get information about course groups              if ($context eq 'course') {
             %curr_groups = &Apache::longroup::coursegroups();                  # Get information about course groups
                   %curr_groups = &Apache::longroup::coursegroups();
               } elsif ($setting eq 'course') {
                   if ($cid) {
                       %curr_groups =
                           &Apache::longroup::coursegroups($env{'form.dcdomain'},
                                                           $env{'form.dccourse'});
                   }
               }
               # determine section number
               if ($defaultsec =~ /,/) {
                   push(@sections,split(/,/,$defaultsec));
               } else {
                   push(@sections,$defaultsec);
               }
               # remove non alphanumeric values from section
               foreach my $item (@sections) {
                   $item =~ s/\W//g;
                   if ($item eq "none" || $item eq 'all') {
                       $defaultwarn = &mt('Default section name [_1] could not be used as it is a reserved word.',$item);
                   } elsif ($item ne ''  && exists($curr_groups{$item})) {
                       $groupwarn = &mt('Default section name "[_1]" is the name of a course group. Section names and group names must be distinct.',$item);
                   } elsif ($item ne '') {
                       push(@cleansec,$item);
                   }
               }
               if ($defaultwarn) {
                   $r->print($defaultwarn.'<br />');
               }
               if ($groupwarn) {
                   $r->print($groupwarn.'<br />');
               }
         }          }
           my (%curr_rules,%got_rules,%alerts);
           my %customroles = &my_custom_roles();
           my @permitted_roles = &roles_on_upload($context,$setting,%customroles); 
         # Get new users list          # Get new users list
         foreach (@userdata) {          foreach my $line (@userdata) {
             my %entries=&Apache::loncommon::record_sep($_);              my @secs;
               my %entries=&Apache::loncommon::record_sep($line);
             # Determine user name              # Determine user name
             unless (($entries{$fields{'username'}} eq '') ||              unless (($entries{$fields{'username'}} eq '') ||
                     (!defined($entries{$fields{'username'}}))) {                      (!defined($entries{$fields{'username'}}))) {
Line 1753  sub upfile_drop_add { Line 3503  sub upfile_drop_add {
       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',        &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).            $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                               '</b>');                                '</b>');
                       next;
                 } else {                  } else {
                     my $username = $entries{$fields{'username'}};                       my $username = $entries{$fields{'username'}};
                     my $sec;                      if (defined($fields{'sec'})) {
                     if ($context eq 'course' || $setting eq 'course') {                          if (defined($entries{$fields{'sec'}})) {
                         # determine section number                              $entries{$fields{'sec'}} =~ s/\W//g;
                         if (defined($fields{'sec'})) {                              my $item = $entries{$fields{'sec'}};
                             if (defined($entries{$fields{'sec'}})) {                              if ($item eq "none" || $item eq 'all') {
                                 $sec=$entries{$fields{'sec'}};                                  $r->print('<br />'.&mt('<b>[_1]</b>: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.',$username,$fname,$mname,$lname,$gen,$item));
                                   next;
                               } elsif (exists($curr_groups{$item})) {
                                   $r->print('<br />'.&mt('<b>[_1]</b>: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.',$username,$fname,$mname,$lname,$gen,$item).' '.&mt('Section names and group names must be distinct.'));
                                   next;
                               } else {
                                   push(@secs,$item);
                             }                              }
                         } else {  
                             $sec = $defaultsec;  
                         }                          }
                         # remove non alphanumeric values from section                      }
                         $sec =~ s/\W//g;                      if ($env{'request.course.sec'} ne '') {
                         if ($sec eq "none" || $sec eq 'all') {                          @secs = ($env{'request.course.sec'});
                             $r->print('<br />'.                          if (ref($userlist{$username.':'.$domain}) eq 'ARRAY') {
       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',                              my $currsec = $userlist{$username.':'.$domain}[$secidx];
                                       $username,$sec,$fname,$mname,$lname,$gen));                              if ($currsec ne $env{'request.course.sec'}) {
                             next;                                  $r->print('<br />'.&mt('<b>[_1]</b>: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".',$username,$fname,$mname,$lname,$gen,$secs[0]).'<br />');
                         } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {                                  if ($currsec eq '') {
                             $r->print('<br />'.                                      $r->print(&mt('This user already has an active/future student role in the course, unaffiliated to any section.'));
       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a course group. Section names and group names must be distinct.',  
                                       $username,$sec,$fname,$mname,$lname,$gen));                                  } else {
                             next;                                      $r->print(&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 />');
                                   next;
                               }
                           }
                       } elsif ($context eq 'course' || $setting eq 'course') {
                           if (@secs == 0) {
                               @secs = @cleansec;
                         }                          }
                     }                      }
                     # determine id number                      # determine id number
Line 1805  sub upfile_drop_add { Line 3568  sub upfile_drop_add {
                     my $role = '';                      my $role = '';
                     if (defined($fields{'role'})) {                      if (defined($fields{'role'})) {
                         if ($entries{$fields{'role'}}) {                          if ($entries{$fields{'role'}}) {
                              my @poss_roles =                               $entries{$fields{'role'}}  =~ s/(\s+$|^\s+)//g;
                                  &curr_role_permissions($context,$setting);                              if ($entries{$fields{'role'}} ne '') {
                              if (grep(/^\Q$entries{$fields{'role'}}\E/,@poss_roles)) {                                  if (grep(/^\Q$entries{$fields{'role'}}\E$/,@permitted_roles)) {
                                 $role=$entries{$fields{'role'}};                                      $role = $entries{$fields{'role'}};
                             } else {                                  }
                                 my $rolestr = join(', ',@poss_roles);                              }
                               if ($role eq '') {
                                   my $rolestr = join(', ',@permitted_roles);
                                 $r->print('<br />'.                                  $r->print('<br />'.
       &mt('<b>[_1]</b>: You do not have permission to add the requested role [_2] for the user.',$entries{$fields{'username'}},$entries{$fields{'role'}}).'<br />'.&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n");        &mt('<b>[_1]</b>: You do not have permission to add the requested role [_2] for the user.',$entries{$fields{'username'}},$entries{$fields{'role'}}).'<br />'.&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n");
                                 next;                                  next;
Line 1822  sub upfile_drop_add { Line 3587  sub upfile_drop_add {
                     }                      }
                     # Clean up whitespace                      # Clean up whitespace
                     foreach (\$domain,\$username,\$id,\$fname,\$mname,                      foreach (\$domain,\$username,\$id,\$fname,\$mname,
                              \$lname,\$gen,\$sec,\$role) {                               \$lname,\$gen) {
                         $$_ =~ s/(\s+$|^\s+)//g;                          $$_ =~ s/(\s+$|^\s+)//g;
                     }                      }
                       # check against rules
                       my $checkid = 0;
                       my $newuser = 0;
                       my (%rulematch,%inst_results,%idinst_results);
                       my $uhome=&Apache::lonnet::homeserver($username,$domain);
                       if ($uhome eq 'no_host') {
                           $checkid = 1;
                           $newuser = 1;
                           my $checkhash;
                           my $checks = { 'username' => 1 };
                           $checkhash->{$username.':'.$domain} = { 'newuser' => 1, };
                           &Apache::loncommon::user_rule_check($checkhash,$checks,
                               \%alerts,\%rulematch,\%inst_results,\%curr_rules,
                               \%got_rules);
                           if (ref($alerts{'username'}) eq 'HASH') {
                               if (ref($alerts{'username'}{$domain}) eq 'HASH') {
                                   next if ($alerts{'username'}{$domain}{$username});
                               }
                           }
                       } else {
                           if ($context eq 'course' || $context eq 'author') {
                               if ($role eq '') {
                                   my @checkroles;
                                   foreach my $role (@poss_roles) {
                                       my $endkey;
                                       if ($role ne 'st') {
                                           $endkey = ':'.$role;
                                       }
                                       if (exists($userlist{$username.':'.$domain.$endkey})) {
                                           if (!grep(/^\Q$role\E$/,@checkroles)) {
                                               push(@checkroles,$role);
                                           }
                                       }
                                   }
                                   if (@checkroles > 0) {
                                       %canmodify = &can_modify_userinfo($context,$domain,\@userinfo,\@checkroles);
                                   }
                               } elsif (ref($modifiable_fields{$role}) eq 'HASH') {
                                   %canmodify = %{$modifiable_fields{$role}};
                               }
                           }
                           my @newinfo = (\$fname,\$mname,\$lname,\$gen,\$email,\$id);
                           for (my $i=0; $i<@userinfo; $i++) {
                               if (${$newinfo[$i]} ne '') {
                                   if (!$canmodify{$userinfo[$i]}) {
                                       ${$newinfo[$i]} = '';
                                   }
                               }
                           }
                       }
                       if ($id ne '') {
                           if (!$newuser) {
                               my %idhash = &Apache::lonnet::idrget($domain,($username));
                               if ($idhash{$username} ne $id) {
                                   $checkid = 1;
                               }
                           }
                           if ($checkid) {
                               my $checkhash;
                               my $checks = { 'id' => 1 };
                               $checkhash->{$username.':'.$domain} = { 'newuser' => $newuser,
                                                                       'id'  => $id };
                               &Apache::loncommon::user_rule_check($checkhash,$checks,
                                   \%alerts,\%rulematch,\%idinst_results,\%curr_rules,
                                   \%got_rules);
                               if (ref($alerts{'id'}) eq 'HASH') {
                                   if (ref($alerts{'id'}{$domain}) eq 'HASH') {
                                       next if ($alerts{'id'}{$domain}{$id});
                                   }
                               }
                           }
                       }
                     if ($password || $env{'form.login'} eq 'loc') {                      if ($password || $env{'form.login'} eq 'loc') {
                         my ($userresult,$authresult,$roleresult);                          my $multiple = 0;
                           my ($userresult,$authresult,$roleresult,$idresult);
                           my (%userres,%authres,%roleres,%idres);
                           my $singlesec = '';
                         if ($role eq 'st') {                          if ($role eq 'st') {
                               my $sec;
                               if (@secs > 0) {
                                   $sec = $secs[0];
                               }
                             &modifystudent($domain,$username,$cid,$sec,                              &modifystudent($domain,$username,$cid,$sec,
                                            $desiredhost);                                             $desiredhost,$context);
                             $roleresult =                               $roleresult =
                                 &Apache::lonnet::modifystudent                                  &Apache::lonnet::modifystudent
                                     ($domain,$username,$id,$amode,$password,                                      ($domain,$username,$id,$amode,$password,
                                      $fname,$mname,$lname,$gen,$sec,$enddate,                                       $fname,$mname,$lname,$gen,$sec,$enddate,
                                      $startdate,$env{'form.forceid'},                                       $startdate,$env{'form.forceid'},
                                      $desiredhost,$email);                                       $desiredhost,$email,'manual','',$cid,
                                        '',$context);
                               $userresult = $roleresult;
                           } else {
                               if ($role ne '') { 
                                   if ($context eq 'course' || $setting eq 'course') {
                                       if ($customroles{$role}) {
                                           $role = 'cr_'.$env{'user.domain'}.'_'.
                                                   $env{'user.name'}.'_'.$role;
                                       }
                                       if ($role ne 'cc') { 
                                           if (@secs > 1) {
                                               $multiple = 1;
                                               foreach my $sec (@secs) {
                                                   ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) =
                                                   &modifyuserrole($context,$setting,
                                                       $changeauth,$cid,$domain,$username,
                                                       $id,$amode,$password,$fname,
                                                       $mname,$lname,$gen,$sec,
                                                       $env{'form.forceid'},$desiredhost,
                                                       $email,$role,$enddate,
                                                       $startdate,$checkid);
                                               }
                                           } elsif (@secs > 0) {
                                               $singlesec = $secs[0];
                                           }
                                       }
                                   }
                               }
                               if (!$multiple) {
                                   ($userresult,$authresult,$roleresult,$idresult) = 
                                       &modifyuserrole($context,$setting,
                                                       $changeauth,$cid,$domain,$username, 
                                                       $id,$amode,$password,$fname,
                                                       $mname,$lname,$gen,$singlesec,
                                                       $env{'form.forceid'},$desiredhost,
                                                       $email,$role,$enddate,$startdate,$checkid);
                               }
                           }
                           if ($multiple) {
                               foreach my $sec (sort(keys(%userres))) {
                                   $flushc =
                                   &user_change_result($r,$userres{$sec},$authres{$sec},
                                                       $roleres{$sec},$idres{$sec},\%counts,$flushc,
                                                       $username,\%userchg);
   
                               }
                         } else {                          } else {
                             ($userresult,$authresult,$roleresult) =                               $flushc = 
                                 &modifyuserrole($context,$setting,                                  &user_change_result($r,$userresult,$authresult,
                                     $changeauth,$cid,$domain,$username,                                                       $roleresult,$idresult,\%counts,$flushc,
                                     $id,$amode,$password,$fname,                                                      $username,\%userchg);
                                     $mname,$lname,$gen,$sec,                          }
                                     $env{'form.forceid'},$desiredhost,  
                                     $email,$role,$enddate,$startdate);  
                         }  
                         $flushc =   
                             &user_change_result($r,$userresult,$authresult,  
                                                 $roleresult,\%counts,$flushc,  
                                                 $username,%userchg);  
                     } else {                      } else {
                         if ($context eq 'course') {                          if ($context eq 'course') {
                             $r->print('<br />'.                               $r->print('<br />'. 
       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)        &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                                      );                                       );
                         } elsif ($context eq 'construction_space') {                          } elsif ($context eq 'author') {
                             $r->print('<br />'.                              $r->print('<br />'.
       &mt('<b>[_1]</b>: Unable to add co-author.  No password specified.',$username)        &mt('<b>[_1]</b>: Unable to add co-author.  No password specified.',$username)
                                      );                                       );
Line 1868  sub upfile_drop_add { Line 3751  sub upfile_drop_add {
             }              }
         } # end of foreach (@userdata)          } # end of foreach (@userdata)
         # Flush the course logs so reverse user roles immediately updated          # Flush the course logs so reverse user roles immediately updated
         if ($context eq 'course' || ($context eq 'domain' && $setting eq 'course')) {          &Apache::lonnet::flushcourselogs();
             &Apache::lonnet::flushcourselogs();          $r->print("</p>\n<p>\n".&mt('Processed [quant,_1,user].',$counts{'user'}).
         }  
         $r->print("</p>\n<p>\n".&mt('Processed [_1] user(s).',$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 [_1] users. If user is active, the new role will be available when the user next logs in to LON-CAPA.',$counts{'role'})."</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 {
               $r->print('<p>'.&mt('No roles added').'</p>');
         }          }
         if ($counts{'auth'} > 0) {          if ($counts{'auth'} > 0) {
             $r->print("<p>\n".              $r->print("<p>\n".
                       &mt('Authentication changed for [_1] existing users.',                        &mt('Authentication changed for [_1] existing users.',
                           $counts{'auth'})."</p>\n");                            $counts{'auth'})."</p>\n");
         }          }
         $r->print('<form name="uploadresult" action="/adm/createuser">');          $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules));
         $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','prevphase','currstate']));  
         $r->print('</form>');  
         #####################################          #####################################
         #           Drop students           #          # Display list of students to drop  #
         #####################################          #####################################
         if ($env{'form.fullup'} eq 'yes') {          if ($env{'form.fullup'} eq 'yes') {
             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");              $r->print('<h3>'.&mt('Students to Drop')."</h3>\n");
             #  Get current classlist              #  Get current classlist
             my ($classlist,$keylist)=&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.').                  $r->print('<form name="studentform" method="post" action="/adm/createuser" />'.
                           "\n");                            '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'.
                             &mt('There are no students with current/future access to the course.').
                             '</form>'."\n");
             } else {              } else {
                 # Remove the students we just added from the list of students.                  # Remove the students we just added from the list of students.
                 foreach (@userdata) {                  foreach my $line (@userdata) {
                     my %entries=&Apache::loncommon::record_sep($_);                      my %entries=&Apache::loncommon::record_sep($line);
                     unless (($entries{$fields{'username'}} eq '') ||                      unless (($entries{$fields{'username'}} eq '') ||
                             (!defined($entries{$fields{'username'}}))) {                              (!defined($entries{$fields{'username'}}))) {
                         delete($classlist->{$entries{$fields{'username'}}.                          delete($classlist->{$entries{$fields{'username'}}.
Line 1906  sub upfile_drop_add { Line 3789  sub upfile_drop_add {
                     }                      }
                 }                  }
                 # Print out list of dropped students.                  # Print out list of dropped students.
                 &show_drop_list($r,$classlist,$keylist,'nosort');                  &show_drop_list($r,$classlist,'nosort',$permission);
             }              }
         }          }
     } # end of unless      } # end of unless
       if ($env{'form.fullup'} ne 'yes') {
           $r->print('</form>');
       }
   }
   
   sub print_namespacing_alerts {
       my ($domain,$alerts,$curr_rules) = @_;
       my $output;
       if (ref($alerts) eq 'HASH') {
           if (keys(%{$alerts}) > 0) {
               if (ref($alerts->{'username'}) eq 'HASH') {
                   foreach my $dom (sort(keys(%{$alerts->{'username'}}))) {
                       my $count;
                       if (ref($alerts->{'username'}{$dom}) eq 'HASH') {
                           $count = keys(%{$alerts->{'username'}{$dom}});
                       }
                       my $domdesc = &Apache::lonnet::domain($domain,'description');
                       if (ref($curr_rules->{$dom}) eq 'HASH') {
                           $output .= &Apache::loncommon::instrule_disallow_msg(
                                           'username',$domdesc,$count,'upload');
                       }
                       $output .= &Apache::loncommon::user_rule_formats($dom,
                                      $domdesc,$curr_rules->{$dom}{'username'},
                                      'username');
                   }
               }
               if (ref($alerts->{'id'}) eq 'HASH') {
                   foreach my $dom (sort(keys(%{$alerts->{'id'}}))) {
                       my $count;
                       if (ref($alerts->{'id'}{$dom}) eq 'HASH') {
                           $count = keys(%{$alerts->{'id'}{$dom}});
                       }
                       my $domdesc = &Apache::lonnet::domain($domain,'description');
                       if (ref($curr_rules->{$dom}) eq 'HASH') {
                           $output .= &Apache::loncommon::instrule_disallow_msg(
                                                 'id',$domdesc,$count,'upload');
                       }
                       $output .= &Apache::loncommon::user_rule_formats($dom,
                                       $domdesc,$curr_rules->{$dom}{'id'},'id');
                   }
               }
           }
       }
 }  }
   
 sub user_change_result {  sub user_change_result {
     my ($r,$userresult,$authresult,$roleresult,$counts,$flushc,$username,      my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
         $userchg) = @_;          $username,$userchg) = @_;
     my $okresult = 0;      my $okresult = 0;
     if ($userresult ne 'ok') {      if ($userresult ne 'ok') {
         if ($userresult =~ /^error:(.+)$/) {          if ($userresult =~ /^error:(.+)$/) {
Line 1955  sub user_change_result { Line 3881  sub user_change_result {
             $flushc=0;              $flushc=0;
         }          }
     }      }
       if ($idresult) {
           $r->print($idresult);
       }
     return $flushc;      return $flushc;
 }  }
   
 # ========================================================= Menu Phase Two Drop  # ========================================================= Menu Phase Two Drop
 sub print_expire_menu {  sub print_drop_menu {
     my ($r,$context) = @_;      my ($r,$context,$permission) = @_;
     $r->print("<h3>".&mt("Expire Users' Roles")."</h3>");      $r->print('<h3>'.&mt("Drop Students").'</h3>'."\n".
     my $cid=$env{'request.course.id'};                '<form name="studentform" method="post">'."\n");
     my ($classlist,$keylist) = &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");          $r->print(&mt('There are no students currently enrolled.')."\n");
         return;      } else {
           &show_drop_list($r,$classlist,'nosort',$permission);
     }      }
     # Print out the available choices      $r->print('</form>'. &Apache::loncommon::end_page());
     &show_drop_list($r,$classlist,$keylist);  
     return;      return;
 }  }
   
   
 # ================================================================== Phase four  # ================================================================== Phase four
   
 sub expire_user_list {  sub update_user_list {
     my ($r,$context) = @_;      my ($r,$context,$setting,$choice) = @_;
       my $now = time;
     my $count=0;      my $count=0;
     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');      my @changelist;
     foreach (@droplist) {      if ($choice eq 'drop') {
         my ($uname,$udom)=split(/\:/,$_);          @changelist = &Apache::loncommon::get_env_multiple('form.droplist');
         # drop student      } else {
         my $result = &modifystudent($udom,$uname,$env{'request.course.id'});          @changelist = &Apache::loncommon::get_env_multiple('form.actionlist');
       }
       my %result_text = ( ok    => { 'revoke'   => 'Revoked',
                                      'delete'   => 'Deleted',
                                      'reenable' => 'Re-enabled',
                                      'activate' => 'Activated',
                                      'chgdates' => 'Changed Access Dates for',
                                      'chgsec'   => 'Changed section for',
                                      'drop'     => 'Dropped',
                                    },
                           error => {'revoke'    => 'revoking',
                                     'delete'    => 'deleting',
                                     'reenable'  => 're-enabling',
                                     'activate'  => 'activating',
                                     'chgdates'  => 'changing access dates for',
                                     'chgsec'    => 'changing section for',
                                     'drop'      => 'dropping',
                                    },
                         );
       my ($startdate,$enddate);
       if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
           ($startdate,$enddate) = &get_dates_from_form();
       }
       foreach my $item (@changelist) {
           my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections,
               $scopestem);
           if ($choice eq 'drop') {
               ($uname,$udom,$sec) = split(/:/,$item,-1);
               $role = 'st';
               $cid = $env{'request.course.id'};
               $scopestem = '/'.$cid;
               $scopestem =~s/\_/\//g;
               if ($sec eq '') {
                   $scope = $scopestem;
               } else {
                   $scope = $scopestem.'/'.$sec;
               }
           } elsif ($context eq 'course') {
               ($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1);
               $cid = $env{'request.course.id'};
               $scopestem = '/'.$cid;
               $scopestem =~s/\_/\//g;
               if ($sec eq '') {
                   $scope = $scopestem;
               } else {
                   $scope = $scopestem.'/'.$sec;
               }
           } elsif ($context eq 'author') {
               ($uname,$udom,$role) = split(/\:/,$item,-1);
               $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
           } elsif ($context eq 'domain') {
               if ($setting eq 'domain') {
                   ($role,$uname,$udom) = split(/\:/,$item,-1);
                   $scope = '/'.$env{'request.role.domain'}.'/';
               } elsif ($setting eq 'author') { 
                   ($uname,$udom,$role,$scope) = split(/\:/,$item);
               } elsif ($setting eq 'course') {
                   ($uname,$udom,$role,$cid,$sec,$type,$locktype) = 
                       split(/\:/,$item);
                   $scope = '/'.$cid;
                   $scope =~s/\_/\//g;
                   if ($sec ne '') {
                       $scope .= '/'.$sec;
                   }
               }
           }
           my $plrole = &Apache::lonnet::plaintext($role);
           my $start = $env{'form.'.$item.'_start'};
           my $end = $env{'form.'.$item.'_end'};
           if ($choice eq 'drop') {
               # drop students
               $end = $now;
               $type = 'manual';
               $result =
                   &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);
           } elsif ($choice eq 'revoke') {
               # revoke or delete user role
               $end = $now; 
               if ($role eq 'st') {
                   $result = 
                       &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);
               } else {
                   $result = 
                       &Apache::lonnet::revokerole($udom,$uname,$scope,$role,
                                                   '','',$context);
               }
           } elsif ($choice eq 'delete') {
               if ($role eq 'st') {
                   &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context);
               }
               $result =
                   &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,
                                               $start,1,'',$context);
           } else {
               #reenable, activate, change access dates or change section
               if ($choice ne 'chgsec') {
                   $start = $startdate; 
                   $end = $enddate;
               }
               if ($choice eq 'reenable') {
                   if ($role eq 'st') {
                       $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);
                   } else {
                       $result = 
                           &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                                       $now,'','',$context);
                   }
               } elsif ($choice eq 'activate') {
                   if ($role eq 'st') {
                       $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);
                   } else {
                       $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                               $now,'','',$context);
                   }
               } elsif ($choice eq 'chgdates') {
                   if ($role eq 'st') {
                       $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context);
                   } else {
                       $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
                                                   $start,'','',$context);
                   }
               } elsif ($choice eq 'chgsec') {
                   my (@newsecs,$revresult,$nochg,@retained);
                   if ($role ne 'cc') {
                       @newsecs = split(/,/,$env{'form.newsecs'});
                   }
                   # remove existing section if not to be retained.   
                   if (!$env{'form.retainsec'}) {
                       if ($sec eq '') {
                           if (@newsecs == 0) {
                               $result = &mt('No change in section assignment (none)');
                               $nochg = 1;
                           } else {
                               $revresult =
                                   &Apache::lonnet::revokerole($udom,$uname,
                                                               $scope,$role,
                                                               '','',$context);
                           } 
                       } else {
                           if (@newsecs > 0) {
                               if (grep(/^\Q$sec\E$/,@newsecs)) {
                                   push(@retained,$sec);
                               } else {
                                   $revresult =
                                       &Apache::lonnet::revokerole($udom,$uname,
                                                                   $scope,$role,
                                                                   '','',$context);
                               }
                           } else {
                               $revresult =
                                   &Apache::lonnet::revokerole($udom,$uname,
                                                               $scope,$role,
                                                               '','',$context);
                           }
                       }
                   } else {
                       if ($sec eq '') {
                           $nochg = 1;
                       } else { 
                           push(@retained,$sec);
                       }
                   }
                   # add new sections
                   if (@newsecs == 0) {
                       if (!$nochg) {
                           if ($role eq 'st') {
                               $result = 
                                   &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context);
                           } else {
                               my $newscope = $scopestem;
                               $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context);
                           }
                       }
                   } else {
                       foreach my $newsec (@newsecs) { 
                           if (!grep(/^\Q$newsec\E$/,@retained)) {
                               if ($role eq 'st') {
                                   $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context);
                               } else {
                                   my $newscope = $scopestem;
                                   if ($newsec ne '') {
                                      $newscope .= '/'.$newsec;
                                   }
                                   $result = &Apache::lonnet::assignrole($udom,$uname,
                                                           $newscope,$role,$end,$start);
                               }
                           }
                       }
                   }
               }
           }
           my $extent = $scope;
           if ($choice eq 'drop' || $context eq 'course') {
               my ($cnum,$cdom,$cdesc) = &get_course_identity($cid);
               if ($cdesc) {
                   $extent = $cdesc;
               }
           }
         if ($result eq 'ok' || $result eq 'ok:') {          if ($result eq 'ok' || $result eq 'ok:') {
             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');              $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]",
                             $plrole,$extent,$uname.':'.$udom).'<br />');
             $count++;              $count++;
         } else {          } else {
             $r->print(              $r->print(
           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).                  &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].",
                       '<br />');                      $plrole,$extent,$uname.':'.$udom,$result).'<br />');
           }
       }
       $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n");
       if ($choice eq 'drop') {
           $r->print('<input type="hidden" name="action" value="listusers" />'."\n".
                     '<input type="hidden" name="Status" value="Active" />'."\n".
                     '<input type="hidden" name="showrole" value="st" />'."\n");
       } else {
           foreach my $item ('action','sortby','roletype','showrole','Status','secfilter','grpfilter') {
               if ($env{'form.'.$item} ne '') {
                   $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.
                             '" />'."\n");
               }
           }
       }
       $r->print('<p><b>'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,no users].",$count).'</b></p>');
       if ($count > 0) {
           if ($choice eq 'revoke' || $choice eq 'drop') {
               $r->print('<p>'.&mt('Re-enabling will re-activate data for the role.</p>'));
           }
           # Flush the course logs so reverse user roles immediately updated
           &Apache::lonnet::flushcourselogs();
       }
       if ($env{'form.makedatesdefault'}) {
           if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
               $r->print(&make_dates_default($startdate,$enddate,$context));
         }          }
     }      }
     $r->print('<p><b>'.&mt('Dropped [_1] user(s).',$count).'</b></p>');      my $linktext = &mt('Display User Lists');
     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);      if ($choice eq 'drop') {
           $linktext = &mt('Display current class roster');
       }
       $r->print('<a href="javascript:document.studentform.submit()">'.$linktext.'</a></form>'."\n");
 }  }
   
 sub section_check_js {  sub classlist_drop {
     my $groupslist;      my ($scope,$uname,$udom,$now) = @_;
     my %curr_groups = &Apache::longroup::coursegroups();      my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)});
     if (%curr_groups) {      if (&Apache::lonnet::is_course($cdom,$cnum)) {
         $groupslist = join('","',sort(keys(%curr_groups)));          my $user = $uname.':'.$udom;
           if (!&active_student_roles($cnum,$cdom,$uname,$udom)) {
               my $result =
                   &Apache::lonnet::cput('classlist',
                                         { $user => $now },$cdom,$cnum);
               return &mt('Drop from classlist: [_1]',
                          '<b>'.$result.'</b>').'<br />';
           }
     }      }
   }
   
   sub active_student_roles {
       my ($cnum,$cdom,$uname,$udom) = @_;
       my %roles =
           &Apache::lonnet::get_my_roles($uname,$udom,'userroles',
                                         ['future','active'],['st']);
       return exists($roles{"$cnum:$cdom:st"});
   }
   
   sub section_check_js {
       my $groupslist= &get_groupslist();
     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+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
Line 2052  sub set_login { Line 4227  sub set_login {
     return $response;      return $response;
 }  }
   
   sub course_sections {
       my ($sections_count,$role,$current_sec) = @_;
       my $output = '';
       my @sections = (sort {$a <=> $b} keys %{$sections_count});
       my $numsec = scalar(@sections);
       my $is_selected = ' selected="selected" ';
       if ($numsec <= 1) {
           $output = '<select name="currsec_'.$role.'" >'."\n".
                     '  <option value="">'.&mt('Select').'</option>'."\n";
           if ($current_sec eq 'none') {
               $output .=       
                     '  <option value=""'.$is_selected.'>'.&mt('No section').'</option>'."\n";
           } else {
               $output .=
                     '  <option value="">'.&mt('No section').'</option>'."\n";
           }
           if ($numsec == 1) {
               if ($current_sec eq $sections[0]) {
                   $output .=
                     '  <option value="'.$sections[0].'"'.$is_selected.'>'.$sections[0].'</option>'."\n";
               } else {
                   $output .=  
                     '  <option value="'.$sections[0].'" >'.$sections[0].'</option>'."\n";
               }
           }
       } else {
           $output = '<select name="currsec_'.$role.'" ';
           my $multiple = 4;
           if (scalar(@sections) < 4) { $multiple = scalar(@sections); }
           if ($role eq 'st') {
               $output .= '>'."\n".
                          '  <option value="">'.&mt('Select').'</option>'."\n";
               if ($current_sec eq 'none') {
                   $output .= 
                          '  <option value=""'.$is_selected.'>'.&mt('No section')."</option>\n";
               } else {
                   $output .=
                          '  <option value="">'.&mt('No section')."</option>\n";
               }
           } else {
               $output .= 'multiple="multiple" size="'.$multiple.'">'."\n";
           }
           foreach my $sec (@sections) {
               if ($current_sec eq $sec) {
                   $output .= '<option value="'.$sec.'"'.$is_selected.'>'.$sec."</option>\n";
               } else {
                   $output .= '<option value="'.$sec.'">'.$sec."</option>\n";
               }
           }
       }
       $output .= '</select>';
       return $output;
   }
   
   sub get_groupslist {
       my $groupslist;
       my %curr_groups = &Apache::longroup::coursegroups();
       if (%curr_groups) {
           $groupslist = join('","',sort(keys(%curr_groups)));
           $groupslist = '"'.$groupslist.'"';
       }
       return $groupslist; 
   }
   
   sub setsections_javascript {
       my ($formname,$groupslist,$mode,$checkauth) = @_;
       my ($checkincluded,$finish,$rolecode,$setsection_js);
       if ($mode eq 'upload') {
           $checkincluded = 'formname.name == "'.$formname.'"';
           $finish = "return 'ok';";
           $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n";
       } elsif ($formname eq 'cu') {
           $checkincluded = 'formname.elements[i-1].checked == true';
           if ($checkauth) {
               $finish = "var authcheck = auth_check();\n".
                         "   if (authcheck == 'ok') {\n".
                         "       formname.submit();\n".
                         "   }\n";
           } else {
               $finish = 'formname.submit()';
           }
           $rolecode = "var match = str.split('_');
                   var role = match[3];\n";
       } elsif ($formname eq 'enrollstudent') {
           $checkincluded = 'formname.name == "'.$formname.'"';
           if ($checkauth) {
               $finish = "var authcheck = auth_check();\n".
                         "   if (authcheck == 'ok') {\n".
                         "       formname.submit();\n".
                         "   }\n";
           } else {
               $finish = 'formname.submit()';
           }
           $rolecode = "var match = str.split('_');
                   var role = match[1];\n";
       } else {
           $checkincluded = 'formname.name == "'.$formname.'"'; 
           $finish = "seccheck = 'ok';";
           $rolecode = "var match = str.split('_');
                   var role = match[1];\n";
           $setsection_js = "var seccheck = 'alert';"; 
       }
       my %alerts = &Apache::lonlocal::texthash(
                       secd => 'Section designations do not apply to Course Coordinator roles.',
                       accr => 'A course 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.',
                       youh => 'You had selected ',
                       secs => 'sections.',
                       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.',
                       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.',
                    );                
       $setsection_js .= <<"ENDSECCODE";
   
   function setSections(formname) {
       var re1 = /^currsec_/;
       var groups = new Array($groupslist);
       for (var i=0;i<formname.elements.length;i++) {
           var str = formname.elements[i].name;
           var checkcurr = str.match(re1);
           if (checkcurr != null) {
               if ($checkincluded) {
                   $rolecode
                   if (role == 'cc') {
                       alert("$alerts{'secd'}\\n$alerts{'accr'}");
                   }
                   else {
                       var sections = '';
                       var numsec = 0;
                       var sections;
                       for (var j=0; j<formname.elements[i].length; j++) {
                           if (formname.elements[i].options[j].selected == true ) {
                               if (formname.elements[i].options[j].value != "") {
                                   if (numsec == 0) {
                                       if (formname.elements[i].options[j].value != "") {
                                           sections = formname.elements[i].options[j].value;
                                           numsec ++;
                                       }
                                   }
                                   else {
                                       sections = sections + "," +  formname.elements[i].options[j].value
                                       numsec ++;
                                   }
                               }
                           }
                       }
                       if (numsec > 0) {
                           if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) {
                               sections = sections + "," +  formname.elements[i+1].value;
                           }
                       }
                       else {
                           sections = formname.elements[i+1].value;
                       }
                       var newsecs = formname.elements[i+1].value;
                       var numsplit;
                       if (newsecs != null && newsecs != "") {
                           numsplit = newsecs.split(/,/g);
                           numsec = numsec + numsplit.length;
                       }
   
                       if ((role == 'st') && (numsec > 1)) {
                           alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}")
                           return;
                       }
                       else {
                           if (numsplit != null) {
                               for (var j=0; j<numsplit.length; j++) {
                                   if ((numsplit[j] == 'all') ||
                                       (numsplit[j] == 'none')) {
                                       alert("'"+numsplit[j]+"' $alerts{'mayn'}\\n$alerts{'plch'}");
                                       return;
                                   }
                                   for (var k=0; k<groups.length; k++) {
                                       if (numsplit[j] == groups[k]) {
                                           alert("'"+numsplit[j]+"' $alerts{'mnot'}\\n$alerts{'secn'}");
                                           return;
                                       }
                                   }
                               }
                           }
                           formname.elements[i+2].value = sections;
                       }
                   }
               }
           }
       }
       $finish
   }
   ENDSECCODE
       return $setsection_js; 
   }
   
   sub can_create_user {
       my ($dom,$context,$usertype) = @_;
       my %domconf = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
       my $cancreate = 1;
       if (&Apache::lonnet::allowed('mau',$dom)) {
           return $cancreate;
       }
       if (ref($domconf{'usercreation'}) eq 'HASH') {
           if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') {
               if ($context eq 'course' || $context eq 'author') {
                   my $creation = $domconf{'usercreation'}{'cancreate'}{$context};
                   if ($creation eq 'none') {
                       $cancreate = 0;
                   } elsif ($creation ne 'any') {
                       if (defined($usertype)) {
                           if ($creation ne $usertype) {
                               $cancreate = 0;
                           }
                       }
                   }
               }
           }
       }
       return $cancreate;
   }
   
   sub can_modify_userinfo {
       my ($context,$dom,$fields,$userroles) = @_;
       my %domconfig =
          &Apache::lonnet::get_dom('configuration',['usermodification'],
                                   $dom);
       my %canmodify;
       if (ref($fields) eq 'ARRAY') {
           foreach my $field (@{$fields}) {
               $canmodify{$field}  = 0;
               if (&Apache::lonnet::allowed('mau',$dom)) {
                   $canmodify{$field} = 1;
               } else {
                   if (ref($domconfig{'usermodification'}) eq 'HASH') {
                       if (ref($domconfig{'usermodification'}{$context}) eq 'HASH') {
                           if (ref($userroles) eq 'ARRAY') {
                               foreach my $role (@{$userroles}) {
                                   my $testrole;
                                   if ($role =~ /^cr\//) {
                                       $testrole = 'cr';
                                   } else {
                                       $testrole = $role;
                                   }
                                   if (ref($domconfig{'usermodification'}{$context}{$testrole}) eq 'HASH') {
                                       if ($domconfig{'usermodification'}{$context}{$testrole}{$field}) {
                                           $canmodify{$field} = 1;
                                           last;
                                       }
                                   }
                               }
                           } else {
                               foreach my $key (keys(%{$domconfig{'usermodification'}{$context}})) {
                                   if (ref($domconfig{'usermodification'}{$context}{$key}) eq 'HASH') {
                                       if ($domconfig{'usermodification'}{$context}{$key}{$field}) {
                                           $canmodify{$field} = 1;
                                           last;
                                       }
                                   }
                               }
                           }
                       }
                   } elsif ($context eq 'course') {
                       if (ref($userroles) eq 'ARRAY') {
                           if (grep(/^st$/,@{$userroles})) {
                               $canmodify{$field} = 1;
                           }
                       } else {
                           $canmodify{$field} = 1;
                       }
                   }
               }
           }
       }
       return %canmodify;
   }
   
   sub check_usertype {
       my ($dom,$uname,$rules) = @_;
       my $usertype;
       if (ref($rules) eq 'HASH') {
           my @user_rules = keys(%{$rules});
           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;
                       }
                   }
               }
           }
       }
       return $usertype;
   }
   
   sub roles_by_context {
       my ($context,$custom) = @_;
       my @allroles;
       if ($context eq 'course') {
           @allroles = ('st','ad','ta','ep','in','cc');
           if ($custom) {
               push(@allroles,'cr');
           }
       } elsif ($context eq 'author') {
           @allroles = ('ca','aa');
       } elsif ($context eq 'domain') {
           @allroles = ('li','dg','sc','au','dc');
       }
       return @allroles;
   }
   
   sub get_permission {
       my ($context,$roles) = @_;
       my %permission;
       if ($context eq 'course') {
           my $custom = 1;
           my @allroles = &roles_by_context($context,$custom);
           foreach my $role (@allroles) {
               if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
                   $permission{'cusr'} = 1;
                   last;
               }
           }
           if (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) {
               $permission{'custom'} = 1;
           }
           if (&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) {
               $permission{'view'} = 1;
           }
           if (!$permission{'view'}) {
               my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
               $permission{'view'} =  &Apache::lonnet::allowed('vcl',$scope);
               if ($permission{'view'}) {
                   $permission{'view_section'} = $env{'request.course.sec'};
               }
           }
           if (!$permission{'cusr'}) {
               if ($env{'request.course.sec'} ne '') {
                   my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
                   $permission{'cusr'} = (&Apache::lonnet::allowed('cst',$scope));
                   if ($permission{'cusr'}) {
                       $permission{'cusr_section'} = $env{'request.course.sec'};
                   }
               }
           }
           if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
               $permission{'grp_manage'} = 1;
           }
       } elsif ($context eq 'author') {
           $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'});
           $permission{'view'} = $permission{'cusr'};
       } else {
           my @allroles = &roles_by_context($context);
           foreach my $role (@allroles) {
               if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
                   $permission{'cusr'} = 1;
                   last;
               }
           }
           if (!$permission{'cusr'}) {
               if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
                   $permission{'cusr'} = 1;
               }
           }
           if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {
               $permission{'custom'} = 1;
           }
           $permission{'view'} = $permission{'cusr'};
       }
       my $allowed = 0;
       foreach my $perm (values(%permission)) {
           if ($perm) { $allowed=1; last; }
       }
       return (\%permission,$allowed);
   }
   
   # ==================================================== Figure out author access
   
   sub authorpriv {
       my ($auname,$audom)=@_;
       unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname))
            || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; }    return 1;
   }
   
   sub roles_on_upload {
       my ($context,$setting,%customroles) = @_;
       my (@possible_roles,@permitted_roles);
       @possible_roles = &curr_role_permissions($context,$setting,1);
       foreach my $role (@possible_roles) {
           if ($role eq 'cr') {
               push(@permitted_roles,keys(%customroles));
           } else {
               push(@permitted_roles,$role);
           }
       }
       return @permitted_roles;
   }
   
   sub get_course_identity {
       my ($cid) = @_;
       my ($cnum,$cdom,$cdesc);
       if ($cid eq '') {
           $cid = $env{'request.course.id'}
       }
       if ($cid ne '') {
           $cnum = $env{'course.'.$cid.'.num'};
           $cdom = $env{'course.'.$cid.'.domain'};
           $cdesc = $env{'course.'.$cid.'.description'};
           if ($cnum eq '' || $cdom eq '') {
               my %coursehash =
                   &Apache::lonnet::coursedescription($cid,{'one_time' => 1});
               $cdom = $coursehash{'domain'};
               $cnum = $coursehash{'num'};
               $cdesc = $coursehash{'description'};
           }
       }
       return ($cnum,$cdom,$cdesc);
   }
   
   sub dc_setcourse_js {
       my ($formname,$mode,$context) = @_;
       my ($dc_setcourse_code,$authen_check);
       my $cctext = &Apache::lonnet::plaintext('cc');
       my %alerts = &sectioncheck_alerts();
       my $role = 'role';
       if ($mode eq 'upload') {
           $role = 'courserole';
       } else {
           $authen_check = &verify_authen($formname,$context);
       }
       $dc_setcourse_code = (<<"SCRIPTTOP");
   $authen_check
   
   function setCourse() {
       var course = document.$formname.dccourse.value;
       if (course != "") {
           if (document.$formname.dcdomain.value != document.$formname.origdom.value) {
               alert("$alerts{'curd'}");
               return;
           }
           var userrole = document.$formname.$role.options[document.$formname.$role.selectedIndex].value
           var section="";
           var numsections = 0;
           var newsecs = new Array();
           for (var i=0; i<document.$formname.currsec.length; i++) {
               if (document.$formname.currsec.options[i].selected == true ) {
                   if (document.$formname.currsec.options[i].value != "" && document.$formname.currsec.options[i].value != null) {
                       if (numsections == 0) {
                           section = document.$formname.currsec.options[i].value
                           numsections = 1;
                       }
                       else {
                           section = section + "," +  document.$formname.currsec.options[i].value
                           numsections ++;
                       }
                   }
               }
           }
           if (document.$formname.newsec.value != "" && document.$formname.newsec.value != null) {
               if (numsections == 0) {
                   section = document.$formname.newsec.value
               }
               else {
                   section = section + "," +  document.$formname.newsec.value
               }
               newsecs = document.$formname.newsec.value.split(/,/g);
               numsections = numsections + newsecs.length;
           }
           if ((userrole == 'st') && (numsections > 1)) {
               alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")
               return;
           }
           for (var j=0; j<newsecs.length; j++) {
               if ((newsecs[j] == 'all') || (newsecs[j] == 'none')) {
                   alert("'"+newsecs[j]+"' $alerts{'mayn'}.\\n$alerts{'plsc'}.");
                   return;
               }
               if (document.$formname.groups.value != '') {
                   var groups = document.$formname.groups.value.split(/,/g);
                   for (var k=0; k<groups.length; k++) {
                       if (newsecs[j] == groups[k]) {
                           alert("'"+newsecs[j]+"' $alerts{'mayt'}.\\n$alerts{'secn'}. $alerts{'plsc'}.");
                           return;
                       }
                   }
               }
           }
           if ((userrole == 'cc') && (numsections > 0)) {
               alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}.");
               section = "";
           }
   SCRIPTTOP
       if ($mode ne 'upload') {
           $dc_setcourse_code .= (<<"ENDSCRIPT");
           var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole
           var numcourse = getIndex(document.$formname.dccourse);
           if (numcourse == "-1") {
               alert("$alerts{'thwa'}");
               return;
           }
           else {
               document.$formname.elements[numcourse].name = "act"+coursename;
               var numnewsec = getIndex(document.$formname.newsec);
               if (numnewsec != "-1") {
                   document.$formname.elements[numnewsec].name = "sec"+coursename;
                   document.$formname.elements[numnewsec].value = section;
               }
               var numstart = getIndex(document.$formname.start);
               if (numstart != "-1") {
                   document.$formname.elements[numstart].name = "start"+coursename;
               }
               var numend = getIndex(document.$formname.end);
               if (numend != "-1") {
                   document.$formname.elements[numend].name = "end"+coursename
               }
           }
       }
       var authcheck = auth_check();
       if (authcheck == 'ok') {
           document.$formname.submit();
       }
   }
   ENDSCRIPT
       } else {
           $dc_setcourse_code .=  "
           document.$formname.sections.value = section;
       }
       return 'ok';
   }
   ";
       }
       $dc_setcourse_code .= (<<"ENDSCRIPT");
   
       function getIndex(caller) {
           for (var i=0;i<document.$formname.elements.length;i++) {
               if (document.$formname.elements[i] == caller) {
                   return i;
               }
           }
           return -1;
       }
   ENDSCRIPT
       return $dc_setcourse_code;
   }
   
   sub verify_authen {
       my ($formname,$context) = @_;
       my %alerts = &authcheck_alerts();
       my $finish = "return 'ok';";
       if ($context eq 'author') {
           $finish = "document.$formname.submit();";
       }
       my $outcome = <<"ENDSCRIPT";
   
   function auth_check() {
       var logintype;
       if (document.$formname.login.length) {
           if (document.$formname.login.length > 0) {
               var loginpicked = 0;
               for (var i=0; i<document.$formname.login.length; i++) {
                   if (document.$formname.login[i].checked == true) {
                       loginpicked = 1;
                       logintype = document.$formname.login[i].value;
                   }
               }
               if (loginpicked == 0) {
                   alert("$alerts{'authen'}");
                   return;
               }
           }
       } else {
           logintype = document.$formname.login.value;
       }
       if (logintype == 'nochange') {
           return 'ok';
       }
       var argpicked = document.$formname.elements[logintype+'arg'].value;
       if ((argpicked == null) || (argpicked == '') || (typeof argpicked == 'undefined')) {
           var alertmsg = '';
           switch (logintype) {
               case 'krb':
                   alertmsg = '$alerts{'krb'}';
                   break;
               case 'int':
                   alertmsg = '$alerts{'ipass'}';
               case 'fsys':
                   alertmsg = '$alerts{'ipass'}';
                   break;
               case 'loc':
                   alertmsg = '';
                   break;
               default:
                   alertmsg = '';
           }
           if (alertmsg != '') {
               alert(alertmsg);
               return;
           }
       }
       $finish
   }
   ENDSCRIPT
   }
   
   sub sectioncheck_alerts {
       my %alerts = &Apache::lonlocal::texthash(
                       curd => 'You must select a course in the current domain',
                       inea => 'In each course, each user may only have one student role at a time',
                       youh => 'You had selected',
                       sect => 'sections',
                       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',
                       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',
                       secn => 'Section names and group names must be distinct',
                       secd => 'Section designations do not apply to ',
                       role => 'roles',
                       accr => 'role will be added with access to all sections',
                       thwa => 'There was a problem with your course selection'
                    );
       return %alerts;
   }
   
   sub authcheck_alerts {
       my %alerts = 
           &Apache::lonlocal::texthash(
                       authen => 'You must choose an authentication type.',
                       krb    => 'You need to specify the Kerberos domain.',
                       ipass  => 'You need to specify the initial password.',
           );
       return %alerts;
   }
   
 1;  1;
   

Removed from v.1.1  
changed lines
  Added in v.1.53


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.