Diff for /loncom/auth/lonroles.pm between versions 1.213 and 1.269.2.23

version 1.213, 2008/12/10 21:46:50 version 1.269.2.23, 2015/04/20 12:11:02
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 $swinfo=&Apache::lonmenu::rawconfig();
     my $navwindow;  
     if ($launch_nav eq 'on') {      # Breadcrumbs
  $navwindow.=&Apache::lonnavdisplay::launch_win('now',undef,undef,      my $brcrum = [{'href' => $url,
        ($url =~ m-^/adm/whatsnew-));                     'text' => 'Switching Role'},];
     } else {  
  $navwindow.=&Apache::lonnavmaps::close();  
     }  
     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 167  sub redirect_user {
     $r->print(<<ENDREDIR);      $r->print(<<ENDREDIR);
 $start_page  $start_page
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 $swinfo  $swinfo
   // ]]>
 </script>  </script>
 $navwindow  <p>$msg</p>
 <h1>$msg</h1>  
 $end_page  $end_page
 ENDREDIR  ENDREDIR
     return;      return;
Line 182  sub error_page { Line 183  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
       '<script type="text/javascript">'.      my $brcrum = [{'href' => $dest,
       &Apache::lonmenu::rawconfig().'</script>'.                     'text' => 'Problems during Course Initialization'},];
       '<p>'.&mt('The following problems occurred:').      $r->print(&Apache::loncommon::start_page('Problems during Course Initialization',
                                                undef,
                                                {'bread_crumbs' => $brcrum,})
       );
       $r->print(
           '<script type="text/javascript">'.
           '// <![CDATA['.
           &Apache::lonmenu::rawconfig().
           '// ]]>'.
           '</script>'.
         '<p class="LC_error">'.&mt('The following problems occurred:').
             '<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 $update=$env{'user.update.time'};
       if (!$refresh) {
           $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 214  sub handler { Line 275  sub handler {
  if ($env{'request.course.id'}) {   if ($env{'request.course.id'}) {
             # Check if user is CC trying to select a course role              # Check if user is CC trying to select a course role
             if ($env{'form.switchrole'}) {              if ($env{'form.switchrole'}) {
                 if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {                  my $switch_is_active;
                     &adhoc_course_role($then);                  if (defined($env{'user.role.'.$env{'form.switchrole'}})) {
                       my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
                       if (!$end || $end > $now) {
                           if (!$start || $start < $update) {
                               $switch_is_active = 1;
                           }
                       }
                   }
                   unless ($switch_is_active) {
                       &adhoc_course_role($refresh,$update,$then);
                 }                  }
             }              }
     my %temp=('logout_'.$env{'request.course.id'} => time);      my %temp=('logout_'.$env{'request.course.id'} => time);
     &Apache::lonnet::put('email_status',\%temp);      &Apache::lonnet::put('email_status',\%temp);
     &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});      &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});
  }   }
  &Apache::lonnet::appenv({"request.course.id"   => '',   &Apache::lonnet::appenv({"request.course.id"           => '',
  "request.course.fn"   => '',   "request.course.fn"           => '',
  "request.course.uri"  => '',   "request.course.uri"          => '',
  "request.course.sec"  => '',   "request.course.sec"          => '',
  "request.role"        => 'cm',                                   "request.course.tied"         => '',
                                  "request.role.adv"    => $env{'user.adv'},                                   "request.course.timechecked"  => '',
  "request.role.domain" => $env{'user.domain'}});   "request.role"                => 'cm',
                                    "request.role.adv"            => $env{'user.adv'},
    "request.role.domain"         => $env{'user.domain'}});
 # Check if 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 CC-role?  # Is this an ad-hoc Coordinator role?
                 if (my ($domain,$coursenum) =                  if (my ($ccrole,$domain,$coursenum) =
     ($envkey =~ m-^form\.cc\./($match_domain)/($match_courseid)$-)) {      ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {
                     if ($dcroles{$domain}) {                      if ($dcroles{$domain}) {
                         &check_privs($domain,$coursenum,$then,$now,'cc');                          if (&Apache::lonnet::check_adhoc_privs($domain,$coursenum,
                                                              $update,$refresh,$now,$ccrole)) {
                               &Apache::lonnet::appenv({"environment.internal.$domain.$coursenum.$ccrole.adhoc" => time});
                           }
                     }                      }
                     last;                      last;
                 }                  }
Line 249  sub handler { Line 324  sub handler {
                         my ($server_status,$home) = &check_author_homeserver($user,$domain);                          my ($server_status,$home) = &check_author_homeserver($user,$domain);
                         if ($server_status eq 'switchserver') {                          if ($server_status eq 'switchserver') {
                             my $trolecode = 'au./'.$domain.'/';                              my $trolecode = 'au./'.$domain.'/';
                             my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;                              my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                             $r->internal_redirect($switchserver);                              $r->internal_redirect($switchserver);
                               return OK;
                         }                          }
                         last;                          last;
                     }                      }
Line 260  sub handler { Line 336  sub handler {
                             my ($server_status,$home) = &check_author_homeserver($user,$domain);                              my ($server_status,$home) = &check_author_homeserver($user,$domain);
                             if ($server_status eq 'switchserver') {                              if ($server_status eq 'switchserver') {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                  my $trolecode = 'ca./'.$domain.'/'.$user;
                                 my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;                                  my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                             last;                              last;
                         }                          }
Line 276  sub handler { Line 353  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')) {
                             &check_privs($domain,$user,$then,$now,'ca');                              &Apache::lonnet::check_adhoc_privs($domain,$user,$update,
                                                                  $refresh,$now,'ca');
                             if ($server_status eq 'switchserver') {                              if ($server_status eq 'switchserver') {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                   my $trolecode = 'ca./'.$domain.'/'.$user; 
                                 my $switchserver = '/adm/switchserver?'                                  my $switchserver = '/adm/switchserver?'
                                                   .'otherserver='.$home.'&role='.$trolecode;                                                    .'otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                         } else {                          } else {
                             delete($env{$envkey});                              delete($env{$envkey});
Line 294  sub handler { Line 373  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);
             &role_status($envkey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend);              &Apache::lonnet::role_status($envkey,$update,$refresh,$now,\$role,\$where,
                                            \$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 364  sub handler { Line 463  sub handler {
  $r->print(<<ENDENTEREDKEY);   $r->print(<<ENDENTEREDKEY);
 $start_page  $start_page
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 $swinfo  $swinfo
   // ]]>
 </script>  </script>
 <form method="post">  <form action="" method="post">
 <input type="hidden" name="selectrole" value="1" />  <input type="hidden" name="selectrole" value="1" />
 <input type="hidden" name="$trolecode" value="1" />  <input type="hidden" name="$trolecode" value="1" />
 <span class="LC_fontsize_large">$message</span><br />  <span class="LC_fontsize_large">$message</span><br />
Line 387  ENDENTEREDKEY Line 488  ENDENTEREDKEY
  $r->print(<<ENDENTERKEY);   $r->print(<<ENDENTERKEY);
 $start_page  $start_page
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 $swinfo  $swinfo
   // ]]>
 </script>  </script>
 <form method="post">  <form action="" method="post">
 <input type="hidden" name="selectrole" value="1" />  <input type="hidden" name="selectrole" value="1" />
 <input type="hidden" name="$trolecode" value="1" />  <input type="hidden" name="$trolecode" value="1" />
 <input type="text" size="20" name="newkey" value="$env{'form.newkey'}" />  <input type="text" size="20" name="newkey" value="$env{'form.newkey'}" />
Line 415  ENDENTERKEY Line 518  ENDENTERKEY
   
     if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {      if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {
                         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 ($dest =~ /\?/) {
                                       $dest .= '&';
                                   } else {
                                       $dest .= '?';
                                   }
                                   $dest .= 'symb='.$env{'form.symb'};
                               }
     if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }      if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }
     &Apache::lonnet::appenv({'request.role.adv'=>$tadv});      &Apache::lonnet::appenv({'request.role.adv'=>$tadv});
                             if (($ferr) && ($tadv)) {                              if (($ferr) && ($tadv)) {
  &error_page($r,$ferr,$dest);   &error_page($r,$ferr,$dest);
     } else {      } else {
                                   if ($dest =~ m{^/adm/coursedocs\?folderpath}) {
                                       if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { 
                                           my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
                                           &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,
                                                                                          $cdom.'_'.$cnum);
                                       }
                                   }
  $r->internal_redirect($dest);   $r->internal_redirect($dest);
     }      }
     return OK;      return OK;
Line 433  ENDENTERKEY Line 574  ENDENTERKEY
  &Apache::lonnet::appenv(   &Apache::lonnet::appenv(
       {"request.course.id"  => $cdom.'_'.$cnum});        {"request.course.id"  => $cdom.'_'.$cnum});
  $furl='/adm/roles?tryagain=1';   $furl='/adm/roles?tryagain=1';
  $msg=                  $msg='<p><span class="LC_error">'
     '<h1><span class="LC_error">'.                      .&mt('Could not initialize [_1] at this time.',
     &mt('Could not initialize [_1] at this time.',                           $env{'course.'.$cdom.'_'.$cnum.'.description'})
  $env{'course.'.$cdom.'_'.$cnum.'.description'}).                      .'</span></p>'
     '</span></h1><h3>'.&mt('Please try again.').'</h3>'.$ferr;                      .'<p>'.&mt('Please try again.').'</p>'
                       .'<p>'.$ferr.'</p>';
     }      }
     if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }      if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }
     &Apache::lonnet::appenv({'request.role.adv'=>$tadv});      &Apache::lonnet::appenv({'request.role.adv'=>$tadv});
Line 447  ENDENTERKEY Line 589  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 ((($role eq 'cc') || ($role eq 'co')) 
  if (substr($courseid, 0, 1) eq '/') {                                      && ($env{'course.'.$cdom.'_'.$cnum.'.course.helper.not.run'})) { 
     $courseid = substr($courseid, 1);  
  }  
  $courseid =~ s/\//_/;  
  if ($role eq 'cc' && $env{'course.' . $courseid .   
       '.course.helper.not.run'}) {  
     $furl = "/adm/helper/course.initialization.helper";      $furl = "/adm/helper/course.initialization.helper";
     # Send the user to the course they selected      # Send the user to the course they selected
  } elsif ($env{'request.course.id'}) {   } elsif ($env{'request.course.id'}) {
                                     if ($env{'form.destinationurl'}) {                                      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 475  ENDENTERKEY Line 652  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 506  ENDENTERKEY Line 695  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 522  ENDENTERKEY Line 710  ENDENTERKEY
                                        $redirect_url);                                         $redirect_url);
                         return OK;                          return OK;
                     }                      }
                       if ($role eq 'sc') {
                           my $redirect_url = '/adm/grades?command=scantronupload';
                           &redirect_user($r,&mt('Loading Data Upload Page'),
                                          $redirect_url);
                           return OK;
                       }
  }   }
             }              }
         }          }
