--- loncom/auth/lonroles.pm 2004/03/05 01:55:01 1.87 +++ loncom/auth/lonroles.pm 2009/05/17 23:38:12 1.222 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # User Roles Screen # -# $Id: lonroles.pm,v 1.87 2004/03/05 01:55:01 www Exp $ +# $Id: lonroles.pm,v 1.222 2009/05/17 23:38:12 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,182 +27,498 @@ # ### +=pod + +=head1 NAME + +Apache::lonroles - User Roles Screen + +=head1 SYNOPSIS + +Invoked by /etc/httpd/conf/srm.conf: + + + PerlAccessHandler Apache::lonacc + SetHandler perl-script + PerlHandler Apache::lonroles + ErrorDocument 403 /adm/login + ErrorDocument 500 /adm/errorhandler + + +=head1 OVERVIEW + +=head2 Choosing Roles + +C is a handler that allows a user to switch roles in +mid-session. LON-CAPA attempts to work with "No Role Specified", the +default role that a user has before selecting a role, as widely as +possible, but certain handlers for example need specification which +course they should act on, etc. Both in this scenario, and when the +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. + +=begin latex + +\begin{figure} +\begin{center} +\includegraphics[width=0.45\paperwidth,keepaspectratio]{Sample_Roles_Screen} + \caption{\label{Sample_Roles_Screen}Sample Roles Screen} +\end{center} +\end{figure} + +=end latex + +=head2 Role Initialization + +The privileges for a user are established at login time and stored in the session environment. As a consequence, a new role does not become active till the next login. Handlers are able to query for privileges using C's C<&allowed> function. When a user first logs in, their role is the "common" role, which means that they have the sum of all of their privileges. During a session it might become necessary to choose a particular role, which as a consequence also limits the user to only the privileges in that particular role. + +=head1 INTRODUCTION + +This module enables a user to select what role he wishes to +operate under (instructor, student, teaching assistant, course +coordinator, etc). These roles are pre-established by the actions +of upper-level users. + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + +=head1 HANDLER SUBROUTINE + +This routine is called by Apache and mod_perl. + +=over 4 + +=item * + +Roles Initialization (yes/no) + +=item * + +Get Error Message from Environment + +=item * + +Who is this? + +=item * + +Generate Page Output + +=item * + +Choice or no choice + +=item * + +Table + +=item * + +Privileges + +=back + +=cut + + package Apache::lonroles; use strict; -use Apache::lonnet(); +use Apache::lonnet; use Apache::lonuserstate(); use Apache::Constants qw(:common); use Apache::File(); use Apache::lonmenu; use Apache::loncommon; +use Apache::lonhtmlcommon; use Apache::lonannounce; use Apache::lonlocal; +use Apache::lonpageflip(); +use Apache::lonnavdisplay(); +use GDBM_File; +use LONCAPA qw(:DEFAULT :match); +use HTML::Entities; + sub redirect_user { - my ($r,$title,$url,$msg) = @_; + my ($r,$title,$url,$msg,$launch_nav) = @_; $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 $bodytag=&Apache::loncommon::bodytag('Switching Role'); - $r->print (<$title - - - -$bodytag - -

$msg

- - +$navwindow +

$msg

