Diff for /loncom/auth/lonroles.pm between versions 1.240.2.19 and 1.315

version 1.240.2.19, 2010/12/05 16:15:02 version 1.315, 2016/10/05 13:30:16
Line 57  course they should act on, etc. Both in Line 57  course they should act on, etc. Both in
 handler determines via C<lonnet>'s C<&allowed> function that a certain  handler determines via C<lonnet>'s C<&allowed> function that a certain
 action is not allowed, C<lonroles> is used as error handler. This  action is not allowed, C<lonroles> is used as error handler. This
 allows the user to select another role which may have permission to do  allows the user to select another role which may have permission to do
 what they were trying to do. C<lonroles> can also be accessed via the  what they were trying to do.
 B<CRS> button in the Remote Control.   
   
 =begin latex  =begin latex
   
Line 129  package Apache::lonroles; Line 128  package Apache::lonroles;
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::lonuserstate();  use Apache::lonuserstate();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common REDIRECT);
 use Apache::File();  use Apache::File();
 use Apache::lonmenu;  use Apache::lonmenu;
 use Apache::loncommon;  use Apache::loncommon;
Line 139  use Apache::lonlocal; Line 138  use Apache::lonlocal;
 use Apache::lonpageflip();  use Apache::lonpageflip();
 use Apache::lonnavdisplay();  use Apache::lonnavdisplay();
 use Apache::loncoursequeueadmin;  use Apache::loncoursequeueadmin;
   use Apache::longroup;
   use Apache::lonrss;
   use Apache::lonplacementtest;
 use GDBM_File;  use GDBM_File;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities;  use HTML::Entities;
    
   
 sub redirect_user {  sub redirect_user {
     my ($r,$title,$url,$msg,$launch_nav) = @_;      my ($r,$title,$url,$msg) = @_;
     $msg = $title if (! defined($msg));      $msg = $title if (! defined($msg));
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     &Apache::loncommon::no_cache($r);      &Apache::loncommon::no_cache($r);
     $r->send_http_header;      $r->send_http_header;
     my $swinfo=&Apache::lonmenu::rawconfig();  
     my $navwindow;  
     if ($launch_nav eq 'on') {  
  $navwindow.=&Apache::lonnavdisplay::launch_win('now',undef,undef,  
        ($url =~ m-^/adm/whatsnew-));  
     } else {  
  $navwindow.=&Apache::lonnavmaps::close();  
     }  
   
     # Breadcrumbs      # Breadcrumbs
     my $brcrum = [{'href' => $url,      my $brcrum = [{'href' => $url,
Line 165  sub redirect_user { Line 159  sub redirect_user {
     my $start_page = &Apache::loncommon::start_page('Switching Role',undef,      my $start_page = &Apache::loncommon::start_page('Switching Role',undef,
                                                     {'redirect' => [1,$url],                                                      {'redirect' => [1,$url],
                                                      'bread_crumbs' => $brcrum,});                                                       'bread_crumbs' => $brcrum,});
     &Apache::lonhtmlcommon::clear_breadcrumbs();  
     my $end_page   = &Apache::loncommon::end_page();      my $end_page   = &Apache::loncommon::end_page();
   
 # Note to style police:   # Note to style police: 
Line 173  sub redirect_user { Line 166  sub redirect_user {
     $url=~s/ /\%20/g;      $url=~s/ /\%20/g;
     $r->print(<<ENDREDIR);      $r->print(<<ENDREDIR);
 $start_page  $start_page
 <script type="text/javascript">  
 // <![CDATA[  
 $swinfo  
 // ]]>  
 </script>  
 $navwindow  
 <p>$msg</p>  <p>$msg</p>
 $end_page  $end_page
 ENDREDIR  ENDREDIR
Line 216  sub handler { Line 203  sub handler {
   
     my $r = shift;      my $r = shift;
   
       # Check for critical messages and redirect if present.
       my ($redirect,$url) = &Apache::loncommon::critical_redirect(300);
       if ($redirect) {
           &Apache::loncommon::content_type($r,'text/html');
           $r->header_out(Location => $url);
           return REDIRECT;
       }
   
     my $now=time;      my $now=time;
     my $then=$env{'user.login.time'};      my $then=$env{'user.login.time'};
     my $refresh=$env{'user.refresh.time'};      my $refresh=$env{'user.refresh.time'};
       my $update=$env{'user.update.time'};
     if (!$refresh) {      if (!$refresh) {
         $refresh = $then;          $refresh = $then;
     }      }
       if (!$update) {
           $update = $then;
       }
   
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
   
   # -------------------------------------------------- Check if setting hot list 
       my $hotlist;
       if ($env{'form.action'} eq 'verify_and_change_rolespref') {
           $hotlist = &Apache::lonpreferences::verify_and_change_rolespref($r);
       }
   
   # -------------------------------------------------------- Check for new roles
       my $updateresult;
       if ($env{'form.state'} eq 'doupdate') {
           my $show_course=&Apache::loncommon::show_course();
           my $checkingtxt;
           if ($show_course) {
               $checkingtxt = &mt('Checking for new courses ...');
           } else {
               $checkingtxt = &mt('Checking for new roles ...');
           }
           $updateresult = $checkingtxt;
           $updateresult .= &update_session_roles();
           &Apache::lonnet::appenv({'user.update.time'  => $now});
           $update = $now;
           &Apache::loncoursequeueadmin::reqauthor_check();
       }
   
   # -------------------------------------------------- Check for author requests
       my $reqauthor;
       if ($env{'form.state'} eq 'requestauthor') {
          $reqauthor = &Apache::loncoursequeueadmin::process_reqauthor(\$update);
       }
   
     my $envkey;      my $envkey;
     my %dcroles = ();      my %dcroles = ();
     my $numdc = &check_fordc(\%dcroles,$then);      my $numdc = &check_fordc(\%dcroles,$update,$then);
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      my $loncaparev = $r->dir_config('lonVersion');
     my $custommenu = &Apache::loncommon::needs_gci_custom();  
   
 # ================================================================== Roles Init  # ================================================================== Roles Init
     if ($env{'form.selectrole'}) {      if ($env{'form.selectrole'}) {
Line 234  sub handler { Line 264  sub handler {
         my $locknum=&Apache::lonnet::get_locks();          my $locknum=&Apache::lonnet::get_locks();
         if ($locknum) { return 409; }          if ($locknum) { return 409; }
   
           my $custom_adhoc;
         if ($env{'form.newrole'}) {          if ($env{'form.newrole'}) {
             $env{'form.'.$env{'form.newrole'}}=1;              $env{'form.'.$env{'form.newrole'}}=1;
   # Check if this is a Domain Helpdesk role trying to enter a course
               if ($env{'form.newrole'} =~ m{^cr/($match_domain)/\1\-domainconfig/\w+\./\1/$match_courseid$}) {
                   if (&Apache::lonnet::allowed('rar',$1)) {
                       $custom_adhoc = 1;
                   }
               }
  }   }
  if ($env{'request.course.id'}) {   if ($env{'request.course.id'}) {
             # Check if user is CC trying to select a course role              # Check if user is CC trying to select a course role
             if ($env{'form.switchrole'}) {              if ($env{'form.switchrole'}) {
                 if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {                  my $switch_is_active;
                     &adhoc_course_role($refresh,$then);                  if (defined($env{'user.role.'.$env{'form.switchrole'}})) {
                       my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
                       if (!$end || $end > $now) {
                           if (!$start || $start < $update) {
                               $switch_is_active = 1;
                           }
                       }
                   }
                   unless ($switch_is_active) {
                       &adhoc_course_role($refresh,$update,$then);
                 }                  }
             }              }
     my %temp=('logout_'.$env{'request.course.id'} => time);      my %temp=('logout_'.$env{'request.course.id'} => time);
     &Apache::lonnet::put('email_status',\%temp);      &Apache::lonnet::put('email_status',\%temp);
     &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});      &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});
  }   }
  &Apache::lonnet::appenv({"request.course.id"   => '',   &Apache::lonnet::appenv({"request.course.id"           => '',
  "request.course.fn"   => '',   "request.course.fn"           => '',
  "request.course.uri"  => '',   "request.course.uri"          => '',
  "request.course.sec"  => '',   "request.course.sec"          => '',
  "request.role"        => 'cm',                                   "request.course.tied"         => '',
                                  "request.role.adv"    => $env{'user.adv'},                                   "request.course.timechecked"  => '',
  "request.role.domain" => $env{'user.domain'}});   "request.role"                => 'cm',
                                    "request.role.adv"            => $env{'user.adv'},
    "request.role.domain"         => $env{'user.domain'}});
   # Check if Domain Helpdesk role trying to enter a course needs privs to be created
           if ($env{'form.newrole'} =~ m{^cr/($match_domain)/\1\-domainconfig/(\w+)\./\1/($match_courseid)$}) {
               my $cdom = $1;
               my $rolename = $2;
               my $cnum = $3;
               if ($custom_adhoc) {
                   my %adhocroles = &Apache::lonnet::userenvironment($env{'user.domain'},$env{'user.name'},
                                                                     'adhocroles.'.$cdom);
                   if (keys(%adhocroles)) {
                       my @adhoc = split(',',$adhocroles{'adhocroles.'.$cdom});
                       if (grep(/^\Q$rolename\E$/,@adhoc)) {
                           if (&Apache::lonnet::check_adhoc_privs($cdom,$cnum,$update,$refresh,$now,
                                                                  "cr/$cdom/$cdom".'-domainconfig/'.$rolename)) {
                               &Apache::lonnet::appenv({"environment.internal.$cdom.$cnum.cr/$cdom/$cdom".'-domainconfig'."$rolename.adhoc" => time});
                           }
                       }
                   }
               }
           } elsif ($numdc > 0) {
 # Check if user is a DC trying to enter a course or author space and needs privs to be created  # Check if user is a DC trying to enter a course or author space and needs privs to be created
         if ($numdc > 0) {              foreach my $envkey (keys(%env)) {
             foreach my $envkey (keys %env) {  
 # Is this an ad-hoc Coordinator role?  # Is this an ad-hoc Coordinator role?
                 if (my ($ccrole,$domain,$coursenum) =                  if (my ($ccrole,$domain,$coursenum) =
     ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {      ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {
                     if ($dcroles{$domain}) {                      if ($dcroles{$domain}) {
                         &Apache::lonnet::check_adhoc_privs($domain,$coursenum,                          if (&Apache::lonnet::check_adhoc_privs($domain,$coursenum,
                                                            $then,$refresh,$now,$ccrole);                                                             $update,$refresh,$now,$ccrole)) {
                               &Apache::lonnet::appenv({"environment.internal.$domain.$coursenum.$ccrole.adhoc" => time});
                           }
                     }                      }
                     last;                      last;
                 }                  }
Line 276  sub handler { Line 344  sub handler {
                         my ($server_status,$home) = &check_author_homeserver($user,$domain);                          my ($server_status,$home) = &check_author_homeserver($user,$domain);
                         if ($server_status eq 'switchserver') {                          if ($server_status eq 'switchserver') {
                             my $trolecode = 'au./'.$domain.'/';                              my $trolecode = 'au./'.$domain.'/';
                             my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;                              my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                             $r->internal_redirect($switchserver);                              $r->internal_redirect($switchserver);
                               return OK;
                         }                          }
                         last;                          last;
                     }                      }
Line 287  sub handler { Line 356  sub handler {
                             my ($server_status,$home) = &check_author_homeserver($user,$domain);                              my ($server_status,$home) = &check_author_homeserver($user,$domain);
                             if ($server_status eq 'switchserver') {                              if ($server_status eq 'switchserver') {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                  my $trolecode = 'ca./'.$domain.'/'.$user;
                                 my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;                                  my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                             last;                              last;
                         }                          }
Line 303  sub handler { Line 373  sub handler {
                     if ($dcroles{$domain}) {                      if ($dcroles{$domain}) {
                         my ($server_status,$home) = &check_author_homeserver($user,$domain);                          my ($server_status,$home) = &check_author_homeserver($user,$domain);
                         if (($server_status eq 'ok') || ($server_status eq 'switchserver')) {                          if (($server_status eq 'ok') || ($server_status eq 'switchserver')) {
                             &Apache::lonnet::check_adhoc_privs($domain,$user,$then,                              &Apache::lonnet::check_adhoc_privs($domain,$user,$update,
                                                                $refresh,$now,'ca');                                                                 $refresh,$now,'ca');
                             if ($server_status eq 'switchserver') {                              if ($server_status eq 'switchserver') {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                   my $trolecode = 'ca./'.$domain.'/'.$user; 
                                 my $switchserver = '/adm/switchserver?'                                  my $switchserver = '/adm/switchserver?'
                                                   .'otherserver='.$home.'&role='.$trolecode;                                                    .'otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                         } else {                          } else {
                             delete($env{$envkey});                              delete($env{$envkey});
Line 321  sub handler { Line 392  sub handler {
                 }                  }
             }              }
         }          }
         if (($env{'form.cm'}) && ($env{'form.orgurl'})) {   
             $r->internal_redirect($env{'form.orgurl'});          foreach $envkey (keys(%env)) {
         }  
         foreach $envkey (keys %env) {  
             next if ($envkey!~/^user\.role\./);              next if ($envkey!~/^user\.role\./);
             my ($where,$trolecode,$role,$tstatus,$tend,$tstart);              my ($where,$trolecode,$role,$tstatus,$tend,$tstart);
             &Apache::lonnet::role_status($envkey,$then,$refresh,$now,\$role,\$where,              &Apache::lonnet::role_status($envkey,$update,$refresh,$now,\$role,\$where,
                                          \$trolecode,\$tstatus,\$tstart,\$tend);                                           \$trolecode,\$tstatus,\$tstart,\$tend);
             if ($env{'form.'.$trolecode}) {              if ($env{'form.'.$trolecode}) {
  if ($tstatus eq 'is') {   if ($tstatus eq 'is') {
     $where=~s/^\///;      $where=~s/^\///;
     my ($cdom,$cnum,$csec)=split(/\//,$where);      my ($cdom,$cnum,$csec)=split(/\//,$where);
                       if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {
                           my $home = $env{'course.'.$cdom.'_'.$cnum.'.home'};
                           my @ids = &Apache::lonnet::current_machine_ids();
                           unless ($loncaparev eq '' && $home && grep(/^\Q$home\E$/,@ids)) {
                               my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
                               if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
                                   my ($switchserver,$switchwarning) =
                                       &Apache::loncommon::check_release_required($loncaparev,$cdom.'_'.$cnum,$trolecode,
                                                                                  $curr_reqd_hash{'internal.releaserequired'});
                                   if ($switchwarning ne '' || $switchserver ne '') {
                                       &Apache::loncommon::content_type($r,'text/html');
                                       &Apache::loncommon::no_cache($r);
                                       $r->send_http_header;
                                       $r->print(&Apache::loncommon::check_release_result($switchwarning,$switchserver));
                                       return OK;
                                   }
                               }
                           }
                       }
 # check for course groups  # check for course groups
                     my %coursegroups = &Apache::lonnet::get_active_groups(                      my %coursegroups = &Apache::lonnet::get_active_groups(
                           $env{'user.domain'},$env{'user.name'},$cdom, $cnum);                            $env{'user.domain'},$env{'user.name'},$cdom, $cnum);
Line 450  ENDENTERKEY Line 538  ENDENTERKEY
   
     if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {      if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {
                         my $msg;                          my $msg;
                         if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }  
                         &Apache::lonnet::appenv({'request.role.adv'=>$tadv});  
  my ($furl,$ferr)=   my ($furl,$ferr)=
     &Apache::lonuserstate::readmap($cdom.'/'.$cnum);      &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                         if ($custommenu) {                          unless ($ferr) {
                             unless (($ferr) || ($env{'form.switchrole'})) {                              unless (($env{'form.switchrole'}) || 
                                 &Apache::lonnet::put('nohist_crslastlogin',{$env{'user.name'}.':'.$env{'user.domain'}.':'.$csec.':'.$role => $now},                                      ($env{"environment.internal.$cdom.$cnum.$role.adhoc"})) {
                                                      $cdom,$cnum);                                  &Apache::lonnet::put('nohist_crslastlogin',
                                       {$env{'user.name'}.':'.$env{'user.domain'}.
                                        ':'.$csec.':'.$role => $now},$cdom,$cnum);
                               }
                               my ($feeds,$syllabus_time);
                               &Apache::lonrss::advertisefeeds($cnum,$cdom,undef,\$feeds);
                               &Apache::lonnet::appenv({'request.course.feeds' => $feeds});
                               &Apache::lonnet::get_numsuppfiles($cnum,$cdom,1);
                               unless ($env{'course.'.$cdom.'_'.$cnum.'.updatedsyllabus'}) {
                                   unless (($env{'course.'.$cdom.'_'.$cnum.'.externalsyllabus'}) ||
                                           ($env{'course.'.$cdom.'_'.$cnum.'.uploadedsyllabus'})) {
                                       my %syllabus=&Apache::lonnet::dump('syllabus',$cdom,$cnum);
                                       $syllabus_time = $syllabus{'uploaded.lastmodified'};
                                       if ($syllabus_time) {
                                           &Apache::lonnet::appenv({'request.course.syllabustime' => $syllabus_time});
                                       }
                                   }
                             }                              }
                         }                          }
  if (($env{'form.orgurl'}) &&    if (($env{'form.orgurl'}) && 
     ($env{'form.orgurl'}!~/^\/adm\/flip/)) {      ($env{'form.orgurl'}!~/^\/adm\/flip/) &&
       ($env{'form.orgurl'} ne '/adm/roles')) {
     my $dest=$env{'form.orgurl'};      my $dest=$env{'form.orgurl'};
                             if ($env{'form.symb'}) {                              if ($env{'form.symb'}) {
                                 if ($dest =~ /\?/) {                                  if ($dest =~ /\?/) {
                                     $dest .= '&';                                      $dest .= '&';
                                 } else {                                  } else {
                                     $dest .= '?'                                      $dest .= '?';
                                 }                                  }
                                 $dest .= 'symb='.$env{'form.symb'};                                  $dest .= 'symb='.$env{'form.symb'};
                             }                              }
       if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }
       &Apache::lonnet::appenv({'request.role.adv'=>$tadv});
                             if (($ferr) && ($tadv)) {                              if (($ferr) && ($tadv)) {
  &error_page($r,$ferr,$dest);   &error_page($r,$ferr,$dest);
     } else {      } else {
                                   if ($dest =~ m{^/adm/coursedocs\?folderpath}) {
                                       if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { 
                                           my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
                                           &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,
                                                                                          $cdom.'_'.$cnum);
                                       }
                                   }
  $r->internal_redirect($dest);   $r->internal_redirect($dest);
     }      }
     return OK;      return OK;
Line 489  ENDENTERKEY Line 601  ENDENTERKEY
                     .'<p>'.&mt('Please try again.').'</p>'                      .'<p>'.&mt('Please try again.').'</p>'
                     .'<p>'.$ferr.'</p>';                      .'<p>'.$ferr.'</p>';
     }      }
       if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }
       &Apache::lonnet::appenv({'request.role.adv'=>$tadv});
   
     if (($ferr) && ($tadv)) {      if (($ferr) && ($tadv)) {
  &error_page($r,$ferr,$furl);   &error_page($r,$ferr,$furl);
     } else {      } else {
  # Check to see if the user is a CC entering a course    # Check to see if the user is a CC entering a course 
  # for the first time   # for the first time
  my (undef, undef, $role, $courseid) = split(/\./, $envkey);   if ((($role eq 'cc') || ($role eq 'co')) 
  if (substr($courseid, 0, 1) eq '/') {                                      && ($env{'course.'.$cdom.'_'.$cnum.'.course.helper.not.run'})) { 
     $courseid = substr($courseid, 1);  
  }  
  $courseid =~ s/\//_/;  
  if (($cdom ne 'gcitest') && (($role eq 'cc') || ($role eq 'co'))   
                                     && ($env{'course.' . $courseid .'.course.helper.not.run'})) {   
     $furl = "/adm/helper/course.initialization.helper";      $furl = "/adm/helper/course.initialization.helper";
     # Send the user to the course they selected      # Send the user to the course they selected
  } elsif ($env{'request.course.id'}) {   } elsif ($env{'request.course.id'}) {
                                     if ($env{'form.destinationurl'}) {                                      if ((&Apache::loncommon::course_type() eq 'Placement') && 
                                         my $dest = $env{'form.destinationurl'};                                          (!$env{'request.role.adv'})) {
                                         if ($env{'form.destsymb'} ne '') {                                          my ($score,$incomplete) = 
                                             my $esc_symb = &HTML::Entities::encode($env{'form.destsymb'},'"<>&');                                              &Apache::lonplacementtest::check_completion(undef,undef,1);
                                             $dest .= '?symb='.$esc_symb;                                          if (($incomplete) && ($incomplete < 100)) {
                                               &redirect_user($r, &mt('Entering [_1]',
                                                             $env{'course.'.$cdom.'_'.$cnum.'.description'}),
                                                             '/adm/placement', $msg);
                                               return OK;
                                         }                                          }
                                         &redirect_user($r,&mt('Entering [_1]',                                      }
                                                       $env{'course.'.$courseid.'.description'}),                                      my ($dest,$destsymb,$checkenc);
                                                $dest,$msg,                                      $dest = $env{'form.destinationurl'};
                                                $env{'environment.remotenavmap'});                                      $destsymb = $env{'form.destsymb'};
                                       if ($dest ne '') {
                                           if ($env{'form.switchrole'}) {
                                               if ($destsymb ne '') {
                                                   if ($destsymb !~ m{^/enc/}) {
                                                       unless ($env{'request.role.adv'}) {
                                                           $checkenc = 1;
                                                       }
                                                   }
                                               }
                                               if ($dest =~ m{^/enc/}) {
                                                   if ($env{'request.role.adv'}) {
                                                       $dest = &Apache::lonenc::unencrypted($dest);
                                                       if ($destsymb eq '') {
                                                           ($destsymb) = ($dest =~ /(?:\?|\&)symb=([^\&]*)/);
                                                           $destsymb = &unescape($destsymb);
                                                       }
                                                   }
                                               } else {
                                                   if ($destsymb eq '') {
                                                       ($destsymb) = ($dest =~ /(?:\?|\&)symb=([^\&]+)/);
                                                       $destsymb = &unescape($destsymb);
                                                   }
                                                   unless ($env{'request.role.adv'}) {
                                                       $checkenc = 1;
                                                   }
                                               }
                                               if (($checkenc) && ($destsymb ne '')) {
                                                   my ($encstate,$unencsymb,$res);
                                                   $unencsymb = &Apache::lonnet::symbclean($destsymb);
                                                   (undef,undef,$res) = &Apache::lonnet::decode_symb($unencsymb);
                                                   &Apache::lonnet::symbverify($unencsymb,$res,\$encstate);
                                                   if ($encstate) {
                                                       if (($dest ne '') && ($dest !~ m{^/enc/})) {
                                                           $dest=&Apache::lonenc::encrypted($dest);
                                                       }
                                                   }
                                               }
                                           }
                                           unless (($dest =~ m{^/enc/}) || ($dest =~ /(\?|\&)symb=.+___\d+___.+/)) {
                                               if (($destsymb ne '') && ($destsymb !~ m{^/enc/})) {
                                                   my $esc_symb = &escape($destsymb);
                                                   $dest .= '?symb='.$esc_symb;
                                               }
                                           }
                                           &redirect_user($r, &mt('Entering [_1]',
                                                          $env{'course.'.$cdom.'_'.$cnum.'.description'}),
                                                          $dest, $msg);
                                         return OK;                                          return OK;
                                     }                                      }
     if (&Apache::lonnet::allowed('whn',      if (&Apache::lonnet::allowed('whn',
Line 523  ENDENTERKEY Line 683  ENDENTERKEY
     $env{'request.course.id'}.'/'      $env{'request.course.id'}.'/'
     .$env{'request.course.sec'})      .$env{'request.course.sec'})
  ) {   ) {
  my $startpage = &courseloadpage($courseid);   my $startpage = &courseloadpage($env{'request.course.id'});
  unless (($startpage eq 'firstres') || ($cdom eq 'gcitest')) {   unless ($startpage eq 'firstres') {         
     $msg = &mt('Entering [_1] ...',      $msg = &mt('Entering [_1] ...',
        $env{'course.'.$courseid.'.description'});         $env{'course.'.$env{'request.course.id'}.'.description'});
     &redirect_user($r,&mt('New in course'),      &redirect_user($r, &mt('New in course'),
    '/adm/whatsnew?refpage=start',$msg,                                         '/adm/whatsnew?refpage=start', $msg);
    $env{'environment.remotenavmap'});  
     return OK;      return OK;
  }   }
     }      }
  }   }
 # Are we allowed to look at the first resource?                                  # Are we allowed to look at the first resource?
  if ($furl !~ m|^/adm/|) {                                  my $access;
 # Guess not ...                                  if ($furl =~ m{^(/adm/wrapper|)/ext/}) {
     $furl=&Apache::lonpageflip::first_accessible_resource();                                      # If it's an external resource,
  }                                      # strip off the symb argument and possible query
                                 if (($cdom eq 'gcitest') && ($custommenu)) {                                      my ($exturl,$symb) = ($furl =~ m{^(.+)(?:\?|\&)symb=(.+)$});
                                     $furl = '/adm/navmaps';                                      # Unencode $symb
                                       $symb = &unescape($symb);
                                       # Then check for permission
                                       $access = &Apache::lonnet::allowed('bre',$exturl,$symb);
                                   # For other resources just check for permission
                                   } else {
                                       $access = &Apache::lonnet::allowed('bre',$furl);
                                   }
                                   if (!$access) {
                                       $furl = &Apache::lonpageflip::first_accessible_resource();
                                   } elsif ($access eq 'B') {
                                       $furl = '/adm/navmaps?showOnlyHomework=1';
                                 }                                  }
                                 $msg = &mt('Entering [_1] ...',                                  $msg = &mt('Entering [_1] ...',
    $env{'course.'.$courseid.'.description'});     $env{'course.'.$cdom.'_'.$cnum.'.description'});
  &redirect_user($r,&mt('Entering [_1]',   &redirect_user($r, &mt('Entering [_1]',
       $env{'course.'.$courseid.'.description'}),                                 $env{'course.'.$cdom.'_'.$cnum.'.description'}),
        $furl,$msg,                                 $furl, $msg);
        $env{'environment.remotenavmap'});  
     }      }
     return OK;      return OK;
  }   }
Line 557  ENDENTERKEY Line 726  ENDENTERKEY
                     if ($role =~ /^(au|ca|aa)$/) {                      if ($role =~ /^(au|ca|aa)$/) {
                         my $redirect_url = '/priv/';                          my $redirect_url = '/priv/';
                         if ($role eq 'au') {                          if ($role eq 'au') {
                             $redirect_url.=$env{'user.name'};                              $redirect_url.=$env{'user.domain'}.'/'.$env{'user.name'};
                         } else {                          } else {
                             $where =~ /\/(.*)$/;                              $redirect_url .= $where;
                             $redirect_url .= $1;  
                         }                          }
                         $redirect_url .= '/';                          $redirect_url .= '/';
                         &redirect_user($r,&mt('Entering Construction Space'),                          &redirect_user($r,&mt('Entering Authoring Space'),
                                        $redirect_url);                                         $redirect_url);
                         return OK;                          return OK;
                     }                      }
Line 573  ENDENTERKEY Line 741  ENDENTERKEY
                                        $redirect_url);                                         $redirect_url);
                         return OK;                          return OK;
                     }                      }
                       if ($role eq 'dh') {
                           my $redirect_url = '/adm/menu/';
                           &redirect_user($r,&mt('Loading Domain Helpdesk Menu'),
                                          $redirect_url);
                           return OK;
                       }
                     if ($role eq 'sc') {                      if ($role eq 'sc') {
                         my $redirect_url = '/adm/grades?command=scantronupload';                          my $redirect_url = '/adm/grades?command=scantronupload';
                         &redirect_user($r,&mt('Loading Data Upload Page'),                          &redirect_user($r,&mt('Loading Data Upload Page'),
Line 584  ENDENTERKEY Line 758  ENDENTERKEY
         }          }
     }      }
   
   
 # =============================================================== No Roles Init  # =============================================================== No Roles Init
   
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
Line 591  ENDENTERKEY Line 766  ENDENTERKEY
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
   
     my ($crumbtext,$pagetitle,$recent,$show_course);      my $crumbtext = 'User Roles';
     $show_course=&Apache::loncommon::show_course();      my $pagetitle = 'My Roles';
     my $noscript='<br /><span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';      my $recent = &mt('Recent Roles');
     if ($custommenu) {      my $standby = &mt('Role selected. Please stand by.');
         my $start_page = &Apache::loncommon::start_page('Main Menu');      my $show_course=&Apache::loncommon::show_course();
         $r->print(<<"ENDCUSTOM");      if ($show_course) {
 $start_page          $crumbtext = 'Courses';
 <noscript>          $pagetitle = 'My Courses';
 $noscript          $recent = &mt('Recent Courses');
 </noscript>          $standby = &mt('Course selected. Please stand by.'); 
 ENDCUSTOM      }
     } else {      my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}];
         $crumbtext = 'User Roles';  
         $pagetitle = 'My Roles';      my %roles_in_env;
         $recent = &mt('Recent Roles');      my $showcount = &roles_from_env(\%roles_in_env,$update); 
         my $standby=&mt('Role selected. Please stand by.');  
         if ($show_course) {      my $swinfo=&Apache::lonmenu::rawconfig();
             $crumbtext = 'Courses';      my %domdefs=&Apache::lonnet::get_domain_defaults($env{'user.domain'}); 
             $pagetitle = 'My Courses';      my $cattype = 'std';
             $recent = &mt('Recent Courses');      if ($domdefs{'catauth'}) {
             $standby = &mt('Course selected. Please stand by.');          $cattype = $domdefs{'catauth'};
         }      }
         my $brcrum = [{ href    => '/adm/roles',      my $placementonly;
                          text    => $crumbtext,},      if ($showcount == 1) {
                      ];          if ($env{'request.course.id'}) {
         my $args;              if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') {
         if ($numdc) {                  $placementonly = 1;
             $args = {bread_crumbs => $brcrum};              }
         } else {          } else {
             $args = {bread_crumbs          => $brcrum,              foreach my $rolecode (keys(%roles_in_env)) {
                      bread_crumbs_menulink => '_nomenu'};                  my ($cid) = ($rolecode =~ m{^\Quser.role.st./\E($match_domain/$match_courseid)(?:/|$)});
                   if ($cid) {
                       my %coursedescription =
                           &Apache::lonnet::coursedescription($cid,{'one_time' => '1'});
                       if ($coursedescription{'type'} eq 'Placement') {
                           $placementonly = 1;
                       }
                       last;
                   }
               }
           }
       }
       my ($start_page,$funcs);
       if ($placementonly) {
           $start_page=&Apache::loncommon::start_page($pagetitle,undef,
                                                     {bread_crumbs=>$brcrum,crstype=>'Placement'});
       } else {
           $funcs = &get_roles_functions($showcount,$cattype);
           my $crumbsright;
           if ($env{'browser.mobile'}) {
               $crumbsright = $funcs;
               undef($funcs);
         }          }
         my $start_page=&Apache::loncommon::start_page($pagetitle,undef,$args);          $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum,
         my $swinfo=&Apache::lonmenu::rawconfig();                                                                       bread_crumbs_component=>$crumbsright});
         $standby=~s/\n/\\n/g;      }
         $r->print(<<ENDHEADER);      &js_escape(\$standby);
       my $noscript='<br /><span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';
   
       $r->print(<<ENDHEADER);
 $start_page  $start_page
   $funcs
 <noscript>  <noscript>
 $noscript  $noscript
 </noscript>  </noscript>
Line 647  function enterrole (thisform,rolecode,bu Line 847  function enterrole (thisform,rolecode,bu
  thisform.submit();   thisform.submit();
     } else {      } else {
        alert('$standby');         alert('$standby');
     }         }
 }  }
   
   function rolesView (caller) {
       if ((caller == 'showall') || (caller == 'noshowall')) {
           document.rolechoice.display.value = caller;
       } else {
           if ((caller == 'doupdate') || (caller == 'requestauthor') ||
               (caller == 'queued')) { 
               document.rolechoice.state.value = caller;
           }
       }
       document.rolechoice.selectrole.value='';
       document.rolechoice.submit();
   }
   
 // ]]>  // ]]>
 </script>  </script>
 ENDHEADER  ENDHEADER
     }  
   
 # ------------------------------------------ Get Error Message from Environment  # ------------------------------------------ Get Error Message from Environment
   
Line 710  ENDHEADER Line 923  ENDHEADER
     }      }
         }          }
     }      }
 # -------------------------------------------------------- Choice or no choice?  
     if ($nochoose) {      if ($nochoose) {
  $r->print("<h2>".&mt('Sorry ...')."</h2>\n<span class='LC_error'>".   $r->print("<h2>".&mt('Sorry ...')."</h2>\n<span class='LC_error'>".
   &mt('This action is currently not authorized.').'</span>'.    &mt('This action is currently not authorized.').'</span>'.
   &Apache::loncommon::end_page());    &Apache::loncommon::end_page());
  return OK;   return OK;
     } else {      } else {
           if ($updateresult || $reqauthor || $hotlist) {
               my $showresult = '<div>';
               if ($updateresult) {
                   $showresult .= &Apache::lonhtmlcommon::confirm_success($updateresult);
               }
               if ($reqauthor) {
                   $showresult .= &Apache::lonhtmlcommon::confirm_success($reqauthor);
               }
               if ($hotlist) {
                   $showresult .= $hotlist;
               } 
               $showresult .= '</div>';
               $r->print($showresult);
           } elsif ($env{'form.state'} eq 'queued') {
               $r->print(&get_queued());
           }
         if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) {          if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) {
        $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'};         $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'};
         }          }
         unless ($custommenu) {          my $display = ($env{'form.display'} =~ /^(showall)$/);
             $r->print('<form method="post" name="rolechoice" action="'.(($fn)?$fn:$r->uri).'">');          $r->print('<form method="post" name="rolechoice" action="'.(($fn)?$fn:$r->uri).'">');
             $r->print('<input type="hidden" name="orgurl" value="'.$fn.'" />');          $r->print('<input type="hidden" name="orgurl" value="'.$fn.'" />');
             $r->print('<input type="hidden" name="selectrole" value="1" />');          $r->print('<input type="hidden" name="selectrole" value="1" />');
             $r->print('<input type="hidden" name="newrole" value="" />');          $r->print('<input type="hidden" name="newrole" value="" />');
         }          $r->print('<input type="hidden" name="display" value="'.$display.'" />');
           $r->print('<input type="hidden" name="state" value="" />');
     }      }
       $r->rflush();
   
     my (%roletext,%sortrole,%roleclass,%futureroles,%timezones);      my (%roletext,%sortrole,%roleclass,%futureroles,%timezones);
     my ($countactive,$countfuture,$inrole,$possiblerole) =       my ($countactive,$countfuture,$inrole,$possiblerole) = 
         &gather_roles($then,$refresh,$now,$reinit,$nochoose,\%roletext,\%sortrole,\%roleclass,          &gather_roles($update,$refresh,$now,$reinit,$nochoose,\%roles_in_env,\%roletext,
                       \%futureroles,\%timezones);                        \%sortrole,\%roleclass,\%futureroles,\%timezones,$loncaparev);
   
     $refresh = $now;      $refresh = $now;
     &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});      &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});
     if (!$countactive && !$countfuture) {      if ($countactive == 1) {
         if (&Apache::loncommon::new_roles_update()) {          if ($env{'request.course.id'}) {
             ($countactive,$countfuture,$inrole,$possiblerole) =              if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') {
                 &gather_roles($then,$refresh,$now,$reinit,$nochoose,\%roletext,\%sortrole,                  $placementonly = 1;
                               \%roleclass,\%futureroles,\%timezones);              }
         }          } elsif ($possiblerole) {
     }              if ($possiblerole =~ m{^st\./($match_domain)/($match_courseid)(?:/|$)}) {
     if ($custommenu) {                  if ($env{'course.'.$1.'_'.$2.'.type'} eq 'Placement') {
         if ($env{'form.destinationurl'} eq '/adm/gci_info') {                      $placementonly = 1;
             $r->print(&gci_info_page()).                  }
             &Apache::loncommon::end_page();              }
             return OK;  
         }  
         my %courses = &Apache::loncommon::existing_gcitest_courses('cc');  
         $env{'browser.interface'}='faketextual';  
         $env{'environment.remote'}='off';  
         my $numcourses = keys(%courses);  
         my $switcher;  
         if ($numcourses > 0) {  
             $switcher = &Apache::loncommon::gcitest_switcher('cc',%courses);  
             my $current;  
             if ($env{'request.course.id'}) {  
                 $current = 'cc./'.$env{'course.'.$env{'request.course.id'}.'.domain'}.  
                            '/'.$env{'course.'.$env{'request.course.id'}.'.num'};  
             }  
         }  
         $r->print(&Apache::lonmenu::inlinemenu('gcicustom',$switcher).  
                   &Apache::loncommon::end_page());  
         return OK;  
     } else {  
         if ($env{'form.destinationurl'} eq '/adm/gci_info') {  
             delete($env{'form.destinationurl'});  
         }          }
     }      }
     if ($env{'user.adv'}) {      if ((($cattype eq 'std') || ($cattype eq 'domonly')) && (!$env{'user.adv'}) &&
         $r->print('<p><label><input type="checkbox" name="showall"');            (!$placementonly)) {
         if ($env{'form.showall'}) { $r->print(' checked="checked" '); }  
         $r->print(' />'.&mt('Show all roles').'</label>'  
                  .' <input type="submit" value="'.&mt('Update display').'" />'  
                  .'</p>');  
     } else {  
         if ($countactive > 0) {          if ($countactive > 0) {
             $r->print(&Apache::loncoursequeueadmin::queued_selfenrollment());  
             my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');              my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
             my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');               my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); 
             unless ($env{'user.domain'} eq 'gcitest') {              $r->print(
                 $r->print(                  '<p>'
                     '<p>'                 .&mt('[_1]Visit the [_2]Course/Community Catalog[_3][_4]'
                    .&mt('[_1]Visit the [_2]Course/Community Catalog[_3]'                     .' to view all [_5] LON-CAPA courses and communities.'
                        .' to view all [_4] LON-CAPA courses and communities.'                     ,'<b>'
                        ,'<b>'                     ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'
                        ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'                     ,'</a>'
                        ,'</a></b>',$domdesc)                     ,'</b>'
                    .'<br />'                     ,'"'.$domdesc.'"')
                    .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'                 .'<br />'
                  .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'
                    .' you may be able to enroll if self-enrollment is permitted.'                     .' you may be able to enroll if self-enrollment is permitted.'
                    ,'<b>','</b>')                     ,'<b>','</b>')
                    .'</p>'                 .'</p>'
                 );              );
             }  
         }          }
     }      }
   
 # No active roles  # No active roles
     if ($countactive==0) {      if ($countactive==0) {
  if ($inrole) {          &requestcourse_advice($r,$cattype,$inrole); 
     $r->print('<h2>'.&mt('Currently no additional roles, courses or communities').'</h2>');  
  } else {  
             if ($show_course) {  
                 if ($env{'user.domain'} eq 'gcitest') {  
                     $r->print('<h2>'.&mt('Currently no active Concept Tests').'</h2>');  
                 } elsif ($env{'user.domain'} eq 'gci') {  
                     $r->print('<h2>'.&mt('Currently not assigned as a GCI contributor').'</h2>');  
                 }  
             } else {  
         $r->print('<h2>'.&mt('Currently no active roles, courses or communities').'</h2>');  
             }  
  }  
         unless ($env{'user.domain'} eq 'gcitest') {  
             &findcourse_advice($r);  
             &requestcourse_advice($r);  
         }  
  $r->print('</form>');   $r->print('</form>');
         if ($countfuture) {          if ($countfuture) {
             if ($show_course) {              $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));
                 if ($env{'user.domain'} eq 'gcitest') {  
                     $r->print(&mt('The following [quant,_1,Concept Test] will be available in the future:',$countfuture));  
                 } else {  
                     $r->print(&mt('The following [quant,_1,course] will become active in the future:',$countfuture));  
                 }  
             } else {  
                 $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));  
             }  
             my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,              my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,
                                                $nochoose);                                                 $nochoose);
             &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,              &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,
