Diff for /loncom/auth/lonroles.pm between versions 1.231.4.14 and 1.298

version 1.231.4.14, 2010/06/02 16:27:43 version 1.298, 2014/02/28 19:19:41
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 138  use Apache::lonannounce; Line 137  use Apache::lonannounce;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonpageflip();  use Apache::lonpageflip();
 use Apache::lonnavdisplay();  use Apache::lonnavdisplay();
   use Apache::loncoursequeueadmin;
   use Apache::longroup;
   use Apache::lonrss;
 use GDBM_File;  use GDBM_File;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities;  use HTML::Entities;
    
   
 sub redirect_user {  sub redirect_user {
     my ($r,$title,$url,$msg,$launch_nav) = @_;      my ($r,$title,$url,$msg) = @_;
     $msg = $title if (! defined($msg));      $msg = $title if (! defined($msg));
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     &Apache::loncommon::no_cache($r);      &Apache::loncommon::no_cache($r);
     $r->send_http_header;      $r->send_http_header;
     my $swinfo=&Apache::lonmenu::rawconfig();  
     my $navwindow;  
     if ($launch_nav eq 'on') {  
  $navwindow.=&Apache::lonnavdisplay::launch_win('now',undef,undef,  
        ($url =~ m-^/adm/whatsnew-));  
     } else {  
  $navwindow.=&Apache::lonnavmaps::close();  
     }  
   
       # Breadcrumbs
       my $brcrum = [{'href' => $url,
                      'text' => 'Switching Role'},];
     my $start_page = &Apache::loncommon::start_page('Switching Role',undef,      my $start_page = &Apache::loncommon::start_page('Switching Role',undef,
                                                     {'redirect' => [1,$url]});                                                      {'redirect' => [1,$url],
                                                        'bread_crumbs' => $brcrum,});
     my $end_page   = &Apache::loncommon::end_page();      my $end_page   = &Apache::loncommon::end_page();
   
 # Note to style police:   # Note to style police: 
Line 167  sub redirect_user { Line 165  sub redirect_user {
     $url=~s/ /\%20/g;      $url=~s/ /\%20/g;
     $r->print(<<ENDREDIR);      $r->print(<<ENDREDIR);
 $start_page  $start_page
 <script type="text/javascript">  
 // <![CDATA[  
 $swinfo  
 // ]]>  
 </script>  
 $navwindow  
 <p>$msg</p>  <p>$msg</p>
 $end_page  $end_page
 ENDREDIR  ENDREDIR
Line 185  sub error_page { Line 177  sub error_page {
     &Apache::loncommon::no_cache($r);      &Apache::loncommon::no_cache($r);
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
     $r->print(&Apache::loncommon::start_page('Problems during Course Initialization').      # Breadcrumbs
       my $brcrum = [{'href' => $dest,
                      'text' => 'Problems during Course Initialization'},];
       $r->print(&Apache::loncommon::start_page('Problems during Course Initialization',
                                                undef,
                                                {'bread_crumbs' => $brcrum,})
       );
       $r->print(
         '<script type="text/javascript">'.          '<script type="text/javascript">'.
         '// <![CDATA['.          '// <![CDATA['.
         &Apache::lonmenu::rawconfig().          &Apache::lonmenu::rawconfig().
         '// ]]>'.          '// ]]>'.
         '</script>'.          '</script>'.
       '<p class="LC_error">'.&mt('The following problems occurred:').        '<p class="LC_error">'.&mt('The following problems occurred:').
               '<br />'.            '<br />'.
       $error.        $error.
       '</p><br /><a href="'.$dest.'">'.&mt('Continue').'</a>'.        '</p><br /><a href="'.$dest.'">'.&mt('Continue').'</a>'
               &Apache::loncommon::end_page());      );
       $r->print(&Apache::loncommon::end_page());
 }  }
   
 sub handler {  sub handler {
Line 205  sub handler { Line 205  sub handler {
     my $now=time;      my $now=time;
     my $then=$env{'user.login.time'};      my $then=$env{'user.login.time'};
     my $refresh=$env{'user.refresh.time'};      my $refresh=$env{'user.refresh.time'};
       my $update=$env{'user.update.time'};
     if (!$refresh) {      if (!$refresh) {
         $refresh = $then;          $refresh = $then;
     }      }
       if (!$update) {
           $update = $then;
       }
   
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
   
   # -------------------------------------------------- Check if setting hot list 
       my $hotlist;
       if ($env{'form.action'} eq 'verify_and_change_rolespref') {
           $hotlist = &Apache::lonpreferences::verify_and_change_rolespref($r);
       }
   
   # -------------------------------------------------------- Check for new roles
       my $updateresult;
       if ($env{'form.state'} eq 'doupdate') {
           my $show_course=&Apache::loncommon::show_course();
           my $checkingtxt;
           if ($show_course) {
               $checkingtxt = &mt('Checking for new courses ...');
           } else {
               $checkingtxt = &mt('Checking for new roles ...');
           }
           $updateresult = $checkingtxt;
           $updateresult .= &update_session_roles();
           &Apache::lonnet::appenv({'user.update.time'  => $now});
           $update = $now;
           &Apache::loncoursequeueadmin::reqauthor_check();
       }
   
   # -------------------------------------------------- Check for author requests
       my $reqauthor;
       if ($env{'form.state'} eq 'requestauthor') {
          $reqauthor = &Apache::loncoursequeueadmin::process_reqauthor(\$update);
       }
   
     my $envkey;      my $envkey;
     my %dcroles = ();      my %dcroles = ();
     my $numdc = &check_fordc(\%dcroles,$then);      my $numdc = &check_fordc(\%dcroles,$update,$then);
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      my $loncaparev = $Apache::lonnet::perlvar{'lonVersion'};
   
 # ================================================================== Roles Init  # ================================================================== Roles Init
     if ($env{'form.selectrole'}) {      if ($env{'form.selectrole'}) {
Line 225  sub handler { Line 261  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($refresh,$then);                  if (defined($env{'user.role.'.$env{'form.switchrole'}})) {
                       my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
                       if (!$end || $end > $now) {
                           if (!$start || $start < $update) {
                               $switch_is_active = 1;
                           }
                       }
                   }
                   unless ($switch_is_active) {
                       &adhoc_course_role($refresh,$update,$then);
                 }                  }
             }              }
     my %temp=('logout_'.$env{'request.course.id'} => time);      my %temp=('logout_'.$env{'request.course.id'} => time);
Line 237  sub handler { Line 282  sub handler {
  "request.course.fn"   => '',   "request.course.fn"   => '',
  "request.course.uri"  => '',   "request.course.uri"  => '',
  "request.course.sec"  => '',   "request.course.sec"  => '',
                                    "request.course.tied" => '',
  "request.role"        => 'cm',   "request.role"        => 'cm',
                                  "request.role.adv"    => $env{'user.adv'},                                   "request.role.adv"    => $env{'user.adv'},
  "request.role.domain" => $env{'user.domain'}});   "request.role.domain" => $env{'user.domain'}});
 # Check if user is a DC trying to enter a course or author space and needs privs to be created  # Check if user is a DC trying to enter a course or author space and needs privs to be created
         if ($numdc > 0) {          if ($numdc > 0) {
             foreach my $envkey (keys %env) {              foreach my $envkey (keys(%env)) {
 # Is this an ad-hoc Coordinator role?  # Is this an ad-hoc Coordinator role?
                 if (my ($ccrole,$domain,$coursenum) =                  if (my ($ccrole,$domain,$coursenum) =
     ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {      ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {
                     if ($dcroles{$domain}) {                      if ($dcroles{$domain}) {
                         &Apache::lonnet::check_adhoc_privs($domain,$coursenum,                          if (&Apache::lonnet::check_adhoc_privs($domain,$coursenum,
                                                            $then,$refresh,$now,$ccrole);                                                             $update,$refresh,$now,$ccrole)) {
                               &Apache::lonnet::appenv({"environment.internal.$domain.$coursenum.$ccrole.adhoc" => time});
                           }
                     }                      }
                     last;                      last;
                 }                  }
Line 263  sub handler { Line 311  sub handler {
                             my $trolecode = 'au./'.$domain.'/';                              my $trolecode = 'au./'.$domain.'/';
                             my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;                              my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                             $r->internal_redirect($switchserver);                              $r->internal_redirect($switchserver);
                               return OK;
                         }                          }
                         last;                          last;
                     }                      }
Line 274  sub handler { Line 323  sub handler {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                  my $trolecode = 'ca./'.$domain.'/'.$user;
                                 my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;                                  my $switchserver = '/adm/switchserver?otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                             last;                              last;
                         }                          }
Line 288  sub handler { Line 338  sub handler {
                     if ($dcroles{$domain}) {                      if ($dcroles{$domain}) {
                         my ($server_status,$home) = &check_author_homeserver($user,$domain);                          my ($server_status,$home) = &check_author_homeserver($user,$domain);
                         if (($server_status eq 'ok') || ($server_status eq 'switchserver')) {                          if (($server_status eq 'ok') || ($server_status eq 'switchserver')) {
                             &Apache::lonnet::check_adhoc_privs($domain,$user,$then,                              &Apache::lonnet::check_adhoc_privs($domain,$user,$update,
                                                                $refresh,$now,'ca');                                                                 $refresh,$now,'ca');
                             if ($server_status eq 'switchserver') {                              if ($server_status eq 'switchserver') {
                                 my $trolecode = 'ca./'.$domain.'/'.$user;                                   my $trolecode = 'ca./'.$domain.'/'.$user; 
                                 my $switchserver = '/adm/switchserver?'                                  my $switchserver = '/adm/switchserver?'
                                                   .'otherserver='.$home.'&amp;role='.$trolecode;                                                    .'otherserver='.$home.'&amp;role='.$trolecode;
                                 $r->internal_redirect($switchserver);                                  $r->internal_redirect($switchserver);
                                   return OK;
                             }                              }
                         } else {                          } else {
                             delete($env{$envkey});                              delete($env{$envkey});
Line 307  sub handler { Line 358  sub handler {
             }              }
         }          }
   
         foreach $envkey (keys %env) {          foreach $envkey (keys(%env)) {
             next if ($envkey!~/^user\.role\./);              next if ($envkey!~/^user\.role\./);
             my ($where,$trolecode,$role,$tstatus,$tend,$tstart);              my ($where,$trolecode,$role,$tstatus,$tend,$tstart);
             &Apache::lonnet::role_status($envkey,$then,$refresh,$now,\$role,\$where,              &Apache::lonnet::role_status($envkey,$update,$refresh,$now,\$role,\$where,
                                          \$trolecode,\$tstatus,\$tstart,\$tend);                                           \$trolecode,\$tstatus,\$tstart,\$tend);
             if ($env{'form.'.$trolecode}) {              if ($env{'form.'.$trolecode}) {
  if ($tstatus eq 'is') {   if ($tstatus eq 'is') {
     $where=~s/^\///;      $where=~s/^\///;
     my ($cdom,$cnum,$csec)=split(/\//,$where);      my ($cdom,$cnum,$csec)=split(/\//,$where);
                       if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) {
                           my $home = $env{'course.'.$cdom.'_'.$cnum.'.home'};
                           my @ids = &Apache::lonnet::current_machine_ids();
                           unless ($loncaparev eq '' && $home && grep(/^\Q$home\E$/,@ids)) {
                               my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
                               if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
                                   my ($switchserver,$switchwarning) =
                                       &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;
                                       my $end_page=&Apache::loncommon::end_page();
                                       $r->print(&Apache::loncommon::start_page('Selected course unavailable on this server').
                                                 '<p class="LC_warning">');
                                       if ($switchwarning) {
                                           $r->print($switchwarning.'<br /><a href="/adm/roles">');
                                           if (&Apache::loncommon::show_course()) {
                                               $r->print(&mt('Display courses'));
                                           } else {
                                               $r->print(&mt('Display roles'));
                                           }
                                           $r->print('</a>');
                                       } elsif ($switchserver) {
           $r->print(&mt('This course requires a newer version of LON-CAPA than is installed on this server.').
                                                     '<br />'.
                                                     '<a href="/adm/switchserver?'.$switchserver.'">'.
                                                     &mt('Switch Server').
                                                     '</a>');
                                       }
                                       $r->print('</p>'.&Apache::loncommon::end_page());
                                       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 435  ENDENTERKEY Line 522  ENDENTERKEY
                         my $msg;                          my $msg;
  my ($furl,$ferr)=   my ($furl,$ferr)=
     &Apache::lonuserstate::readmap($cdom.'/'.$cnum);      &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                           unless ($ferr) {
                               unless (($env{'form.switchrole'}) || 
                                       ($env{"environment.internal.$cdom.$cnum.$role.adhoc"})) {
                                   &Apache::lonnet::put('nohist_crslastlogin',
                                       {$env{'user.name'}.':'.$env{'user.domain'}.
                                        ':'.$csec.':'.$role => $now},$cdom,$cnum);
                               }
                               my ($feeds,$syllabus_time);
                               &Apache::lonrss::advertisefeeds($cnum,$cdom,undef,\$feeds);
                               &Apache::lonnet::appenv({'request.course.feeds' => $feeds});
                               &Apache::lonnet::get_numsuppfiles($cnum,$cdom,1);
                               unless ($env{'course.'.$cdom.'_'.$cnum.'.updatedsyllabus'}) {
                                   unless (($env{'course.'.$cdom.'_'.$cnum.'.externalsyllabus'}) ||
                                           ($env{'course.'.$cdom.'_'.$cnum.'.uploadedsyllabus'})) {
                                       my %syllabus=&Apache::lonnet::dump('syllabus',$cdom,$cnum);
                                       $syllabus_time = $syllabus{'uploaded.lastmodified'};
                                       if ($syllabus_time) {
                                           &Apache::lonnet::appenv({'request.course.syllabustime' => $syllabus_time});
                                       }
                                   }
                               }
                           }
  if (($env{'form.orgurl'}) &&    if (($env{'form.orgurl'}) && 
     ($env{'form.orgurl'}!~/^\/adm\/flip/)) {      ($env{'form.orgurl'}!~/^\/adm\/flip/) &&
       ($env{'form.orgurl'} ne '/adm/roles')) {
     my $dest=$env{'form.orgurl'};      my $dest=$env{'form.orgurl'};
                             if ($env{'form.symb'}) {                              if ($env{'form.symb'}) {
                                 if ($dest =~ /\?/) {                                  if ($dest =~ /\?/) {
                                     $dest .= '&';                                      $dest .= '&';
                                 } else {                                  } else {
                                     $dest .= '?'                                      $dest .= '?';
                                 }                                  }
                                 $dest .= 'symb='.$env{'form.symb'};                                  $dest .= 'symb='.$env{'form.symb'};
                             }                              }
Line 451  ENDENTERKEY Line 561  ENDENTERKEY
                             if (($ferr) && ($tadv)) {                              if (($ferr) && ($tadv)) {
  &error_page($r,$ferr,$dest);   &error_page($r,$ferr,$dest);
     } else {      } else {
                                   if ($dest =~ m{^/adm/coursedocs\?folderpath}) {
                                       if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { 
                                           my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
                                           &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,
                                                                                          $cdom.'_'.$cnum);
                                       }
                                   }
  $r->internal_redirect($dest);   $r->internal_redirect($dest);
     }      }
     return OK;      return OK;
Line 474  ENDENTERKEY Line 591  ENDENTERKEY
     } else {      } else {
  # Check to see if the user is a CC entering a course    # Check to see if the user is a CC entering a course 
  # for the first time   # for the first time
  my (undef, undef, $role, $courseid) = split(/\./, $envkey);  
  if (substr($courseid, 0, 1) eq '/') {  
     $courseid = substr($courseid, 1);  
  }  
  $courseid =~ s/\//_/;  
  if ((($role eq 'cc') || ($role eq 'co'))    if ((($role eq 'cc') || ($role eq 'co')) 
                                       && ($env{'course.' . $courseid .'.course.helper.not.run'})) {                                       && ($env{'course.'.$cdom.'_'.$cnum.'.course.helper.not.run'})) { 
     $furl = "/adm/helper/course.initialization.helper";      $furl = "/adm/helper/course.initialization.helper";
     # Send the user to the course they selected      # Send the user to the course they selected
  } elsif ($env{'request.course.id'}) {   } elsif ($env{'request.course.id'}) {
                                     if ($env{'form.destinationurl'}) {                                      my ($dest,$destsymb,$checkenc);
                                         my $dest = $env{'form.destinationurl'};                                      $dest = $env{'form.destinationurl'};
                                         if ($env{'form.destsymb'} ne '') {                                      $destsymb = $env{'form.destsymb'};
                                             my $esc_symb = &HTML::Entities::encode($env{'form.destsymb'},'"<>&');                                      if ($dest ne '') {
                                             $dest .= '?symb='.$esc_symb;                                          if ($env{'form.switchrole'}) {
                                               if ($destsymb ne '') {
                                                   if ($destsymb !~ m{^/enc/}) {
                                                       unless ($env{'request.role.adv'}) {
                                                           $checkenc = 1;
                                                       }
                                                   }
                                               }
                                               if ($dest =~ m{^/enc/}) {
                                                   if ($env{'request.role.adv'}) {
                                                       $dest = &Apache::lonenc::unencrypted($dest);
                                                       if ($destsymb eq '') {
                                                           ($destsymb) = ($dest =~ /(?:\?|\&)symb=([^\&]*)/);
                                                           $destsymb = &unescape($destsymb);
                                                       }
                                                   }
                                               } else {
                                                   if ($destsymb eq '') {
                                                       ($destsymb) = ($dest =~ /(?:\?|\&)symb=([^\&]+)/);
                                                       $destsymb = &unescape($destsymb);
                                                   }
                                                   unless ($env{'request.role.adv'}) {
                                                       $checkenc = 1;
                                                   }
                                               }
                                               if (($checkenc) && ($destsymb ne '')) {
                                                   my ($encstate,$unencsymb,$res);
                                                   $unencsymb = &Apache::lonnet::symbclean($destsymb);
                                                   (undef,undef,$res) = &Apache::lonnet::decode_symb($unencsymb);
                                                   &Apache::lonnet::symbverify($unencsymb,$res,\$encstate);
                                                   if ($encstate) {
                                                       if (($dest ne '') && ($dest !~ m{^/enc/})) {
                                                           $dest=&Apache::lonenc::encrypted($dest);
                                                       }
                                                   }
                                               }
                                         }                                          }
                                         &redirect_user($r,&mt('Entering [_1]',                                          unless (($dest =~ m{^/enc/}) || ($dest =~ /(\?|\&)symb=.+___\d+___.+/)) {
                                                       $env{'course.'.$courseid.'.description'}),                                              if (($destsymb ne '') && ($destsymb !~ m{^/enc/})) {
                                                $dest,$msg,                                                  my $esc_symb = &escape($destsymb);
                                                $env{'environment.remotenavmap'});                                                  $dest .= '?symb='.$esc_symb;
                                               }
                                           }
                                           &redirect_user($r, &mt('Entering [_1]',
                                                          $env{'course.'.$cdom.'_'.$cnum.'.description'}),
                                                          $dest, $msg);
                                         return OK;                                          return OK;
                                     }                                      }
     if (&Apache::lonnet::allowed('whn',      if (&Apache::lonnet::allowed('whn',
Line 502  ENDENTERKEY Line 654  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;
  }   }
     }      }
Line 519  ENDENTERKEY Line 670  ENDENTERKEY
     $furl=&Apache::lonpageflip::first_accessible_resource();      $furl=&Apache::lonpageflip::first_accessible_resource();
  }   }
                                 $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 533  ENDENTERKEY Line 683  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 571  ENDENTERKEY Line 720  ENDENTERKEY
     my $crumbtext = 'User Roles';      my $crumbtext = 'User Roles';
     my $pagetitle = 'My Roles';      my $pagetitle = 'My Roles';
     my $recent = &mt('Recent Roles');      my $recent = &mt('Recent Roles');
       my $standby = &mt('Role selected. Please stand by.');
     my $show_course=&Apache::loncommon::show_course();      my $show_course=&Apache::loncommon::show_course();
     if ($show_course) {      if ($show_course) {
         $crumbtext = 'Courses';          $crumbtext = 'Courses';
         $pagetitle = 'My Courses';          $pagetitle = 'My Courses';
         $recent = &mt('Recent Courses');          $recent = &mt('Recent Courses');
           $standby = &mt('Course selected. Please stand by.'); 
     }      }
     my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}];      my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}];
   
       my %roles_in_env;
       my $showcount = &roles_from_env(\%roles_in_env,$update); 
   
     my $swinfo=&Apache::lonmenu::rawconfig();      my $swinfo=&Apache::lonmenu::rawconfig();
     my $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum});      my $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum});
     my $standby=&mt('Role selected. Please stand by.');      my $funcs = &get_roles_functions($showcount);
     $standby=~s/\n/\\n/g;      $standby=~s/\n/\\n/g;
     my $noscript='<span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';      my $noscript='<br /><span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';
   
     $r->print(<<ENDHEADER);      $r->print(<<ENDHEADER);
 $start_page  $start_page
 <br />  $funcs
 <noscript>  <noscript>
 $noscript  $noscript
 </noscript>  </noscript>
Line 606  function enterrole (thisform,rolecode,bu Line 761  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 668  ENDHEADER Line 837  ENDHEADER
     }      }
         }          }
     }      }
 # -------------------------------------------------------- Choice or no choice?  
     if ($nochoose) {      if ($nochoose) {
  $r->print("<h2>".&mt('Sorry ...')."</h2>\n<span class='LC_error'>".   $r->print("<h2>".&mt('Sorry ...')."</h2>\n<span class='LC_error'>".
   &mt('This action is currently not authorized.').'</span>'.    &mt('This action is currently not authorized.').'</span>'.
   &Apache::loncommon::end_page());    &Apache::loncommon::end_page());
  return OK;   return OK;
     } else {      } else {
           if ($updateresult || $reqauthor || $hotlist) {
               my $showresult = '<div>';
               if ($updateresult) {
                   $showresult .= &Apache::lonhtmlcommon::confirm_success($updateresult);
               }
               if ($reqauthor) {
                   $showresult .= &Apache::lonhtmlcommon::confirm_success($reqauthor);
               }
               if ($hotlist) {
                   $showresult .= $hotlist;
               } 
               $showresult .= '</div>';
               $r->print($showresult);
           } elsif ($env{'form.state'} eq 'queued') {
               $r->print(&get_queued());
           }
         if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) {          if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) {
        $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'};         $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'};
         }          }
           my $display = ($env{'form.display'} =~ /^(showall)$/);
         $r->print('<form method="post" name="rolechoice" action="'.(($fn)?$fn:$r->uri).'">');          $r->print('<form method="post" name="rolechoice" action="'.(($fn)?$fn:$r->uri).'">');
         $r->print('<input type="hidden" name="orgurl" value="'.$fn.'" />');          $r->print('<input type="hidden" name="orgurl" value="'.$fn.'" />');
         $r->print('<input type="hidden" name="selectrole" value="1" />');          $r->print('<input type="hidden" name="selectrole" value="1" />');
         $r->print('<input type="hidden" name="newrole" value="" />');          $r->print('<input type="hidden" name="newrole" value="" />');
           $r->print('<input type="hidden" name="display" value="'.$display.'" />');
           $r->print('<input type="hidden" name="state" value="" />');
     }      }
       $r->rflush();
   
     my (%roletext,%sortrole,%roleclass,%futureroles,%timezones);      my (%roletext,%sortrole,%roleclass,%futureroles,%timezones);
     my ($countactive,$countfuture,$inrole,$possiblerole) =       my ($countactive,$countfuture,$inrole,$possiblerole) = 
         &gather_roles($then,$refresh,$now,$reinit,$nochoose,\%roletext,\%sortrole,\%roleclass,          &gather_roles($update,$refresh,$now,$reinit,$nochoose,\%roles_in_env,\%roletext,
                       \%futureroles,\%timezones);                        \%sortrole,\%roleclass,\%futureroles,\%timezones,$loncaparev);
   
     $refresh = $now;      $refresh = $now;
     &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});      &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});
     if ($env{'user.adv'}) {      unless ($env{'user.adv'}) { 
         $r->print('<p><label><input type="checkbox" name="showall"');  
         if ($env{'form.showall'}) { $r->print(' checked="checked" '); }  
         $r->print(' />'.&mt('Show all roles').'</label>'  
                  .' <input type="submit" value="'.&mt('Update display').'" />'  
                  .'</p>');  
     } else {  
         if ($countactive > 0) {          if ($countactive > 0) {
             $r->print(&Apache::loncoursequeueadmin::queued_selfenrollment());  
             my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');              my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
             my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');               my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); 
   
             $r->print(              $r->print(
                 '<p>'                  '<p>'
                .&mt('[_1]Visit the [_2]Course/Community Catalog[_3]'                 .&mt('[_1]Visit the [_2]Course/Community Catalog[_3][_4]'
                    .' to view all [_4] LON-CAPA courses and communities.'                     .' to view all [_5] LON-CAPA courses and communities.'
                    ,'<b>'                     ,'<b>'
                    ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'                     ,'<a href="/adm/coursecatalog?showdom='.$esc_dom.'">'
                    ,'</a></b>',$domdesc)                     ,'</a>'
                      ,'</b>'
                      ,'"'.$domdesc.'"')
                .'<br />'                 .'<br />'
                .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'                 .&mt('If a course or community is [_1]not[_2] in your list of current courses and communities below,'
                    .' you may be able to enroll if self-enrollment is permitted.'                     .' you may be able to enroll if self-enrollment is permitted.'
Line 727  ENDHEADER Line 908  ENDHEADER
     $r->print('<h2>'.&mt('Currently no active roles, courses or communities').'</h2>');      $r->print('<h2>'.&mt('Currently no active roles, courses or communities').'</h2>');
  }   }
         &findcourse_advice($r);          &findcourse_advice($r);
         &requestcourse_advice($r);          &requestcourse_advice($r); 
  $r->print('</form>');   $r->print('</form>');
         if ($countfuture) {          if ($countfuture) {
             $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));              $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture));
Line 758  ENDHEADER Line 939  ENDHEADER
  return OK;   return OK;
     }      }
 # ----------------------------------------------------------------------- Table  # ----------------------------------------------------------------------- Table
   
     if ($numdc > 0) {      if ($numdc > 0) {
         $r->print(&coursepick_jscript());          $r->print(&coursepick_jscript());
         $r->print(&Apache::loncommon::coursebrowser_javascript().          $r->print(&Apache::loncommon::coursebrowser_javascript().
Line 775  ENDHEADER Line 957  ENDHEADER
                       $env{'form.destsymb'}.'" />');                        $env{'form.destsymb'}.'" />');
         }          }
     }      }
   
     my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);      my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose);
     if ($env{'environment.recentroles'}) {      if ($env{'environment.recentroles'}) {
         my %recent_roles =          my %recent_roles =
Line 797  ENDHEADER Line 980  ENDHEADER
     } elsif ($numdc > 0) {      } elsif ($numdc > 0) {
                 unless ($role =~/^error\:/) {                  unless ($role =~/^error\:/) {
                     my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);                      my ($roletext,$role_text_end) = &display_cc_role('user.role.'.$role);
                     $output.= &Apache::loncommon::start_data_table_row().                      if ($roletext) {
                               $roletext.                          $output.= &Apache::loncommon::start_data_table_row().
                               &Apache::loncommon::end_data_table_row().                                    $roletext.
                               &Apache::loncommon::continue_data_table_row().                                    &Apache::loncommon::end_data_table_row();
                               $role_text_end.                          if ($role_text_end) {
                               &Apache::loncommon::end_data_table_row();                              $output .= &Apache::loncommon::continue_data_table_row().
                                          $role_text_end.
                                          &Apache::loncommon::end_data_table_row();
                           }
                       }
                 }                  }
             }              }
  }   }
