--- loncom/auth/lonroles.pm 2009/10/26 21:16:38 1.236
+++ loncom/auth/lonroles.pm 2013/01/01 03:06:27 1.279
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# User Roles Screen
#
-# $Id: lonroles.pm,v 1.236 2009/10/26 21:16:38 raeburn Exp $
+# $Id: lonroles.pm,v 1.279 2013/01/01 03:06:27 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -57,8 +57,7 @@ course they should act on, etc. Both in
handler determines via C's C<&allowed> function that a certain
action is not allowed, C is used as error handler. This
allows the user to select another role which may have permission to do
-what they were trying to do. C can also be accessed via the
-B button in the Remote Control.
+what they were trying to do.
=begin latex
@@ -138,25 +137,19 @@ use Apache::lonannounce;
use Apache::lonlocal;
use Apache::lonpageflip();
use Apache::lonnavdisplay();
+use Apache::loncoursequeueadmin;
+use Apache::longroup;
use GDBM_File;
use LONCAPA qw(:DEFAULT :match);
use HTML::Entities;
-
+
sub redirect_user {
- my ($r,$title,$url,$msg,$launch_nav) = @_;
+ my ($r,$title,$url,$msg) = @_;
$msg = $title if (! defined($msg));
&Apache::loncommon::content_type($r,'text/html');
&Apache::loncommon::no_cache($r);
$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,
@@ -171,12 +164,6 @@ sub redirect_user {
$url=~s/ /\%20/g;
$r->print(<
-//
-
-$navwindow
$msg
$end_page
ENDREDIR
@@ -217,13 +204,49 @@ sub handler {
my $now=time;
my $then=$env{'user.login.time'};
my $refresh=$env{'user.refresh.time'};
+ my $update=$env{'user.update.time'};
if (!$refresh) {
$refresh = $then;
}
+ if (!$update) {
+ $update = $then;
+ }
+
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
+
+# -------------------------------------------------- Check if setting hot list
+ my $hotlist;
+ if ($env{'form.action'} eq 'verify_and_change_rolespref') {
+ $hotlist = &Apache::lonpreferences::verify_and_change_rolespref($r);
+ }
+
+# -------------------------------------------------------- Check for new roles
+ my $updateresult;
+ if ($env{'form.state'} eq 'doupdate') {
+ my $show_course=&Apache::loncommon::show_course();
+ my $checkingtxt;
+ if ($show_course) {
+ $checkingtxt = &mt('Checking for new courses ...');
+ } else {
+ $checkingtxt = &mt('Checking for new roles ...');
+ }
+ $updateresult = $checkingtxt;
+ $updateresult .= &update_session_roles();
+ &Apache::lonnet::appenv({'user.update.time' => $now});
+ $update = $now;
+ &Apache::loncoursequeueadmin::reqauthor_check();
+ }
+
+# -------------------------------------------------- Check for author requests
+ my $reqauthor;
+ if ($env{'form.state'} eq 'requestauthor') {
+ $reqauthor = &Apache::loncoursequeueadmin::process_reqauthor(\$update);
+ }
+
my $envkey;
my %dcroles = ();
- my $numdc = &check_fordc(\%dcroles,$then);
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
+ my $numdc = &check_fordc(\%dcroles,$update,$then);
+ my $loncaparev = $Apache::lonnet::perlvar{'lonVersion'};
# ================================================================== Roles Init
if ($env{'form.selectrole'}) {
@@ -237,8 +260,17 @@ sub handler {
if ($env{'request.course.id'}) {
# Check if user is CC trying to select a course role
if ($env{'form.switchrole'}) {
- if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {
- &adhoc_course_role($refresh,$then);
+ my $switch_is_active;
+ 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);
@@ -249,18 +281,21 @@ sub handler {
"request.course.fn" => '',
"request.course.uri" => '',
"request.course.sec" => '',
+ "request.course.tied" => '',
"request.role" => 'cm',
"request.role.adv" => $env{'user.adv'},
"request.role.domain" => $env{'user.domain'}});
# Check if user is a DC trying to enter a course or author space and needs privs to be created
if ($numdc > 0) {
foreach my $envkey (keys %env) {
-# Is this an ad-hoc CC-role?
- if (my ($domain,$coursenum) =
- ($envkey =~ m-^form\.cc\./($match_domain)/($match_courseid)$-)) {
+# Is this an ad-hoc Coordinator role?
+ if (my ($ccrole,$domain,$coursenum) =
+ ($envkey =~ m-^form\.(cc|co)\./($match_domain)/($match_courseid)$-)) {
if ($dcroles{$domain}) {
- &Apache::lonnet::check_adhoc_privs($domain,$coursenum,
- $then,$refresh,$now,'cc');
+ if (&Apache::lonnet::check_adhoc_privs($domain,$coursenum,
+ $update,$refresh,$now,$ccrole)) {
+ &Apache::lonnet::appenv({"environment.internal.$domain.$coursenum.$ccrole.adhoc" => time});
+ }
}
last;
}
@@ -273,7 +308,7 @@ sub handler {
my ($server_status,$home) = &check_author_homeserver($user,$domain);
if ($server_status eq 'switchserver') {
my $trolecode = 'au./'.$domain.'/';
- my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
+ my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
$r->internal_redirect($switchserver);
}
last;
@@ -284,7 +319,7 @@ sub handler {
my ($server_status,$home) = &check_author_homeserver($user,$domain);
if ($server_status eq 'switchserver') {
my $trolecode = 'ca./'.$domain.'/'.$user;
- my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
+ my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
$r->internal_redirect($switchserver);
}
last;
@@ -300,12 +335,12 @@ sub handler {
if ($dcroles{$domain}) {
my ($server_status,$home) = &check_author_homeserver($user,$domain);
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');
if ($server_status eq 'switchserver') {
my $trolecode = 'ca./'.$domain.'/'.$user;
my $switchserver = '/adm/switchserver?'
- .'otherserver='.$home.'&role='.$trolecode;
+ .'otherserver='.$home.'&role='.$trolecode;
$r->internal_redirect($switchserver);
}
} else {
@@ -322,12 +357,48 @@ sub handler {
foreach $envkey (keys %env) {
next if ($envkey!~/^user\.role\./);
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);
if ($env{'form.'.$trolecode}) {
if ($tstatus eq 'is') {
$where=~s/^\///;
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').
+ '
'.
''.&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.'&role='.$trolecode;
+ }
+ }
+ }
+ return ($switchserver,$warning);
+}
+
sub courselink {
my ($dcdom,$rowtype) = @_;
my $courseform=&Apache::loncommon::selectcourse_link
('rolechoice','dccourse'.$rowtype.'_'.$dcdom,
'dcdomain'.$rowtype.'_'.$dcdom,'coursedesc'.$rowtype.'_'.
- $dcdom,$dcdom,undef);
+ $dcdom,$dcdom,undef,'Course/Community');
my $hiddenitems = ''.
''.
''.
@@ -1531,7 +1795,7 @@ sub courselink {
sub coursepick_jscript {
my %lt = &Apache::lonlocal::texthash(
- plsu => "Please use the 'Select Course' link to open a separate pick course window where you may select the course or community you wish to enter.",
+ plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",
youc => 'You can only use this screen to select courses and communities in the current domain.',
);
my $verify_script = <<"END";
@@ -1584,26 +1848,29 @@ sub display_cc_role {
my $advanced = $env{'user.adv'};
my $tryagain = $env{'form.tryagain'};
unless ($rolekey =~/^error\:/) {
- if ($rolekey =~ m-^user\.role.cc\./($match_domain)/($match_courseid)$-) {
- my $tcourseid = $1.'_'.$2;
- my $trolecode = 'cc./'.$1.'/'.$2;
+ if ($rolekey =~ m{^user\.role\.(cc|co)\./($match_domain)/($match_courseid)$}) {
+ my $ccrole = $1;
+ my $tdom = $2;
+ my $trest = $3;
+ my $tcourseid = $tdom.'_'.$trest;
+ my $trolecode = $ccrole.'./'.$tdom.'/'.$trest;
my $twhere;
my $ttype;
my $tbg='LC_roles_is';
my %newhash=&Apache::lonnet::coursedescription($tcourseid);
if (%newhash) {
$twhere=$newhash{'description'}.
- ' '.
- &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$2,$1).
+ ' '.
+ &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom).
'';
$ttype = $newhash{'type'};
} else {
$twhere=&mt('Currently not available');
$env{'course.'.$tcourseid.'.description'}=$twhere;
}
- my $trole = &Apache::lonnet::plaintext('cc',$ttype);
- $twhere.=" ".&mt('Domain').":".$1;
- ($roletext,$roletext_end) = &build_roletext($trolecode,$1,$2,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');
+ my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);
+ $twhere.=" ".&mt('Domain').":".$tdom;
+ ($roletext,$roletext_end) = &build_roletext($trolecode,$tdom,$trest,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');
}
}
return ($roletext,$roletext_end);
@@ -1617,11 +1884,11 @@ sub adhoc_roles_row {
,'','',$dcdom)
.' ';
my $selectcclink = &courselink($dcdom,$rowtype);
- my $ccrole = &Apache::lonnet::plaintext('cc');
+ my $ccrole = &Apache::lonnet::plaintext('co',undef,undef,1);
my $carole = &Apache::lonnet::plaintext('ca');
my $selectcalink = &coauthorlink($dcdom,$rowtype);
$output.=$ccrole.': '.$selectcclink
- .' | '.$carole.': '.$selectcalink
+ .' | '.$carole.': '.$selectcalink.'
'
.&Apache::loncommon::end_data_table_row();
return $output;
}
@@ -1648,6 +1915,872 @@ sub courseloadpage {
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 ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role);
+ 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(/\./,$rolekey,2);
+ 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 = '
'.&mt('The section has changed for your current role. Log-out and log-in again to select a role for the new section.').'
'.
+ ''.
+ ''.
+ ''.
+ &mt('Your section has changed for your current [_1] role in [_2].',$rolename,$coursedesc).' ';
+ my $button = '';
+ 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 .= '';
+ }
+ } elsif ($currrole_expired) {
+ $msg .= '
';
+ if (&Apache::loncommon::show_course()) {
+ $msg .= &mt('Your role in the current course has expired.');
+ } else {
+ $msg .= &mt('Your current role has expired.');
+ }
+ $msg .= ' '.&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.').'
';
+ }
+ &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 .= '
';
+ if ($rolesmsg) {
+ $msg .= '
'.$rolesmsg.'
';
+ }
+ if ($groupsmsg) {
+ $msg .= '
'.$groupsmsg.'
';
+ }
+ $msg .= '
';
+ } else {
+ $msg = ' '.$rolesmsg.' ';
+ }
+ 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 .= '
';
+ }
+ 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 .= '
'.&mt('Author role request').' ';
+ 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 .= ''.
+ &mt('Your request for an author role has been approved.').' '.
+ &mt('Use the "Check for changes" link to update your list of roles.').
+ '';
+ }
+ }
+ $output .= '
';
+ }
+ }
+ }
+ 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 ' ';
+}
+
1;
__END__
@@ -1679,8 +2812,7 @@ course they should act on, etc. Both in
handler determines via C's C<&allowed> function that a certain
action is not allowed, C is used as error handler. This
allows the user to select another role which may have permission to do
-what they were trying to do. C can also be accessed via the
-B button in the Remote Control.
+what they were trying to do.
=begin latex