Line 853  ENDHEADER Line 1031  ENDHEADER
         }          }
         $r->print(&Apache::loncommon::end_page());          $r->print(&Apache::loncommon::end_page());
  return OK;   return OK;
     } elsif ($countactive==1) { # Is there only one choice?      } elsif (($placementonly) && ($env{'request.role'} eq 'cm')) {
         my $needs_switchserver;   $r->print('<h3>'.&mt('Please stand by.').'</h3>
         if ($env{'user.author'}) {            <input type="hidden" name="'.$possiblerole.'" value="1" />
             $needs_switchserver = &check_needs_switchserver($possiblerole);                    <noscript><br />
         }                    <input type="submit" name="submit" value="'.&mt('Continue').'" />
         if ((!$needs_switchserver) && ($env{'request.role'} eq 'cm')) {                    </noscript></form>');
             $r->print('<h3>'.&mt('Please stand by.').'</h3>'.   $r->rflush();
                 '<input type="hidden" name="'.$possiblerole.'" value="1" />'.   $r->print('<script type="text/javascript">document.forms.rolechoice.submit();</script>');
             '<noscript><br /><input type="submit" name="submit" value="'.&mt('Continue').'" /></noscript>');   $r->print(&Apache::loncommon::end_page());
             $r->print("</form>\n");   return OK;
             $r->rflush();  
             $r->print('<script type="text/javascript">document.forms.rolechoice.submit();</script>');  
             $r->print(&Apache::loncommon::end_page());  
             return OK;  
         }  
         if ($needs_switchserver) {  
             $r->print("<h2>".&mt('Server Switch Required')."</h2>\n".  
                       &mt('Construction Space access is only available from '.  
                           'the home server of the corresponding Author.').'<br />'.  
                       &mt("Click the 'Switch Server' link to go there.").'<br />');  
         }  
     }      }
 # ----------------------------------------------------------------------- Table  # ----------------------------------------------------------------------- Table
     unless ((!$show_course) || ($nochoose) || ($countactive==1)) {  
       if ($numdc > 0) {
           $r->print(&coursepick_jscript());
           $r->print(&Apache::loncommon::coursebrowser_javascript().
                     &Apache::loncommon::authorbrowser_javascript());
       }
   
       unless ((!&Apache::loncommon::show_course()) || ($nochoose) || ($countactive==1)) {
  $r->print("<h2>".&mt('Select a Course to Enter')."</h2>\n");   $r->print("<h2>".&mt('Select a Course to Enter')."</h2>\n");
     }      }
     if ($env{'form.destinationurl'}) {      if ($env{'form.destinationurl'}) {
Line 887  ENDHEADER Line 1061  ENDHEADER
                       $env{'form.destsymb'}.'" />');                        $env{'form.destsymb'}.'" />');
         }          }
     }      }
   
     my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);      my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);
     if ($env{'environment.recentroles'}) {      if ($env{'environment.recentroles'}) {
         my %recent_roles =          my %recent_roles =
                &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});                 &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
  my $output='';   my $output='';
  foreach (sort(keys(%recent_roles))) {   foreach my $role (sort(keys(%recent_roles))) {
     if (ref($roletext{'user.role.'.$_}) eq 'ARRAY') {      if (ref($roletext{'user.role.'.$role}) eq 'ARRAY') {
  $output.= &Apache::loncommon::start_data_table_row().   $output.= &Apache::loncommon::start_data_table_row().
                           $roletext{'user.role.'.$_}->[0].                            $roletext{'user.role.'.$role}->[0].
                           &Apache::loncommon::end_data_table_row().  
                           &Apache::loncommon::continue_data_table_row().  
                           $roletext{'user.role.'.$_}->[1].  
                           &Apache::loncommon::end_data_table_row();                            &Apache::loncommon::end_data_table_row();
                 if ($_ =~ m-dc\./($match_domain)/-                   if ($roletext{'user.role.'.$role}->[1] ne '') {
                       $output .= &Apache::loncommon::continue_data_table_row().
                                  $roletext{'user.role.'.$role}->[1].
                                  &Apache::loncommon::end_data_table_row();
                   }
                   if ($role =~ m{dc\./($match_domain)/} 
     && $dcroles{$1}) {      && $dcroles{$1}) {
     $output .= &adhoc_roles_row($1,'recent');      $output .= &adhoc_roles_row($1,'recent');
                 }                  }
     } elsif ($numdc > 0) {      } elsif ($numdc > 0) {
                 unless ($_ =~/^error\:/) {                  unless ($role =~/^error\:/) {
                     $output.=&display_cc_role('user.role.'.$_);                      my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);
                       if ($roletext) {
                           $output.= &Apache::loncommon::start_data_table_row().
                                     $roletext.
                                     &Apache::loncommon::end_data_table_row();
                           if ($role_text_end) {
                               $output .= &Apache::loncommon::continue_data_table_row().
                                          $role_text_end.
                                          &Apache::loncommon::end_data_table_row();
                           }
                       }
                 }                  }
             }               }
  }   }
  if ($output) {   if ($output) {
     $r->print(&Apache::loncommon::start_data_table_empty_row()      $r->print(&Apache::loncommon::start_data_table_empty_row()
Line 921  ENDHEADER Line 1108  ENDHEADER
             $doheaders ++;              $doheaders ++;
  }   }
     }      }
   
     if ($numdc > 0) {  
         $r->print(&coursepick_jscript());  
         $r->print(&Apache::loncommon::coursebrowser_javascript().  
                   &Apache::loncommon::authorbrowser_javascript());  
     }  
     &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext);      &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext);
     if ($countactive > 1) {      if ($countactive > 1) {
         my $tremark='';          my $tremark='';
Line 962  ENDHEADER Line 1143  ENDHEADER
  $r->print('<hr /><h2>'.&mt('Current Privileges').'</h2>');   $r->print('<hr /><h2>'.&mt('Current Privileges').'</h2>');
  $r->print(&privileges_info());   $r->print(&privileges_info());
     }      }
     $r->print(&Apache::lonnet::getannounce());      my $announcements = &Apache::lonnet::getannounce();
       $r->print(
           '<br />'.
           '<h2>'.&mt('Announcements').'</h2>'.
           $announcements
       ) unless (!$announcements);
     if ($advanced) {      if ($advanced) {
         my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');          my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');
         $r->print('<p><small><i>'          $r->print('<p><small><i>'
                  .&mt('This LON-CAPA server is version [_1]',$r->dir_config('lonVersion'))                   .&mt('This LON-CAPA server is version [_1]',$r->dir_config('lonVersion'))
                  .'</i><br />'                   .'</i></small></p>');
                  .'<a href="/adm/logout">'.&mt('Logout').'</a>&nbsp;&nbsp;'  
                  .'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'  
                  .&mt('Course/Community Catalog')  
                  .'</a></small></p>');  
     }      }
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
     return OK;      return OK;
 }  }
   
 sub gci_info_page {  sub roles_from_env {
     return <<"END";      my ($roleshash,$update) = @_;
 <br clear="all">      my $count = 0;
 <div>      if (ref($roleshash) eq 'HASH') {
 <h2>Welcome to the Geoscience Concept Inventory WebCenter</h2>          foreach my $envkey (keys(%env)) {
 <p>              if ($envkey =~ m{^user\.role\.(\w+)[./]}) {
 Use the tabs to navigate the WebCenter and...                  next if ($1 eq 'gr');
 <ul>                  $roleshash->{$envkey} = $env{$envkey};
 <li>Review and comment on existing GCI questions</li>                  my ($start,$end) = split(/\./,$env{$envkey});
 <li>Submit GCI questions of your own</li>                  unless ($end && $end<$update) {
 <li>Create an online test for your students</li>                      $count ++;
 <li>View tutorials on creating online tests</li>                  }
 </ul>              }
 </p>          }
 <p>For more information about writing and reviewing Concept Inventory questions      }
 please refer to the <a href="/res/gci/gci/internal/pdfs/GCIWorkbook.pdf">GCI Workbook</a>.      return $count;
 </div>  
 END  
 }  }
   
 sub gather_roles {  sub gather_roles {
     my ($then,$refresh,$now,$reinit,$nochoose,$roletext,$sortrole,$roleclass,$futureroles,$timezones) = @_;      my ($update,$refresh,$now,$reinit,$nochoose,$roles_in_env,$roletext,$sortrole,$roleclass,$futureroles,
           $timezones,$loncaparev) = @_;
     my ($countactive,$countfuture,$inrole,$possiblerole) = (0,0,0,'');      my ($countactive,$countfuture,$inrole,$possiblerole) = (0,0,0,'');
     my $advanced = $env{'user.adv'};      my $advanced = $env{'user.adv'};
     my $tryagain = $env{'form.tryagain'};      my $tryagain = $env{'form.tryagain'};
     foreach my $envkey (sort(keys(%env))) {      my @ids = &Apache::lonnet::current_machine_ids();
         my $button = 1;      if (ref($roles_in_env) eq 'HASH') {
         my $switchserver='';          foreach my $envkey (sort(keys(%{$roles_in_env}))) {
         my ($role_text,$role_text_end,$sortkey);              my $button = 1;
         if ($envkey=~/^user\.role\./) {              my $switchserver='';
             my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);              my $switchwarning;
             &Apache::lonnet::role_status($envkey,$then,$refresh,$now,\$role,\$where,              my ($role_text,$role_text_end,$sortkey,$role,$where,$trolecode,$tstart,
                   $tend,$tremark,$tstatus,$tpstart,$tpend);
               &Apache::lonnet::role_status($envkey,$update,$refresh,$now,\$role,\$where,
                                          \$trolecode,\$tstatus,\$tstart,\$tend);                                           \$trolecode,\$tstatus,\$tstart,\$tend);
             next if (!defined($role) || $role eq '' || $role =~ /^gr/);              next if (!defined($role) || $role eq '' || $role =~ /^gr/);
             my $timezone = &role_timezone($where,$timezones);  
             $tremark='';              $tremark='';
             $tpstart='&nbsp;';              $tpstart='&nbsp;';
             $tpend='&nbsp;';              $tpend='&nbsp;';
             if ($tstart) {  
                 $tpstart=&Apache::lonlocal::locallocaltime($tstart,$timezone);  
             }  
             if ($tend) {  
                 $tpend=&Apache::lonlocal::locallocaltime($tend,$timezone);  
             }  
             if ($env{'request.role'} eq $trolecode) {              if ($env{'request.role'} eq $trolecode) {
                 $tstatus='selected';                  $tstatus='selected';
             }              }
Line 1028  sub gather_roles { Line 1204  sub gather_roles {
             if (($tstatus eq 'is')              if (($tstatus eq 'is')
                 || ($tstatus eq 'selected')                  || ($tstatus eq 'selected')
                 || ($tstatus eq 'future')                  || ($tstatus eq 'future')
                 || ($env{'form.showall'})) {                  || ($env{'form.display'} eq 'showall')) {
                   my $timezone = &role_timezone($where,$timezones);
                   if ($tstart) {
                       $tpstart=&Apache::lonlocal::locallocaltime($tstart,$timezone);
                   }
                   if ($tend) {
                       $tpend=&Apache::lonlocal::locallocaltime($tend,$timezone);
                   }
                 if ($tstatus eq 'is') {                  if ($tstatus eq 'is') {
                     $tbg='LC_roles_is';                      $tbg='LC_roles_is';
                     $possiblerole=$trolecode;                      $possiblerole=$trolecode;
Line 1054  sub gather_roles { Line 1237  sub gather_roles {
                 if ($role =~ /^cr\//) {                  if ($role =~ /^cr\//) {
                     my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);                      my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);
                     if ($tremark) { $tremark.='<br />'; }                      if ($tremark) { $tremark.='<br />'; }
                     $tremark.=&mt('Defined by [_1] at [_2].',$rauthor,$rdomain);                      $tremark.=&mt('Custom role defined by [_1].',$rauthor.':'.$rdomain);
                 }                  }
                 $trole=Apache::lonnet::plaintext($role);                  $trole=Apache::lonnet::plaintext($role);
                 my $ttype;                  my $ttype;
                 my $twhere;                  my $twhere;
                   my $skipcal;
                 my ($tdom,$trest,$tsection)=                  my ($tdom,$trest,$tsection)=
                     split(/\//,Apache::lonnet::declutter($where));                      split(/\//,Apache::lonnet::declutter($where));
                 # First, Co-Authorship roles                  # First, Co-Authorship roles
                 if (($role eq 'ca') || ($role eq 'aa')) {                  if (($role eq 'ca') || ($role eq 'aa')) {
                     my $home = &Apache::lonnet::homeserver($trest,$tdom);                      my $home = &Apache::lonnet::homeserver($trest,$tdom);
                     my $allowed=0;                      my $allowed=0;
                     my @ids=&Apache::lonnet::current_machine_ids();  
                     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }                      foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                     if (!$allowed) {                      if (!$allowed) {
                         $button=0;                          $button=0;
                         $switchserver='otherserver='.$home.'&role='.$trolecode;                          $switchserver='otherserver='.$home.'&amp;role='.$trolecode;
                     }                      }
                     #next if ($home eq 'no_host');                      #next if ($home eq 'no_host');
                     $home = &Apache::lonnet::hostname($home);                      $home = &Apache::lonnet::hostname($home);
                     $ttype='Construction Space';                      $ttype='Authoring Space';
                     $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').                      $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').
                         ': '.$tdom.'<br />'.                          ': '.$tdom.'<br />'.
                         ' '.&mt('Server').':&nbsp;'.$home;                          ' '.&mt('Server').':&nbsp;'.$home;
Line 1085  sub gather_roles { Line 1268  sub gather_roles {
                     my $home = &Apache::lonnet::homeserver                      my $home = &Apache::lonnet::homeserver
                         ($env{'user.name'},$env{'user.domain'});                          ($env{'user.name'},$env{'user.domain'});
                     my $allowed=0;                      my $allowed=0;
                     my @ids=&Apache::lonnet::current_machine_ids();  
                     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }                      foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                     if (!$allowed) {                      if (!$allowed) {
                         $button=0;                          $button=0;
                         $switchserver='otherserver='.$home.'&role='.$trolecode;                          $switchserver='otherserver='.$home.'&amp;role='.$trolecode;
                     }                      }
                     #next if ($home eq 'no_host');                      #next if ($home eq 'no_host');
                     $home = &Apache::lonnet::hostname($home);                      $home = &Apache::lonnet::hostname($home);
                     $ttype='Construction Space';                      $ttype='Authoring Space';
                     $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').                      $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').
                         ':&nbsp;'.$home;                          ':&nbsp;'.$home;
                     $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';                      $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';
Line 1104  sub gather_roles { Line 1286  sub gather_roles {
                     $ttype = &Apache::loncommon::course_type($tcourseid);                      $ttype = &Apache::loncommon::course_type($tcourseid);
                     $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);                      $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);
                     if ($env{'course.'.$tcourseid.'.description'}) {                      if ($env{'course.'.$tcourseid.'.description'}) {
                           my $home=$env{'course.'.$tcourseid.'.home'};
                         $twhere=$env{'course.'.$tcourseid.'.description'};                          $twhere=$env{'course.'.$tcourseid.'.description'};
                         $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;                          $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                           $twhere = &HTML::Entities::encode($twhere,'"<>&');
                         unless ($twhere eq &mt('Currently not available')) {                          unless ($twhere eq &mt('Currently not available')) {
                             $twhere.=' <span class="LC_fontsize_small">'.                              $twhere.=' <span class="LC_fontsize_small">'.
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                                     '</span>';                                      '</span>';
                               unless ($home && grep(/^\Q$home\E$/,@ids) && $loncaparev eq '') {
                                   my $required = $env{'course.'.$tcourseid.'.internal.releaserequired'};
                                   if ($required ne '') {
                                       ($switchserver,$switchwarning) = 
                                           &Apache::loncommon::check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                       if ($switchserver || $switchwarning) {
                                           $button = 0;
                                       }
                                   }
                               }
                         }                          }
                     } else {                      } else {
                         my %newhash=&Apache::lonnet::coursedescription($tcourseid);                          my %newhash=&Apache::lonnet::coursedescription($tcourseid);
                         if (%newhash) {                          if (%newhash) {
                             $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.                              $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.
                                 "\0".$envkey;                                  "\0".$envkey;
                             $twhere=$newhash{'description'}.                              $twhere=&HTML::Entities::encode($newhash{'description'},'"<>&').
                               ' <span class="LC_fontsize_small">'.                                      ' <span class="LC_fontsize_small">'.
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).                                       &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                               '</span>';                                      '</span>';
                             $ttype = $newhash{'type'};                              $ttype = $newhash{'type'};
                             $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);                              $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);
                               my $home = $newhash{'home'};
                               unless ($home && grep(/^\Q$home\E$/,@ids) && $loncaparev eq '') {
                                   my $required = $newhash{'internal.releaserequired'};
                                   if ($required ne '') {
                                       ($switchserver,$switchwarning) =
                                           &Apache::loncommon::check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                       if ($switchserver || $switchwarning) {
                                           $button = 0;
                                       }
                                   }
                               }
                         } else {                          } else {
                             $twhere=&mt('Currently not available');                              $twhere=&mt('Currently not available');
                             $env{'course.'.$tcourseid.'.description'}=$twhere;                              $env{'course.'.$tcourseid.'.description'}=$twhere;
                             $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;                              $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                             $ttype = 'Unavailable';                              $ttype = 'Unavailable';
                               $skipcal = 1;
                         }                          }
                     }                      }
                       if ($ttype eq 'Placement') {
                           $ttype = 'Placement Test';
                       }
                     if ($tsection) {                      if ($tsection) {
                         $twhere.='<br />'.&mt('Section').': '.$tsection;                          $twhere.='<br />'.&mt('Section').': '.$tsection;
                     }                      }
Line 1145  sub gather_roles { Line 1354  sub gather_roles {
                 ($role_text,$role_text_end) =                  ($role_text,$role_text_end) =
                     &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,                      &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,
                                     $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,                                      $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,
                                     $tpend,$nochoose,$button,$switchserver,$reinit);                                      $tpend,$nochoose,$button,$switchserver,$reinit,
                                       $switchwarning,$skipcal);
                 $roletext->{$envkey}=[$role_text,$role_text_end];                  $roletext->{$envkey}=[$role_text,$role_text_end];
                 if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}                  if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}
                 $sortrole->{$sortkey}=$envkey;                  $sortrole->{$sortkey}=$envkey;
Line 1165  sub role_timezone { Line 1375  sub role_timezone {
             my $cnum = $2;              my $cnum = $2;
             if ($cdom && $cnum) {              if ($cdom && $cnum) {
                 if (!exists($timezones->{$cdom.'_'.$cnum})) {                  if (!exists($timezones->{$cdom.'_'.$cnum})) {
                     my %timehash =                      my $tz;
                         &Apache::lonnet::get('environment',['timezone'],$cdom,$cnum);                      if ($env{'course.'.$cdom.'_'.$cnum.'.description'}) {
                     if ($timehash{'timezone'} eq '') {                          $tz = $env{'course.'.$cdom.'_'.$cnum.'.timezone'};
                       } else {
                           my %timehash =
                               &Apache::lonnet::get('environment',['timezone'],$cdom,$cnum);
                           $tz = $timehash{'timezone'};
                       }
                       if ($tz eq '') {
                         if (!exists($timezones->{$cdom})) {                          if (!exists($timezones->{$cdom})) {
                             my %domdefaults =                               my %domdefaults = 
                                 &Apache::lonnet::get_domain_defaults($cdom);                                  &Apache::lonnet::get_domain_defaults($cdom);
Line 1180  sub role_timezone { Line 1396  sub role_timezone {
                         $timezones->{$cdom.'_'.$cnum} = $timezones->{$cdom};                          $timezones->{$cdom.'_'.$cnum} = $timezones->{$cdom};
                     } else {                      } else {
                         $timezones->{$cdom.'_'.$cnum} =                           $timezones->{$cdom.'_'.$cnum} = 
                             &Apache::lonlocal::gettimezone($timehash{'timezone'});                              &Apache::lonlocal::gettimezone($tz);
                     }                      }
                 }                  }
                 $timezone = $timezones->{$cdom.'_'.$cnum};                  $timezone = $timezones->{$cdom.'_'.$cnum};
Line 1211  sub roletable_headers { Line 1427  sub roletable_headers {
     my $doheaders;      my $doheaders;
     if ((ref($sortrole) eq 'HASH') && (ref($roleclass) eq 'HASH')) {      if ((ref($sortrole) eq 'HASH') && (ref($roleclass) eq 'HASH')) {
         $r->print('<br />'          $r->print('<br />'
                  .&Apache::loncommon::start_data_table()                   .&Apache::loncommon::start_data_table('LC_textsize_mobile')
                  .&Apache::loncommon::start_data_table_header_row()                   .&Apache::loncommon::start_data_table_header_row()
         );          );
         if (!$nochoose) { $r->print('<th>&nbsp;</th>'); }          if (!$nochoose) { $r->print('<th>&nbsp;</th>'); }
Line 1237  sub roletable_headers { Line 1453  sub roletable_headers {
 }  }
   
 sub roletypes {  sub roletypes {
     my @types = ('Domain','Construction Space','Course','Community','Unavailable','System');      my @types = ('Domain','Authoring Space','Course','Placement Test','Community','Unavailable','System');
     return @types;       return @types; 
 }  }
   
Line 1253  sub print_rolerows { Line 1469  sub print_rolerows {
                         if (ref($roletext->{$sortrole->{$which}}) eq 'ARRAY') {                          if (ref($roletext->{$sortrole->{$which}}) eq 'ARRAY') {
                             $output.= &Apache::loncommon::start_data_table_row().                              $output.= &Apache::loncommon::start_data_table_row().
                                       $roletext->{$sortrole->{$which}}->[0].                                        $roletext->{$sortrole->{$which}}->[0].
                                       &Apache::loncommon::end_data_table_row().  
                                       &Apache::loncommon::continue_data_table_row().  
                                       $roletext->{$sortrole->{$which}}->[1].  
                                       &Apache::loncommon::end_data_table_row();                                        &Apache::loncommon::end_data_table_row();
                               if ($roletext->{$sortrole->{$which}}->[1] ne '') {
                                   $output .= &Apache::loncommon::continue_data_table_row().
                                              $roletext->{$sortrole->{$which}}->[1].
                                              &Apache::loncommon::end_data_table_row();
                               }
                         }                          }
                         if ($sortrole->{$which} =~ m-dc\./($match_domain)/-) {                          if ($sortrole->{$which} =~ m-dc\./($match_domain)/-) {
                             if (ref($dcroles) eq 'HASH') {                              if (ref($dcroles) eq 'HASH') {
Line 1284  sub print_rolerows { Line 1502  sub print_rolerows {
 }  }
   
 sub findcourse_advice {  sub findcourse_advice {
     my ($r) = @_;      my ($r,$cattype) = @_;
     my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');      my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
     my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');      my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');
     if (&Apache::lonnet::auto_run(undef,$env{'user.domain'})) {      if (&Apache::lonnet::auto_run(undef,$env{'user.domain'})) {
Line 1299  sub findcourse_advice { Line 1517  sub findcourse_advice {
     } else {      } else {
         $r->print(&mt('If you were expecting to see an active role listed for a particular course, that course may not have been created yet.').'<br />');          $r->print(&mt('If you were expecting to see an active role listed for a particular course, that course may not have been created yet.').'<br />');
     }      }
     my $queued = &Apache::loncoursequeueadmin::queued_selfenrollment();      if (($cattype eq 'std') || ($cattype eq 'domonly')) {
     if ($queued) {          $r->print('<h3>'.&mt('Self-Enrollment').'</h3>'.
         $r->print($queued);                    '<p>'.&mt('The [_1]Course/Community Catalog[_2] provides information about all [_3] classes for which LON-CAPA courses have been created, as well as any communities in the domain.','<a href="/adm/coursecatalog?showdom='.$esc_dom.'">','</a>',$domdesc).'<br />');
     } else {          $r->print(&mt('You can search for courses and communities which permit self-enrollment, if you would like to enroll in one.').'</p>'.
         $r->print(&mt('You have no request for contributor access pending approval by the GCI WebCenter team.').'<ul>'.          &Apache::loncoursequeueadmin::queued_selfenrollment());
             '<li>'.&mt('This may mean that action was taken on your request in the time since your most recent log-in.[_1]View [_2]Message[_3] to see if this is the case.','<br />','<a href="/adm/communicate">','</a>').'</li>'.  
             '<li>'.&mt('If you logout and log-in again you may find you now have access to the Geoscience Concept Inventory, as a contributor.').'</li>'.  
            '</ul>');  
     }      }
     return;      return;
 }  }
   
 sub requestcourse_advice {  sub requestcourse_advice {
     my ($r) = @_;      my ($r,$cattype,$inrole) = @_;
     my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');      my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
     my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');      my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');
     my (%can_request,%request_doms);      my (%can_request,%request_doms,$output);
     &Apache::lonnet::check_can_request($env{'user.domain'},\%can_request,\%request_doms);      &Apache::lonnet::check_can_request($env{'user.domain'},\%can_request,\%request_doms);
     if (keys(%request_doms) > 0) {      if (keys(%request_doms) > 0) {
         my ($types,$typename) = &Apache::loncommon::course_types();          my ($types,$typename) = &Apache::loncommon::course_types();
         if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) {           if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) { 
             $r->print('<h3>'.&mt('Request creation of a course or community').'</h3>'.  
                       '<p>'.&mt('You have rights to request the creation of courses and/or communities in the following domain(s):').'<ul>');  
             my (@reqdoms,@reqtypes);              my (@reqdoms,@reqtypes);
             foreach my $type (sort(keys(%request_doms))) {              foreach my $type (sort(keys(%request_doms))) {
                 push(@reqtypes,$type);                   push(@reqtypes,$type); 
                 if (ref($request_doms{$type}) eq 'ARRAY') {                  if (ref($request_doms{$type}) eq 'ARRAY') {
                     my $domstr = join(', ',map { &Apache::lonnet::domain($_) } sort(@{$request_doms{$type}}));                      my $domstr = join(', ',map { &Apache::lonnet::domain($_) } sort(@{$request_doms{$type}}));
                     $r->print(                      $output .=
                         '<li>'                          '<li>'
                        .&mt('[_1]'.$typename->{$type}.'[_2] in domain: [_3]',                         .&mt('[_1]'.$typename->{$type}.'[_2] in domain: [_3]',
                             '<i>',                              '<i>',
                             '</i>',                              '</i>',
                             '<b>'.$domstr.'</b>')                              '<b>'.$domstr.'</b>')
                        .'</li>'                         .'</li>';
                     );  
                     foreach my $dom (@{$request_doms{$type}}) {                      foreach my $dom (@{$request_doms{$type}}) {
                         unless (grep(/^\Q$dom\E/,@reqdoms)) {                          unless (grep(/^\Q$dom\E/,@reqdoms)) {
                             push(@reqdoms,$dom);                              push(@reqdoms,$dom);
Line 1357  sub requestcourse_advice { Line 1569  sub requestcourse_advice {
             }              }
             if (@reqdoms == 1 || @showtypes > 0) {              if (@reqdoms == 1 || @showtypes > 0) {
                 $requrl .= '&state=crstype&action=new';                  $requrl .= '&state=crstype&action=new';
             }               }
             $r->print('</ul>'.&mt('Use the [_1]request form[_2] to submit a request for creation of a new course or community.','<a href="'.$requrl.'">','</a>').'</p>');              if ($output) {
                   $r->print('<h3>'.&mt('Request creation of a course or community').'</h3>'.
                             '<p>'.
                             &mt('You have rights to request the creation of courses and/or communities in the following domain(s):').
                             '<ul>'.
                             $output.
                             '</ul>'.
                             &mt('Use the [_1]request form[_2] to submit a request for creation of a new course or community.',
                                 '<a href="'.$requrl.'">','</a>').
                             '</p>');
               }
         }          }
       } elsif (!$env{'user.adv'}) {
          if ($inrole) {
               $r->print('<h3>'.&mt('Currently no additional roles, courses or communities').'</h3>');
           } else {
               $r->print('<h3>'.&mt('Currently no active roles, courses or communities').'</h3>');
           }
           &findcourse_advice($r,$cattype);
     }      }
     return;      return;
 }  }
Line 1379  sub privileges_info { Line 1608  sub privileges_info {
  my (undef,$tdom,$trest,$tsec)=split(m{/},$where);   my (undef,$tdom,$trest,$tsec)=split(m{/},$where);
  if ($trest) {   if ($trest) {
     if ($env{'course.'.$tdom.'_'.$trest.'.description'} eq 'ca') {      if ($env{'course.'.$tdom.'_'.$trest.'.description'} eq 'ca') {
  $ttype='Construction Space';   $ttype='Authoring Space';
  $twhere='User: '.$trest.', Domain: '.$tdom;   $twhere='User: '.$trest.', Domain: '.$tdom;
     } else {      } else {
  $ttype= &Apache::loncommon::course_type($tdom.'_'.$trest);   $ttype= &Apache::loncommon::course_type($tdom.'_'.$trest);
Line 1420  sub privileges_info { Line 1649  sub privileges_info {
 }  }
   
 sub build_roletext {  sub build_roletext {
     my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit) = @_;      my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,
           $tpstart,$tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning,$skipcal) = @_;
     my ($roletext,$roletext_end);      my ($roletext,$roletext_end);
     my $is_dc=($trolecode =~ m/^dc\./);      my $is_dc=($trolecode =~ m/^dc\./);
     my $rowspan=($is_dc) ? ''      my $rowspan=($is_dc) ? ''
Line 1438  sub build_roletext { Line 1668  sub build_roletext {
             } else {              } else {
                 $roletext.=('<td'.$rowspan.' class="'.$tbg.'">&nbsp;</td>');                  $roletext.=('<td'.$rowspan.' class="'.$tbg.'">&nbsp;</td>');
             }              }
               if ($switchwarning) {
                   if ($tremark eq '') {
                       $tremark = $switchwarning;
                   } else {
                       $tremark .= '<br />'.$switchwarning;
                   }
               }
         } elsif ($tstatus eq 'is') {          } elsif ($tstatus eq 'is') {
             $roletext.='<td'.$rowspan.' class="'.$tbg.'">'.              $roletext.='<td'.$rowspan.' class="'.$tbg.'">'.
                         '<input name="'.$buttonname.'" type="button" value="'.                          '<input name="'.$buttonname.'" type="button" value="'.
Line 1469  sub build_roletext { Line 1706  sub build_roletext {
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         }          }
     }      }
     if ($trolecode !~ m/^(dc|ca|au|aa)\./) {      if (($trolecode !~ m/^(dc|ca|au|aa)\./)  && (!$skipcal)) {
  $tremark.=&Apache::lonannounce::showday(time,1,   $tremark.=&Apache::lonannounce::showday(time,1,
  &Apache::lonannounce::readcalendar($tdom.'_'.$trest));   &Apache::lonannounce::readcalendar($tdom.'_'.$trest));
     }      }
Line 1485  sub build_roletext { Line 1722  sub build_roletext {
     return ($roletext,$roletext_end);      return ($roletext,$roletext_end);
 }  }
   
 sub check_needs_switchserver {  
     my ($possiblerole) = @_;  
     my $needs_switchserver;  
     my ($role,$where) = split(/\./,$possiblerole,2);  
     my (undef,$tdom,$twho) = split(/\//,$where);  
     my ($server_status,$home);  
     if (($role eq 'ca') || ($role eq 'aa')) {  
         ($server_status,$home) = &check_author_homeserver($twho,$tdom);  
     } else {  
         ($server_status,$home) = &check_author_homeserver($env{'user.name'},  
                                                           $env{'user.domain'});  
     }  
     if ($server_status eq 'switchserver') {  
         $needs_switchserver = 1;  
     }  
     return $needs_switchserver;  
 }  
   
 sub check_author_homeserver {  sub check_author_homeserver {
     my ($uname,$udom)=@_;      my ($uname,$udom)=@_;
     if (($uname eq '') || ($udom eq '')) {      if (($uname eq '') || ($udom eq '')) {
Line 1521  sub check_author_homeserver { Line 1740  sub check_author_homeserver {
 }  }
   
 sub check_fordc {  sub check_fordc {
     my ($dcroles,$then) = @_;      my ($dcroles,$update,$then) = @_;
     my $numdc = 0;      my $numdc = 0;
     if ($env{'user.adv'}) {      if ($env{'user.adv'}) {
         foreach my $envkey (sort keys %env) {          foreach my $envkey (sort(keys(%env))) {
             if ($envkey=~/^user\.role\.dc\.\/($match_domain)\/$/) {              if ($envkey=~/^user\.role\.dc\.\/($match_domain)\/$/) {
                 my $dcdom = $1;                  my $dcdom = $1;
                 my $livedc = 1;                  my $livedc = 1;
                 my ($tstart,$tend)=split(/\./,$env{$envkey});                  my ($tstart,$tend)=split(/\./,$env{$envkey});
                 if ($tstart && $tstart>$then) { $livedc = 0; }                  my $limit = $update;
                 if ($tend   && $tend  <$then) { $livedc = 0; }                  if ($env{'request.role'} eq 'dc./'.$dcdom.'/') {
                       $limit = $then;
                   }
                   if ($tstart && $tstart>$limit) { $livedc = 0; }
                   if ($tend   && $tend  <$limit) { $livedc = 0; }
                 if ($livedc) {                  if ($livedc) {
                     $$dcroles{$dcdom} = $envkey;                      $$dcroles{$dcdom} = $envkey;
                     $numdc++;                      $numdc++;
Line 1542  sub check_fordc { Line 1765  sub check_fordc {
 }  }
   
 sub adhoc_course_role {  sub adhoc_course_role {
     my ($refresh,$then) = @_;      my ($refresh,$update,$then) = @_;
     my ($cdom,$cnum,$crstype);      my ($cdom,$cnum,$crstype);
     $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     $crstype = &Apache::loncommon::course_type();      $crstype = &Apache::loncommon::course_type();
     if (&check_forcc($cdom,$cnum,$refresh,$then,$crstype)) {      if (&check_forcc($cdom,$cnum,$refresh,$update,$then,$crstype)) {
         my $setprivs;          my $setprivs;
         if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {          if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {
             $setprivs = 1;              $setprivs = 1;
         } else {          } else {
             my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});              my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
             if (($start && ($start>$refresh || $start == -1)) ||              if (($start && ($start>$refresh || $start == -1)) ||
                 ($end && $end<$then)) {                  ($end && $end<$update)) {
                   $setprivs = 1;
               }
           }
           unless ($setprivs) {
               if (!exists($env{'user.priv.'.$env{'form.switchrole'}.'./'})) {
                 $setprivs = 1;                  $setprivs = 1;
             }              }
         }          }
         if ($setprivs) {          if ($setprivs) {
             if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)([\w/]*)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {              if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)(.*?)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
                 my $role = $1;                  my $role = $1;
                 my $custom_role = $2;                  my $custom_role = $2;
                 my $usec = $3;                  my $usec = $3;
Line 1585  sub adhoc_course_role { Line 1813  sub adhoc_course_role {
                     $spec .= '/'.$usec;                      $spec .= '/'.$usec;
                     $area .= '/'.$usec;                      $area .= '/'.$usec;
                 }                  }
                 &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area);                  if ($role =~ /^cr/) {
                       &Apache::lonnet::custom_roleprivs(\%newrole,$role,$cdom,$cnum,$spec,$area);
                   } else {
                       &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area);
                   }
                 &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups);                  &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups);
                 my $adhocstart = $refresh-1;                  my $adhocstart = $refresh-1;
                 $userroles{'user.role.'.$spec} = $adhocstart.'.';                  $userroles{'user.role.'.$spec} = $adhocstart.'.';
Line 1597  sub adhoc_course_role { Line 1829  sub adhoc_course_role {
 }  }
   
 sub check_forcc {  sub check_forcc {
     my ($cdom,$cnum,$refresh,$then,$crstype) = @_;      my ($cdom,$cnum,$refresh,$update,$then,$crstype) = @_;
     my ($is_cc,$ccrole);      my ($is_cc,$ccrole);
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $ccrole = 'co';          $ccrole = 'co';
     } else {      } else {
         $ccrole = 'cc';          $ccrole = 'cc';
     }      }
     if ($cdom ne '' && $cnum ne '') {      if (&Apache::lonnet::is_course($cdom,$cnum)) {
         if (&Apache::lonnet::is_course($cdom,$cnum)) {          my $envkey = 'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum;
             my $envkey = 'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum;          if (defined($env{$envkey})) {
             if (defined($env{$envkey})) {              $is_cc = 1;
                 $is_cc = 1;              my ($tstart,$tend)=split(/\./,$env{$envkey});
                 my ($tstart,$tend)=split(/\./,$env{$envkey});              my $limit = $update;
                 if ($tstart && $tstart>$refresh) { $is_cc = 0; }              if ($env{'request.role'} eq $ccrole.'./'.$cdom.'/'.$cnum) {
                 if ($tend   && $tend  <$then) { $is_cc = 0; }                  $limit = $then;
             }              }
               if ($tstart && $tstart>$refresh) { $is_cc = 0; }
               if ($tend   && $tend  <$limit) { $is_cc = 0; }
         }          }
     }      }
     return $is_cc;      return $is_cc;
Line 1632  sub courselink { Line 1866  sub courselink {
 }  }
   
 sub coursepick_jscript {  sub coursepick_jscript {
     my %lt = &Apache::lonlocal::texthash(      my %js_lt = &Apache::lonlocal::texthash(
                   plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",                    plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",
                   youc => 'You can only use this screen to select courses and communities in the current domain.',                    youc => 'You can only use this screen to select courses and communities in the current domain.',
              );               );
       &js_escape(\%js_lt);
     my $verify_script = <<"END";      my $verify_script = <<"END";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 1652  function verifyCoursePick(caller) { Line 1887  function verifyCoursePick(caller) {
             }              }
         }          }
         else {          else {
             alert("$lt{'plsu'}");              alert("$js_lt{'plsu'}");
         }          }
     }      }
     else {      else {
         alert("$lt{'youc'}")          alert("$js_lt{'youc'}")
     }      }
 }  }
 function getIndex(caller) {  function getIndex(caller) {
Line 1688  sub display_cc_role { Line 1923  sub display_cc_role {
     unless ($rolekey =~/^error\:/) {      unless ($rolekey =~/^error\:/) {
         if ($rolekey =~ m{^user\.role\.(cc|co)\./($match_domain)/($match_courseid)$}) {          if ($rolekey =~ m{^user\.role\.(cc|co)\./($match_domain)/($match_courseid)$}) {
             my $ccrole = $1;              my $ccrole = $1;
             my $tcourseid = $2.'_'.$3;              my $tdom = $2;
             my $trolecode = $1.'./'.$2.'/'.$3;              my $trest = $3;
               my $tcourseid = $tdom.'_'.$trest;
               my $trolecode = $ccrole.'./'.$tdom.'/'.$trest;
             my $twhere;              my $twhere;
             my $ttype;              my $ttype;
               my $skipcal;
             my $tbg='LC_roles_is';              my $tbg='LC_roles_is';
             my %newhash=&Apache::lonnet::coursedescription($tcourseid);              my %newhash=&Apache::lonnet::coursedescription($tcourseid);
             if (%newhash) {              if (%newhash) {
                 $twhere=$newhash{'description'}.                  $twhere=$newhash{'description'}.
                         ' <span style="LC_fontsize_small">'.                          ' <span class="LC_fontsize_small">'.
                         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$2,$1).                          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                         '</span>';                          '</span>';
                 $ttype = $newhash{'type'};                  $ttype = $newhash{'type'};
             } else {              } else {
                 $twhere=&mt('Currently not available');                  $twhere=&mt('Currently not available');
                 $env{'course.'.$tcourseid.'.description'}=$twhere;                  $env{'course.'.$tcourseid.'.description'}=$twhere;
                   $skipcal = 1;
             }              }
             my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);              my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);
             $twhere.="<br />".&mt('Domain').":".$1;              $twhere.="<br />".&mt('Domain').":".$tdom;
             ($roletext,$roletext_end) = &build_roletext($trolecode,$1,$2,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');              ($roletext,$roletext_end) = &build_roletext($trolecode,$tdom,$trest,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'','','',$skipcal);
         }          }
     }      }
     return ($roletext,$roletext_end);      return ($roletext,$roletext_end);
Line 1715  sub display_cc_role { Line 1954  sub display_cc_role {
 sub adhoc_roles_row {  sub adhoc_roles_row {
     my ($dcdom,$rowtype) = @_;      my ($dcdom,$rowtype) = @_;
     my $output = &Apache::loncommon::continue_data_table_row()      my $output = &Apache::loncommon::continue_data_table_row()
                  .' <td colspan="5">'                   .' <td colspan="5" class="LC_textsize_mobile">'
                  .&mt('[_1]Ad hoc[_2] roles in domain [_3] --'                   .&mt('[_1]Ad hoc[_2] roles in domain [_3] --'
                      ,'<span class="LC_cusr_emph">','</span>',$dcdom)                       ,'<span class="LC_cusr_emph">','</span>',$dcdom)
                  .' ';                   .' ';
Line 1724  sub adhoc_roles_row { Line 1963  sub adhoc_roles_row {
     my $carole = &Apache::lonnet::plaintext('ca');      my $carole = &Apache::lonnet::plaintext('ca');
     my $selectcalink = &coauthorlink($dcdom,$rowtype);      my $selectcalink = &coauthorlink($dcdom,$rowtype);
     $output.=$ccrole.': '.$selectcclink      $output.=$ccrole.': '.$selectcclink
             .' | '.$carole.': '.$selectcalink              .' | '.$carole.': '.$selectcalink.'</td>'
             .&Apache::loncommon::end_data_table_row();              .&Apache::loncommon::end_data_table_row();
     return $output;      return $output;
 }  }
Line 1751  sub courseloadpage { Line 1990  sub courseloadpage {
     return $startpage;      return $startpage;
 }  }
   
   sub update_session_roles {
       my $then=$env{'user.login.time'};
       my $refresh=$env{'user.refresh.time'};
       if (!$refresh) {
           $refresh = $then;
       }
       my $update = $env{'user.update.time'};
       if (!$update) {
           $update = $then;
       }
       my $now = time;
       my %roleshash =
           &Apache::lonnet::get_my_roles('','','userroles',
                                         ['active','future','previous'],
                                         undef,undef,1);
       my ($msg,@newsec,$oldsec,$currrole_expired,@changed_roles,
           %changed_groups,%dbroles,%deletedroles,%allroles,%allgroups,
           %userroles,%checkedgroup,%crprivs,$hasgroups,%rolechange,
           %groupchange,%newrole,%newgroup,%customprivchg,%groups_roles,
           @rolecodes);
       my @possroles = ('cr','st','ta','ad','ep','in','co','cc');
       my %courseroles;
       foreach my $item (keys(%roleshash)) {
           my ($uname,$udom,$role,$remainder) = split(/:/,$item,4);
           my ($tstart,$tend) = split(/:/,$roleshash{$item});
           my ($section,$group,@group_privs);
           if ($role =~ m{^gr/(\w*)$}) {
               $role = 'gr';
               my $priv = $1;
               next if ($tstart eq '-1');
               if (&curr_role_status($tstart,$tend,$refresh,$now) eq 'active') {
                   if ($priv ne '') {
                       push(@group_privs,$priv);
                   }
               }
               if ($remainder =~ /:/) {
                   (my $additional_privs,$group) =
                       ($remainder =~ /^([\w:]+):([^:]+)$/);
                   if ($additional_privs ne '') {
                       if (&curr_role_status($tstart,$tend,$refresh,$now) eq 'active') {
                           push(@group_privs,split(/:/,$additional_privs));
                           @group_privs = sort(@group_privs);
                       }
                   }
               } else {
                   $group = $remainder;
               }
           } else {
               $section = $remainder;
           }
           my $where = "/$udom/$uname";
           if ($section ne '') {
               $where .= "/$section";
           } elsif ($group ne '') {
               $where .= "/$group";
           }
           my $rolekey = "$role.$where";
           my $envkey = "user.role.$rolekey";
           $dbroles{$envkey} = 1;
           if (($env{'request.role'} eq $rolekey) && ($role ne 'st')) {
               if (&curr_role_status($tstart,$tend,$refresh,$now) ne 'active') {
                   $currrole_expired = 1;
               }
           }
           if ($env{$envkey} eq '') {
               my $status_in_db =
                   &curr_role_status($tstart,$tend,$now,$now);
                   &gather_roleprivs(\%allroles,\%allgroups,\%userroles,$where,$role,$tstart,$tend,$status_in_db);
               if (($role eq 'st') && ($env{'request.role'} =~ m{^\Q$role\E\.\Q/$udom/$uname\E})) {
                   if ($status_in_db eq 'active') {
                       if ($section eq '') {
                           push(@newsec,'none');
                       } else {
                           push(@newsec,$section);
                       }
                   }
               } else {
                   unless (grep(/^\Q$role\E$/,@changed_roles)) {
                       push(@changed_roles,$role);
                   }
                   if ($status_in_db ne 'previous') {
                       if ($role eq 'gr') {
                           $newgroup{$rolekey} = $status_in_db;
                           if ($status_in_db eq 'active') {
                               unless (ref($courseroles{$udom}) eq 'HASH') {
                                   %{$courseroles{$udom}} =
                                       &Apache::lonnet::get_my_roles('','','userroles',
                                                                     ['active'],\@possroles,
                                                                     [$udom],1);
                               }
                               &Apache::lonnet::get_groups_roles($udom,$uname,
                                                                 $courseroles{$udom},
                                                                 \@rolecodes,\%groups_roles);
                           }
                       } else {
                           $newrole{$rolekey} = $status_in_db;
                       }
                   }
               }
           } else {
               my ($currstart,$currend) = split(/\./,$env{$envkey});
               if ($role eq 'gr') {
                   if (&curr_role_status($currstart,$currend,$refresh,$update) ne 'previous') {
                       $hasgroups = 1;
                   }
               }
               if (($currstart ne $tstart) || ($currend ne $tend)) {
                   my $status_in_env =
                       &curr_role_status($currstart,$currend,$refresh,$update);
                   my $status_in_db =
                       &curr_role_status($tstart,$tend,$now,$now);
                   if ($status_in_env ne $status_in_db) {
                       if ($status_in_env eq 'active') {
                           if ($role eq 'st') {
                               if ($env{'request.role'} eq $rolekey) {
                                   my $switchsection;
                                   unless (ref($courseroles{$udom}) eq 'HASH') {
                                       %{$courseroles{$udom}} =
                                           &Apache::lonnet::get_my_roles('','','userroles',
                                                                         ['active'],
                                                                         \@possroles,[$udom],1);
                                   }
                                   foreach my $crsrole (keys(%{$courseroles{$udom}})) {
                                       if ($crsrole =~ /^\Q$uname\E:\Q$udom\E:st/) {
                                           $switchsection = 1;
                                           last;
                                       }
                                   }
                                   if ($switchsection) {
                                       if ($section eq '') {
                                           $oldsec = 'none';
                                       } else {
                                           $oldsec = $section;
                                       }
                                       &gather_roleprivs(\%allroles,\%allgroups,\%userroles,$where,$role,$tstart,$tend,$status_in_db);
                                   } else {
                                       $currrole_expired = 1;
                                       next;
                                   }
                               }
                           }
                           unless ($rolekey eq $env{'request.role'}) {
                               if ($role eq 'gr') {
                                   &Apache::lonnet::delete_env_groupprivs($where,\%courseroles,\@possroles);
                               } else {
                                   &Apache::lonnet::delenv("user.priv.$rolekey",undef,[$role]);
                                   &Apache::lonnet::delenv("user.priv.cm.$where",undef,['cm']);
                               }
                               &gather_roleprivs(\%allroles,\%allgroups,\%userroles,$where,$role,$tstart,$tend,$status_in_db);
                           }
                       } elsif ($status_in_db eq 'active') {
                           if (($role eq 'st') &&
                               ($env{'request.role'} =~ m{^\Q$role\E\.\Q/$udom/$uname\E})) {
                               if ($section eq '') {
                                   push(@newsec,'none');
                               } else {
                                   push(@newsec,$section);
                               }
                           } elsif ($role eq 'gr') {
                               unless (ref($courseroles{$udom}) eq 'HASH') {
                                   %{$courseroles{$udom}} =
                                       &Apache::lonnet::get_my_roles('','','userroles',
                                                                     ['active'],
                                                                     \@possroles,[$udom],1);
                               }
                               &Apache::lonnet::get_groups_roles($udom,$uname,
                                                                 $courseroles{$udom},
                                                                 \@rolecodes,\%groups_roles);
                           }
                           &gather_roleprivs(\%allroles,\%allgroups,\%userroles,$where,$role,$tstart,$tend,$status_in_db);
                       }
                       unless (grep(/^\Q$role\E$/,@changed_roles)) {
                           push(@changed_roles,$role);
                       }
                       if ($role eq 'gr') {
                           $groupchange{"/$udom/$uname"}{$group} = $status_in_db;
                       } else {
                           $rolechange{$rolekey} = $status_in_db;
                       }
                   }
               } else {
                   if ($role eq 'gr') {
                       unless ($checkedgroup{$where}) {
                           my $status_in_db =
                               &curr_role_status($tstart,$tend,$refresh,$now);
                           if ($tstart eq '-1') {
                               $status_in_db = 'deleted';
                           }
                           unless (ref($courseroles{$udom}) eq 'HASH') {
                               %{$courseroles{$udom}} =
                                   &Apache::lonnet::get_my_roles('','','userroles',
                                                                 ['active'],
                                                                 \@possroles,[$udom],1);
                           }
                           if (ref($courseroles{$udom}) eq 'HASH') {
                               foreach my $item (keys(%{$courseroles{$udom}})) {
                                   next unless ($item =~ /^\Q$uname\E/);
                                   my ($cnum,$cdom,$crsrole,$crssec) = split(/:/,$item);
                                   my $area = '/'.$cdom.'/'.$cnum;
                                   if ($crssec ne '') {
                                       $area .= '/'.$crssec;
                                   }
                                   my $crsrolekey = $crsrole.'.'.$area;
                                   my $currprivs = $env{'user.priv.'.$crsrole.'.'.$area.'.'.$where};
                                   $currprivs =~ s/^://;
                                   $currprivs =~ s/\&F$//;
                                   my @curr_grp_privs = split(/\&F:/,$currprivs);
                                   @curr_grp_privs = sort(@curr_grp_privs);
                                   my @diffs;
                                   if (@group_privs > 0 || @curr_grp_privs > 0) {
                                       @diffs = &Apache::loncommon::compare_arrays(\@group_privs,\@curr_grp_privs);
                                   }
                                   if (@diffs == 0) {
                                       last;
                                   } else {
                                       unless(grep(/^\Qgr\E$/,@rolecodes)) {
                                           push(@rolecodes,'gr');
                                       }
                                       &gather_roleprivs(\%allroles,\%allgroups,
                                                         \%userroles,$where,$role,
                                                         $tstart,$tend,$status_in_db);
                                       if ($status_in_db eq 'active') {
                                           &Apache::lonnet::get_groups_roles($udom,$uname,
                                                                             $courseroles{$udom},
                                                                             \@rolecodes,\%groups_roles);
                                       }
                                       $changed_groups{$udom.'_'.$uname}{$group} = $status_in_db;
                                       last;
                                   }
                               }
                           }
                           $checkedgroup{$where} = 1;
                       }
                   } elsif ($role =~ /^cr/) {
                       my $status_in_db =
                           &curr_role_status($tstart,$tend,$refresh,$now);
                       my ($rdummy,$rest) = split(/\//,$role,2);
                       my %currpriv;
                       unless (exists($crprivs{$rest})) {
                           my ($rdomain,$rauthor,$rrole)=split(/\//,$rest);
                           my $homsvr=&Apache::lonnet::homeserver($rauthor,$rdomain);
                           if (&Apache::lonnet::hostname($homsvr) ne '') {
                               my ($rdummy,$roledef)=
                               &Apache::lonnet::get('roles',["rolesdef_$rrole"],
                                                    $rdomain,$rauthor);
                               if (($rdummy ne 'con_lost') && ($roledef ne '')) {
                                   my $i = 0;
                                   my @scopes = ('sys','dom','crs');
                                   my @privs = split(/\_/,$roledef);
                                   foreach my $priv (@privs) {
                                       my ($blank,@prv) = split(/:/,$priv);
                                       @prv = map { $_ .= (/\&\w+$/ ? '':'&F') } @prv;
                                       if (@prv) {
                                           $priv = ':'.join(':',sort(@prv));
                                       }
                                       $crprivs{$rest}{$scopes[$i]} = $priv;
                                       $i++;
                                   }
                               }
                           }
                       }
                       my $status_in_env =
                           &curr_role_status($currstart,$currend,$refresh,$update);
                       if ($status_in_env eq 'active') {
                           $currpriv{sys} = $env{"user.priv.$rolekey./"};
                           $currpriv{dom} = $env{"user.priv.$rolekey./$udom/"};
                           $currpriv{crs} = $env{"user.priv.$rolekey.$where"};
                           if (keys(%crprivs)) {
                               if (($crprivs{$rest}{sys} ne $currpriv{sys}) ||
                                   ($crprivs{$rest}{dom} ne $currpriv{dom})
    ||
                                   ($crprivs{$rest}{crs} ne $currpriv{crs})) {
                                   &gather_roleprivs(\%allroles,\%allgroups,
                                                     \%userroles,$where,$role,
                                                     $tstart,$tend,$status_in_db);
                                   unless (grep(/^\Q$role\E$/,@changed_roles)) {
                                       push(@changed_roles,$role);
                                   }
                                   $customprivchg{$rolekey} = $status_in_env;
                               }
                           }
                       }
                   }
               }
           }
       }
       foreach my $envkey (keys(%env)) {
           next unless ($envkey =~ /^user\.role\./);
           next if ($dbroles{$envkey});
           next if ($envkey eq 'user.role.'.$env{'request.role'});
           my ($currstart,$currend) = split(/\./,$env{$envkey});
           my $status_in_env =
               &curr_role_status($currstart,$currend,$refresh,$update);
           my ($rolekey) = ($envkey =~ /^user\.role\.(.+)$/);
           my ($role,$rest)=split(m{\./},$rolekey,2);
           $rest = '/'.$rest;
           if (&Apache::lonnet::delenv($envkey,undef,[$role])) {
               if ($status_in_env eq 'active') {
                   if ($role eq 'gr') {
                       &Apache::lonnet::delete_env_groupprivs($rest,\%courseroles,
                                                              \@possroles);
                   } else {
                       &Apache::lonnet::delenv("user.priv.$rolekey",undef,[$role]);
                       &Apache::lonnet::delenv("user.priv.cm.$rest",undef,['cm']);
                   }
                   unless (grep(/^\Q$role\E$/,@changed_roles)) {
                       push(@changed_roles,$role);
                   }
                   $deletedroles{$rolekey} = 1;
               }
           }
       }
       if (($oldsec) && (@newsec > 0)) {
           if (@newsec > 1) {
               $msg = '<p class="LC_warning">'.&mt('The section has changed for your current role. Log-out and log-in again to select a role for the new section.').'</p>';
           } else {
               my $newrole = $env{'request.role'};
               if ($newsec[0] eq 'none') {
                   $newrole =~ s{(/[^/])$}{};
               } elsif ($oldsec eq 'none') {
                   $newrole .= '/'.$newsec[0];
               } else {
                   $newrole =~ s{([^/]+)$}{$newsec[0]};
               }
               my $coursedesc = $env{'course.'.$env{'request.course.id'}.'.description'};
               my ($curr_role) = ($env{'request.role'} =~ m{^(\w+)\./$match_domain/$match_courseid});
               my %temp=('logout_'.$env{'request.course.id'} => time);
               &Apache::lonnet::put('email_status',\%temp);
               &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});
               &Apache::lonnet::appenv({"request.course.id"   => '',
                                        "request.course.fn"   => '',
                                        "request.course.uri"  => '',
                                        "request.course.sec"  => '',
                                        "request.role"        => 'cm',
                                        "request.role.adv"    => $env{'user.adv'},
                                        "request.role.domain" => $env{'user.domain'}});
               my $rolename = &Apache::loncommon::plainname($curr_role);
               $msg = '<p><form name="reselectrole" action="/adm/roles" method="post" />'.
                      '<input type="hidden" name="newrole" value="" />'.
                      '<input type="hidden" name="selectrole" value="1" />'.
                      '<span class="LC_info">'.
                      &mt('Your section has changed for your current [_1] role in [_2].',$rolename,$coursedesc).'</span><br />';
               my $button = '<input type="button" name="sectionchanged" value="'.
                            &mt('Re-Select').'" onclick="javascript:enterrole(this.form,'."'$newrole','sectionchanged'".')" />';
               if ($newsec[0] eq 'none') {
                   $msg .= &mt('[_1] to continue with your new section-less role.',$button);
               } else {
                   $msg .= &mt('[_1] to continue with your new role in section ([_2]).',$button,$newsec[0]);
               }
               $msg .= '</form></p>';
           }
       } elsif ($currrole_expired) {
           $msg .= '<p class="LC_warning">';
           if (&Apache::loncommon::show_course()) {
               $msg .= &mt('Your role in the current course has expired.');
           } else {
               $msg .= &mt('Your current role has expired.');
           }
           $msg .= '<br />'.&mt('However you can continue to use this role until you logout, click the "Re-Select" button, or your session has been idle for more than 24 hours.').'</p>';
       }
       &Apache::lonnet::set_userprivs(\%userroles,\%allroles,\%allgroups,\%groups_roles);
       my ($curr_is_adv,$curr_role_adv,$curr_author,$curr_role_author);
       $curr_author = $env{'user.author'};
       if (($env{'request.role'} =~/^au/) || ($env{'request.role'} =~/^ca/) ||
           ($env{'request.role'} =~/^aa/)) {
           $curr_role_author=1;
       }
       $curr_is_adv = $env{'user.adv'};
       $curr_role_adv = $env{'request.role.adv'};
       if (keys(%userroles) > 0) {
           foreach my $role (@changed_roles) {
               unless(grep(/^\Q$role\E$/,@rolecodes)) {
                   push(@rolecodes,$role);
               }
           }
           unless(grep(/^\Qcm\E$/,@rolecodes)) {
               push(@rolecodes,'cm');
           }
           &Apache::lonnet::appenv(\%userroles,\@rolecodes);
       }
       my %newenv;
       if (&Apache::lonnet::is_advanced_user($env{'user.domain'},$env{'user.name'})) {
           unless ($curr_is_adv) {
               $newenv{'user.adv'} = 1;
           }
       } elsif ($curr_is_adv && !$curr_role_adv) {
           &Apache::lonnet::delenv('user.adv');
       }
       my %authorroleshash =
           &Apache::lonnet::get_my_roles('','','userroles',['active'],['au','ca','aa']);
       if (keys(%authorroleshash)) {
           unless ($curr_author) {
               $newenv{'user.author'} = 1;
           }
       } elsif ($curr_author && !$curr_role_author) {
           &Apache::lonnet::delenv('user.author');
       }
       if ($env{'request.course.id'}) {
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           my (@activecrsgroups,$crsgroupschanged);
           if ($env{'request.course.groups'}) {
               @activecrsgroups = split(/:/,$env{'request.course.groups'});
               foreach my $item (keys(%deletedroles)) {
                   if ($item =~ m{^gr\./\Q$cdom\E/\Q$cnum\E/(\w+)$}) {
                       if (grep(/^\Q$1\E$/,@activecrsgroups)) {
                           $crsgroupschanged = 1;
                           last;
                       }
                   }
               }
           }
           unless ($crsgroupschanged) {
               foreach my $item (keys(%newgroup)) {
                   if ($item =~ m{^gr\./\Q$cdom\E/\Q$cnum\E/(\w+)$}) {
                       if ($newgroup{$item} eq 'active') {
                           $crsgroupschanged = 1;
                           last;
                       }
                   }
               }
           }
           if ((ref($changed_groups{$env{'request.course.id'}}) eq 'HASH') ||
               (ref($groupchange{"/$cdom/$cnum"}) eq 'HASH') ||
               ($crsgroupschanged)) {
               my %grouproles =  &Apache::lonnet::get_my_roles('','','userroles',
                                                               ['active'],['gr'],[$cdom],1);
               my @activegroups;
               foreach my $item (keys(%grouproles)) {
                   next unless($item =~ /^\Q$cnum\E:\Q$cdom\E/);
                   my $group;
                   my ($crsn,$crsd,$role,$remainder) = split(/:/,$item,4);
                   if ($remainder =~ /:/) {
                       (my $other,$group) = ($remainder =~ /^([\w:]+):([^:]+)$/);
                   } else {
                       $group = $remainder;
                   }
                   if ($group ne '') {
                       push(@activegroups,$group);
                   }
               }
               $newenv{'request.course.groups'} = join(':',@activegroups);
           }
       }
       if (keys(%newenv)) {
           &Apache::lonnet::appenv(\%newenv);
       }
       if (!@changed_roles || !(keys(%changed_groups))) {
           my ($rolesmsg,$groupsmsg);
           if (!@changed_roles) {
               if (&Apache::loncommon::show_course()) {
                   $rolesmsg = &mt('No new courses or communities');
               } else {
                   $rolesmsg = &mt('No role changes');
               }
           }
           if ($hasgroups && !(keys(%changed_groups)) && !(grep(/gr/,@changed_roles))) {
               $groupsmsg = &mt('No changes in course/community groups');
           }
           if (!@changed_roles && !(keys(%changed_groups))) {
               if (($msg ne '') || ($groupsmsg ne '')) {
                   $msg .= '<ul>';
                   if ($rolesmsg) {
                       $msg .= '<li>'.$rolesmsg.'</li>';
                   }
                   if ($groupsmsg) {
                       $msg .= '<li>'.$groupsmsg.'</li>';
                   }
                   $msg .= '</ul>';
               } else {
                   $msg = '&nbsp;<span class="LC_cusr_emph">'.$rolesmsg.'</span><br />';
               }
               return $msg;
           }
       }
       my $changemsg;
       if (@changed_roles > 0) {
           if (keys(%newgroup) > 0) {
               my $groupmsg;
               my (%curr_groups,%groupdescs,$currcrs);
               foreach my $item (sort(keys(%newgroup))) {
                   if (&is_active_course($item,$refresh,$update,\%roleshash)) {
                       if ($item =~ m{^gr\./($match_domain/$match_courseid)/(\w+)$}) {
                           my ($cdom,$cnum) = split(/\//,$1);
                           my $group = $2;
                           if ($currcrs ne $cdom.'_'.$cnum) {
                               if ($currcrs) {
                                   $groupmsg .= '</ul><li>';
                               }
                               $groupmsg .= '<li><b>'.
                                            $env{'course.'.$cdom.'_'.$cnum.'.description'}.'</b><ul>';
                               $currcrs = $cdom.'_'.$cnum;
                           }
                           my $groupdesc;
                           unless (ref($curr_groups{$cdom.'_'.$cnum}) eq 'HASH') {
                               %{$curr_groups{$cdom.'_'.$cnum}} = 
                                   &Apache::longroup::coursegroups($cdom,$cnum);
                           }
                           unless ((ref($groupdescs{$cdom.'_'.$cnum}) eq 'HASH') &&
                               ($groupdescs{$cdom.'_'.$cnum}{$group})) {
   
                               my %groupinfo = 
                                   &Apache::longroup::get_group_settings($curr_groups{$cdom.'_'.$cnum}{$group});
                               $groupdescs{$cdom.'_'.$cnum}{$group} = 
                                   &unescape($groupinfo{'description'});
                           }
                           $groupdesc = $groupdescs{$cdom.'_'.$cnum}{$group};
                           if ($groupdesc) {
                               $groupmsg .= '<li>'.
                                            &mt('[_1] with status: [_2].',
                                            '<b>'.$groupdesc.'</b>',$newgroup{$item}).'</li>';
                           }
                       }
                   }
                   if ($groupmsg) {
                       $groupmsg .= '</ul></li>';
                   }
               }
               if ($groupmsg) {
                   $changemsg .= '<li>'.
                                 &mt('Courses with new groups').'</li>'.
                                 '<ul>'.$groupmsg.'</ul></li>';
               }
           }
           if (keys(%newrole) > 0) {
               my $newmsg;
               foreach my $item (sort(keys(%newrole))) {
                   my $desc = &role_desc($item,$update,$refresh,$now);
                   if ($desc) {
                       $newmsg .= '<li>'.
                                  &mt('[_1] with status: [_2].',
                                  $desc,&mt($newrole{$item})).'</li>';
                   }
               }
               if ($newmsg) {
                   $changemsg .= '<li>'.&mt('New roles').
                                 '<ul>'.$newmsg.'</ul>'.
                                 '</li>';
               }
           }
           if (keys(%customprivchg) > 0) {
               my $privmsg;
               foreach my $item (sort(keys(%customprivchg))) {
                   my $desc = &role_desc($item,$update,$refresh,$now);
                   if ($desc) {
                       $privmsg .= '<li>'.$desc.'</li>';
                   }
               }
               if ($privmsg) {
                   $changemsg .= '<li>'.
                                 &mt('Custom roles with privilege changes').
                                 '<ul>'.$privmsg.'</ul>'.
                                 '</li>';
                }
           }
           if (keys(%rolechange) > 0) {
               my $rolemsg;
               foreach my $item (sort(keys(%rolechange))) {
                   my $desc = &role_desc($item,$update,$refresh,$now);  
                   if ($desc) {
                       $rolemsg .= '<li>'.
                                   &mt('[_1] status now: [_2].',$desc,
                                   $rolechange{$item}).'</li>';
                   }
               }
               if ($rolemsg) {
                   $changemsg .= '<li>'.
                                 &mt('Existing roles with status changes').'</li>'.
                                 '<ul>'.$rolemsg.'</ul>'.
                                 '</li>';
               }
           }
           if (keys(%deletedroles) > 0) {
               my $delmsg;
               foreach my $item (sort(keys(%deletedroles))) {
                   my $desc = &role_desc($item,$update,$refresh,$now);
                   if ($desc) {
                       $delmsg .= '<li>'.$desc.'</li>';
                   }
               }
               if ($delmsg) {
                   $changemsg .= '<li>'.
                                 &mt('Existing roles now expired').'</li>'.
                                 '<ul>'.$delmsg.'</ul>'.
                                 '</li>';
               }
           }
       }
       if ((keys(%changed_groups) > 0) || (keys(%groupchange) > 0)) {
           my $groupchgmsg;
           foreach my $key (sort(keys(%changed_groups))) {
               my $crs = 'gr/'.$key;
               $crs =~ s/_/\//;
               if (&is_active_course($crs,$refresh,$update,\%roleshash)) {
                   if (ref($changed_groups{$key}) eq 'HASH') {
                       my @showgroups;
                       foreach my $group (sort(keys(%{$changed_groups{$key}}))) {
                           if ($changed_groups{$key}{$group} eq 'active') {
                               push(@showgroups,$group);
                           }
                       }
                       if (@showgroups > 0) {
                           $groupchgmsg .= '<li>'.
                                           &mt('Course: [_1], groups: [_2].',$key,
                                           join(', ',@showgroups)).
                                           '</li>';
                       }
                   }
               }
           }
           if (keys(%groupchange) > 0) {
               $groupchgmsg .= '<li>'.
                             &mt('Existing course/community groups with status changes').'</li>'.
                             '<ul>';
               foreach my $crs (sort(keys(%groupchange))) {
                   my $cid = $crs;
                   $cid=~s{^/}{};
                   $cid=~s{/}{_};
                   my $crsdesc = $env{'course.'.$cid.'.description'};
                   my $cdom = $env{'course.'.$cid.'.domain'};
                   my $cnum = $env{'course.'.$cid.'.num'};
                   my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
                   my %groupdesc; 
                   if (ref($groupchange{$crs}) eq 'HASH') {
                       $groupchgmsg .= '<li>'.&mt('Course/Community: [_1]','<b>'.$crsdesc.'</b><ul>');
                       foreach my $group (sort(keys(%{$groupchange{$crs}}))) {
                           unless ($groupdesc{$group}) {
                               my %groupinfo = &Apache::longroup::get_group_settings($curr_groups{$group});
                               $groupdesc{$group} =  &unescape($groupinfo{'description'});
                           }
                           $groupchgmsg .= '<li>'.&mt('Group: [_1] status now: [_2].','<b>'.$groupdesc{$group}.'</b>',$groupchange{$crs}{$group}).'</li>';
                       }
                       $groupchgmsg .= '</ul></li>';
                   }
               }
               $groupchgmsg .= '</ul></li>';
           }
           if ($groupchgmsg) {
               $changemsg .= '<li>'.
                             &mt('Courses with changes in groups').'</li>'.
                             '<ul>'.$groupchgmsg.'</ul></li>';
           }
       }
       if ($changemsg) {
           $msg .= '<ul>'.$changemsg.'</ul>';
       } else {
           if (&Apache::loncommon::show_course()) {
               $msg = &mt('No new courses or communities');
           } else {
               $msg = &mt('No role changes');
           }
       }
       return $msg;
   }
   
   sub role_desc {
       my ($item,$update,$refresh,$now) = @_;
       my ($where,$trolecode,$role,$tstatus,$tend,$tstart,$twhere,
           $trole,$tremark);
       &Apache::lonnet::role_status('user.role.'.$item,$update,$refresh,
                                    $now,\$role,\$where,\$trolecode,
                                    \$tstatus,\$tstart,\$tend);
       return unless ($role);
       if ($role =~ /^cr\//) {
           my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);
           $tremark = &mt('Custom role defined by [_1].',$rauthor.':'.$rdomain);
       }
       $trole=Apache::lonnet::plaintext($role);
       my ($tdom,$trest,$tsection)=
           split(/\//,Apache::lonnet::declutter($where));
       if (($role eq 'ca') || ($role eq 'aa')) {
           my $home = &Apache::lonnet::homeserver($trest,$tdom);
           $home = &Apache::lonnet::hostname($home);
           $twhere=&mt('User').':&nbsp;'.$trest.'&nbsp; '.&mt('Domain').
                   ':&nbsp;'.$tdom.'&nbsp; '.&mt('Server').':&nbsp;'.$home;
       } elsif ($role eq 'au') {
           my $home = &Apache::lonnet::homeserver
                          ($env{'user.name'},$env{'user.domain'});
           $home = &Apache::lonnet::hostname($home);
           $twhere=&mt('Domain').':&nbsp;'.$tdom.'&nbsp; '.&mt('Server').
                           ':&nbsp;'.$home;
       } elsif ($trest) {
           my $tcourseid=$tdom.'_'.$trest;
           my $crstype = &Apache::loncommon::course_type($tcourseid);
           $trole = &Apache::lonnet::plaintext($role,$crstype,$tcourseid);
           if ($env{'course.'.$tcourseid.'.description'}) {
               $twhere=$env{'course.'.$tcourseid.'.description'};
           } else {
               my %newhash=&Apache::lonnet::coursedescription($tcourseid);
               if (%newhash) {
                   $twhere=$newhash{'description'};
               } else {
                   $twhere=&mt('Currently not available');
               }
           }
           if ($tsection) {
               $twhere.= '&nbsp; '.&mt('Section').':&nbsp;'.$tsection;
           }
           if ($role ne 'st') {
               $twhere.= '&nbsp; '.&mt('Domain').':&nbsp;'.$tdom;
           }
       } elsif ($tdom) {
           $twhere = &mt('Domain').':&nbsp;'.$tdom;
       }
       my $output;
       if ($trole) {
           $output = $trole;
           if ($twhere) {
               $output .= " -- $twhere";
           }
           if ($tremark) {
               $output .= '<br />'.$tremark;
           }
       }
       return $output;
   }
   
   sub curr_role_status {
       my ($start,$end,$refresh,$update) = @_;
       if (($start) && ($start<0)) { return 'deleted' };
       my $status = 'active';
       if (($end) && ($end<=$update)) {
           $status = 'previous';
       }
       if (($start) && ($refresh<$start)) {
           $status = 'future';
       }
       return $status;
   }
   
   sub gather_roleprivs {
       my ($allroles,$allgroups,$userroles,$area,$role,$tstart,$tend,$status) = @_;
       return unless ((ref($allroles) eq 'HASH') && (ref($allgroups) eq 'HASH') && (ref($userroles) eq 'HASH'));
       if (($area ne '') && ($role ne '')) {
           &Apache::lonnet::userrolelog($role,$env{'user.name'},$env{'user.domain'},
                                        $area,$tstart,$tend);
           my $spec=$role.'.'.$area;
           $userroles->{'user.role.'.$spec} = $tstart.'.'.$tend;
           my ($tdummy,$tdomain,$trest)=split(/\//,$area);
           if ($status eq 'active') { 
               if ($role =~ /^cr\//) {
                   &Apache::lonnet::custom_roleprivs($allroles,$role,$tdomain,$trest,$spec,$area);
               } elsif ($role eq 'gr') {
                   my %rolehash = &Apache::lonnet::get('roles',[$area.'_'.$role],
                                                       $env{'user.domain'},
                                                       $env{'user.name'});
                   my ($trole) = split(/_/,$rolehash{$area.'_'.$role},2);
                   (undef,my $group_privs) = split(/\//,$trole);
                   $group_privs = &unescape($group_privs);
                   &Apache::lonnet::group_roleprivs($allgroups,$area,$group_privs,$tend,$tstart);
               } else {
                   &Apache::lonnet::standard_roleprivs($allroles,$role,$tdomain,$spec,$trest,$area);
               }
           }
       }
       return;
   }
   
   sub is_active_course {
       my ($rolekey,$refresh,$update,$roleshashref) = @_;
       return unless(ref($roleshashref) eq 'HASH');
       my ($role,$cdom,$cnum) = split(/\//,$rolekey);
       my $is_active;
       foreach my $key (keys(%{$roleshashref})) {
           if ($key =~ /^\Q$cnum\E:\Q$cdom\E:/) {
               my ($tstart,$tend) = split(/:/,$roleshashref->{$key});
               my $status = &curr_role_status($tstart,$tend,$refresh,$update);
               if ($status eq 'active') {
                   $is_active = 1;
                   last;
               }
           }
       }
       return $is_active;
   }
   
   sub get_roles_functions {
       my ($rolescount,$cattype) = @_;
       my @links;
       push(@links,["javascript:rolesView('doupdate');",'start-here-22x22',&mt('Check for changes')]);
       if ($env{'environment.canrequest.author'}) {
           unless (&Apache::loncoursequeueadmin::is_active_author()) {
               push(@links,["javascript:rolesView('requestauthor');",'list-add-22x22',&mt('Request author role')]);
           }
       }
       if (($rolescount > 3) || ($env{'environment.recentroles'})) {
           push(@links,['/adm/preferences?action=changerolespref&amp;returnurl=/adm/roles','role_hotlist-22x22',&mt('Hotlist')]);
       }
       if (&Apache::lonmenu::check_for_rcrs()) {
           push(@links,['/adm/requestcourse','rcrs-22x22',&mt('Request course')]);
       }
       if ($env{'form.state'} eq 'queued') {
           push(@links,["javascript:rolesView('noqueued');",'selfenrl-queue-22x22',&mt('Hide queued')]);
       } else {
           push(@links,["javascript:rolesView('queued');",'selfenrl-queue-22x22',&mt('Show queued')]);
       }
       if ($env{'user.adv'}) {
           if ($env{'form.display'} eq 'showall') {
               push(@links,["javascript:rolesView('noshowall');",'edit-redo-22x22',&mt('Exclude expired')]);
           } else {
               push(@links,["javascript:rolesView('showall');",'edit-undo-22x22',&mt('Include expired')]);
           }
       }
       unless ($cattype eq 'none') {
           push(@links,['/adm/coursecatalog','ccat-22x22',&mt('Course catalog')]);
       }
       my $funcs;
       if ($env{'browser.mobile'}) {
           my @functions;
           foreach my $link (@links) {
               push(@functions,[$link->[0],$link->[2]]);
           }
           my $title = 'Display options';
           if ($env{'user.adv'}) {
               $title = 'Roles options';
           }
           $funcs = &Apache::lonmenu::create_submenu('','',$title,\@functions,1,'LC_breadcrumbs_hoverable');
           $funcs = '<ol class="LC_primary_menu LC_floatright">'.$funcs.'</ol>';
       } else {
           $funcs = &Apache::lonhtmlcommon::start_funclist();
           foreach my $link (@links) {
               $funcs .= &Apache::lonhtmlcommon::add_item_funclist(
                             '<a href="'.$link->[0].'" class="LC_menubuttons_link">'.
                             '<img src="/res/adm/pages/'.$link->[1].'.png" class="LC_icon" alt="'.$link->[2].'" />'.
                             $link->[2].'</a>');
           }
           $funcs .= &Apache::lonhtmlcommon::end_funclist();
           $funcs = &Apache::loncommon::head_subbox($funcs);
       }
       return $funcs;
   }
   
   sub get_queued {
       my ($output,%reqcrs);
       my ($types,$typenames) = &Apache::loncommon::course_types();
       my %statusinfo = &Apache::lonnet::dump('courserequests',$env{'user.domain'},
                                              $env{'user.name'},'^status:');
       foreach my $key (keys(%statusinfo)) {
           next unless (($statusinfo{$key} eq 'approval') || ($statusinfo{$key} eq 'pending'));
           (undef,my($cdom,$cnum)) = split(/:/,$key);
           my $requestkey = $cdom.'_'.$cnum;
           if ($requestkey =~ /^($match_domain)_($match_courseid)$/) {
               my %history = &Apache::lonnet::restore($requestkey,'courserequests',
                                                      $env{'user.domain'},$env{'user.name'});
               next if ((exists($history{'status'})) && ($history{'status'} eq 'created'));
               my $reqtime = $history{'reqtime'};
               my $lastupdate = $history{'timestamp'};
               my $showtype = $history{'crstype'};
               if (defined($typenames->{$history{'crstype'}})) {
                   $showtype = $typenames->{$history{'crstype'}};
               }
               my $description;
               if (ref($history{'details'}) eq 'HASH') {
                   $description = $history{details}{'cdescr'};
               }
               @{$reqcrs{$reqtime}} = ($description,$showtype); 
           }
       }
       my @sortedtimes = sort {$a <=> $b} (keys(%reqcrs));
       if (@sortedtimes > 0) {
           $output .= '<p><b>'.&mt('Course/Community requests').'</b><br />'.
                      &Apache::loncommon::start_data_table().
                      &Apache::loncommon::start_data_table_header_row().
                      '<th>'.&mt('Date requested').'</th>'.
                      '<th>'.&mt('Course title').'</th>'.
                      '<th>'.&mt('Course type').'</th>';
                      &Apache::loncommon::end_data_table_header_row();
           foreach my $reqtime (@sortedtimes) {
               next unless (ref($reqcrs{$reqtime}) eq 'ARRAY');
               $output .= &Apache::loncommon::start_data_table_row().
                          '<td>'.&Apache::lonlocal::locallocaltime($reqtime).'</td>'.
                          '<td>'.join('</td><td>',@{$reqcrs{$reqtime}}).'</td>'.
                          &Apache::loncommon::end_data_table_row();
           }
           $output .= &Apache::loncommon::end_data_table().
                      '<br /></p>';
       }
       my $queuedselfenroll = &Apache::loncoursequeueadmin::queued_selfenrollment(1);
       if ($queuedselfenroll) {
           $output .= '<p><b>'.&mt('Enrollment requests').'</b><br />'.
                      $queuedselfenroll.'<br /></p>';
       }
       if ($env{'environment.canrequest.author'}) {
           unless (&Apache::loncoursequeueadmin::is_active_author()) {
               my $requestauthor;
               my ($status,$timestamp) = split(/:/,$env{'environment.requestauthorqueued'});
               if (($status eq 'approval') || ($status eq 'approved')) {
                   $output .= '<p><b>'.&mt('Author role request').'</b><br />';
                   if ($status eq 'approval') {
                       $output .= &mt('A request for Authoring Space submitted on [_1] is awaiting approval',
                                     &Apache::lonlocal::locallocaltime($timestamp));
                   } elsif ($status eq 'approved') {
                       my %roleshash =
                           &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
                                                         ['active'],['au'],[$env{'user.domain'}]);
                       if (keys(%roleshash)) {
                           $output .= '<span class="LC_info">'.
                                      &mt('Your request for an author role has been approved.').'<br />'.
                                      &mt('Use the "Check for changes" link to update your list of roles.').
                                      '</span>';
                       }
                   }
                   $output .= '</p>';
               }
           }
       }
       unless ($output) {
           if ($env{'environment.canrequest.author'} || $env{'environment.canrequest.official'} ||
               $env{'environment.canrequest.unofficial'} || $env{'environment.canrequest.community'}) {
               $output = &mt('No requests for courses, communities or authoring currently queued');
           } else {
               $output = &mt('No enrollment requests currently queued awaiting approval');
           }
       }
       return '<div class="LC_left_float"><fieldset><legend>'.&mt('Queued requests').'</legend>'.
              $output.'</fieldset></div><br clear="all" />';
   }
   
 1;  1;
 __END__  __END__
   
Line 1782  course they should act on, etc. Both in Line 2939  course they should act on, etc. Both in
 handler determines via C<lonnet>'s C<&allowed> function that a certain  handler determines via C<lonnet>'s C<&allowed> function that a certain
 action is not allowed, C<lonroles> is used as error handler. This  action is not allowed, C<lonroles> is used as error handler. This
 allows the user to select another role which may have permission to do  allows the user to select another role which may have permission to do
 what they were trying to do. C<lonroles> can also be accessed via the  what they were trying to do.
 B<CRS> button in the Remote Control.   
   
 =begin latex  =begin latex
   

Removed from v.1.240.2.19  
changed lines
  Added in v.1.315


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>