Diff for /loncom/auth/lonroles.pm between versions 1.231.4.15 and 1.311

version 1.231.4.15, 2010/08/20 03:40:01 version 1.311, 2015/04/13 18:32:43
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 138  use Apache::lonannounce; Line 137  use Apache::lonannounce;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonpageflip();  use Apache::lonpageflip();
 use Apache::lonnavdisplay();  use Apache::lonnavdisplay();
   use Apache::loncoursequeueadmin;
   use Apache::longroup;
   use Apache::lonrss;
 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
       my $brcrum = [{'href' => $url,
                      'text' => 'Switching Role'},];
     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,});
     my $end_page   = &Apache::loncommon::end_page();      my $end_page   = &Apache::loncommon::end_page();
   
 # Note to style police:   # Note to style police: 
Line 167  sub redirect_user { Line 165  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 185  sub error_page { Line 177  sub error_page {
     &Apache::loncommon::no_cache($r);      &Apache::loncommon::no_cache($r);
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
     $r->print(&Apache::loncommon::start_page('Problems during Course Initialization').      # Breadcrumbs
       my $brcrum = [{'href' => $dest,
                      'text' => 'Problems during Course Initialization'},];
       $r->print(&Apache::loncommon::start_page('Problems during Course Initialization',
                                                undef,
                                                {'bread_crumbs' => $brcrum,})
       );
       $r->print(
         '<script type="text/javascript">'.          '<script type="text/javascript">'.
         '// <![CDATA['.          '// <![CDATA['.
         &Apache::lonmenu::rawconfig().          &Apache::lonmenu::rawconfig().
         '// ]]>'.          '// ]]>'.
         '</script>'.          '</script>'.
       '<p class="LC_error">'.&mt('The following problems occurred:').        '<p class="LC_error">'.&mt('The following problems occurred:').
               '<br />'.            '<br />'.
       $error.        $error.
       '</p><br /><a href="'.$dest.'">'.&mt('Continue').'</a>'.        '</p><br /><a href="'.$dest.'">'.&mt('Continue').'</a>'
               &Apache::loncommon::end_page());      );
       $r->print(&Apache::loncommon::end_page());
 }  }
   
 sub handler {  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');
   
 # ================================================================== Roles Init  # ================================================================== Roles Init
     if ($env{'form.selectrole'}) {      if ($env{'form.selectrole'}) {
Line 229  sub handler { Line 273  sub handler {
                 if (defined($env{'user.role.'.$env{'form.switchrole'}})) {                  if (defined($env{'user.role.'.$env{'form.switchrole'}})) {
                     my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});                      my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
                     if (!$end || $end > $now) {                      if (!$end || $end > $now) {
                         if (!$start || $start < $refresh) {                          if (!$start || $start < $update) {
                             $switch_is_active = 1;                              $switch_is_active = 1;
                         }                          }
                     }                      }
                 }                  }
                 unless ($switch_is_active) {                  unless ($switch_is_active) {
                     &adhoc_course_role($refresh,$then);                      &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 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) {          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 272  sub handler { Line 320  sub handler {
                             my $trolecode = 'au./'.$domain.'/';                              my $trolecode = 'au./'.$domain.'/';
                             my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;                              my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                             $r->internal_redirect($switchserver);                              $r->internal_redirect($switchserver);
                               return OK;
                         }                          }
                         last;                          last;
                     }                      }
Line 283  sub handler { Line 332  sub handler {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                  my $trolecode = 'ca./'.$domain.'/'.$user;
                                 my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;                                  my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                             last;                              last;
                         }                          }
Line 297  sub handler { Line 347  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.'&amp;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 316  sub handler { Line 367  sub handler {
             }              }
         }          }
   
         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 444  ENDENTERKEY Line 514  ENDENTERKEY
                         my $msg;                          my $msg;
  my ($furl,$ferr)=   my ($furl,$ferr)=
     &Apache::lonuserstate::readmap($cdom.'/'.$cnum);      &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                           unless ($ferr) {
                               unless (($env{'form.switchrole'}) || 
                                       ($env{"environment.internal.$cdom.$cnum.$role.adhoc"})) {
                                   &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'};
                             }                              }
Line 460  ENDENTERKEY Line 553  ENDENTERKEY
                             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 483  ENDENTERKEY Line 583  ENDENTERKEY
     } 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 (substr($courseid, 0, 1) eq '/') {  
     $courseid = substr($courseid, 1);  
  }  
  $courseid =~ s/\//_/;  
  if ((($role eq 'cc') || ($role eq 'co'))    if ((($role eq 'cc') || ($role eq 'co')) 
                                       && ($env{'course.' . $courseid .'.course.helper.not.run'})) {                                       && ($env{'course.'.$cdom.'_'.$cnum.'.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'}) {                                      my ($dest,$destsymb,$checkenc);
                                         my $dest = $env{'form.destinationurl'};                                      $dest = $env{'form.destinationurl'};
                                         if ($env{'form.destsymb'} ne '') {                                      $destsymb = $env{'form.destsymb'};
                                             my $esc_symb = &HTML::Entities::encode($env{'form.destsymb'},'"<>&');                                      if ($dest ne '') {
                                             $dest .= '?symb='.$esc_symb;                                          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);
                                                       }
                                                   }
                                               }
                                         }                                          }
                                         &redirect_user($r,&mt('Entering [_1]',                                          unless (($dest =~ m{^/enc/}) || ($dest =~ /(\?|\&)symb=.+___\d+___.+/)) {
                                                       $env{'course.'.$courseid.'.description'}),                                              if (($destsymb ne '') && ($destsymb !~ m{^/enc/})) {
                                                $dest,$msg,                                                  my $esc_symb = &escape($destsymb);
                                                $env{'environment.remotenavmap'});                                                  $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 511  ENDENTERKEY Line 646  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') {            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
                                       my ($exturl,$symb) = ($furl =~ m{^(.+)(?:\?|\&)symb=(.+)$});
                                       # 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 542  ENDENTERKEY Line 689  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 580  ENDENTERKEY Line 726  ENDENTERKEY
     my $crumbtext = 'User Roles';      my $crumbtext = 'User Roles';
     my $pagetitle = 'My Roles';      my $pagetitle = 'My Roles';
     my $recent = &mt('Recent Roles');      my $recent = &mt('Recent Roles');
       my $standby = &mt('Role selected. Please stand by.');
     my $show_course=&Apache::loncommon::show_course();      my $show_course=&Apache::loncommon::show_course();
     if ($show_course) {      if ($show_course) {
         $crumbtext = 'Courses';          $crumbtext = 'Courses';
         $pagetitle = 'My Courses';          $pagetitle = 'My Courses';
         $recent = &mt('Recent Courses');          $recent = &mt('Recent Courses');
           $standby = &mt('Course selected. Please stand by.'); 
     }      }
     my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}];      my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}];
   
       my %roles_in_env;
       my $showcount = &roles_from_env(\%roles_in_env,$update); 
   
     my $swinfo=&Apache::lonmenu::rawconfig();      my $swinfo=&Apache::lonmenu::rawconfig();
     my $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum});      my $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum});
     my $standby=&mt('Role selected. Please stand by.');      my %domdefs=&Apache::lonnet::get_domain_defaults($env{'user.domain'}); 
       my $cattype = 'std';
       if ($domdefs{'catauth'}) {
           $cattype = $domdefs{'catauth'};
       }
       my $funcs = &get_roles_functions($showcount,$cattype);
     $standby=~s/\n/\\n/g;      $standby=~s/\n/\\n/g;
     my $noscript='<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 $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);      $r->print(<<ENDHEADER);
 $start_page  $start_page
 <br />  $funcs
 <noscript>  <noscript>
 $noscript  $noscript
 </noscript>  </noscript>