+$end_page ENDREDIR return; } +sub error_page { + my ($r,$error,$dest)=@_; + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + $r->send_http_header; + return OK if $r->header_only; + $r->print(&Apache::loncommon::start_page('Problems during Course Initialization'). + ''. + '

'.&mt('The following problems occurred:'). + $error. + '


'.&mt('Continue').''. + &Apache::loncommon::end_page()); +} + sub handler { my $r = shift; my $now=time; - my $then=$ENV{'user.login.time'}; + my $then=$env{'user.login.time'}; my $envkey; - + my %dcroles = (); + my $numdc = &check_fordc(\%dcroles,$then); + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); # ================================================================== Roles Init + if ($env{'form.selectrole'}) { + + my $locknum=&Apache::lonnet::get_locks(); + if ($locknum) { return 409; } - if ($ENV{'form.selectrole'}) { - if ($ENV{'request.course.id'}) { - my %temp=('logout_'.$ENV{'request.course.id'} => time); + if ($env{'form.newrole'}) { + $env{'form.'.$env{'form.newrole'}}=1; + } + 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($then); + } + } + 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'}}); +# 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)$-)) { + if ($dcroles{$domain}) { + &Apache::lonnet::check_adhoc_privs($domain,$coursenum, + $then,$now,'cc'); + } + last; + } +# Is this an ad-hoc CA-role? + if (my ($domain,$user) = + ($envkey =~ m-^form\.ca\./($match_domain)/($match_username)$-)) { + if (($domain eq $env{'user.domain'}) && ($user eq $env{'user.name'})) { + delete($env{$envkey}); + $env{'form.au./'.$domain.'/'} = 1; + 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; + $r->internal_redirect($switchserver); + } + last; + } + if (my ($castart,$caend) = ($env{'user.role.ca./'.$domain.'/'.$user} =~ /^(\d*)\.(\d*)$/)) { + if (((($castart) && ($castart < $now)) || !$castart) && + ((!$caend) || (($caend) && ($caend > $now)))) { + 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; + $r->internal_redirect($switchserver); + } + last; + } + } + # Check if author blocked ca-access + my %blocked=&Apache::lonnet::get('environment',['domcoord.author'],$domain,$user); + if ($blocked{'domcoord.author'} eq 'blocked') { + delete($env{$envkey}); + $env{'user.error.msg'}=':::1:User '.$user.' in domain '.$domain.' blocked domain coordinator access'; + last; + } + 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, + $now,'ca'); + if ($server_status eq 'switchserver') { + my $trolecode = 'ca./'.$domain.'/'.$user; + my $switchserver = '/adm/switchserver?' + .'otherserver='.$home.'&role='.$trolecode; + $r->internal_redirect($switchserver); + } + } else { + delete($env{$envkey}); + } + } else { + delete($env{$envkey}); + } + last; + } + } } - &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'}); - foreach $envkey (keys %ENV) { + + foreach $envkey (keys %env) { next if ($envkey!~/^user\.role\./); - my (undef,undef,$role,@pwhere)=split(/\./,$envkey); - my $where=join('.',@pwhere); - my $trolecode=$role.'.'.$where; - if ($ENV{'form.'.$trolecode}) { - my ($tstart,$tend)=split(/\./,$ENV{$envkey}); - my $tstatus='is'; - if ($tstart) { - if ($tstart>$then) { - $tstatus='future'; - } - } - if ($tend) { - if ($tend<$then) { $tstatus='expired'; } - if ($tend<$now) { $tstatus='will_not'; } - } + my ($where,$trolecode,$role,$tstatus,$tend,$tstart); + &Apache::lonnet::role_status($envkey,$then,$now,\$role,\$where, + \$trolecode,\$tstatus,\$tstart,\$tend); + if ($env{'form.'.$trolecode}) { if ($tstatus eq 'is') { $where=~s/^\///; my ($cdom,$cnum,$csec)=split(/\//,$where); +# check for course groups + my %coursegroups = &Apache::lonnet::get_active_groups( + $env{'user.domain'},$env{'user.name'},$cdom, $cnum); + my $cgrps = join(':',keys(%coursegroups)); + +# store role if recent_role list being kept + if ($env{'environment.recentroles'}) { + my %frozen_roles = + &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'}); + &Apache::lonhtmlcommon::store_recent('roles', + $trolecode,' ',$frozen_roles{$trolecode}); + } + + # check for keyed access if (($role eq 'st') && - ($ENV{'course.'.$cdom.'_'.$cnum.'.keyaccess'} eq 'yes')) { - unless (&Apache::lonnet::validate_access_key( - $ENV{'environment.key.'.$cdom.'_'.$cnum}, - $cdom,$cnum)) { + ($env{'course.'.$cdom.'_'.$cnum.'.keyaccess'} eq 'yes')) { +# who is key authority? + my $authdom=$cdom; + my $authnum=$cnum; + if ($env{'course.'.$cdom.'_'.$cnum.'.keyauth'}) { + ($authnum,$authdom)= + split(/:/,$env{'course.'.$cdom.'_'.$cnum.'.keyauth'}); + } +# check with key authority + unless (&Apache::lonnet::validate_access_key( + $env{'environment.key.'.$cdom.'_'.$cnum}, + $authdom,$authnum)) { # there is no valid key - if ($ENV{'form.newkey'}) { + if ($env{'form.newkey'}) { # student attempts to register a new key + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + $r->send_http_header; + my $swinfo=&Apache::lonmenu::rawconfig(); + my $start_page=&Apache::loncommon::start_page + ('Verifying Access Key to Unlock this Course'); + my $end_page=&Apache::loncommon::end_page(); + my $buttontext=&mt('Enter Course'); + my $message=&mt('Successfully registered key'); + my $assignresult= + &Apache::lonnet::assign_access_key( + $env{'form.newkey'}, + $authdom,$authnum, + $cdom,$cnum, + $env{'user.domain'}, + $env{'user.name'}, + &mt('Assigned from [_1] at [_2] for [_3]' + ,$ENV{'REMOTE_ADDR'} + ,&Apache::lonlocal::locallocaltime() + ,$trolecode) + ); + unless ($assignresult eq 'ok') { + $assignresult=~s/^error\:\s*//; + $message=&mt($assignresult). + '
'. + &mt('Logout').''; + $buttontext=&mt('Re-Enter Key'); + } + $r->print(< +$swinfo + +
+ + +$message
+ +
+$end_page +ENDENTEREDKEY + return OK; } else { # print form to enter a new key &Apache::loncommon::content_type($r,'text/html'); &Apache::loncommon::no_cache($r); $r->send_http_header; my $swinfo=&Apache::lonmenu::rawconfig(); - my $bodytag=&Apache::loncommon::bodytag + my $start_page=&Apache::loncommon::start_page ('Enter Access Key to Unlock this Course'); + my $end_page=&Apache::loncommon::end_page(); $r->print(<Entering Course Access Key - - -$bodytag -
- - + + +
- +$end_page ENDENTERKEY return OK; } } } - &Apache::lonnet::log($ENV{'user.domain'}, - $ENV{'user.name'}, - $ENV{'user.home'}, + &Apache::lonnet::log($env{'user.domain'}, + $env{'user.name'}, + $env{'user.home'}, "Role ".$trolecode); - my $tadv=0; - if (($trolecode!~/^st/) && - ($trolecode!~/^ta/) && - ($trolecode!~/^cm/)) { $tadv=1; } + &Apache::lonnet::appenv( - 'request.role' => $trolecode, - 'request.role.adv' => $tadv, - 'request.role.domain' => $cdom, - 'request.course.sec' => $csec); - my $msg=&mt('Entering course ...'); + {'request.role' => $trolecode, + 'request.role.domain' => $cdom, + 'request.course.sec' => $csec, + 'request.course.groups' => $cgrps}); + my $tadv=0; - if (($cnum) && ($role ne 'ca')) { + if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) { + my $msg; my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum); - if (($ENV{'form.orgurl'}) && - ($ENV{'form.orgurl'}!~/^\/adm\/flip/)) { - my $dest=$ENV{'form.orgurl'}; - if ( &Apache::lonnet::mod_perl_version() == 2 ) { - &Apache::lonnet::cleanenv(); + if (($env{'form.orgurl'}) && + ($env{'form.orgurl'}!~/^\/adm\/flip/)) { + my $dest=$env{'form.orgurl'}; + if ($env{'form.symb'}) { + if ($dest =~ /\?/) { + $dest .= '&'; + } else { + $dest .= '?' + } + $dest .= 'symb='.$env{'form.symb'}; + } + if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } + &Apache::lonnet::appenv({'request.role.adv'=>$tadv}); + if (($ferr) && ($tadv)) { + &error_page($r,$ferr,$dest); + } else { + $r->internal_redirect($dest); } - $r->internal_redirect($dest); return OK; } else { - unless ($ENV{'request.course.id'}) { + if (!$env{'request.course.id'}) { &Apache::lonnet::appenv( - "request.course.id" => $cdom.'_'.$cnum); + {"request.course.id" => $cdom.'_'.$cnum}); $furl='/adm/roles?tryagain=1'; - $msg= - '

'. - &mt('Could not initialize course at this time.'). - '

'.&mt('Please try again.').'

'.$ferr; + $msg='

' + .&mt('Could not initialize [_1] at this time.', + $env{'course.'.$cdom.'_'.$cnum.'.description'}) + .'

' + .'

'.&mt('Please try again.').'

' + .'

'.$ferr.'

'; } + if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } + &Apache::lonnet::appenv({'request.role.adv'=>$tadv}); - # Check to see if the user is a CC entering a course - # for the first time - my (undef, undef, $role, $courseid) = split(/\./, $envkey); - if (substr($courseid, 0, 1) eq '/') { - $courseid = substr($courseid, 1); + if (($ferr) && ($tadv)) { + &error_page($r,$ferr,$furl); + } else { + # Check to see if the user is a CC entering a course + # 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' && $env{'course.' . $courseid . + '.course.helper.not.run'}) { + $furl = "/adm/helper/course.initialization.helper"; + # Send the user to the course they selected + } elsif ($env{'request.course.id'}) { + if ($env{'form.destinationurl'}) { + my $dest = $env{'form.destinationurl'}; + if ($env{'form.destsymb'} ne '') { + my $esc_symb = &HTML::Entities::encode($env{'form.destsymb'},'"<>&'); + $dest .= '?symb='.$esc_symb; + } + &redirect_user($r,&mt('Entering [_1]', + $env{'course.'.$courseid.'.description'}), + $dest,$msg, + $env{'environment.remotenavmap'}); + return OK; + } + if (&Apache::lonnet::allowed('whn', + $env{'request.course.id'}) + || &Apache::lonnet::allowed('whn', + $env{'request.course.id'}.'/' + .$env{'request.course.sec'}) + ) { + my $startpage = &courseloadpage($courseid); + unless ($startpage eq 'firstres') { + $msg = &mt('Entering [_1] ...', + $env{'course.'.$courseid.'.description'}); + &redirect_user($r,&mt('New in course'), + '/adm/whatsnew?refpage=start',$msg, + $env{'environment.remotenavmap'}); + return OK; + } + } + } +# Are we allowed to look at the first resource? + if ($furl !~ m|^/adm/|) { +# Guess not ... + $furl=&Apache::lonpageflip::first_accessible_resource(); + } + $msg = &mt('Entering [_1] ...', + $env{'course.'.$courseid.'.description'}); + &redirect_user($r,&mt('Entering [_1]', + $env{'course.'.$courseid.'.description'}), + $furl,$msg, + $env{'environment.remotenavmap'}); } - $courseid =~ s/\//_/; - if ($role eq 'cc' && $ENV{'course.' . $courseid . - '.course.helper.not.run'}) { - $furl = "/adm/helper/course.initialization.helper"; - } - # - # Send the user to the course they selected - &redirect_user($r,&mt('Entering Course'), - $furl,$msg); - return OK; + return OK; } } # # Send the user to the construction space they selected - if ($role =~ /^(au|ca)$/) { + if ($role =~ /^(au|ca|aa)$/) { my $redirect_url = '/priv/'; if ($role eq 'au') { - $redirect_url.=$ENV{'user.name'}; + $redirect_url.=$env{'user.name'}; } else { $where =~ /\/(.*)$/; $redirect_url .= $1; @@ -212,6 +528,18 @@ ENDENTERKEY $redirect_url); return OK; } + if ($role eq 'dc') { + my $redirect_url = '/adm/menu/'; + &redirect_user($r,&mt('Loading Domain Coordinator Menu'), + $redirect_url); + return OK; + } + if ($role eq 'sc') { + my $redirect_url = '/adm/grades?command=scantronupload'; + &redirect_user($r,&mt('Loading Data Upload Page'), + $redirect_url); + return OK; + } } } } @@ -225,247 +553,255 @@ ENDENTERKEY $r->send_http_header; return OK if $r->header_only; + my $brcrum =[{href=>"/admm/roles",text=>"User Roles"}]; my $swinfo=&Apache::lonmenu::rawconfig(); - my $bodytag=&Apache::loncommon::bodytag('User Roles'); - my $helptag='
'.&Apache::loncommon::help_open_topic - ("General_Intro",&mt("Click here for help")).''. - &Apache::loncommon::help_open_faq(1,&mt('Click here for FAQ')).''. - &Apache::loncommon::help_open_bug('',&mt('Click here to report bugs')).'
'; + my $start_page=&Apache::loncommon::start_page('My Roles',undef,{bread_crumbs=>$brcrum}); + my $standby=&mt('Role selected. Please stand by.'); + $standby=~s/\n/\\n/g; + my $noscript=''.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'
'.&mt('As this is not the case, most functionality in the system will be unavailable.').'

'; + $r->print(< - -LON-CAPA User Roles - -$bodytag -$helptag
- ENDHEADER # ------------------------------------------ Get Error Message from Environment - my ($fn,$priv,$nochoose,$error,$msg)=split(/:/,$ENV{'user.error.msg'}); - if ($ENV{'user.error.msg'}) { + my ($fn,$priv,$nochoose,$error,$msg)=split(/:/,$env{'user.error.msg'}); + if ($env{'user.error.msg'}) { $r->log_reason( - "$msg for $ENV{'user.name'} domain $ENV{'user.domain'} access $priv",$fn); + "$msg for $env{'user.name'} domain $env{'user.domain'} access $priv",$fn); } # ------------------------------------------------- Can this user re-init, etc? - my $advanced=$ENV{'user.adv'}; + my $advanced=$env{'user.adv'}; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['tryagain']); - my $tryagain=$ENV{'form.tryagain'}; + my $tryagain=$env{'form.tryagain'}; + my $reinit=$env{'user.reinit'}; + delete $env{'user.reinit'}; # -------------------------------------------------------- Generate Page Output # --------------------------------------------------------------- Error Header? if ($error) { - $r->print("

LON-CAPA Access Control

"); - $r->print("
Access  : ".
-                  Apache::lonnet::plaintext($priv)."\n");
-        $r->print("Resource: $fn\n");
-        $r->print("Action  : $msg\n

"); - } else { - if ($ENV{'user.error.msg'}) { - $r->print( - '

'. - &mt('You need to choose another user role or enter a specific course for this function').'

'); + $r->print("

".&mt('LON-CAPA Access Control')."

"); + $r->print("
");
+	if ($priv ne '') {
+            $r->print(&mt('Access  : ').&Apache::lonnet::plaintext($priv)."\n");
+	}
+	if ($fn ne '') {
+            $r->print(&mt('Resource: ').&Apache::lonenc::check_encrypt($fn)."\n");
+	}
+	if ($msg ne '') {
+            $r->print(&mt('Action  : ').$msg."\n");
 	}
+	$r->print("

"); + my $url=$fn; + my $last; + if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', + &GDBM_READER(),0640)) { + $last=$hash{'last_known'}; + untie(%hash); + } + if ($last) { $fn.='?symb='.&escape($last); } + + &Apache::londocs::changewarning($r,undef,'You have modified your course recently, [_1] may fix this access problem.', + &Apache::lonenc::check_encrypt($fn)); + } else { + if ($env{'user.error.msg'}) { + if ($reinit) { + $r->print( + '

'. + &mt('As your session file for the course has expired, you will need to re-select the course.').'

'); + } else { + $r->print( + '

'. + &mt('You need to choose another user role or enter a specific course for this function').'

'); + } + } } # -------------------------------------------------------- Choice or no choice? if ($nochoose) { - if ($advanced) { - $r->print("

".&mt('Assigned User Roles')."

\n"); - } else { - $r->print("

".&mt('Sorry ...')."

\n". - &mt('This resource might be part of')); - if ($ENV{'request.course.id'}) { - $r->print(&mt(' another')); - } else { - $r->print(&mt(' a certain')); - } - $r->print(&mt(' course.').''); - return OK; - } + $r->print("

".&mt('Sorry ...')."

\n". + &mt('This action is currently not authorized.').''. + &Apache::loncommon::end_page()); + return OK; } else { - if ($advanced) { - $r->print(&mt("Your home server is "). - $Apache::lonnet::hostname{&Apache::lonnet::homeserver - ($ENV{'user.name'},$ENV{'user.domain'})}. - "
\n"); - $r->print(&mt( - "Author and Co-Author roles may not be available on servers other than your home server.")); - } if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) { $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'}; } $r->print('
'); - $r->print(''); - $r->print(''); + $r->print(''); + $r->print(''); + $r->print(''); } - if ($ENV{'user.adv'}) { - $r->print( - '
'.&mt('Show all roles').': print(' checked'); } - $r->print('>'); - } - my (%roletext,%sortrole,%roleclass); my $countactive=0; + my $countfuture=0; + my $countwill=0; my $inrole=0; my $possiblerole=''; - foreach $envkey (sort keys %ENV) { + my %futureroles; + my %roles_nextlogin; + my %timezones; + foreach $envkey (sort keys %env) { my $button = 1; my $switchserver=''; my $roletext; my $sortkey; if ($envkey=~/^user\.role\./) { - my (undef,undef,$role,@pwhere)=split(/\./,$envkey); - next if (!defined($role) || $role eq ''); - my $where=join('.',@pwhere); - my $trolecode=$role.'.'.$where; - my ($tstart,$tend)=split(/\./,$ENV{$envkey}); - my $tremark=''; - my $tstatus='is'; - my $tpstart=' '; - my $tpend=' '; - my $tfont='#000000'; + my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend); + &Apache::lonnet::role_status($envkey,$then,$now,\$role,\$where, + \$trolecode,\$tstatus,\$tstart,\$tend); + next if (!defined($role) || $role eq '' || $role =~ /^gr/); + my $timezone = &role_timezone($where,\%timezones); + $tremark=''; + $tpstart=' '; + $tpend=' '; if ($tstart) { - if ($tstart>$then) { - $tstatus='future'; - if ($tstart<$now) { $tstatus='will'; } - } - $tpstart=&Apache::lonlocal::locallocaltime($tstart); + $tpstart=&Apache::lonlocal::locallocaltime($tstart,$timezone); } if ($tend) { - if ($tend<$then) { - $tstatus='expired'; - } elsif ($tend<$now) { - $tstatus='will_not'; - } - $tpend=&Apache::lonlocal::locallocaltime($tend); + $tpend=&Apache::lonlocal::locallocaltime($tend,$timezone); } - if ($ENV{'request.role'} eq $trolecode) { + if ($env{'request.role'} eq $trolecode) { $tstatus='selected'; } my $tbg; - if (($tstatus eq 'is') || ($tstatus eq 'selected') || - ($ENV{'form.showall'})) { + if (($tstatus eq 'is') + || ($tstatus eq 'selected') + || ($tstatus eq 'will') + || ($tstatus eq 'future') + || ($env{'form.showall'})) { if ($tstatus eq 'is') { - $tbg='#77FF77'; - $tfont='#003300'; + $tbg='LC_roles_is'; $possiblerole=$trolecode; $countactive++; } elsif ($tstatus eq 'future') { - $tbg='#FFFF77'; + $tbg='LC_roles_future'; $button=0; + $futureroles{$trolecode} = $tstart.':'.$tend; + $countfuture ++; } elsif ($tstatus eq 'will') { - $tbg='#FFAA77'; - $tremark.=&mt('Active at next login. '); + $tbg='LC_roles_will'; + $tremark.=&mt('Active at next login.').' '; + $roles_nextlogin{$trolecode} = $tstart.':'.$tend; + $countwill ++; } elsif ($tstatus eq 'expired') { - $tbg='#FF7777'; - $tfont='#330000'; + $tbg='LC_roles_expired'; $button=0; } elsif ($tstatus eq 'will_not') { - $tbg='#AAFF77'; - $tremark.=&mt('Expired after logout. '); + $tbg='LC_roles_will_not'; + $tremark.=&mt('Expired after logout.').' '; } elsif ($tstatus eq 'selected') { - $tbg='#11CC55'; - $tfont='#002200'; + $tbg='LC_roles_selected'; $inrole=1; $countactive++; - $tremark.=&mt('Currently selected. '); + $tremark.=&mt('Currently selected.').' '; } my $trole; if ($role =~ /^cr\//) { my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role); - $tremark.='
'.&mt('Defined by ').$rauthor. - &mt(' at ').$rdomain.'.'; - $trole=$rrole; - } else { - $trole=Apache::lonnet::plaintext($role); - } + if ($tremark) { $tremark.='
'; } + $tremark.=&mt('Defined by [_1] at [_2].',$rauthor,$rdomain); + } + $trole=Apache::lonnet::plaintext($role); my $ttype; my $twhere; my ($tdom,$trest,$tsection)= split(/\//,Apache::lonnet::declutter($where)); # First, Co-Authorship roles - if ($role eq 'ca') { + if (($role eq 'ca') || ($role eq 'aa')) { my $home = &Apache::lonnet::homeserver($trest,$tdom); my $allowed=0; my @ids=&Apache::lonnet::current_machine_ids(); foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } if (!$allowed) { $button=0; - $switchserver=&Apache::lonnet::escape('http://'. - $Apache::lonnet::hostname{$home}. - '/adm/login?domain='.$ENV{'user.domain'}. - '&username='.$ENV{'user.name'}. - '&firsturl=/priv/'.$trest); + $switchserver='otherserver='.$home.'&role='.$trolecode; } #next if ($home eq 'no_host'); - $home = $Apache::lonnet::hostname{$home}; + $home = &Apache::lonnet::hostname($home); $ttype='Construction Space'; $twhere=&mt('User').': '.$trest.'
'.&mt('Domain'). ': '.$tdom.'
'. ' '.&mt('Server').': '.$home; - $ENV{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $env{'course.'.$tdom.'_'.$trest.'.description'}='ca'; $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$trest.'/'); $sortkey=$role."$trest:$tdom"; } elsif ($role eq 'au') { # Authors my $home = &Apache::lonnet::homeserver - ($ENV{'user.name'},$ENV{'user.domain'}); + ($env{'user.name'},$env{'user.domain'}); my $allowed=0; my @ids=&Apache::lonnet::current_machine_ids(); foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } if (!$allowed) { $button=0; - $switchserver=&Apache::lonnet::escape('http://'. - $Apache::lonnet::hostname{$home}. - '/adm/login?domain='.$ENV{'user.domain'}. - '&username='.$ENV{'user.name'}. - '&firsturl=/priv/'.$ENV{'user.name'}); + $switchserver='otherserver='.$home.'&role='.$trolecode; } #next if ($home eq 'no_host'); - $home = $Apache::lonnet::hostname{$home}; + $home = &Apache::lonnet::hostname($home); $ttype='Construction Space'; $twhere=&mt('Domain').': '.$tdom.'
'.&mt('Server'). ': '.$home; - $ENV{'course.'.$tdom.'_'.$trest.'.description'}='ca'; - $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$ENV{'user.name'}.'/'); + $env{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$env{'user.name'}.'/'); $sortkey=$role; } elsif ($trest) { - $ttype='Course'; - if ($tsection) { - $ttype.='
'.&mt('Section/Group').': '.$tsection; - } my $tcourseid=$tdom.'_'.$trest; - if ($ENV{'course.'.$tcourseid.'.description'}) { - $twhere=$ENV{'course.'.$tcourseid.'.description'}; + $ttype = &Apache::loncommon::course_type($tcourseid); + $trole = &Apache::lonnet::plaintext($role,$ttype); + if ($env{'course.'.$tcourseid.'.description'}) { + $twhere=$env{'course.'.$tcourseid.'.description'}; $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey; unless ($twhere eq &mt('Currently not available')) { - $twhere.=' '. - &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom,$tfont). - ''; + $twhere.=' '. + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom). + ''; } } else { - my %newhash=Apache::lonnet::coursedescription - ($tcourseid); + my %newhash=&Apache::lonnet::coursedescription($tcourseid); if (%newhash) { $sortkey=$role."\0".$tdom."\0".$newhash{'description'}. "\0".$envkey; $twhere=$newhash{'description'}. - ' '. - &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom,$tfont). - ''; + ' '. + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom). + ''; + $ttype = $newhash{'type'}; + $trole = &Apache::lonnet::plaintext($role,$ttype); } else { $twhere=&mt('Currently not available'); - $ENV{'course.'.$tcourseid.'.description'}=$twhere; + $env{'course.'.$tcourseid.'.description'}=$twhere; $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey; + $ttype = 'Unavailable'; } } + if ($tsection) { + $twhere.='
'.&mt('Section').': '.$tsection; + } if ($role ne 'st') { $twhere.="
".&mt('Domain').":".$tdom; } } elsif ($tdom) { $ttype='Domain'; @@ -476,42 +812,7 @@ ENDHEADER $twhere=&mt('system wide'); $sortkey=$role.$twhere; } - - $roletext.=''; - unless ($nochoose) { - if (!$button) { - if ($switchserver) { - $roletext.=''.&mt('Switch Server').''; - } else { - $roletext.=(' '); - } - } elsif ($tstatus eq 'is') { - $roletext.=(''); - } elsif ($tryagain) { - $roletext.= - ''; - } elsif ($advanced) { - $roletext.= - ''; - } else { - $roletext.=' '; - } - } - $tremark.=&Apache::lonannounce::showday(time,1, - &Apache::lonannounce::readcalendar($tdom.'_'.$trest)); - - $roletext.=''.$trole. - ''.$ttype. - ''.$twhere. - ''.$tpstart. - ''.$tpend. - ''.$tremark. - ' '."\n"; + $roletext.=&build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit); $roletext{$envkey}=$roletext; if (!$sortkey) {$sortkey=$twhere."\0".$envkey;} $sortrole{$sortkey}=$envkey; @@ -519,6 +820,20 @@ ENDHEADER } } } + if ($env{'user.adv'}) { + $r->print( + '

'); + } else { + if ($countactive > 0) { + &queued_selfenrollment($r); + my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description'); + my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); + $r->print('

'.&mt('[_1]Visit the [_2]Course Catalog[_3] to view all [_4] LON-CAPA courses.','','','',$domdesc).'
'.&mt('If a course is [_1]not[_2] in your list of current courses below, you may be able to enroll if self-enrollment is permitted.','','').'

'); + } + } + # No active roles if ($countactive==0) { if ($inrole) { @@ -526,141 +841,696 @@ ENDHEADER } else { $r->print('

'.&mt('Currently no active roles or courses').'

'); } - $r->print('
'); - return OK; -# Is there only one choice? - } elsif ($countactive==1) { - $r->print('

'.&mt('Please stand by.').'

'. - ''); - $r->print("\n"); - $r->rflush(); - $r->print(''); - $r->print(''); + &findcourse_advice($r); + $r->print(''); + if ($countfuture) { + $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture)); + my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole, + $nochoose); + &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles, + \%roletext); + my $tremark=''; + my $tbg; + if ($env{'request.role'} eq 'cm') { + $tbg="LC_roles_selected"; + $tremark=&mt('Currently selected.').' '; + } else { + $tbg="LC_roles_is"; + } + $r->print(&Apache::loncommon::start_data_table_row() + .' ' + .'' + .&mt('No role specified') + .'' + .''.$tremark.' ' + .&Apache::loncommon::end_data_table_row() + ); + + $r->print(&Apache::loncommon::end_data_table()); + } + $r->print(&Apache::loncommon::end_page()); return OK; } -# More than one possible role # ----------------------------------------------------------------------- Table - unless (($advanced) || ($nochoose)) { + unless ((!&Apache::lonmenu::show_course()) || ($nochoose) || ($countactive==1)) { $r->print("

".&mt('Select a Course to Enter')."

\n"); } - $r->print('
'); - unless ($nochoose) { $r->print(''); } - $r->print(''."\n"); - my $doheaders=-1; - foreach my $type ('Construction Space','Course','Domain','System') { - my $haverole=0; - foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { - if ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/) { - $haverole=1; - } - } - if ($haverole) { $doheaders++; } - } - foreach my $type ('Construction Space','Course','Domain','System') { - my $output; - foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { - if ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/) { - $output.=&mt($roletext{$sortrole{$which}}); - } + my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose); + if ($env{'environment.recentroles'}) { + my %recent_roles = + &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'}); + my $output=''; + foreach (sort(keys(%recent_roles))) { + if (defined($roletext{'user.role.'.$_})) { + $output.=$roletext{'user.role.'.$_}; + if ($_ =~ m-dc\./($match_domain)/- + && $dcroles{$1}) { + $output .= &adhoc_roles_row($1,'recent'); + } + } elsif ($numdc > 0) { + unless ($_ =~/^error\:/) { + $output.=&display_cc_role('user.role.'.$_); + } + } } if ($output) { - if ($doheaders > 0) { - $r->print("". - ""); - } - $r->print($output); - } - } - my $tremark=''; - my $tfont='#003300'; - if ($ENV{'request.role'} eq 'cm') { - $r->print(''); - $tremark=&mt('Currently selected. '); - $tfont='#002200'; - } else { - $r->print(''); - } - unless ($nochoose) { - if ($ENV{'request.role'} ne 'cm') { - $r->print(''); - } else { - $r->print(''); + $r->print(&Apache::loncommon::start_data_table_empty_row() + .'' + .&Apache::loncommon::end_data_table_empty_row() + ); + $r->print($output); + $doheaders ++; } } - $r->print(''."\n"); - $r->print('
 '.&mt('User Role').''.&mt('Extent'). - ''.&mt('Start').''.&mt('End').''. - &mt('Remark').'
".&mt($type)."
 ' + .&mt('Recent Roles') + .''.&mt('No role specified'). - ''.$tremark. - ' 
'); + if ($numdc > 0) { + $r->print(&coursepick_jscript()); + $r->print(&Apache::loncommon::coursebrowser_javascript(). + &Apache::loncommon::authorbrowser_javascript()); + } + &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext); + if ($countactive > 1) { + my $tremark=''; + my $tbg; + if ($env{'request.role'} eq 'cm') { + $tbg="LC_roles_selected"; + $tremark=&mt('Currently selected.').' '; + } else { + $tbg="LC_roles_is"; + } + $r->print(&Apache::loncommon::start_data_table_row()); + unless ($nochoose) { + if ($env{'request.role'} ne 'cm') { + $r->print(''); + } else { + $r->print(' '); + } + } + $r->print('' + .&mt('No role specified') + .'' + .''.$tremark.' ' + .&Apache::loncommon::end_data_table_row() + ); + } + $r->print(&Apache::loncommon::end_data_table()); unless ($nochoose) { $r->print("\n"); } # ------------------------------------------------------------ Privileges Info - if (($advanced) && (($ENV{'user.error.msg'}) || ($error))) { - $r->print('

Current Privileges

'); + if (($advanced) && (($env{'user.error.msg'}) || ($error))) { + $r->print('

'.&mt('Current Privileges').'

'); + $r->print(&privileges_info()); + } + $r->print(&Apache::lonnet::getannounce()); + if ($advanced) { + my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); + $r->print('

' + .&mt('This is LON-CAPA [_1]',$r->dir_config('lonVersion')) + .'
' + .''.&mt('Logout').'  ' + .'' + .&mt('Course Catalog') + .'

'); + } + $r->print(&Apache::loncommon::end_page()); + return OK; +} - foreach $envkey (sort keys %ENV) { - if ($envkey=~/^user\.priv\.$ENV{'request.role'}\./) { - my $where=$envkey; - $where=~s/^user\.priv\.$ENV{'request.role'}\.//; - my $ttype; - my $twhere; - my ($tdom,$trest,$tsec)= - split(/\//,Apache::lonnet::declutter($where)); - if ($trest) { - if ($ENV{'course.'.$tdom.'_'.$trest.'.description'} eq 'ca') { - $ttype='Construction Space'; - $twhere='User: '.$trest.', Domain: '.$tdom; - } else { - $ttype='Course'; - $twhere=$ENV{'course.'.$tdom.'_'.$trest.'.description'}; - if ($tsec) { - $twhere.=' (Section/Group: '.$tsec.')'; - } - } - } elsif ($tdom) { - $ttype='Domain'; - $twhere=$tdom; - } else { - $ttype='System'; - $twhere='/'; - } - $r->print("\n

".$ttype.': '.$twhere.'

'); } + } elsif ($tdom) { + $ttype='Domain'; + $twhere=$tdom; + } else { + $ttype='System'; + $twhere='/'; + } + $output .= "\n

".&mt($ttype).': '.$twhere.'

'."\n
    "; + foreach my $priv (sort(split(/:/,$env{$envkey}))) { + next if (!$priv); + + my ($prv,$restr)=split(/\&/,$priv); + my $trestr=''; + if ($restr ne 'F') { + $trestr.=' ('. + join(', ', + map { &Apache::lonnet::plaintext($_) } + (split('',$restr))).') '; + } + $output .= "\n\t". + '
  • '.&Apache::lonnet::plaintext($prv).$trestr.'
  • '; } + $output .= "\n".'
'; } - $r->print(&Apache::lonnet::getannounce()); - if ($advanced) { - $r->print('

This is LON-CAPA '. - $r->dir_config('lonVersion').'
'. - ''.&mt('Logout').'

'); + return $output; +} + +sub build_roletext { + my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit) = @_; + my $roletext=&Apache::loncommon::start_data_table_row(); + my $is_dc=($trolecode =~ m/^dc\./); + my $rowspan=($is_dc) ? '' + : ' rowspan="2" '; + + unless ($nochoose) { + my $buttonname=$trolecode; + $buttonname=~s/\W//g; + if (!$button) { + if ($switchserver) { + $roletext.='' + .'' + .&mt('Switch Server') + .''; + } else { + $roletext.=(' '); + } + } elsif ($tstatus eq 'is') { + $roletext.=''. + ''; + } elsif ($tryagain) { + $roletext.= + ''. + ''; + } elsif ($advanced) { + $roletext.= + ''. + ''; + } elsif ($reinit) { + $roletext.= + ''. + ''; + } else { + $roletext.= + ''. + ''; + } } - $r->print("\n"); - return OK; -} + if ($trolecode !~ m/^(dc|ca|au|aa)\./) { + $tremark.=&Apache::lonannounce::showday(time,1, + &Apache::lonannounce::readcalendar($tdom.'_'.$trest)); + } + $roletext.=''.$trole.'' + .''.$twhere.'' + .''.$tpstart.'' + .''.$tpend.'' + .&Apache::loncommon::end_data_table_row(); + if (!$is_dc) { + $roletext.=&Apache::loncommon::continue_data_table_row() + .'' + .$tremark.' ' + .'' + .&Apache::loncommon::end_data_table_row(); + } + return $roletext; +} + +sub check_needs_switchserver { + my ($possiblerole) = @_; + my $needs_switchserver; + my ($role,$where) = split(/\./,$possiblerole,2); + my (undef,$tdom,$twho) = split(/\//,$where); + my ($server_status,$home); + if (($role eq 'ca') || ($role eq 'aa')) { + ($server_status,$home) = &check_author_homeserver($twho,$tdom); + } else { + ($server_status,$home) = &check_author_homeserver($env{'user.name'}, + $env{'user.domain'}); + } + if ($server_status eq 'switchserver') { + $needs_switchserver = 1; + } + return $needs_switchserver; +} + +sub check_author_homeserver { + my ($uname,$udom)=@_; + if (($uname eq '') || ($udom eq '')) { + return ('fail',''); + } + my $home = &Apache::lonnet::homeserver($uname,$udom); + if (&Apache::lonnet::host_domain($home) ne $udom) { + return ('fail',$home); + } + my @ids=&Apache::lonnet::current_machine_ids(); + if (grep(/^\Q$home\E$/,@ids)) { + return ('ok',$home); + } else { + return ('switchserver',$home); + } +} + +sub check_fordc { + my ($dcroles,$then) = @_; + my $numdc = 0; + if ($env{'user.adv'}) { + foreach my $envkey (sort keys %env) { + if ($envkey=~/^user\.role\.dc\.\/($match_domain)\/$/) { + my $dcdom = $1; + my $livedc = 1; + my ($tstart,$tend)=split(/\./,$env{$envkey}); + if ($tstart && $tstart>$then) { $livedc = 0; } + if ($tend && $tend <$then) { $livedc = 0; } + if ($livedc) { + $$dcroles{$dcdom} = $envkey; + $numdc++; + } + } + } + } + return $numdc; +} + +sub adhoc_course_role { + my ($then) = @_; + my ($cdom,$cnum); + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + if (&check_forcc($cdom,$cnum,$then)) { + my $setprivs; + if (!defined($env{'user.role.'.$env{'form.switchrole'}})) { + $setprivs = 1; + } else { + my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}}); + if (($start && ($start>$then || $start == -1)) || + ($end && $end<$then)) { + $setprivs = 1; + } + } + if ($setprivs) { + if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)([\w/]*)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) { + my $role = $1; + my $custom_role = $2; + my $usec = $3; + if ($role eq 'cr') { + if ($custom_role =~ m-^/$match_domain/$match_username/\w+$-) { + $role .= $custom_role; + } else { + return; + } + } + my (%userroles,%newrole,%newgroups,%group_privs); + my %cgroups = + &Apache::lonnet::get_active_groups($env{'user.domain'}, + $env{'user.name'},$cdom,$cnum); + foreach my $group (keys(%cgroups)) { + $group_privs{$group} = + $env{'user.priv.cc./'.$cdom.'/'.$cnum.'./'.$cdom.'/'.$cnum.'/'.$group}; + } + $newgroups{'/'.$cdom.'/'.$cnum} = \%group_privs; + my $area = '/'.$cdom.'/'.$cnum; + my $spec = $role.'.'.$area; + if ($usec ne '') { + $spec .= '/'.$usec; + $area .= '/'.$usec; + } + &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area); + &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups); + my $adhocstart = $then-1; + $userroles{'user.role.'.$spec} = $adhocstart.'.'; + &Apache::lonnet::appenv(\%userroles,[$role,'cm']); + } + } + } + return; +} + +sub check_forcc { + my ($cdom,$cnum,$then) = @_; + my $is_cc; + if ($cdom ne '' && $cnum ne '') { + if (&Apache::lonnet::is_course($cdom,$cnum)) { + my $envkey = 'user.role.cc./'.$cdom.'/'.$cnum; + if (defined($env{$envkey})) { + $is_cc = 1; + my ($tstart,$tend)=split(/\./,$env{$envkey}); + if ($tstart && $tstart>$then) { $is_cc = 0; } + if ($tend && $tend <$then) { $is_cc = 0; } + } + } + } + return $is_cc; +} + +sub courselink { + my ($dcdom,$rowtype) = @_; + my $courseform=&Apache::loncommon::selectcourse_link + ('rolechoice','dccourse'.$rowtype.'_'.$dcdom, + 'dcdomain'.$rowtype.'_'.$dcdom,'coursedesc'.$rowtype.'_'. + $dcdom,$dcdom,undef); + my $hiddenitems = ''. + ''. + ''. + ''; + return $courseform.$hiddenitems; +} + +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 you wish to enter.", + youc => 'You can only use this screen to select courses in the current domain.', + ); + my $verify_script = <<"END"; + +END + return $verify_script; +} + +sub coauthorlink { + my ($dcdom,$rowtype) = @_; + my $coauthorform=&Apache::loncommon::selectauthor_link('rolechoice',$dcdom); + my $hiddenitems = ''; + return $coauthorform.$hiddenitems; +} + +sub display_cc_role { + my $rolekey = shift; + my $roletext; + 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; + 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). + ''; + $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 = &build_roletext($trolecode,$1,$2,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,''); + } + } + return ($roletext); +} + +sub adhoc_roles_row { + my ($dcdom,$rowtype) = @_; + my $output = &Apache::loncommon::continue_data_table_row() + .' ' + .'' + .'' + .'' + .'' + .'
' + .&mt('[_1]Ad hoc[_2] roles in domain [_3] --' + ,'','',$dcdom) + .''; + my $selectcclink = &courselink($dcdom,$rowtype); + my $ccrole = &Apache::lonnet::plaintext('cc'); + my $carole = &Apache::lonnet::plaintext('ca'); + my $selectcalink = &coauthorlink($dcdom,$rowtype); + $output.=&mt('[_1]: [_2]',$ccrole,$selectcclink) + .'
  '.&mt('[_1]: [_2]',$carole,$selectcalink).'
' + .'' + .&Apache::loncommon::end_data_table_row(); + return $output; +} + +sub recent_filename { + my $area=shift; + return 'nohist_recent_'.&escape($area); +} + +sub courseloadpage { + my ($courseid) = @_; + my $startpage; + my %entry_settings = &Apache::lonnet::get('nohist_whatsnew', + [$courseid.':courseinit']); + my ($tmp) = %entry_settings; + unless ($tmp =~ /^error: 2 /) { + $startpage = $entry_settings{$courseid.':courseinit'}; + } + if ($startpage eq '') { + if (exists($env{'environment.course_init_display'})) { + $startpage = $env{'environment.course_init_display'}; + } + } + return $startpage; +} 1; __END__