Line 535  ENDENTERKEY Line 729  ENDENTERKEY
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
   
  my @brcrum =[{href=>"/admmm/roles",text=>"User Roles"}];      my $crumbtext = 'User Roles';
       my $pagetitle = 'My Roles';
       my $recent = &mt('Recent Roles');
       my $standby = &mt('Role selected. Please stand by.');
       my $show_course=&Apache::loncommon::show_course();
       if ($show_course) {
           $crumbtext = 'Courses';
           $pagetitle = 'My Courses';
           $recent = &mt('Recent Courses');
           $standby = &mt('Course selected. Please stand by.');
       }
       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('User Roles',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>
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 $swinfo  $swinfo
 window.focus();  window.focus();
   
Line 563  function enterrole (thisform,rolecode,bu Line 778  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 615  ENDHEADER Line 845  ENDHEADER
             if ($reinit) {              if ($reinit) {
                 $r->print(                  $r->print(
  '<h3><span class="LC_error">'.   '<h3><span class="LC_error">'.
  &mt('As your session file for the course has expired, you will need to re-select the course.').'</span></h3>');   &mt('As your session file for the course or community has expired, you will need to re-select it.').'</span></h3>');
             } else {              } else {
         $r->print(          $r->print(
  '<h3><span class="LC_error">'.   '<h3><span class="LC_error">'.
  &mt('You need to choose another user role or enter a specific course for this function').'</span></h3>');   &mt('You need to choose another user role or enter a specific course or community for this function.').
    '</span></h3>');
     }      }
         }          }
     }      }
 # -------------------------------------------------------- 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="" />');
     }      }
     my (%roletext,%sortrole,%roleclass);      $r->rflush();
     my $countactive=0;  
     my $countfuture=0;      my (%roletext,%sortrole,%roleclass,%futureroles,%timezones);
     my $countwill=0;      my ($countactive,$countfuture,$inrole,$possiblerole) = 
     my $inrole=0;          &gather_roles($update,$refresh,$now,$reinit,$nochoose,\%roles_in_env,\%roletext,
     my $possiblerole='';                        \%sortrole,\%roleclass,\%futureroles,\%timezones,$loncaparev);
     my %futureroles;      $refresh = $now;
     my %roles_nextlogin;      &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});
     foreach $envkey (sort keys %env) {      if ((($cattype eq 'std') || ($cattype eq 'domonly')) && (!$env{'user.adv'})) {
         my $button = 1;  
         my $switchserver='';  
  my $roletext;  
  my $sortkey;  
         if ($envkey=~/^user\.role\./) {  
             my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);  
             &role_status($envkey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend);  
             next if (!defined($role) || $role eq '' || $role =~ /^gr/);  
             $tremark='';  
             $tpstart='&nbsp;';  
             $tpend='&nbsp;';  
             if ($tstart) {  
                 $tpstart=&Apache::lonlocal::locallocaltime($tstart);  
             }  
             if ($tend) {  
                 $tpend=&Apache::lonlocal::locallocaltime($tend);  
             }  
             if ($env{'request.role'} eq $trolecode) {  
  $tstatus='selected';  
             }  
             my $tbg;  
             if (($tstatus eq 'is')   
  || ($tstatus eq 'selected')   
  || ($tstatus eq 'will')   
  || ($tstatus eq 'future')   
                 || ($env{'form.showall'})) {  
                 if ($tstatus eq 'is') {  
                     $tbg='LC_roles_is';  
     $possiblerole=$trolecode;  
     $countactive++;  
                 } elsif ($tstatus eq 'future') {  
                     $tbg='LC_roles_future';  
                     $button=0;  
                     $futureroles{$trolecode} = $tstart.':'.$tend;  
                     $countfuture ++;  
                 } elsif ($tstatus eq 'will') {  
                     $tbg='LC_roles_will';  
                     $tremark.=&mt('Active at next login.').' ';  
                     $roles_nextlogin{$trolecode} = $tstart.':'.$tend;  
                     $countwill ++;  
                 } elsif ($tstatus eq 'expired') {  
                     $tbg='LC_roles_expired';  
                     $button=0;  
                 } elsif ($tstatus eq 'will_not') {  
                     $tbg='LC_roles_will_not';  
                     $tremark.=&mt('Expired after logout.').' ';  
                 } elsif ($tstatus eq 'selected') {  
                     $tbg='LC_roles_selected';  
     $inrole=1;  
     $countactive++;  
                     $tremark.=&mt('Currently selected.').' ';  
                 }  
                 my $trole;  
                 if ($role =~ /^cr\//) {  
                     my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);  
     if ($tremark) { $tremark.='<br />'; }  
                     $tremark.=&mt('Defined by [_1] at [_2].',$rauthor,$rdomain);  
  }  
  $trole=Apache::lonnet::plaintext($role);  
                 my $ttype;  
                 my $twhere;  
                 my ($tdom,$trest,$tsection)=  
                     split(/\//,Apache::lonnet::declutter($where));  
                 # First, Co-Authorship roles  
                 if (($role eq 'ca') || ($role eq 'aa')) {  
                     my $home = &Apache::lonnet::homeserver($trest,$tdom);  
     my $allowed=0;  
     my @ids=&Apache::lonnet::current_machine_ids();  
     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }  
                     if (!$allowed) {  
  $button=0;  
                         $switchserver='otherserver='.$home.'&role='.$trolecode;  
                     }  
                     #next if ($home eq 'no_host');  
                     $home = &Apache::lonnet::hostname($home);  
                     $ttype='Construction Space';  
                     $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').  
  ': '.$tdom.'<br />'.  
                         ' '.&mt('Server').':&nbsp;'.$home;  
                     $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';  
     $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$trest.'/');  
     $sortkey=$role."$trest:$tdom";  
                 } elsif ($role eq 'au') {  
                     # Authors  
                     my $home = &Apache::lonnet::homeserver  
                         ($env{'user.name'},$env{'user.domain'});  
     my $allowed=0;  
     my @ids=&Apache::lonnet::current_machine_ids();  
     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }  
                     if (!$allowed) {  
  $button=0;  
                         $switchserver='otherserver='.$home.'&role='.$trolecode;  
                     }  
                     #next if ($home eq 'no_host');  
                     $home = &Apache::lonnet::hostname($home);  
                     $ttype='Construction Space';  
                     $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').  
  ':&nbsp;'.$home;  
                     $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';  
     $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$env{'user.name'}.'/');  
     $sortkey=$role;  
                 } elsif ($trest) {  
                     my $tcourseid=$tdom.'_'.$trest;  
                     $ttype = &Apache::loncommon::course_type($tcourseid);  
                     $trole = &Apache::lonnet::plaintext($role,$ttype);  
                     if ($env{'course.'.$tcourseid.'.description'}) {  
                         $twhere=$env{'course.'.$tcourseid.'.description'};  
  $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;  
                         unless ($twhere eq &mt('Currently not available')) {  
     $twhere.=' <span class="LC_fontsize_small">'.  
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).  
                                     '</span>';  
  }  
                     } else {  
                         my %newhash=&Apache::lonnet::coursedescription($tcourseid);  
                         if (%newhash) {  
     $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.  
  "\0".$envkey;  
                             $twhere=$newhash{'description'}.  
                               ' <span class="LC_fontsize_small">'.  
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).  
                               '</span>';  
                             $ttype = $newhash{'type'};  
                             $trole = &Apache::lonnet::plaintext($role,$ttype);  
                         } else {  
                             $twhere=&mt('Currently not available');  
                             $env{'course.'.$tcourseid.'.description'}=$twhere;  
     $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;  
                             $ttype = 'Unavailable';  
                         }  
                     }  
                     if ($tsection) {  
                         $twhere.='<br />'.&mt('Section').': '.$tsection;  
     }  
     if ($role ne 'st') { $twhere.="<br />".&mt('Domain').":".$tdom; }  
                 } elsif ($tdom) {  
                     $ttype='Domain';  
                     $twhere=$tdom;  
     $sortkey=$role.$twhere;  
                 } else {  
                     $ttype='System';  
                     $twhere=&mt('system wide');  
     $sortkey=$role.$twhere;  
                 }  
                 $roletext.=&build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit);  
  $roletext{$envkey}=$roletext;  
  if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}  
  $sortrole{$sortkey}=$envkey;  
  $roleclass{$envkey}=$ttype;  
     }  
         }  
     }  
     if ($env{'user.adv'}) {  
         $r->print(  
               '<p><label>'.&mt('Show all roles').': <input type="checkbox" name="showall"');  
         if ($env{'form.showall'}) { $r->print(' checked="checked" '); }  
         $r->print(' /></label><input type="submit" value="'.&mt('Display').'" /></p>');  
     } else {  
         if ($countactive > 0) {          if ($countactive > 0) {
             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('<p>'.&mt('[_1]Visit the [_2]Course Catalog[_3] to view all [_4] LON-CAPA courses.','<b>','<a href="/adm/coursecatalog?showdom='.$esc_dom.'">','</a></b>',$domdesc).'<br />'.&mt('If a course is [_1]not[_2] in your list of current courses below, you may be able to enroll if self-enrollment is permitted.','<b>','</b>').'</p>');              $r->print(
                   '<p>'
                  .&mt('[_1]Visit the [_2]Course/Community Catalog[_3][_4]'
                      .' to view all [_5] LON-CAPA courses and communities.'
                      ,'<b>'
                      ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'
                      ,'</a>'
                      ,'</b>'
                      ,'"'.$domdesc.'"')
                  .'<br />'
                  .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'
                      .' you may be able to enroll if self-enrollment is permitted.'
                      ,'<b>','</b>')
                  .'</p>'
               );
         }          }
     }      }
   
 # No active roles  # No active roles
     if ($countactive==0) {      if ($countactive==0) {
  if ($inrole) {          &requestcourse_advice($r,$cattype,$inrole); 
     $r->print('<h2>'.&mt('Currently no additional roles or courses').'</h2>');  
  } else {  
     $r->print('<h2>'.&mt('Currently no active roles or courses').'</h2>');  
  }  
         &findcourse_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 850  ENDHEADER Line 950  ENDHEADER
  return OK;   return OK;
     }      }
 # ----------------------------------------------------------------------- Table  # ----------------------------------------------------------------------- Table
     unless ((!&Apache::lonmenu::show_course()) || ($nochoose) || ($countactive==1)) {  
       if ($numdc > 0) {
           $r->print(&coursepick_jscript());
           $r->print(&Apache::loncommon::coursebrowser_javascript().
                     &Apache::loncommon::authorbrowser_javascript());
       }
   
       unless ((!&Apache::loncommon::show_course()) || ($nochoose) || ($countactive==1)) {
  $r->print("<h2>".&mt('Select a Course to Enter')."</h2>\n");   $r->print("<h2>".&mt('Select a Course to Enter')."</h2>\n");
     }      }
       if ($env{'form.destinationurl'}) {
           $r->print('<input type="hidden" name="destinationurl" value="'.
                     $env{'form.destinationurl'}.'" />');
           if ($env{'form.destsymb'} ne '') {
               $r->print('<input type="hidden" name="destsymb" value="'.
                         $env{'form.destsymb'}.'" />');
           }
       }
   
     my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);      my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);
     if ($env{'environment.recentroles'}) {      if ($env{'environment.recentroles'}) {
         my %recent_roles =          my %recent_roles =
                &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});                 &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
  my $output='';   my $output='';
  foreach (sort(keys(%recent_roles))) {   foreach my $role (sort(keys(%recent_roles))) {
     if (defined($roletext{'user.role.'.$_})) {      if (ref($roletext{'user.role.'.$role}) eq 'ARRAY') {
  $output.=$roletext{'user.role.'.$_};   $output.= &Apache::loncommon::start_data_table_row().
                 if ($_ =~ m-dc\./($match_domain)/-                             $roletext{'user.role.'.$role}->[0].
                             &Apache::loncommon::end_data_table_row();
                   if ($roletext{'user.role.'.$role}->[1] ne '') {
                       $output .= &Apache::loncommon::continue_data_table_row().
                                  $roletext{'user.role.'.$role}->[1].
                                  &Apache::loncommon::end_data_table_row();
                   }
                   if ($role =~ m{dc\./($match_domain)/} 
     && $dcroles{$1}) {      && $dcroles{$1}) {
     $output .= &adhoc_roles_row($1,'recent');      $output .= &adhoc_roles_row($1,'recent');
                 }                  }
     } elsif ($numdc > 0) {      } elsif ($numdc > 0) {
                 unless ($_ =~/^error\:/) {                  unless ($role =~/^error\:/) {
                     $output.=&display_cc_role('user.role.'.$_);                      my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);
                       if ($roletext) {
                           $output.= &Apache::loncommon::start_data_table_row().
                                     $roletext.
                                     &Apache::loncommon::end_data_table_row();
                           if ($role_text_end) {
                               $output .= &Apache::loncommon::continue_data_table_row().
                                          $role_text_end.
                                          &Apache::loncommon::end_data_table_row();
                           }
                       }
                 }                  }
             }               }
  }   }
  if ($output) {   if ($output) {
     $r->print(&Apache::loncommon::start_data_table_empty_row()      $r->print(&Apache::loncommon::start_data_table_empty_row()
                      .'<td align="center" colspan="5">'                       .'<td align="center" colspan="5">'
                      .&mt('Recent Roles')                       .$recent
                      .'</td>'                       .'</td>'
                      .&Apache::loncommon::end_data_table_empty_row()                       .&Apache::loncommon::end_data_table_empty_row()
             );              );
Line 882  ENDHEADER Line 1015  ENDHEADER
             $doheaders ++;              $doheaders ++;
  }   }
     }      }
   
     if ($numdc > 0) {  
         $r->print(&coursepick_jscript());  
         $r->print(&Apache::loncommon::coursebrowser_javascript().  
                   &Apache::loncommon::authorbrowser_javascript());  
     }  
     &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext);      &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext);
     if ($countactive > 1) {      if ($countactive > 1) {
         my $tremark='';          my $tremark='';
Line 923  ENDHEADER Line 1050  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 is LON-CAPA [_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 Catalog')  
                  .'</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 {
       my ($update,$refresh,$now,$reinit,$nochoose,$roles_in_env,$roletext,$sortrole,$roleclass,$futureroles,
           $timezones,$loncaparev) = @_;
       my ($countactive,$countfuture,$inrole,$possiblerole) = (0,0,0,'');
       my $advanced = $env{'user.adv'};
       my $tryagain = $env{'form.tryagain'};
       my @ids = &Apache::lonnet::current_machine_ids();
       if (ref($roles_in_env) eq 'HASH') {
           foreach my $envkey (sort(keys(%{$roles_in_env}))) {
               my $button = 1;
               my $switchserver='';
               my $switchwarning;
               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);
               next if (!defined($role) || $role eq '' || $role =~ /^gr/);
               $tremark='';
               $tpstart='&nbsp;';
               $tpend='&nbsp;';
               if ($env{'request.role'} eq $trolecode) {
                   $tstatus='selected';
               }
               my $tbg;
               if (($tstatus eq 'is')
                   || ($tstatus eq 'selected')
                   || ($tstatus eq 'future')
                   || ($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') {
                       $tbg='LC_roles_is';
                       $possiblerole=$trolecode;
                       $countactive++;
                   } elsif ($tstatus eq 'future') {
                       $tbg='LC_roles_future';
                       $button=0;
                       $futureroles->{$trolecode} = $tstart.':'.$tend;
                       $countfuture ++;
                   } elsif ($tstatus eq 'expired') {
                       $tbg='LC_roles_expired';
                       $button=0;
                   } elsif ($tstatus eq 'will_not') {
                       $tbg='LC_roles_will_not';
                       $tremark.=&mt('Expired after logout.').' ';
                   } elsif ($tstatus eq 'selected') {
                       $tbg='LC_roles_selected';
                       $inrole=1;
                       $countactive++;
                       $tremark.=&mt('Currently selected.').' ';
                   }
                   my $trole;
                   if ($role =~ /^cr\//) {
                       my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);
                       if ($tremark) { $tremark.='<br />'; }
                       $tremark.=&mt('Custom role defined by [_1].',$rauthor.':'.$rdomain);
                   }
                   $trole=Apache::lonnet::plaintext($role);
                   my $ttype;
                   my $twhere;
                   my ($tdom,$trest,$tsection)=
                       split(/\//,Apache::lonnet::declutter($where));
                   # First, Co-Authorship roles
                   if (($role eq 'ca') || ($role eq 'aa')) {
                       my $home = &Apache::lonnet::homeserver($trest,$tdom);
                       my $allowed=0;
                       foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                       if (!$allowed) {
                           $button=0;
                           $switchserver='otherserver='.$home.'&amp;role='.$trolecode;
                       }
                       #next if ($home eq 'no_host');
                       $home = &Apache::lonnet::hostname($home);
                       $ttype='Authoring Space';
                       $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').
                           ': '.$tdom.'<br />'.
                           ' '.&mt('Server').':&nbsp;'.$home;
                       $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';
                       $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$trest.'/');
                       $sortkey=$role."$trest:$tdom";
                   } elsif ($role eq 'au') {
                       # Authors
                       my $home = &Apache::lonnet::homeserver
                           ($env{'user.name'},$env{'user.domain'});
                       my $allowed=0;
                       foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                       if (!$allowed) {
                           $button=0;
                           $switchserver='otherserver='.$home.'&amp;role='.$trolecode;
                       }
                       #next if ($home eq 'no_host');
                       $home = &Apache::lonnet::hostname($home);
                       $ttype='Authoring Space';
                       $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').
                           ':&nbsp;'.$home;
                       $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';
                       $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$env{'user.name'}.'/');
                       $sortkey=$role;
                   } elsif ($trest) {
                       my $tcourseid=$tdom.'_'.$trest;
                       $ttype = &Apache::loncommon::course_type($tcourseid);
                       $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);
                       if ($env{'course.'.$tcourseid.'.description'}) {
                           my $home=$env{'course.'.$tcourseid.'.home'};
                           $twhere=$env{'course.'.$tcourseid.'.description'};
                           $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                           $twhere = &HTML::Entities::encode($twhere,'"<>&');
                           unless ($twhere eq &mt('Currently not available')) {
                               $twhere.=' <span class="LC_fontsize_small">'.
           &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                                       '</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 {
                           my %newhash=&Apache::lonnet::coursedescription($tcourseid);
                           if (%newhash) {
                               $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.
                                   "\0".$envkey;
                               $twhere=&HTML::Entities::encode($newhash{'description'},'"<>&').
                                       ' <span class="LC_fontsize_small">'.
                                        &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                                       '</span>';
                               $ttype = $newhash{'type'};
                               $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 {
                               $twhere=&mt('Currently not available');
                               $env{'course.'.$tcourseid.'.description'}=$twhere;
                               $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                               $ttype = 'Unavailable';
                           }
                       }
                       if ($tsection) {
                           $twhere.='<br />'.&mt('Section').': '.$tsection;
                       }
                       if ($role ne 'st') { $twhere.="<br />".&mt('Domain').":".$tdom; }
                   } elsif ($tdom) {
                       $ttype='Domain';
                       $twhere=$tdom;
                       $sortkey=$role.$twhere;
                   } else {
                       $ttype='System';
                       $twhere=&mt('system wide');
                       $sortkey=$role.$twhere;
                   }
                   ($role_text,$role_text_end) =
                       &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,
                                       $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,
                                       $tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning);
                   $roletext->{$envkey}=[$role_text,$role_text_end];
                   if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}
                   $sortrole->{$sortkey}=$envkey;
                   $roleclass->{$envkey}=$ttype;
               }
           }
       }
       return ($countactive,$countfuture,$inrole,$possiblerole);
   }
   
   sub role_timezone {
       my ($where,$timezones) = @_;
       my $timezone;
       if (ref($timezones) eq 'HASH') { 
           if ($where =~ m{^/($match_domain)/($match_courseid)}) {
               my $cdom = $1;
               my $cnum = $2;
               if ($cdom && $cnum) {
                   if (!exists($timezones->{$cdom.'_'.$cnum})) {
                       my $tz;
                       if ($env{'course.'.$cdom.'_'.$cnum.'.description'}) {
                           $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})) {
                               my %domdefaults = 
                                   &Apache::lonnet::get_domain_defaults($cdom);
                               if ($domdefaults{'timezone_def'} eq '') {
                                   $timezones->{$cdom} = 'local';
                               } else {
                                   $timezones->{$cdom} = $domdefaults{'timezone_def'};
                               }
                           }
                           $timezones->{$cdom.'_'.$cnum} = $timezones->{$cdom};
                       } else {
                           $timezones->{$cdom.'_'.$cnum} = 
                               &Apache::lonlocal::gettimezone($tz);
                       }
                   }
                   $timezone = $timezones->{$cdom.'_'.$cnum};
               }
           } else {
               my ($tdom) = ($where =~ m{^/($match_domain)});
               if ($tdom) {
                   if (!exists($timezones->{$tdom})) {
                       my %domdefaults = &Apache::lonnet::get_domain_defaults($tdom);
                       if ($domdefaults{'timezone_def'} eq '') {
                           $timezones->{$tdom} = 'local';
                       } else {
                           $timezones->{$tdom} = $domdefaults{'timezone_def'};
                       }
                   }
                   $timezone = $timezones->{$tdom};
               }
           }
           if ($timezone eq 'local') {
               $timezone = undef;
           }
       }
       return $timezone;
   }
   
 sub roletable_headers {  sub roletable_headers {
     my ($r,$roleclass,$sortrole,$nochoose) = @_;      my ($r,$roleclass,$sortrole,$nochoose) = @_;
     my $doheaders;      my $doheaders;
Line 969  sub roletable_headers { Line 1354  sub roletable_headers {
 }  }
   
 sub roletypes {  sub roletypes {
     my @types = ('Domain','Construction Space','Course','Unavailable','System');      my @types = ('Domain','Authoring Space','Course','Community','Unavailable','System');
     return @types;       return @types; 
 }  }
   
Line 982  sub print_rolerows { Line 1367  sub print_rolerows {
             foreach my $which (sort {uc($a) cmp uc($b)} (keys(%{$sortrole}))) {              foreach my $which (sort {uc($a) cmp uc($b)} (keys(%{$sortrole}))) {
                 if ($roleclass->{$sortrole->{$which}} =~ /^\Q$type\E/) {                  if ($roleclass->{$sortrole->{$which}} =~ /^\Q$type\E/) {
                     if (ref($roletext) eq 'HASH') {                      if (ref($roletext) eq 'HASH') {
                         $output.=$roletext->{$sortrole->{$which}};                          if (ref($roletext->{$sortrole->{$which}}) eq 'ARRAY') {
                               $output.= &Apache::loncommon::start_data_table_row().
                                         $roletext->{$sortrole->{$which}}->[0].
                                         &Apache::loncommon::end_data_table_row();
                               if ($roletext->{$sortrole->{$which}}->[1] ne '') {
                                   $output .= &Apache::loncommon::continue_data_table_row().
                                              $roletext->{$sortrole->{$which}}->[1].
                                              &Apache::loncommon::end_data_table_row();
                               }
                           }
                         if ($sortrole->{$which} =~ m-dc\./($match_domain)/-) {                          if ($sortrole->{$which} =~ m-dc\./($match_domain)/-) {
                             if (ref($dcroles) eq 'HASH') {                              if (ref($dcroles) eq 'HASH') {
                                 if ($dcroles->{$1}) {                                  if ($dcroles->{$1}) {
Line 1009  sub print_rolerows { Line 1403  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 1024  sub findcourse_advice { Line 1418  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('<p>'.&mt('The [_1]Course Catalog[_2] provides information about all [_3] classes for which LON-CAPA courses have been created.','<a href="/adm/coursecatalog?showdom='.$esc_dom.'">','</a>',$domdesc).'<br />');      if (($cattype eq 'std') || ($cattype eq 'domonly')) {
     $r->print(&mt('You can search the course catalog for courses which permit self-enrollment, if you would like to enroll in a course.').'</p>');          $r->print('<h3>'.&mt('Self-Enrollment').'</h3>'.
                     '<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(&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;
   }
   
   sub requestcourse_advice {
       my ($r,$cattype,$inrole) = @_;
       my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
       my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');
       my (%can_request,%request_doms,$output);
       &Apache::lonnet::check_can_request($env{'user.domain'},\%can_request,\%request_doms);
       if (keys(%request_doms) > 0) {
           my ($types,$typename) = &Apache::loncommon::course_types();
           if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) { 
               my (@reqdoms,@reqtypes);
               foreach my $type (sort(keys(%request_doms))) {
                   push(@reqtypes,$type); 
                   if (ref($request_doms{$type}) eq 'ARRAY') {
                       my $domstr = join(', ',map { &Apache::lonnet::domain($_) } sort(@{$request_doms{$type}}));
                       $output .=
                           '<li>'
                          .&mt('[_1]'.$typename->{$type}.'[_2] in domain: [_3]',
                               '<i>',
                               '</i>',
                               '<b>'.$domstr.'</b>')
                          .'</li>';
                       foreach my $dom (@{$request_doms{$type}}) {
                           unless (grep(/^\Q$dom\E/,@reqdoms)) {
                               push(@reqdoms,$dom);
                           }
                       }
                   }
               }
               my @showtypes;
               foreach my $type (@{$types}) {
                   if (grep(/^\Q$type\E$/,@reqtypes)) {
                       push(@showtypes,$type);
                   }
               }
               my $requrl = '/adm/requestcourse';
               if (@reqdoms == 1) {
                   $requrl .= '?showdom='.$reqdoms[0];
               }
               if (@showtypes > 0) {
                   $requrl.=(($requrl=~/\?/)?'&':'?').'crstype='.$showtypes[0];
               }
               if (@reqdoms == 1 || @showtypes > 0) {
                   $requrl .= '&state=crstype&action=new';
               }
               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 1044  sub privileges_info { Line 1509  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 1084  sub privileges_info { Line 1549  sub privileges_info {
     return $output;      return $output;
 }  }
   
 sub role_status {  
     my ($rolekey,$then,$now,$role,$where,$trolecode,$tstatus,$tstart,$tend) = @_;  
     my @pwhere = ();  
     if (exists($env{$rolekey}) && $env{$rolekey} ne '') {  
         (undef,undef,$$role,@pwhere)=split(/\./,$rolekey);  
         unless (!defined($$role) || $$role eq '') {  
             $$where=join('.',@pwhere);  
             $$trolecode=$$role.'.'.$$where;  
             ($$tstart,$$tend)=split(/\./,$env{$rolekey});  
             $$tstatus='is';  
             if ($$tstart && $$tstart>$then) {  
  $$tstatus='future';  
  if ($$tstart<$now) { $$tstatus='will'; }  
             }  
             if ($$tend) {  
                 if ($$tend<$then) {  
                     $$tstatus='expired';  
                 } elsif ($$tend<$now) {  
                     $$tstatus='will_not';  
                 }  
             }  
         }  
     }  
 }  
   
 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=&Apache::loncommon::start_data_table_row();      my ($roletext,$roletext_end);
     my $is_dc=($trolecode =~ m/^dc\./);      my $is_dc=($trolecode =~ m/^dc\./);
     my $rowspan=($is_dc) ? ''      my $rowspan=($is_dc) ? ''
                          : ' rowspan="2" ';                           : ' rowspan="2" ';
Line 1128  sub build_roletext { Line 1568  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="'.
                         &mt('Select').'" onClick="javascript:enterrole(this.form,\''.                          &mt('Select').'" onclick="javascript:enterrole(this.form,\''.
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         } elsif ($tryagain) {          } elsif ($tryagain) {
             $roletext.=              $roletext.=
                 '<td'.$rowspan.' class="'.$tbg.'">'.                  '<td'.$rowspan.' class="'.$tbg.'">'.
                 '<input name="'.$buttonname.'" type="button" value="'.                  '<input name="'.$buttonname.'" type="button" value="'.
                 &mt('Try Selecting Again').'" onClick="javascript:enterrole(this.form,\''.                  &mt('Try Selecting Again').'" onclick="javascript:enterrole(this.form,\''.
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         } elsif ($advanced) {          } elsif ($advanced) {
             $roletext.=              $roletext.=
                 '<td'.$rowspan.' class="'.$tbg.'">'.                  '<td'.$rowspan.' class="'.$tbg.'">'.
                 '<input name="'.$buttonname.'" type="button" value="'.                  '<input name="'.$buttonname.'" type="button" value="'.
                 &mt('Re-Initialize').'" onClick="javascript:enterrole(this.form,\''.                  &mt('Re-Initialize').'" onclick="javascript:enterrole(this.form,\''.
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         } elsif ($reinit) {          } elsif ($reinit) {
             $roletext.=               $roletext.= 
                 '<td'.$rowspan.' class="'.$tbg.'">'.                  '<td'.$rowspan.' class="'.$tbg.'">'.
                 '<input name="'.$buttonname.'" type="button" value="'.                  '<input name="'.$buttonname.'" type="button" value="'.
                 &mt('Re-Select').'" onClick="javascript:enterrole(this.form,\''.                  &mt('Re-Select').'" onclick="javascript:enterrole(this.form,\''.
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         } else {          } else {
             $roletext.=              $roletext.=
                 '<td'.$rowspan.' class="'.$tbg.'">'.                  '<td'.$rowspan.' class="'.$tbg.'">'.
                 '<input name="'.$buttonname.'" type="button" value="'.                  '<input name="'.$buttonname.'" type="button" value="'.
                 &mt('Re-Initialize').'" onClick="javascript:enterrole(this.form,\''.                  &mt('Re-Select').'" onclick="javascript:enterrole(this.form,\''.
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         }          }
     }      }
Line 1166  sub build_roletext { Line 1613  sub build_roletext {
     $roletext.='<td>'.$trole.'</td>'      $roletext.='<td>'.$trole.'</td>'
               .'<td>'.$twhere.'</td>'                .'<td>'.$twhere.'</td>'
               .'<td>'.$tpstart.'</td>'                .'<td>'.$tpstart.'</td>'
               .'<td>'.$tpend.'</td>'                .'<td>'.$tpend.'</td>';
               .&Apache::loncommon::end_data_table_row();  
     if (!$is_dc) {      if (!$is_dc) {
         $roletext.=&Apache::loncommon::continue_data_table_row()          $roletext_end = '<td colspan="4">'.
                   .'<td colspan="4">'                          $tremark.'&nbsp;'.
                   .$tremark.'&nbsp;'                          '</td>';
                   .'</td>'  
                   .&Apache::loncommon::end_data_table_row();  
     }  
     return $roletext;  
 }  
   
 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;      return ($roletext,$roletext_end);
 }  }
   
 sub check_author_homeserver {  sub check_author_homeserver {
Line 1213  sub check_author_homeserver { Line 1639  sub check_author_homeserver {
     }      }
 }  }
   
 sub check_privs {  
     my ($cdom,$cnum,$then,$now,$checkrole) = @_;  
     my $cckey = 'user.role.'.$checkrole.'./'.$cdom.'/'.$cnum;   
     if ($env{$cckey}) {  
         my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);  
         &role_status($cckey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend);  
         unless (($tstatus eq 'is') || ($tstatus eq 'will_not')) {  
             &set_privileges($cdom,$cnum,$checkrole);  
         }  
     } else {  
         &set_privileges($cdom,$cnum,$checkrole);  
     }  
 }  
   
 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 1249  sub check_fordc { Line 1665  sub check_fordc {
 }  }
   
 sub adhoc_course_role {  sub adhoc_course_role {
     my ($then) = @_;       my ($refresh,$update,$then) = @_;
     my ($cdom,$cnum);      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'};
     if (&check_forcc($cdom,$cnum,$then)) {      $crstype = &Apache::loncommon::course_type();
       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>$then || $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 1291  sub adhoc_course_role { Line 1713  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 = $then-1;                  my $adhocstart = $refresh-1;
                 $userroles{'user.role.'.$spec} = $adhocstart.'.';                  $userroles{'user.role.'.$spec} = $adhocstart.'.';
                 &Apache::lonnet::appenv(\%userroles,[$role,'cm']);                  &Apache::lonnet::appenv(\%userroles,[$role,'cm']);
             }              }
Line 1303  sub adhoc_course_role { Line 1729  sub adhoc_course_role {
 }  }
   
 sub check_forcc {  sub check_forcc {
     my ($cdom,$cnum,$then) = @_;      my ($cdom,$cnum,$refresh,$update,$then,$crstype) = @_;
     my $is_cc;      my ($is_cc,$ccrole);
     if ($cdom ne '' && $cnum ne '') {      if ($crstype eq 'Community') {
         if (&Apache::lonnet::is_course($cdom,$cnum)) {          $ccrole = 'co';
             my $envkey = 'user.role.cc./'.$cdom.'/'.$cnum;      } else {
             if (defined($env{$envkey})) {          $ccrole = 'cc';
                 $is_cc = 1;      }
                 my ($tstart,$tend)=split(/\./,$env{$envkey});      if (&Apache::lonnet::is_course($cdom,$cnum)) {
                 if ($tstart && $tstart>$then) { $is_cc = 0; }          my $envkey = 'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum;
                 if ($tend   && $tend  <$then) { $is_cc = 0; }          if (defined($env{$envkey})) {
               $is_cc = 1;
               my ($tstart,$tend)=split(/\./,$env{$envkey});
               my $limit = $update;
               if ($env{'request.role'} eq $ccrole.'./'.$cdom.'/'.$cnum) {
                   $limit = $then;
             }              }
               if ($tstart && $tstart>$refresh) { $is_cc = 0; }
               if ($tend   && $tend  <$limit) { $is_cc = 0; }
         }          }
     }      }
     return $is_cc;      return $is_cc;
Line 1324  sub courselink { Line 1757  sub courselink {
     my $courseform=&Apache::loncommon::selectcourse_link      my $courseform=&Apache::loncommon::selectcourse_link
                    ('rolechoice','dccourse'.$rowtype.'_'.$dcdom,                     ('rolechoice','dccourse'.$rowtype.'_'.$dcdom,
                     'dcdomain'.$rowtype.'_'.$dcdom,'coursedesc'.$rowtype.'_'.                      'dcdomain'.$rowtype.'_'.$dcdom,'coursedesc'.$rowtype.'_'.
                     $dcdom,$dcdom,undef);                      $dcdom,$dcdom,undef,'Course/Community');
     my $hiddenitems = '<input type="hidden" name="dcdomain'.$rowtype.'_'.$dcdom.'" value="'.$dcdom.'" />'.      my $hiddenitems = '<input type="hidden" name="dcdomain'.$rowtype.'_'.$dcdom.'" value="'.$dcdom.'" />'.
                       '<input type="hidden" name="origdom'.$rowtype.'_'.$dcdom.'" value="'.$dcdom.'" />'.                        '<input type="hidden" name="origdom'.$rowtype.'_'.$dcdom.'" value="'.$dcdom.'" />'.
                       '<input type="hidden" name="dccourse'.$rowtype.'_'.$dcdom.'" value="" />'.                        '<input type="hidden" name="dccourse'.$rowtype.'_'.$dcdom.'" value="" />'.
Line 1334  sub courselink { Line 1767  sub courselink {
   
 sub coursepick_jscript {  sub coursepick_jscript {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                   plsu => "Please use the 'Select Course' link to open a separate pick course window where you may select the course you wish to enter.",                    plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",
                   youc => 'You can only use this screen to select courses in the current domain.',                    youc => 'You can only use this screen to select courses and communities in the current domain.',
              );               );
     my $verify_script = <<"END";      my $verify_script = <<"END";
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 function verifyCoursePick(caller) {  function verifyCoursePick(caller) {
     var numbutton = getIndex(caller)      var numbutton = getIndex(caller)
     var pickedCourse = document.rolechoice.elements[numbutton+4].value      var pickedCourse = document.rolechoice.elements[numbutton+4].value
Line 1367  function getIndex(caller) { Line 1801  function getIndex(caller) {
     }      }
     return -1;      return -1;
 }  }
   // ]]>
 </script>  </script>
 END  END
     return $verify_script;      return $verify_script;
Line 1381  sub coauthorlink { Line 1816  sub coauthorlink {
   
 sub display_cc_role {  sub display_cc_role {
     my $rolekey = shift;      my $rolekey = shift;
     my $roletext;      my ($roletext,$roletext_end);
     my $advanced = $env{'user.adv'};      my $advanced = $env{'user.adv'};
     my $tryagain = $env{'form.tryagain'};      my $tryagain = $env{'form.tryagain'};
     unless ($rolekey =~/^error\:/) {      unless ($rolekey =~/^error\:/) {
         if ($rolekey =~ m-^user\.role.cc\./($match_domain)/($match_courseid)$-) {          if ($rolekey =~ m{^user\.role\.(cc|co)\./($match_domain)/($match_courseid)$}) {
             my $tcourseid = $1.'_'.$2;              my $ccrole = $1;
             my $trolecode = 'cc./'.$1.'/'.$2;              my $tdom = $2;
               my $trest = $3;
               my $tcourseid = $tdom.'_'.$trest;
               my $trolecode = $ccrole.'./'.$tdom.'/'.$trest;
             my $twhere;              my $twhere;
             my $ttype;              my $ttype;
             my $tbg='LC_roles_is';              my $tbg='LC_roles_is';
             my %newhash=&Apache::lonnet::coursedescription($tcourseid);              my %newhash=&Apache::lonnet::coursedescription($tcourseid);
             if (%newhash) {              if (%newhash) {
                 $twhere=$newhash{'description'}.                  $twhere=$newhash{'description'}.
                         ' <span style="LC_fontsize_small">'.                          ' <span class="LC_fontsize_small">'.
                         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$2,$1).                          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                         '</span>';                          '</span>';
                 $ttype = $newhash{'type'};                  $ttype = $newhash{'type'};
             } else {              } else {
                 $twhere=&mt('Currently not available');                  $twhere=&mt('Currently not available');
                 $env{'course.'.$tcourseid.'.description'}=$twhere;                  $env{'course.'.$tcourseid.'.description'}=$twhere;
             }              }
             my $trole = &Apache::lonnet::plaintext('cc',$ttype);              my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);
             $twhere.="<br />".&mt('Domain').":".$1;              $twhere.="<br />".&mt('Domain').":".$tdom;
             $roletext = &build_roletext($trolecode,$1,$2,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');              ($roletext,$roletext_end) = &build_roletext($trolecode,$tdom,$trest,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');
         }          }
     }      }
     return ($roletext);      return ($roletext,$roletext_end);
 }  }
   
 sub adhoc_roles_row {  sub adhoc_roles_row {
     my ($dcdom,$rowtype) = @_;      my ($dcdom,$rowtype) = @_;
     my $output = &Apache::loncommon::continue_data_table_row()      my $output = &Apache::loncommon::continue_data_table_row()
                  .' <td colspan="5">'                   .' <td colspan="5">'
                  .'<table><tr><td>'  
                  .&mt('[_1]Ad hoc[_2] roles in domain [_3] --'                   .&mt('[_1]Ad hoc[_2] roles in domain [_3] --'
                      ,'<span class="LC_cusr_emph">','</span>',$dcdom)                       ,'<span class="LC_cusr_emph">','</span>',$dcdom)
                  .'</td>'                   .' ';
                  .'<td>';  
     my $selectcclink = &courselink($dcdom,$rowtype);      my $selectcclink = &courselink($dcdom,$rowtype);
     my $ccrole = &Apache::lonnet::plaintext('cc');      my $ccrole = &Apache::lonnet::plaintext('co',undef,undef,1);
     my $carole = &Apache::lonnet::plaintext('ca');      my $carole = &Apache::lonnet::plaintext('ca');
     my $selectcalink = &coauthorlink($dcdom,$rowtype);      my $selectcalink = &coauthorlink($dcdom,$rowtype);
     $output.=&mt('[_1]: [_2]',$ccrole,$selectcclink)      $output.=$ccrole.': '.$selectcclink
             .'<br /></td>'              .' | '.$carole.': '.$selectcalink.'</td>'
             .'<td>&nbsp;&nbsp;</td>'  
             .'<td>'.&mt('[_1]: [_2]',$carole,$selectcalink).'<br /></td>'  
             .'</tr></table>'  
             .'</td>'  
             .&Apache::loncommon::end_data_table_row();              .&Apache::loncommon::end_data_table_row();
     return $output;      return $output;
 }  }
Line 1438  sub recent_filename { Line 1870  sub recent_filename {
     return 'nohist_recent_'.&escape($area);      return 'nohist_recent_'.&escape($area);
 }  }
   
 sub set_privileges {  
 # role can be cc or ca  
     my ($dcdom,$pickedcourse,$role) = @_;  
     my $area = '/'.$dcdom.'/'.$pickedcourse;  
     my $spec = $role.'.'.$area;  
     my %userroles = &Apache::lonnet::set_arearole($role,$area,'','',  
   $env{'user.domain'},  
   $env{'user.name'});  
     my %ccrole = ();  
     &Apache::lonnet::standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area);  
     my ($author,$adv)= &Apache::lonnet::set_userprivs(\%userroles,\%ccrole);  
     &Apache::lonnet::appenv(\%userroles,[$role,'cm']);  
   
     &Apache::lonnet::log($env{'user.domain'},  
                          $env{'user.name'},  
                          $env{'user.home'},  
                         "Role ".$role);  
     &Apache::lonnet::appenv(  
                           {'request.role'        => $spec,  
                           'request.role.domain' => $dcdom,  
                           'request.course.sec'  => ''});  
     my $tadv=0;  
     if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; }  
     &Apache::lonnet::appenv({'request.role.adv'    => $tadv});  
 }  
   
 sub courseloadpage {  sub courseloadpage {
     my ($courseid) = @_;      my ($courseid) = @_;
     my $startpage;      my $startpage;
Line 1481  sub courseloadpage { Line 1887  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 1512  course they should act on, etc. Both in Line 2821  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.213  
changed lines
  Added in v.1.269.2.23


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