Line 615  function enterrole (thisform,rolecode,bu Line 772  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
Line 677  ENDHEADER Line 848  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'};
         }          }
           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 ($env{'user.adv'}) {      if ((($cattype eq 'std') || ($cattype eq 'domonly')) && (!$env{'user.adv'})) {
         $r->print('<p><label><input type="checkbox" name="showall"');  
         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'},'"<>&'); 
   
             $r->print(              $r->print(
                 '<p>'                  '<p>'
                .&mt('[_1]Visit the [_2]Course/Community Catalog[_3]'                 .&mt('[_1]Visit the [_2]Course/Community Catalog[_3][_4]'
                    .' to view all [_4] LON-CAPA courses and communities.'                     .' to view all [_5] LON-CAPA courses and communities.'
                    ,'<b>'                     ,'<b>'
                    ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'                     ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'
                    ,'</a></b>',$domdesc)                     ,'</a>'
                      ,'</b>'
                      ,'"'.$domdesc.'"')
                .'<br />'                 .'<br />'
                .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'                 .&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.'
Line 730  ENDHEADER Line 913  ENDHEADER
   
 # 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 {  
     $r->print('<h2>'.&mt('Currently no active roles, courses or communities').'</h2>');  
  }  
         &findcourse_advice($r);  
         &requestcourse_advice($r);  
  $r->print('</form>');   $r->print('</form>');
         if ($countfuture) {          if ($countfuture) {
             $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));              $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));
Line 767  ENDHEADER Line 944  ENDHEADER
  return OK;   return OK;
     }      }
 # ----------------------------------------------------------------------- Table  # ----------------------------------------------------------------------- Table
   
     if ($numdc > 0) {      if ($numdc > 0) {
         $r->print(&coursepick_jscript());          $r->print(&coursepick_jscript());
         $r->print(&Apache::loncommon::coursebrowser_javascript().          $r->print(&Apache::loncommon::coursebrowser_javascript().
Line 784  ENDHEADER Line 962  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 =
Line 806  ENDHEADER Line 985  ENDHEADER
     } elsif ($numdc > 0) {      } elsif ($numdc > 0) {
                 unless ($role =~/^error\:/) {                  unless ($role =~/^error\:/) {
                     my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);                      my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);
                     $output.= &Apache::loncommon::start_data_table_row().                      if ($roletext) {
                               $roletext.                          $output.= &Apache::loncommon::start_data_table_row().
                               &Apache::loncommon::end_data_table_row().                                    $roletext.
                               &Apache::loncommon::continue_data_table_row().                                    &Apache::loncommon::end_data_table_row();
                               $role_text_end.                          if ($role_text_end) {
                               &Apache::loncommon::end_data_table_row();                              $output .= &Apache::loncommon::continue_data_table_row().
                                          $role_text_end.
                                          &Apache::loncommon::end_data_table_row();
                           }
                       }
                 }                  }
             }              }
  }   }