Line 852  ENDHEADER Line 1039  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>'
Line 867  ENDHEADER Line 1059  ENDHEADER
     return OK;      return OK;
 }  }
   
   sub roles_from_env {
       my ($roleshash,$update) = @_;
       my $count = 0;
       if (ref($roleshash) eq 'HASH') {
           foreach my $envkey (keys(%env)) {
               if ($envkey =~ m{^user\.role\.(\w+)[./]}) {
                   next if ($1 eq 'gr');
                   $roleshash->{$envkey} = $env{$envkey};
                   my ($start,$end) = split(/\./,$env{$envkey});
                   unless ($end && $end<$update) {
                       $count ++;
                   }
               }
           }
       }
       return $count;
   }
   
 sub gather_roles {  sub gather_roles {
     my ($then,$refresh,$now,$reinit,$nochoose,$roletext,$sortrole,$roleclass,$futureroles,$timezones) = @_;      my ($update,$refresh,$now,$reinit,$nochoose,$roles_in_env,$roletext,$sortrole,$roleclass,$futureroles,
           $timezones,$loncaparev) = @_;
     my ($countactive,$countfuture,$inrole,$possiblerole) = (0,0,0,'');      my ($countactive,$countfuture,$inrole,$possiblerole) = (0,0,0,'');
     my $advanced = $env{'user.adv'};      my $advanced = $env{'user.adv'};
     my $tryagain = $env{'form.tryagain'};      my $tryagain = $env{'form.tryagain'};
     foreach my $envkey (sort(keys(%env))) {      my @ids = &Apache::lonnet::current_machine_ids();
         my $button = 1;      if (ref($roles_in_env) eq 'HASH') {
         my $switchserver='';          foreach my $envkey (sort(keys(%{$roles_in_env}))) {
         my ($role_text,$role_text_end,$sortkey);              my $button = 1;
         if ($envkey=~/^user\.role\./) {              my $switchserver='';
             my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);              my $switchwarning;
             &Apache::lonnet::role_status($envkey,$then,$refresh,$now,\$role,\$where,              my ($role_text,$role_text_end,$sortkey,$role,$where,$trolecode,$tstart,
                   $tend,$tremark,$tstatus,$tpstart,$tpend);
               &Apache::lonnet::role_status($envkey,$update,$refresh,$now,\$role,\$where,
                                          \$trolecode,\$tstatus,\$tstart,\$tend);                                           \$trolecode,\$tstatus,\$tstart,\$tend);
             next if (!defined($role) || $role eq '' || $role =~ /^gr/);              next if (!defined($role) || $role eq '' || $role =~ /^gr/);
             my $timezone = &role_timezone($where,$timezones);  
             $tremark='';              $tremark='';
             $tpstart='&nbsp;';              $tpstart='&nbsp;';
             $tpend='&nbsp;';              $tpend='&nbsp;';
             if ($tstart) {  
                 $tpstart=&Apache::lonlocal::locallocaltime($tstart,$timezone);  
             }  
             if ($tend) {  
                 $tpend=&Apache::lonlocal::locallocaltime($tend,$timezone);  
             }  
             if ($env{'request.role'} eq $trolecode) {              if ($env{'request.role'} eq $trolecode) {
                 $tstatus='selected';                  $tstatus='selected';
             }              }
Line 898  sub gather_roles { Line 1104  sub gather_roles {
             if (($tstatus eq 'is')              if (($tstatus eq 'is')
                 || ($tstatus eq 'selected')                  || ($tstatus eq 'selected')
                 || ($tstatus eq 'future')                  || ($tstatus eq 'future')
                 || ($env{'form.showall'})) {                  || ($env{'form.display'} eq 'showall')) {
                   my $timezone = &role_timezone($where,$timezones);
                   if ($tstart) {
                       $tpstart=&Apache::lonlocal::locallocaltime($tstart,$timezone);
                   }
                   if ($tend) {
                       $tpend=&Apache::lonlocal::locallocaltime($tend,$timezone);
                   }
                 if ($tstatus eq 'is') {                  if ($tstatus eq 'is') {
                     $tbg='LC_roles_is';                      $tbg='LC_roles_is';
                     $possiblerole=$trolecode;                      $possiblerole=$trolecode;
Line 924  sub gather_roles { Line 1137  sub gather_roles {
                 if ($role =~ /^cr\//) {                  if ($role =~ /^cr\//) {
                     my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);                      my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);
                     if ($tremark) { $tremark.='<br />'; }                      if ($tremark) { $tremark.='<br />'; }
                     $tremark.=&mt('Defined by [_1] at [_2].',$rauthor,$rdomain);                      $tremark.=&mt('Custom role defined by [_1].',$rauthor.':'.$rdomain);
                 }                  }
                 $trole=Apache::lonnet::plaintext($role);                  $trole=Apache::lonnet::plaintext($role);
                 my $ttype;                  my $ttype;
Line 935  sub gather_roles { Line 1148  sub gather_roles {
                 if (($role eq 'ca') || ($role eq 'aa')) {                  if (($role eq 'ca') || ($role eq 'aa')) {
                     my $home = &Apache::lonnet::homeserver($trest,$tdom);                      my $home = &Apache::lonnet::homeserver($trest,$tdom);
                     my $allowed=0;                      my $allowed=0;
                     my @ids=&Apache::lonnet::current_machine_ids();  
                     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }                      foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                     if (!$allowed) {                      if (!$allowed) {
                         $button=0;                          $button=0;
Line 943  sub gather_roles { Line 1155  sub gather_roles {
                     }                      }
                     #next if ($home eq 'no_host');                      #next if ($home eq 'no_host');
                     $home = &Apache::lonnet::hostname($home);                      $home = &Apache::lonnet::hostname($home);
                     $ttype='Construction Space';                      $ttype='Authoring Space';
                     $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').                      $twhere=&mt('User').': '.$trest.'<br />'.&mt('Domain').
                         ': '.$tdom.'<br />'.                          ': '.$tdom.'<br />'.
                         ' '.&mt('Server').':&nbsp;'.$home;                          ' '.&mt('Server').':&nbsp;'.$home;
Line 955  sub gather_roles { Line 1167  sub gather_roles {
                     my $home = &Apache::lonnet::homeserver                      my $home = &Apache::lonnet::homeserver
                         ($env{'user.name'},$env{'user.domain'});                          ($env{'user.name'},$env{'user.domain'});
                     my $allowed=0;                      my $allowed=0;
                     my @ids=&Apache::lonnet::current_machine_ids();  
                     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }                      foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                     if (!$allowed) {                      if (!$allowed) {
                         $button=0;                          $button=0;
Line 963  sub gather_roles { Line 1174  sub gather_roles {
                     }                      }
                     #next if ($home eq 'no_host');                      #next if ($home eq 'no_host');
                     $home = &Apache::lonnet::hostname($home);                      $home = &Apache::lonnet::hostname($home);
                     $ttype='Construction Space';                      $ttype='Authoring Space';
                     $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').                      $twhere=&mt('Domain').': '.$tdom.'<br />'.&mt('Server').
                         ':&nbsp;'.$home;                          ':&nbsp;'.$home;
                     $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';                      $env{'course.'.$tdom.'_'.$trest.'.description'}='ca';
Line 974  sub gather_roles { Line 1185  sub gather_roles {
                     $ttype = &Apache::loncommon::course_type($tcourseid);                      $ttype = &Apache::loncommon::course_type($tcourseid);
                     $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);                      $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);
                     if ($env{'course.'.$tcourseid.'.description'}) {                      if ($env{'course.'.$tcourseid.'.description'}) {
                           my $home=$env{'course.'.$tcourseid.'.home'};
                         $twhere=$env{'course.'.$tcourseid.'.description'};                          $twhere=$env{'course.'.$tcourseid.'.description'};
                         $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;                          $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                         $twhere = &HTML::Entities::encode($twhere,'"<>&');                          $twhere = &HTML::Entities::encode($twhere,'"<>&');
Line 981  sub gather_roles { Line 1193  sub gather_roles {
                             $twhere.=' <span class="LC_fontsize_small">'.                              $twhere.=' <span class="LC_fontsize_small">'.
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                                     '</span>';                                      '</span>';
                               unless ($home && grep(/^\Q$home\E$/,@ids) && $loncaparev eq '') {
                                   my $required = $env{'course.'.$tcourseid.'.internal.releaserequired'};
                                   if ($required ne '') {
                                       ($switchserver,$switchwarning) = 
                                           &check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                       if ($switchserver || $switchwarning) {
                                           $button = 0;
                                       }
                                   }
                               }
                         }                          }
                     } else {                      } else {
                         my %newhash=&Apache::lonnet::coursedescription($tcourseid);                          my %newhash=&Apache::lonnet::coursedescription($tcourseid);
Line 988  sub gather_roles { Line 1210  sub gather_roles {
                             $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.                              $sortkey=$role."\0".$tdom."\0".$newhash{'description'}.
                                 "\0".$envkey;                                  "\0".$envkey;
                             $twhere=&HTML::Entities::encode($newhash{'description'},'"<>&').                              $twhere=&HTML::Entities::encode($newhash{'description'},'"<>&').
                               ' <span class="LC_fontsize_small">'.                                      ' <span class="LC_fontsize_small">'.
         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).                                       &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                               '</span>';                                      '</span>';
                             $ttype = $newhash{'type'};                              $ttype = $newhash{'type'};
                             $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);                              $trole = &Apache::lonnet::plaintext($role,$ttype,$tcourseid);
                               my $home = $newhash{'home'};
                               unless ($home && grep(/^\Q$home\E$/,@ids) && $loncaparev eq '') {
                                   my $required = $newhash{'internal.releaserequired'};
                                   if ($required ne '') {
                                       ($switchserver,$switchwarning) =
                                           &check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                       if ($switchserver || $switchwarning) {
                                           $button = 0;
                                       }
                                   }
                               }
                         } else {                          } else {
                             $twhere=&mt('Currently not available');                              $twhere=&mt('Currently not available');
                             $env{'course.'.$tcourseid.'.description'}=$twhere;                              $env{'course.'.$tcourseid.'.description'}=$twhere;
Line 1016  sub gather_roles { Line 1249  sub gather_roles {
                 ($role_text,$role_text_end) =                  ($role_text,$role_text_end) =
                     &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,                      &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,
                                     $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,                                      $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,
                                     $tpend,$nochoose,$button,$switchserver,$reinit);                                      $tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning);
                 $roletext->{$envkey}=[$role_text,$role_text_end];                  $roletext->{$envkey}=[$role_text,$role_text_end];
                 if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}                  if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}
                 $sortrole->{$sortkey}=$envkey;                  $sortrole->{$sortkey}=$envkey;
Line 1036  sub role_timezone { Line 1269  sub role_timezone {
             my $cnum = $2;              my $cnum = $2;
             if ($cdom && $cnum) {              if ($cdom && $cnum) {
                 if (!exists($timezones->{$cdom.'_'.$cnum})) {                  if (!exists($timezones->{$cdom.'_'.$cnum})) {
                     my %timehash =                      my $tz;
                         &Apache::lonnet::get('environment',['timezone'],$cdom,$cnum);                      if ($env{'course.'.$cdom.'_'.$cnum.'.description'}) {
                     if ($timehash{'timezone'} eq '') {                          $tz = $env{'course.'.$cdom.'_'.$cnum.'.timezone'};
                       } else {
                           my %timehash =
                               &Apache::lonnet::get('environment',['timezone'],$cdom,$cnum);
                           $tz = $timehash{'timezone'};
                       }
                       if ($tz eq '') {
                         if (!exists($timezones->{$cdom})) {                          if (!exists($timezones->{$cdom})) {
                             my %domdefaults =                               my %domdefaults = 
                                 &Apache::lonnet::get_domain_defaults($cdom);                                  &Apache::lonnet::get_domain_defaults($cdom);
Line 1051  sub role_timezone { Line 1290  sub role_timezone {
                         $timezones->{$cdom.'_'.$cnum} = $timezones->{$cdom};                          $timezones->{$cdom.'_'.$cnum} = $timezones->{$cdom};
                     } else {                      } else {
                         $timezones->{$cdom.'_'.$cnum} =                           $timezones->{$cdom.'_'.$cnum} = 
                             &Apache::lonlocal::gettimezone($timehash{'timezone'});                              &Apache::lonlocal::gettimezone($tz);
                     }                      }
                 }                  }
                 $timezone = $timezones->{$cdom.'_'.$cnum};                  $timezone = $timezones->{$cdom.'_'.$cnum};
Line 1108  sub roletable_headers { Line 1347  sub roletable_headers {
 }  }
   
 sub roletypes {  sub roletypes {
     my @types = ('Domain','Construction Space','Course','Community','Unavailable','System');      my @types = ('Domain','Authoring Space','Course','Community','Unavailable','System');
     return @types;       return @types; 
 }  }
   
Line 1187  sub requestcourse_advice { Line 1426  sub requestcourse_advice {
     &Apache::lonnet::check_can_request($env{'user.domain'},\%can_request,\%request_doms);      &Apache::lonnet::check_can_request($env{'user.domain'},\%can_request,\%request_doms);
     if (keys(%request_doms) > 0) {      if (keys(%request_doms) > 0) {
         my ($types,$typename) = &Apache::loncommon::course_types();          my ($types,$typename) = &Apache::loncommon::course_types();
         if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) {          if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) { 
             $r->print('<h3>'.&mt('Request creation of a course or community').'</h3>'.              $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>');                        '<p>'.&mt('You have rights to request the creation of courses and/or communities in the following domain(s):').'<ul>');
             my (@reqdoms,@reqtypes);              my (@reqdoms,@reqtypes);
             foreach my $type (sort(keys(%request_doms))) {              foreach my $type (sort(keys(%request_doms))) {
                 push(@reqtypes,$type);                  push(@reqtypes,$type); 
                 if (ref($request_doms{$type}) eq 'ARRAY') {                  if (ref($request_doms{$type}) eq 'ARRAY') {
                     my $domstr = join(', ',map { &Apache::lonnet::domain($_) } sort(@{$request_doms{$type}}));                      my $domstr = join(', ',map { &Apache::lonnet::domain($_) } sort(@{$request_doms{$type}}));
                     $r->print(                      $r->print(
Line 1225  sub requestcourse_advice { Line 1464  sub requestcourse_advice {
             }              }
             if (@reqdoms == 1 || @showtypes > 0) {              if (@reqdoms == 1 || @showtypes > 0) {
                 $requrl .= '&state=crstype&action=new';                  $requrl .= '&state=crstype&action=new';
             }              } 
             $r->print('</ul>'.&mt('Use the [_1]request form[_2] to submit a request for creation of a new course or community.','<a href="'.$requrl.'">','</a>').'</p>');              $r->print('</ul>'.&mt('Use the [_1]request form[_2] to submit a request for creation of a new course or community.','<a href="'.$requrl.'">','</a>').'</p>');
         }          }
     }      }
Line 1247  sub privileges_info { Line 1486  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 1288  sub privileges_info { Line 1527  sub privileges_info {
 }  }
   
 sub build_roletext {  sub build_roletext {
     my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit) = @_;      my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning) = @_;
     my ($roletext,$roletext_end);      my ($roletext,$roletext_end);
     my $is_dc=($trolecode =~ m/^dc\./);      my $is_dc=($trolecode =~ m/^dc\./);
     my $rowspan=($is_dc) ? ''      my $rowspan=($is_dc) ? ''
Line 1306  sub build_roletext { Line 1545  sub build_roletext {
             } else {              } else {
                 $roletext.=('<td'.$rowspan.' class="'.$tbg.'">&nbsp;</td>');                  $roletext.=('<td'.$rowspan.' class="'.$tbg.'">&nbsp;</td>');
             }              }
               if ($switchwarning) {
                   if ($tremark eq '') {
                       $tremark = $switchwarning;
                   } else {
                       $tremark .= '<br />'.$switchwarning;
                   }
               }
         } elsif ($tstatus eq 'is') {          } elsif ($tstatus eq 'is') {
             $roletext.='<td'.$rowspan.' class="'.$tbg.'">'.              $roletext.='<td'.$rowspan.' class="'.$tbg.'">'.
                         '<input name="'.$buttonname.'" type="button" value="'.                          '<input name="'.$buttonname.'" type="button" value="'.
Line 1353  sub build_roletext { Line 1599  sub build_roletext {
     return ($roletext,$roletext_end);      return ($roletext,$roletext_end);
 }  }
   
 sub check_needs_switchserver {  
     my ($possiblerole) = @_;  
     my $needs_switchserver;  
     my ($role,$where) = split(/\./,$possiblerole,2);  
     my (undef,$tdom,$twho) = split(/\//,$where);  
     my ($server_status,$home);  
     if (($role eq 'ca') || ($role eq 'aa')) {  
         ($server_status,$home) = &check_author_homeserver($twho,$tdom);  
     } else {  
         ($server_status,$home) = &check_author_homeserver($env{'user.name'},  
                                                           $env{'user.domain'});  
     }  
     if ($server_status eq 'switchserver') {  
         $needs_switchserver = 1;  
     }  
     return $needs_switchserver;  
 }  
   
 sub check_author_homeserver {  sub check_author_homeserver {
     my ($uname,$udom)=@_;      my ($uname,$udom)=@_;
     if (($uname eq '') || ($udom eq '')) {      if (($uname eq '') || ($udom eq '')) {
Line 1389  sub check_author_homeserver { Line 1617  sub check_author_homeserver {
 }  }
   
 sub check_fordc {  sub check_fordc {
     my ($dcroles,$then) = @_;      my ($dcroles,$update,$then) = @_;
     my $numdc = 0;      my $numdc = 0;
     if ($env{'user.adv'}) {      if ($env{'user.adv'}) {
         foreach my $envkey (sort keys %env) {          foreach my $envkey (sort keys %env) {
Line 1397  sub check_fordc { Line 1625  sub check_fordc {
                 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 1410  sub check_fordc { Line 1642  sub check_fordc {
 }  }
   
 sub adhoc_course_role {  sub adhoc_course_role {
     my ($refresh,$then) = @_;      my ($refresh,$update,$then) = @_;
     my ($cdom,$cnum,$crstype);      my ($cdom,$cnum,$crstype);
     $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     $crstype = &Apache::loncommon::course_type();      $crstype = &Apache::loncommon::course_type();
     if (&check_forcc($cdom,$cnum,$refresh,$then,$crstype)) {      if (&check_forcc($cdom,$cnum,$refresh,$update,$then,$crstype)) {
         my $setprivs;          my $setprivs;
         if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {          if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {
             $setprivs = 1;              $setprivs = 1;
         } else {          } else {
             my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});              my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}});
             if (($start && ($start>$refresh || $start == -1)) ||              if (($start && ($start>$refresh || $start == -1)) ||
                 ($end && $end<$then)) {                  ($end && $end<$update)) {
                   $setprivs = 1;
               }
           }
           unless ($setprivs) {
               if (!exists($env{'user.priv.'.$env{'form.switchrole'}.'./'})) {
                 $setprivs = 1;                  $setprivs = 1;
             }              }
         }          }
         if ($setprivs) {          if ($setprivs) {
             if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)([\w/]*)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {              if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)(.*?)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
                 my $role = $1;                  my $role = $1;
                 my $custom_role = $2;                  my $custom_role = $2;
                 my $usec = $3;                  my $usec = $3;
Line 1453  sub adhoc_course_role { Line 1690  sub adhoc_course_role {
                     $spec .= '/'.$usec;                      $spec .= '/'.$usec;
                     $area .= '/'.$usec;                      $area .= '/'.$usec;
                 }                  }
                 &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area);                  if ($role =~ /^cr/) {
                       &Apache::lonnet::custom_roleprivs(\%newrole,$role,$cdom,$cnum,$spec,$area);
                   } else {
                       &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area);
                   }
                 &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups);                  &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups);
                 my $adhocstart = $refresh-1;                  my $adhocstart = $refresh-1;
                 $userroles{'user.role.'.$spec} = $adhocstart.'.';                  $userroles{'user.role.'.$spec} = $adhocstart.'.';
Line 1465  sub adhoc_course_role { Line 1706  sub adhoc_course_role {
 }  }
   
 sub check_forcc {  sub check_forcc {
     my ($cdom,$cnum,$refresh,$then,$crstype) = @_;      my ($cdom,$cnum,$refresh,$update,$then,$crstype) = @_;
     my ($is_cc,$ccrole);      my ($is_cc,$ccrole);
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $ccrole = 'co';          $ccrole = 'co';
     } else {      } else {
         $ccrole = 'cc';          $ccrole = 'cc';
     }      }
     if ($cdom ne '' && $cnum ne '') {      if (&Apache::lonnet::is_course($cdom,$cnum)) {
         if (&Apache::lonnet::is_course($cdom,$cnum)) {          my $envkey = 'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum;
             my $envkey = 'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum;          if (defined($env{$envkey})) {
             if (defined($env{$envkey})) {              $is_cc = 1;
                 $is_cc = 1;              my ($tstart,$tend)=split(/\./,$env{$envkey});
                 my ($tstart,$tend)=split(/\./,$env{$envkey});              my $limit = $update;
                 if ($tstart && $tstart>$refresh) { $is_cc = 0; }              if ($env{'request.role'} eq $ccrole.'./'.$cdom.'/'.$cnum) {
                 if ($tend   && $tend  <$then) { $is_cc = 0; }                  $limit = $then;
             }              }
               if ($tstart && $tstart>$refresh) { $is_cc = 0; }
               if ($tend   && $tend  <$limit) { $is_cc = 0; }
         }          }
     }      }
     return $is_cc;      return $is_cc;
 }  }
   
   sub check_release_required {
       my ($loncaparev,$tcourseid,$trolecode,$required) = @_;
       my ($switchserver,$warning);
       if ($required ne '') {
           my ($reqdmajor,$reqdminor) = ($required =~ /^(\d+)\.(\d+)$/);
           my ($major,$minor) = ($loncaparev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);
           if ($reqdmajor ne '' && $reqdminor ne '') {
               my $otherserver;
               if (($major eq '' && $minor eq '') || 
                   (($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)))) {
                   my ($userdomserver) = &Apache::lonnet::choose_server($env{'user.domain'});
                   my $switchlcrev = 
                       &Apache::lonnet::get_server_loncaparev($env{'user.domain'},
                                                              $userdomserver);
                   my ($swmajor,$swminor) = ($switchlcrev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);
                   if (($swmajor eq '' && $swminor eq '') || ($reqdmajor > $swmajor) || 
                       (($reqdmajor == $swmajor) && ($reqdminor > $swminor))) {
                       my $cdom = $env{'course.'.$tcourseid.'.domain'};
                       if ($cdom ne $env{'user.domain'}) {
                           my ($coursedomserver,$coursehostname) = &Apache::lonnet::choose_server($cdom); 
                           my $serverhomeID = &Apache::lonnet::get_server_homeID($coursehostname);
                           my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);
                           my %defdomdefaults = &Apache::lonnet::get_domain_defaults($serverhomedom);
                           my %udomdefaults = &Apache::lonnet::get_domain_defaults($env{'user.domain'});
                           my $remoterev = &Apache::lonnet::get_server_loncaparev($serverhomedom,$coursedomserver);
                           my $canhost =
                               &Apache::lonnet::can_host_session($env{'user.domain'},
                                                                 $coursedomserver,
                                                                 $remoterev,
                                                                 $udomdefaults{'remotesessions'},
                                                                 $defdomdefaults{'hostedsessions'});
   
                           if ($canhost) {
                               $otherserver = $coursedomserver;
                           } else {
                               $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$tcourseid.'.internal.releaserequired'}).'<br />'. &mt("No suitable server could be found amongst servers in either your own domain or in the course's domain.");
                           }
                       } else {
                           $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$tcourseid.'.internal.releaserequired'}).'<br />'.&mt("No suitable server could be found amongst servers in your own domain (which is also the course's domain).");
                       }
                   } else {
                       $otherserver = $userdomserver;
                   }
               }
               if ($otherserver ne '') {
                   $switchserver = 'otherserver='.$otherserver.'&amp;role='.$trolecode;
               }
           }
       }
       return ($switchserver,$warning);
   }
   
 sub courselink {  sub courselink {
     my ($dcdom,$rowtype) = @_;      my ($dcdom,$rowtype) = @_;
     my $courseform=&Apache::loncommon::selectcourse_link      my $courseform=&Apache::loncommon::selectcourse_link
Line 1566  sub display_cc_role { Line 1861  sub display_cc_role {
             my %newhash=&Apache::lonnet::coursedescription($tcourseid);              my %newhash=&Apache::lonnet::coursedescription($tcourseid);
             if (%newhash) {              if (%newhash) {
                 $twhere=$newhash{'description'}.                  $twhere=$newhash{'description'}.
                         ' <span style="LC_fontsize_small">'.                          ' <span class="LC_fontsize_small">'.
                         &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).                          &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
                         '</span>';                          '</span>';
                 $ttype = $newhash{'type'};                  $ttype = $newhash{'type'};
Line 1621  sub courseloadpage { Line 1916  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) = @_;
       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')]);
           }
       }
       if (&Apache::loncommon::designparm('login.coursecatalog',$env{'user.domain'})) {
           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 1652  course they should act on, etc. Both in Line 2850  course they should act on, etc. Both in
 handler determines via C<lonnet>'s C<&allowed> function that a certain  handler determines via C<lonnet>'s C<&allowed> function that a certain
 action is not allowed, C<lonroles> is used as error handler. This  action is not allowed, C<lonroles> is used as error handler. This
 allows the user to select another role which may have permission to do  allows the user to select another role which may have permission to do
 what they were trying to do. C<lonroles> can also be accessed via the  what they were trying to do.
 B<CRS> button in the Remote Control.   
   
 =begin latex  =begin latex
   

Removed from v.1.231.4.14  
changed lines
  Added in v.1.298


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