Line 861  ENDHEADER Line 1044  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 roles_from_env {
       my ($roleshash,$update) = @_;
       my $count = 0;
       if (ref($roleshash) eq 'HASH') {
           foreach my $envkey (keys(%env)) {
               if ($envkey =~ m{^user\.role\.(\w+)[./]}) {
                   next if ($1 eq 'gr');
                   $roleshash->{$envkey} = $env{$envkey};
                   my ($start,$end) = split(/\./,$env{$envkey});
                   unless ($end && $end<$update) {
                       $count ++;
                   }
               }
           }
       }
       return $count;
   }
   
 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 907  sub gather_roles { Line 1105  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 933  sub gather_roles { Line 1138  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('Customrole defined by [_1].',$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;
Line 944  sub gather_roles { Line 1149  sub gather_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;
Line 952  sub gather_roles { Line 1156  sub gather_roles {
                     }                      }
                     #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 964  sub gather_roles { Line 1168  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;
Line 972  sub gather_roles { Line 1175  sub gather_roles {
                     }                      }
                     #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 983  sub gather_roles { Line 1186  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,'"<>&');                          $twhere = &HTML::Entities::encode($twhere,'"<>&');
Line 990  sub gather_roles { Line 1194  sub gather_roles {
                             $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);
Line 997  sub gather_roles { Line 1211  sub gather_roles {
                             $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.                              $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.
                                 "\0".$envkey;                                  "\0".$envkey;
                             $twhere=&HTML::Entities::encode($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;
Line 1025  sub gather_roles { Line 1250  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);
                 $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 1045  sub role_timezone { Line 1270  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 1060  sub role_timezone { Line 1291  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 1117  sub roletable_headers { Line 1348  sub roletable_headers {
 }  }
   
 sub roletypes {  sub roletypes {
     my @types = ('Domain','Construction Space','Course','Community','Unavailable','System');      my @types = ('Domain','Authoring Space','Course','Community','Unavailable','System');
     return @types;       return @types; 
 }  }
   
Line 1166  sub print_rolerows { Line 1397  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 1181  sub findcourse_advice { Line 1412  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 />');
     }      }
     $r->print('<h3>'.&mt('Self-Enrollment').'</h3>'.      if (($cattype eq 'std') || ($cattype eq 'domonly')) {
               '<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 />');          $r->print('<h3>'.&mt('Self-Enrollment').'</h3>'.
     $r->print(&mt('You can search for courses and communities which permit self-enrollment, if you would like to enroll in one.').'</p>'.                    '<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 />');
               &Apache::loncoursequeueadmin::queued_selfenrollment());          $r->print(&mt('You can search for courses and communities which permit self-enrollment, if you would like to enroll in one.').'</p>'.
           &Apache::loncoursequeueadmin::queued_selfenrollment());
       }
     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 1235  sub requestcourse_advice { Line 1465  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 1256  sub privileges_info { Line 1503  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 1297  sub privileges_info { Line 1544  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) = @_;
     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 1315  sub build_roletext { Line 1562  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 1362  sub build_roletext { Line 1616  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 1398  sub check_author_homeserver { Line 1634  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 1419  sub check_fordc { Line 1659  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 1462  sub adhoc_course_role { Line 1707  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 1474  sub adhoc_course_role { Line 1723  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 1575  sub display_cc_role { Line 1826  sub display_cc_role {
             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'),$trest,$tdom).                          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                         '</span>';                          '</span>';
                 $ttype = $newhash{'type'};                  $ttype = $newhash{'type'};
Line 1630  sub courseloadpage { Line 1881  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 = &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();
       return &Apache::loncommon::head_subbox($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 1661  course they should act on, etc. Both in Line 2815  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.231.4.15  
changed lines
  Added in v.1.311


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