# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
# $Id: lonuserutils.pm,v 1.50 2008/01/20 22:25:05 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
#
###############################################################
###############################################################
package Apache::lonuserutils;
use strict;
use Apache::lonnet;
use Apache::loncommon();
use Apache::lonhtmlcommon;
use Apache::lonlocal;
use Apache::longroup;
use LONCAPA qw(:DEFAULT :match);
###############################################################
###############################################################
# Drop student from all sections of a course, except optional $csec
sub modifystudent {
my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
# if $csec is undefined, drop the student from all the courses matching
# this one. If $csec is defined, drop them from all other sections of
# this course and add them to section $csec
my ($cnum,$cdom) = &get_course_identity($courseid);
my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
my ($tmp) = keys(%roles);
# Bail out if we were unable to get the students roles
return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
# Go through the roles looking for enrollment in this course
my $result = '';
foreach my $course (keys(%roles)) {
if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) {
# We are in this course
my $section=$1;
$section='' if ($course eq "/$cdom/$cnum".'_st');
if (defined($csec) && $section eq $csec) {
$result .= 'ok:';
} elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
my (undef,$end,$start)=split(/\_/,$roles{$course});
my $now=time;
# if this is an active role
if (!($start && ($now<$start)) || !($end && ($now>$end))) {
my $reply=&Apache::lonnet::modifystudent
# dom name id mode pass f m l g
($udom,$unam,'', '', '',undef,undef,undef,undef,
$section,time,undef,undef,$desiredhost,'','manual',
'',$courseid);
$result .= $reply.':';
}
}
}
}
if ($result eq '') {
$result = &mt('Unable to find section for this student');
} else {
$result =~ s/(ok:)+/ok/g;
}
return $result;
}
sub modifyuserrole {
my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass,
$first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role,
$end,$start,$checkid) = @_;
my ($scope,$userresult,$authresult,$roleresult,$idresult);
if ($setting eq 'course' || $context eq 'course') {
$scope = '/'.$cid;
$scope =~ s/\_/\//g;
if ($role ne 'cc' && $sec ne '') {
$scope .='/'.$sec;
}
} elsif ($context eq 'domain') {
$scope = '/'.$env{'request.role.domain'}.'/';
} elsif ($context eq 'author') {
$scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
}
if ($context eq 'domain') {
my $uhome = &Apache::lonnet::homeserver($uname,$udom);
if ($uhome ne 'no_host') {
if (($changeauth eq 'Yes') && (&Apache::lonnet::allowed('mau',$udom))) {
if ((($umode =~ /^krb4|krb5|internal$/) && $upass ne '') ||
($umode eq 'localauth')) {
$authresult = &Apache::lonnet::modifyuserauth($udom,$uname,$umode,$upass);
}
}
if (($forceid) && (&Apache::lonnet::allowed('mau',$udom)) &&
($env{'form.recurseid'}) && ($checkid)) {
my %userupdate = (
lastname => $last,
middlename => $middle,
firstname => $first,
generation => $gene,
id => $uid,
);
$idresult = &propagate_id_change($uname,$udom,\%userupdate);
}
}
}
$userresult =
&Apache::lonnet::modifyuser($udom,$uname,$uid,$umode,$upass,$first,
$middle,$last,$gene,$forceid,$desiredhome,
$email,$role,$start,$end);
if ($userresult eq 'ok') {
if ($role ne '') {
$role =~ s/_/\//g;
$roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope,
$role,$end,$start);
}
}
return ($userresult,$authresult,$roleresult,$idresult);
}
sub propagate_id_change {
my ($uname,$udom,$user) = @_;
my (@types,@roles);
@types = ('active','future');
@roles = ('st');
my $idresult;
my %roleshash = &Apache::lonnet::get_my_roles($uname,
$udom,'userroles',\@types,\@roles);
my %args = (
one_time => 1,
);
foreach my $item (keys(%roleshash)) {
my ($cnum,$cdom,$role) = split(/:/,$item,-1);
my ($start,$end) = split(/:/,$roleshash{$item});
if (&Apache::lonnet::is_course($cdom,$cnum)) {
my $result = &update_classlist($cdom,$cnum,$udom,$uname,$user);
my %coursehash =
&Apache::lonnet::coursedescription($cdom.'_'.$cnum,\%args);
my $cdesc = $coursehash{'description'};
if ($cdesc eq '') {
$cdesc = $cdom.'_'.$cnum;
}
if ($result eq 'ok') {
$idresult .= &mt('Classlist update for "[_1]" in "[_2]".',$uname.':'.$udom,$cdesc).' '."\n";
} else {
$idresult .= &mt('Error: "[_1]" during classlist update for "[_2]" in "[_3]".',$result,$uname.':'.$udom,$cdesc).' '."\n";
}
}
}
return $idresult;
}
sub update_classlist {
my ($cdom,$cnum,$udom,$uname,$user) = @_;
my ($uid,$classlistentry);
my $fullname =
&Apache::lonnet::format_name($user->{'firstname'},$user->{'middlename'},
$user->{'lastname'},$user->{'generation'},
'lastname');
my %classhash = &Apache::lonnet::get('classlist',[$uname.':'.$udom],
$cdom,$cnum);
my @classinfo = split(/:/,$classhash{$uname.':'.$udom});
my $ididx=&Apache::loncoursedata::CL_ID() - 2;
my $nameidx=&Apache::loncoursedata::CL_FULLNAME() - 2;
for (my $i=0; $i<@classinfo; $i++) {
if ($i == $ididx) {
if (defined($user->{'id'})) {
$classlistentry .= $user->{'id'}.':';
} else {
$classlistentry .= $classinfo[$i].':';
}
} elsif ($i == $nameidx) {
$classlistentry .= $fullname.':';
} else {
$classlistentry .= $classinfo[$i].':';
}
}
$classlistentry =~ s/:$//;
my $reply=&Apache::lonnet::cput('classlist',
{"$uname:$udom" => $classlistentry},
$cdom,$cnum);
if (($reply eq 'ok') || ($reply eq 'delayed')) {
return 'ok';
} else {
return 'error: '.$reply;
}
}
###############################################################
###############################################################
# build a role type and role selection form
sub domain_roles_select {
# Set up the role type and role selection boxes when in
# domain context
#
# Role types
my @roletypes = ('domain','author','course');
my %lt = &role_type_names();
#
# build up the menu information to be passed to
# &Apache::loncommon::linked_select_forms
my %select_menus;
if ($env{'form.roletype'} eq '') {
$env{'form.roletype'} = 'domain';
}
foreach my $roletype (@roletypes) {
# set up the text for this domain
$select_menus{$roletype}->{'text'}= $lt{$roletype};
# we want a choice of 'default' as the default in the second menu
if ($env{'form.roletype'} ne '') {
$select_menus{$roletype}->{'default'} = $env{'form.showrole'};
} else {
$select_menus{$roletype}->{'default'} = 'Any';
}
# Now build up the other items in the second menu
my @roles;
if ($roletype eq 'domain') {
@roles = &domain_roles();
} elsif ($roletype eq 'author') {
@roles = &construction_space_roles();
} else {
my $custom = 1;
@roles = &course_roles('domain',undef,$custom);
}
my $order = ['Any',@roles];
$select_menus{$roletype}->{'order'} = $order;
foreach my $role (@roles) {
if ($role eq 'cr') {
$select_menus{$roletype}->{'select2'}->{$role} =
&mt('Custom role');
} else {
$select_menus{$roletype}->{'select2'}->{$role} =
&Apache::lonnet::plaintext($role);
}
}
$select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');
}
my $result = &Apache::loncommon::linked_select_forms
('studentform',(' 'x3).&mt('Role: '),$env{'form.roletype'},
'roletype','showrole',\%select_menus,['domain','author','course']);
return $result;
}
###############################################################
###############################################################
sub hidden_input {
my ($name,$value) = @_;
return ''."\n";
}
sub print_upload_manager_header {
my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_;
my $javascript;
#
if (! exists($env{'form.upfile_associate'})) {
$env{'form.upfile_associate'} = 'forward';
}
if ($env{'form.associate'} eq 'Reverse Association') {
if ( $env{'form.upfile_associate'} ne 'reverse' ) {
$env{'form.upfile_associate'} = 'reverse';
} else {
$env{'form.upfile_associate'} = 'forward';
}
}
if ($env{'form.upfile_associate'} eq 'reverse') {
$javascript=&upload_manager_javascript_reverse_associate();
} else {
$javascript=&upload_manager_javascript_forward_associate();
}
#
# Deal with restored settings
my $password_choice = '';
if (exists($env{'form.ipwd_choice'}) &&
$env{'form.ipwd_choice'} ne '') {
# If a column was specified for password, assume it is for an
# internal password. This is a bug waiting to be filed (could be
# local or krb auth instead of internal) but I do not have the
# time to mess around with this now.
$password_choice = 'int';
}
#
my $groupslist;
if ($context eq 'course') {
$groupslist = &get_groupslist();
}
my $javascript_validations =
&javascript_validations('upload',$krbdefdom,$password_choice,undef,
$env{'request.role.domain'},$context,
$groupslist);
my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');
$r->print(&mt('Total number of records found in file: [_1].',$distotal).
" \n");
$r->print('
'.
&mt('Identify fields in uploaded list')."
\n");
$r->print(&mt('Enter as many fields as you can. The system will inform you and bring you back to this page, if the data selected are insufficient to add users.')." \n");
$r->print(&hidden_input('action','upload').
&hidden_input('state','got_file').
&hidden_input('associate','').
&hidden_input('datatoken',$datatoken).
&hidden_input('fileupload',$env{'form.fileupload'}).
&hidden_input('upfiletype',$env{'form.upfiletype'}).
&hidden_input('upfile_associate',$env{'form.upfile_associate'}));
$r->print(' ');
$r->print('');
$r->print("
\n".
'');
}
###############################################################
###############################################################
sub javascript_validations {
my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain,
$context,$groupslist)=@_;
my %param = (
kerb_def_dom => $krbdefdom,
curr_authtype => $curr_authtype,
);
if ($mode eq 'upload') {
$param{'formname'} = 'studentform';
} elsif ($mode eq 'createcourse') {
$param{'formname'} = 'ccrs';
} elsif ($mode eq 'modifycourse') {
$param{'formname'} = 'cmod';
$param{'mode'} = 'modifycourse',
$param{'curr_autharg'} = $curr_authfield;
}
my ($setsection_call,$setsections_js);
my $finish = " vf.submit();\n";
if ($mode eq 'upload') {
if (($context eq 'course') || ($context eq 'domain')) {
if ($context eq 'course') {
if ($env{'request.course.sec'} eq '') {
$setsection_call = 'setSections(document.'.$param{'formname'}.');';
$setsections_js =
&setsections_javascript($param{'formname'},$groupslist,
$mode);
} else {
$setsection_call = "'ok'";
}
} elsif ($context eq 'domain') {
$setsection_call = 'setCourse()';
$setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context);
}
$finish = " var checkSec = $setsection_call\n".
" if (checkSec == 'ok') {\n".
" vf.submit();\n".
" }\n";
}
}
my $authheader = &Apache::loncommon::authform_header(%param);
my %alert = &Apache::lonlocal::texthash
(username => 'You need to specify the username field.',
authen => 'You must choose an authentication type.',
krb => 'You need to specify the Kerberos domain.',
ipass => 'You need to specify the initial password.',
name => 'The optional name field was not specified.',
snum => 'The optional ID number field was not specified.',
section => 'The optional section field was not specified.',
email => 'The optional email address field was not specified.',
role => 'The optional role field was not specified.',
continue => 'Continue adding users?',
);
my $function_name = <<"END";
$setsections_js
function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
END
my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($domain);
my $auth_checks;
if ($mode eq 'createcourse') {
$auth_checks .= (< 1) {
$auth_checks .= (<=2) && (tw<=6)) { foundname=1; }
if (tw==7) { foundid=1; }
if (tw==8) { foundsec=1; }
if (tw==9) { foundpwd=1; }
if (tw==10) { foundemail=1; }
if (tw==11) { foundrole=1; }
}
verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole);
}
//
// vf = this.form
// tf = column number
//
// values of nw
//
// 0 = none
// 1 = username
// 2 = names (lastname, firstnames)
// 3 = fname (firstname)
// 4 = mname (middlename)
// 5 = lname (lastname)
// 6 = gen (generation)
// 7 = id
// 8 = section
// 9 = ipwd (password)
// 10 = email address
// 11 = role
function flip(vf,tf) {
var nw=eval('vf.f'+tf+'.selectedIndex');
var i;
// make sure no other columns are labeled the same as this one
for (i=0;i<=vf.nfields.value;i++) {
if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
eval('vf.f'+i+'.selectedIndex=0;')
}
}
// If we set this to 'lastname, firstnames', clear out all the ones
// set to 'fname','mname','lname','gen' (3,4,5,6) currently.
if (nw==2) {
for (i=0;i<=vf.nfields.value;i++) {
if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
(eval('vf.f'+i+'.selectedIndex')<=6)) {
eval('vf.f'+i+'.selectedIndex=0;')
}
}
}
// If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
// clear out any that are set to 'lastname, firstnames' (2)
if ((nw>=3) && (nw<=6)) {
for (i=0;i<=vf.nfields.value;i++) {
if (eval('vf.f'+i+'.selectedIndex')==2) {
eval('vf.f'+i+'.selectedIndex=0;')
}
}
}
// If we set the password, make the password form below correspond to
// the new value.
if (nw==9) {
changed_radio('int',document.studentform);
set_auth_radio_buttons('int',document.studentform);
vf.intarg.value='';
vf.krbarg.value='';
vf.locarg.value='';
}
}
function clearpwd(vf) {
var i;
for (i=0;i<=vf.nfields.value;i++) {
if (eval('vf.f'+i+'.selectedIndex')==9) {
eval('vf.f'+i+'.selectedIndex=0;')
}
}
}
ENDPICK
}
###############################################################
###############################################################
sub upload_manager_javascript_reverse_associate {
return(<=1) && (i<=5)) && tw!=0 ) { foundname=1; }
if (i==6 && tw!=0) { foundid=1; }
if (i==7 && tw!=0) { foundsec=1; }
if (i==8 && tw!=0) { foundpwd=1; }
if (i==9 && tw!=0) { foundrole=1; }
}
verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundrole);
}
function flip(vf,tf) {
var nw=eval('vf.f'+tf+'.selectedIndex');
var i;
// picked the all one name field, reset the other name ones to blank
if (tf==1 && nw!=0) {
for (i=2;i<=5;i++) {
eval('vf.f'+i+'.selectedIndex=0;')
}
}
//picked one of the piecewise name fields, reset the all in
//one field to blank
if ((tf>=2) && (tf<=5) && (nw!=0)) {
eval('vf.f1.selectedIndex=0;')
}
// intial password specified, pick internal authentication
if (tf==8 && nw!=0) {
changed_radio('int',document.studentform);
set_auth_radio_buttons('int',document.studentform);
vf.krbarg.value='';
vf.intarg.value='';
vf.locarg.value='';
}
}
function clearpwd(vf) {
var i;
if (eval('vf.f8.selectedIndex')!=0) {
eval('vf.f8.selectedIndex=0;')
}
}
ENDPICK
}
###############################################################
###############################################################
sub print_upload_manager_footer {
my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission) = @_;
my $form = 'document.studentform';
my $formname = 'studentform';
my ($krbdef,$krbdefdom) =
&Apache::loncommon::get_kerberos_defaults($defdom);
my %param = ( formname => $form,
kerb_def_dom => $krbdefdom,
kerb_def_auth => $krbdef
);
if (exists($env{'form.ipwd_choice'}) &&
defined($env{'form.ipwd_choice'}) &&
$env{'form.ipwd_choice'} ne '') {
$param{'curr_authtype'} = 'int';
}
my $krbform = &Apache::loncommon::authform_kerberos(%param);
my $intform = &Apache::loncommon::authform_internal(%param);
my $locform = &Apache::loncommon::authform_local(%param);
my $date_table = &date_setting_table(undef,undef,$context,undef,
$formname,$permission);
my $Str = "\n".'
'."\n");
} elsif ($mode eq 'csv') {
close($CSVfile);
$r->print(''.
&mt('Your CSV file').' is ready for download.'.
"\n");
$r->rflush();
}
if ($mode eq 'autoenroll') {
return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
} else {
return ($usercount);
}
}
sub print_username_link {
my ($mode,$in) = @_;
my $output;
if ($mode eq 'autoenroll') {
$output = $in->{'username'};
} else {
$output = '{'username'}','$in->{'domain'}'".')" />'.
$in->{'username'}.'';
}
return $output;
}
sub role_type_names {
my %lt = &Apache::lonlocal::texthash (
'domain' => 'Domain Roles',
'author' => 'Co-Author Roles',
'course' => 'Course Roles',
);
return %lt;
}
sub select_actions {
my ($context,$setting,$statusmode) = @_;
my %lt = &Apache::lonlocal::texthash(
revoke => "Revoke user roles",
delete => "Delete user roles",
reenable => "Re-enable expired user roles",
activate => "Make future user roles active now",
chgdates => "Change starting/ending dates",
chgsec => "Change section associated with user roles",
);
my ($output,$options,%choices);
# FIXME Disable actions for now for roletype=course in domain context
if ($context eq 'domain' && $setting eq 'course') {
return;
}
if ($context eq 'course') {
if ($env{'form.showrole'} ne 'Any') {
if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},
$env{'request.course.id'})) {
if ($env{'request.course.sec'} eq '') {
return;
} else {
if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
return;
}
}
}
}
}
if ($statusmode eq 'Any') {
$options .= '
';
$choices{'dates'} = 1;
} else {
if ($statusmode eq 'Future') {
$options .= '
';
$choices{'dates'} = 1;
} elsif ($statusmode eq 'Expired') {
$options .= '
';
$choices{'dates'} = 1;
}
if ($statusmode eq 'Active' || $statusmode eq 'Future') {
$options .= '
';
$choices{'dates'} = 1;
}
}
if ($context eq 'domain') {
$options .= '
';
}
if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) {
if (($statusmode ne 'Expired') && ($env{'request.course.sec'} eq '')) {
$options .= '
';
$choices{'sections'} = 1;
}
}
if ($options) {
$output = ''."\n".
''."\n".$options."\n".'';
if ($choices{'dates'}) {
$output .=
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n".
''."\n";
if ($context eq 'course') {
$output .= ''."\n";
}
}
if ($choices{'sections'}) {
$output .= ''."\n".
''."\n";
}
}
return $output;
}
sub date_section_javascript {
my ($context,$setting) = @_;
my $title = 'Date_And_Section_Selector';
my %nopopup = &Apache::lonlocal::texthash (
revoke => "Check the boxes for any users for whom roles are to be revoked, and click 'Proceed'",
delete => "Check the boxes for any users for whom roles are to be deleted, and click 'Proceed'",
none => "Choose an action to take for selected users",
);
my $output = '
ENDTWO
return $output;
}
sub date_section_selector {
my ($context,$permission) = @_;
my $callingform = $env{'form.callingform'};
my $formname = 'dateselect';
my $groupslist = &get_groupslist();
my $sec_js = &setsections_javascript($formname,$groupslist);
my $output = <<"END";
';
my %lt = &Apache::lonlocal::texthash (
chac => 'Access dates to apply for selected users',
chse => 'Changes in section affiliation to apply to selected users',
fors => 'For student roles changing the section, will result in a section switch as students may only be in one section of a course at a time.',
forn => 'For a role in a course that is not a student role, a user may have roles in more than one section of a course at a time.',
reta => "Retain each user's current section affiliations?",
dnap => '(Does not apply to student roles).',
);
my ($date_items,$headertext);
if ($env{'form.bulkaction'} eq 'chgsec') {
$headertext = $lt{'chse'};
} else {
$headertext = $lt{'chac'};
my $starttime;
if (($env{'form.bulkaction'} eq 'activate') ||
($env{'form.bulkaction'} eq 'reenable')) {
$starttime = time;
}
$date_items = &date_setting_table($starttime,undef,$context,
$env{'form.bulkaction'},$formname,
$permission);
}
$output .= '
'.$headertext.'
'.
'';
return $output;
}
sub section_picker {
my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_;
my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
my $sections_select .= &course_sections(\%sections_count,$role);
my $secbox = '
'.&Apache::lonhtmlcommon::start_pick_box()."\n";
if ($mode eq 'upload') {
my ($options,$cb_script,$coursepick) =
&default_role_selector($context,1);
$secbox .= &Apache::lonhtmlcommon::row_title('role','LC_oddrow_value').
$options. &Apache::lonhtmlcommon::row_closure(1)."\n";
}
$secbox .= &Apache::lonhtmlcommon::row_title($rowtitle,'LC_oddrow_value')."\n";
if ($env{'request.course.sec'} eq '') {
$secbox .= '
'."\n";
} else {
$secbox .= ''.
$env{'request.course.sec'};
}
$secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n".
&Apache::lonhtmlcommon::end_pick_box().'';
return $secbox;
}
sub results_header_row {
my ($rolefilter,$statusmode,$context,$permission,$mode) = @_;
my ($description,$showfilter);
if ($rolefilter ne 'Any') {
$showfilter = $rolefilter;
}
if ($context eq 'course') {
if ($mode eq 'csv' || $mode eq 'excel') {
$description = &mt('Course - ').$env{'course.'.$env{'request.course.id'}.'.description'}.': ';
}
if ($statusmode eq 'Expired') {
$description .= &mt('Users in course with expired [_1] roles',$showfilter);
} elsif ($statusmode eq 'Future') {
$description .= &mt('Users in course with future [_1] roles',$showfilter);
} elsif ($statusmode eq 'Active') {
$description .= &mt('Users in course with active [_1] roles',$showfilter);
} else {
if ($rolefilter eq 'Any') {
$description .= &mt('All users in course');
} else {
$description .= &mt('All users in course with [_1] roles',$rolefilter);
}
}
my $constraint;
my $viewablesec = &viewable_section($permission);
if ($viewablesec ne '') {
if ($env{'form.showrole'} eq 'st') {
$constraint = &mt('only users in section "[_1]"',$viewablesec);
} elsif ($env{'form.showrole'} ne 'cc') {
$constraint = &mt('only users affiliated with no section or section "[_1]"',$viewablesec);
}
if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) {
if ($env{'form.grpfilter'} eq 'none') {
$constraint .= &mt(' and not in any group');
} else {
$constraint .= &mt(' and members of group: "[_1]"',$env{'form.grpfilter'});
}
}
} else {
if (($env{'form.secfilter'} ne 'all') && ($env{'form.secfilter'} ne '')) {
if ($env{'form.secfilter'} eq 'none') {
$constraint = &mt('only users affiliated with no section');
} else {
$constraint = &mt('only users affiliated with section "[_1]"',$env{'form.secfilter'});
}
}
if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) {
if ($env{'form.grpfilter'} eq 'none') {
if ($constraint eq '') {
$constraint = &mt('only users not in any group');
} else {
$constraint .= &mt(' and also not in any group');
}
} else {
if ($constraint eq '') {
$constraint = &mt('only members of group: "[_1]"',$env{'form.grpfilter'});
} else {
$constraint .= &mt(' and also members of group: "[_1]"'.$env{'form.grpfilter'});
}
}
}
}
if ($constraint ne '') {
$description .= ' ('.$constraint.')';
}
} elsif ($context eq 'author') {
$description =
&mt('Author space for [_1]',
&Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'})).': ';
if ($statusmode eq 'Expired') {
$description .= &mt('Co-authors with expired [_1] roles',$showfilter);
} elsif ($statusmode eq 'Future') {
$description .= &mt('Co-authors with future [_1] roles',$showfilter);
} elsif ($statusmode eq 'Active') {
$description .= &mt('Co-authors with active [_1] roles',$showfilter);
} else {
if ($rolefilter eq 'Any') {
$description .= &mt('All co-authors');
} else {
$description .= &mt('All co-authors with [_1] roles',$rolefilter);
}
}
} elsif ($context eq 'domain') {
my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description');
$description = &mt('Domain - ').$domdesc.': ';
if ($env{'form.roletype'} eq 'domain') {
if ($statusmode eq 'Expired') {
$description .= &mt('Users in domain with expired [_1] roles',$showfilter);
} elsif ($statusmode eq 'Future') {
$description .= &mt('Users in domain with future [_1] roles',$showfilter);
} elsif ($statusmode eq 'Active') {
$description .= &mt('Users in domain with active [_1] roles',$showfilter);
} else {
if ($rolefilter eq 'Any') {
$description .= &mt('All users in domain');
} else {
$description .= &mt('All users in domain with [_1] roles',$rolefilter);
}
}
} elsif ($env{'form.roletype'} eq 'author') {
if ($statusmode eq 'Expired') {
$description .= &mt('Co-authors in domain with expired [_1] roles',$showfilter);
} elsif ($statusmode eq 'Future') {
$description .= &mt('Co-authors in domain with future [_1] roles',$showfilter);
} elsif ($statusmode eq 'Active') {
$description .= &mt('Co-authors in domain with active [_1] roles',$showfilter);
} else {
if ($rolefilter eq 'Any') {
$description .= &mt('All users with co-author roles in domain',$showfilter);
} else {
$description .= &mt('All co-authors in domain with [_1] roles',$rolefilter);
}
}
} elsif ($env{'form.roletype'} eq 'course') {
my $coursefilter = $env{'form.coursepick'};
if ($coursefilter eq 'category') {
my $instcode = &instcode_from_coursefilter();
if ($instcode eq '.') {
$description .= &mt('All courses in domain').' - ';
} else {
$description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - ';
}
} elsif ($coursefilter eq 'selected') {
$description .= &mt('Selected courses in domain').' - ';
} elsif ($coursefilter eq 'all') {
$description .= &mt('All courses in domain').' - ';
}
if ($statusmode eq 'Expired') {
$description .= &mt('users with expired [_1] roles',$showfilter);
} elsif ($statusmode eq 'Future') {
$description .= &mt('users with future [_1] roles',$showfilter);
} elsif ($statusmode eq 'Active') {
$description .= &mt('users with active [_1] roles',$showfilter);
} else {
if ($rolefilter eq 'Any') {
$description .= &mt('all users');
} else {
$description .= &mt('users with [_1] roles',$rolefilter);
}
}
}
}
return $description;
}
sub viewable_section {
my ($permission) = @_;
my $viewablesec;
if (ref($permission) eq 'HASH') {
if (exists($permission->{'view_section'})) {
$viewablesec = $permission->{'view_section'};
} elsif (exists($permission->{'cusr_section'})) {
$viewablesec = $permission->{'cusr_section'};
}
}
return $viewablesec;
}
#################################################
#################################################
sub show_drop_list {
my ($r,$classlist,$nosort,$permission) = @_;
my $cid = $env{'request.course.id'};
my ($cnum,$cdom) = &get_course_identity($cid);
if (! exists($env{'form.sortby'})) {
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['sortby']);
}
my $sortby = $env{'form.sortby'};
if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
$sortby = 'username';
}
my $action = "drop";
my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
$r->print(<
END
my ($indexhash,$keylist) = &make_keylist_array();
my $studentcount = 0;
if (ref($classlist) eq 'HASH') {
foreach my $student (keys(%{$classlist})) {
my $sdata = $classlist->{$student};
my $status = $sdata->[$indexhash->{'status'}];
my $section = $sdata->[$indexhash->{'section'}];
if ($status ne 'Active') {
delete($classlist->{$student});
next;
}
if ($env{'request.course.sec'} ne '') {
if ($section ne $env{'request.course.sec'}) {
delete($classlist->{$student});
next;
}
}
$studentcount ++;
}
}
if (!$studentcount) {
$r->print(&mt('There are no students to drop.'));
return;
}
my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
$classlist,$keylist,$cdom,$cnum);
my %lt=&Apache::lonlocal::texthash('usrn' => "username",
'dom' => "domain",
'sn' => "student name",
'sec' => "section",
'start' => "start date",
'end' => "end date",
'groups' => "active groups",
);
if ($nosort) {
$r->print(&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row());
$r->print(<
$lt{'usrn'}
$lt{'dom'}
ID
$lt{'sn'}
$lt{'sec'}
$lt{'start'}
$lt{'end'}
$lt{'groups'}
END
$r->print(&Apache::loncommon::end_data_table_header_row());
} else {
$r->print(&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row());
$r->print(<
END
return;
}
#
# Print out the initial form to get the file containing a list of users
#
sub print_first_users_upload_form {
my ($r,$context) = @_;
my $str;
$str = '';
$str .= '';
$str .= '';
$str .= "
".&mt('Upload a file containing information about users')."
\n";
$str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
&mt("How do I create a users list from a spreadsheet")).
" \n";
$str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
&mt("How do I create a CSV file from a spreadsheet")).
" \n";
$str .= &Apache::loncommon::end_page();
$r->print($str);
return;
}
# ================================================= Drop/Add from uploaded file
sub upfile_drop_add {
my ($r,$context,$permission) = @_;
&Apache::loncommon::load_tmp_file($r);
my @userdata=&Apache::loncommon::upfile_record_sep();
if($env{'form.noFirstLine'}){shift(@userdata);}
my @keyfields = split(/\,/,$env{'form.keyfields'});
my %fields=();
for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
if ($env{'form.upfile_associate'} eq 'reverse') {
if ($env{'form.f'.$i} ne 'none') {
$fields{$keyfields[$i]}=$env{'form.f'.$i};
}
} else {
$fields{$env{'form.f'.$i}}=$keyfields[$i];
}
}
if ($env{'form.fullup'} ne 'yes') {
$r->print(''.
''.
&mt('There are no students with current/future access to the course.').
''."\n");
} else {
# Remove the students we just added from the list of students.
foreach my $line (@userdata) {
my %entries=&Apache::loncommon::record_sep($line);
unless (($entries{$fields{'username'}} eq '') ||
(!defined($entries{$fields{'username'}}))) {
delete($classlist->{$entries{$fields{'username'}}.
':'.$domain});
}
}
# Print out list of dropped students.
&show_drop_list($r,$classlist,'nosort',$permission);
}
}
} # end of unless
if ($env{'form.fullup'} ne 'yes') {
$r->print('');
}
}
sub print_namespacing_alerts {
my ($domain,$alerts,$curr_rules) = @_;
my $output;
if (ref($alerts) eq 'HASH') {
if (keys(%{$alerts}) > 0) {
if (ref($alerts->{'username'}) eq 'HASH') {
foreach my $dom (sort(keys(%{$alerts->{'username'}}))) {
my $count;
if (ref($alerts->{'username'}{$dom}) eq 'HASH') {
$count = keys(%{$alerts->{'username'}{$dom}});
}
my $domdesc = &Apache::lonnet::domain($domain,'description');
if (ref($curr_rules->{$dom}) eq 'HASH') {
$output .= &Apache::loncommon::instrule_disallow_msg(
'username',$domdesc,$count,'upload');
}
$output .= &Apache::loncommon::user_rule_formats($dom,
$domdesc,$curr_rules->{$dom}{'username'},
'username');
}
}
if (ref($alerts->{'id'}) eq 'HASH') {
foreach my $dom (sort(keys(%{$alerts->{'id'}}))) {
my $count;
if (ref($alerts->{'id'}{$dom}) eq 'HASH') {
$count = keys(%{$alerts->{'id'}{$dom}});
}
my $domdesc = &Apache::lonnet::domain($domain,'description');
if (ref($curr_rules->{$dom}) eq 'HASH') {
$output .= &Apache::loncommon::instrule_disallow_msg(
'id',$domdesc,$count,'upload');
}
$output .= &Apache::loncommon::user_rule_formats($dom,
$domdesc,$curr_rules->{$dom}{'id'},'id');
}
}
}
}
}
sub user_change_result {
my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
$username,$userchg) = @_;
my $okresult = 0;
if ($userresult ne 'ok') {
if ($userresult =~ /^error:(.+)$/) {
my $error = $1;
$r->print(' '.
&mt('[_1]: Unable to add/modify: [_2]',$username,$error));
}
} else {
$counts->{'user'} ++;
$okresult = 1;
}
if ($authresult ne 'ok') {
if ($authresult =~ /^error:(.+)$/) {
my $error = $1;
$r->print(' '.
&mt('[_1]: Unable to modify authentication: [_2]',$username,$error));
}
} else {
$counts->{'auth'} ++;
$okresult = 1;
}
if ($roleresult ne 'ok') {
if ($roleresult =~ /^error:(.+)$/) {
my $error = $1;
$r->print(' '.
&mt('[_1]: Unable to add role: [_2]',$username,$error));
}
} else {
$counts->{'role'} ++;
$okresult = 1;
}
if ($okresult) {
$flushc++;
$userchg->{$username}=1;
$r->print('. ');
if ($flushc>15) {
$r->rflush;
$flushc=0;
}
}
if ($idresult) {
$r->print($idresult);
}
return $flushc;
}
# ========================================================= Menu Phase Two Drop
sub print_drop_menu {
my ($r,$context,$permission) = @_;
$r->print('
'.&mt("Drop Students").'
'."\n".
''. &Apache::loncommon::end_page());
return;
}
# ================================================================== Phase four
sub update_user_list {
my ($r,$context,$setting,$choice) = @_;
my $now = time;
my $count=0;
my @changelist;
if ($choice eq 'drop') {
@changelist = &Apache::loncommon::get_env_multiple('form.droplist');
} else {
@changelist = &Apache::loncommon::get_env_multiple('form.actionlist');
}
my %result_text = ( ok => { 'revoke' => 'Revoked',
'delete' => 'Deleted',
'reenable' => 'Re-enabled',
'activate' => 'Activated',
'chgdates' => 'Changed Access Dates for',
'chgsec' => 'Changed section for',
'drop' => 'Dropped',
},
error => {'revoke' => 'revoking',
'delete' => 'deleting',
'reenable' => 're-enabling',
'activate' => 'activating',
'chgdates' => 'changing access dates for',
'chgsec' => 'changing section for',
'drop' => 'dropping',
},
);
my ($startdate,$enddate);
if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
($startdate,$enddate) = &get_dates_from_form();
}
foreach my $item (@changelist) {
my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections,
$scopestem);
if ($choice eq 'drop') {
($uname,$udom,$sec) = split(/:/,$item,-1);
$role = 'st';
$cid = $env{'request.course.id'};
$scopestem = '/'.$cid;
$scopestem =~s/\_/\//g;
if ($sec eq '') {
$scope = $scopestem;
} else {
$scope = $scopestem.'/'.$sec;
}
} elsif ($context eq 'course') {
($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1);
$cid = $env{'request.course.id'};
$scopestem = '/'.$cid;
$scopestem =~s/\_/\//g;
if ($sec eq '') {
$scope = $scopestem;
} else {
$scope = $scopestem.'/'.$sec;
}
} elsif ($context eq 'author') {
($uname,$udom,$role) = split(/\:/,$item,-1);
$scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
} elsif ($context eq 'domain') {
if ($setting eq 'domain') {
($role,$uname,$udom) = split(/\:/,$item,-1);
$scope = '/'.$env{'request.role.domain'}.'/';
} elsif ($setting eq 'author') {
($uname,$udom,$role,$scope) = split(/\:/,$item);
} elsif ($setting eq 'course') {
($uname,$udom,$role,$cid,$sec,$type,$locktype) =
split(/\:/,$item);
$scope = '/'.$cid;
$scope =~s/\_/\//g;
if ($sec ne '') {
$scope .= '/'.$sec;
}
}
}
my $plrole = &Apache::lonnet::plaintext($role);
my $start = $env{'form.'.$item.'_start'};
my $end = $env{'form.'.$item.'_end'};
if ($choice eq 'drop') {
# drop students
$end = $now;
$type = 'manual';
$result =
&Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
} elsif ($choice eq 'revoke') {
# revoke or delete user role
$end = $now;
if ($role eq 'st') {
$result =
&Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
} else {
$result =
&Apache::lonnet::revokerole($udom,$uname,$scope,$role);
}
} elsif ($choice eq 'delete') {
if ($role eq 'st') {
&Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid);
}
$result =
&Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,
$start,1);
} else {
#reenable, activate, change access dates or change section
if ($choice ne 'chgsec') {
$start = $startdate;
$end = $enddate;
}
if ($choice eq 'reenable') {
if ($role eq 'st') {
$result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
} else {
$result =
&Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
$now);
}
} elsif ($choice eq 'activate') {
if ($role eq 'st') {
$result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
} else {
$result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
$now);
}
} elsif ($choice eq 'chgdates') {
if ($role eq 'st') {
$result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
} else {
$result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
$start);
}
} elsif ($choice eq 'chgsec') {
my (@newsecs,$revresult,$nochg,@retained);
if ($role ne 'cc') {
@newsecs = split(/,/,$env{'form.newsecs'});
}
# remove existing section if not to be retained.
if (!$env{'form.retainsec'}) {
if ($sec eq '') {
if (@newsecs == 0) {
$result = &mt('No change in section assignment (none)');
$nochg = 1;
} else {
$revresult =
&Apache::lonnet::revokerole($udom,$uname,
$scope,$role);
}
} else {
if (@newsecs > 0) {
if (grep(/^\Q$sec\E$/,@newsecs)) {
push(@retained,$sec);
} else {
$revresult =
&Apache::lonnet::revokerole($udom,$uname,
$scope,$role);
}
} else {
$revresult =
&Apache::lonnet::revokerole($udom,$uname,
$scope,$role);
}
}
} else {
if ($sec eq '') {
$nochg = 1;
} else {
push(@retained,$sec);
}
}
# add new sections
if (@newsecs == 0) {
if (!$nochg) {
if ($role eq 'st') {
$result =
&Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid);
} else {
my $newscope = $scopestem;
$result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start);
}
}
} else {
foreach my $newsec (@newsecs) {
if (!grep(/^\Q$newsec\E$/,@retained)) {
if ($role eq 'st') {
$result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid);
} else {
my $newscope = $scopestem;
if ($newsec ne '') {
$newscope .= '/'.$newsec;
}
$result = &Apache::lonnet::assignrole($udom,$uname,
$newscope,$role,$end,$start);
}
}
}
}
}
}
my $extent = $scope;
if ($choice eq 'drop' || $context eq 'course') {
my ($cnum,$cdom,$cdesc) = &get_course_identity($cid);
if ($cdesc) {
$extent = $cdesc;
}
}
if ($result eq 'ok' || $result eq 'ok:') {
$r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]",
$plrole,$extent,$uname.':'.$udom).' ');
$count++;
} else {
$r->print(
&mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].",
$plrole,$extent,$uname.':'.$udom,$result).' ');
}
}
$r->print(''."\n");
}
sub classlist_drop {
my ($scope,$uname,$udom,$now) = @_;
my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)});
if (&Apache::lonnet::is_course($cdom,$cnum)) {
my $user = $uname.':'.$udom;
if (!&active_student_roles($cnum,$cdom,$uname,$udom)) {
my $result =
&Apache::lonnet::cput('classlist',
{ $user => $now },$cdom,$cnum);
return &mt('Drop from classlist: [_1]',
''.$result.'').' ';
}
}
}
sub active_student_roles {
my ($cnum,$cdom,$uname,$udom) = @_;
my %roles =
&Apache::lonnet::get_my_roles($uname,$udom,'userroles',
['future','active'],['st']);
return exists($roles{"$cnum:$cdom:st"});
}
sub section_check_js {
my $groupslist= &get_groupslist();
return <<"END";
function validate(caller) {
var groups = new Array($groupslist);
var secname = caller.value;
if ((secname == 'all') || (secname == 'none')) {
alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
return 'error';
}
if (secname != '') {
for (var k=0; k'.$authformkrb.''.
&Apache::loncommon::end_data_table_row()."\n";
}
if ($can_assign{'int'}) {
$response .= &Apache::loncommon::start_data_table_row().
'
'.$authformint.'
'.
&Apache::loncommon::end_data_table_row()."\n"
}
if ($can_assign{'loc'}) {
$response .= &Apache::loncommon::start_data_table_row().
'
'.$authformloc.'
'.
&Apache::loncommon::end_data_table_row()."\n";
}
$response .= &Apache::loncommon::end_data_table();
}
return $response;
}
sub course_sections {
my ($sections_count,$role) = @_;
my $output = '';
my @sections = (sort {$a <=> $b} keys %{$sections_count});
my $numsec = scalar(@sections);
if ($numsec <= 1) {
$output = ''."\n".
' '."\n".
' '."\n";
if ($numsec == 1) {
$output .=
' '."\n";
}
} else {
$output = ''.&mt('Select').''."\n".
' \n";
} else {
$output .= 'multiple="multiple" size="'.$multiple.'">'."\n";
}
foreach my $sec (@sections) {
$output .= '\n";
}
}
$output .= '';
return $output;
}
sub get_groupslist {
my $groupslist;
my %curr_groups = &Apache::longroup::coursegroups();
if (%curr_groups) {
$groupslist = join('","',sort(keys(%curr_groups)));
$groupslist = '"'.$groupslist.'"';
}
return $groupslist;
}
sub setsections_javascript {
my ($formname,$groupslist,$mode,$checkauth) = @_;
my ($checkincluded,$finish,$rolecode,$setsection_js);
if ($mode eq 'upload') {
$checkincluded = 'formname.name == "'.$formname.'"';
$finish = "return 'ok';";
$rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n";
} elsif ($formname eq 'cu') {
$checkincluded = 'formname.elements[i-1].checked == true';
if ($checkauth) {
$finish = "var authcheck = auth_check();\n".
" if (authcheck == 'ok') {\n".
" formname.submit();\n".
" }\n";
} else {
$finish = 'formname.submit()';
}
$rolecode = "var match = str.split('_');
var role = match[3];\n";
} elsif ($formname eq 'enrollstudent') {
$checkincluded = 'formname.name == "'.$formname.'"';
if ($checkauth) {
$finish = "var authcheck = auth_check();\n".
" if (authcheck == 'ok') {\n".
" formname.submit();\n".
" }\n";
} else {
$finish = 'formname.submit()';
}
$rolecode = "var match = str.split('_');
var role = match[1];\n";
} else {
$checkincluded = 'formname.name == "'.$formname.'"';
$finish = "seccheck = 'ok';";
$rolecode = "var match = str.split('_');
var role = match[1];\n";
$setsection_js = "var seccheck = 'alert';";
}
my %alerts = &Apache::lonlocal::texthash(
secd => 'Section designations do not apply to Course Coordinator roles.',
accr => 'A course coordinator role will be added with access to all sections.',
inea => 'In each course, each user may only have one student role at a time.',
youh => 'You had selected ',
secs => 'sections.',
plmo => 'Please modify your selections so they include no more than one section.',
mayn => 'may not be used as the name for a section, as it is a reserved word.',
plch => 'Please choose a different section name.',
mnot => 'may not be used as a section name, as it is the name of a course group.',
secn => 'Section names and group names must be distinct. Please choose a different section name.',
);
$setsection_js .= <<"ENDSECCODE";
function setSections(formname) {
var re1 = /^currsec_/;
var groups = new Array($groupslist);
for (var i=0;i 0) {
if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) {
sections = sections + "," + formname.elements[i+1].value;
}
}
else {
sections = formname.elements[i+1].value;
}
var newsecs = formname.elements[i+1].value;
var numsplit;
if (newsecs != null && newsecs != "") {
numsplit = newsecs.split(/,/g);
numsec = numsec + numsplit.length;
}
if ((role == 'st') && (numsec > 1)) {
alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}")
return;
}
else {
if (numsplit != null) {
for (var j=0; j 0) {
my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules);
if (keys(%rule_check) > 0) {
$usertype = 'unofficial';
foreach my $item (keys(%rule_check)) {
if ($rule_check{$item}) {
$usertype = 'official';
last;
}
}
}
}
}
return $usertype;
}
sub roles_by_context {
my ($context,$custom) = @_;
my @allroles;
if ($context eq 'course') {
@allroles = ('st','ad','ta','ep','in','cc');
if ($custom) {
push(@allroles,'cr');
}
} elsif ($context eq 'author') {
@allroles = ('ca','aa');
} elsif ($context eq 'domain') {
@allroles = ('li','dg','sc','au','dc');
}
return @allroles;
}
sub get_permission {
my ($context,$roles) = @_;
my %permission;
if ($context eq 'course') {
my $custom = 1;
my @allroles = &roles_by_context($context,$custom);
foreach my $role (@allroles) {
if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
$permission{'cusr'} = 1;
last;
}
}
if (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) {
$permission{'custom'} = 1;
}
if (&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) {
$permission{'view'} = 1;
}
if (!$permission{'view'}) {
my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
$permission{'view'} = &Apache::lonnet::allowed('vcl',$scope);
if ($permission{'view'}) {
$permission{'view_section'} = $env{'request.course.sec'};
}
}
if (!$permission{'cusr'}) {
if ($env{'request.course.sec'} ne '') {
my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
$permission{'cusr'} = (&Apache::lonnet::allowed('cst',$scope));
if ($permission{'cusr'}) {
$permission{'cusr_section'} = $env{'request.course.sec'};
}
}
}
if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
$permission{'grp_manage'} = 1;
}
} elsif ($context eq 'author') {
$permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'});
$permission{'view'} = $permission{'cusr'};
} else {
my @allroles = &roles_by_context($context);
foreach my $role (@allroles) {
if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
$permission{'cusr'} = 1;
last;
}
}
if (!$permission{'cusr'}) {
if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
$permission{'cusr'} = 1;
}
}
if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {
$permission{'custom'} = 1;
}
$permission{'view'} = $permission{'cusr'};
}
my $allowed = 0;
foreach my $perm (values(%permission)) {
if ($perm) { $allowed=1; last; }
}
return (\%permission,$allowed);
}
# ==================================================== Figure out author access
sub authorpriv {
my ($auname,$audom)=@_;
unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname))
|| (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; } return 1;
}
sub roles_on_upload {
my ($context,$setting,%customroles) = @_;
my (@possible_roles,@permitted_roles);
@possible_roles = &curr_role_permissions($context,$setting,1);
foreach my $role (@possible_roles) {
if ($role eq 'cr') {
push(@permitted_roles,keys(%customroles));
} else {
push(@permitted_roles,$role);
}
}
return @permitted_roles;
}
sub get_course_identity {
my ($cid) = @_;
my ($cnum,$cdom,$cdesc);
if ($cid eq '') {
$cid = $env{'request.course.id'}
}
if ($cid ne '') {
$cnum = $env{'course.'.$cid.'.num'};
$cdom = $env{'course.'.$cid.'.domain'};
$cdesc = $env{'course.'.$cid.'.description'};
if ($cnum eq '' || $cdom eq '') {
my %coursehash =
&Apache::lonnet::coursedescription($cid,{'one_time' => 1});
$cdom = $coursehash{'domain'};
$cnum = $coursehash{'num'};
$cdesc = $coursehash{'description'};
}
}
return ($cnum,$cdom,$cdesc);
}
sub dc_setcourse_js {
my ($formname,$mode,$context) = @_;
my ($dc_setcourse_code,$authen_check);
my $cctext = &Apache::lonnet::plaintext('cc');
my %alerts = §ioncheck_alerts();
my $role = 'role';
if ($mode eq 'upload') {
$role = 'courserole';
} else {
$authen_check = &verify_authen($formname,$context);
}
$dc_setcourse_code = (<<"SCRIPTTOP");
$authen_check
function setCourse() {
var course = document.$formname.dccourse.value;
if (course != "") {
if (document.$formname.dcdomain.value != document.$formname.origdom.value) {
alert("$alerts{'curd'}");
return;
}
var userrole = document.$formname.$role.options[document.$formname.$role.selectedIndex].value
var section="";
var numsections = 0;
var newsecs = new Array();
for (var i=0; i 1)) {
alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")
return;
}
for (var j=0; j 0)) {
alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}.");
section = "";
}
SCRIPTTOP
if ($mode ne 'upload') {
$dc_setcourse_code .= (<<"ENDSCRIPT");
var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole
var numcourse = getIndex(document.$formname.dccourse);
if (numcourse == "-1") {
alert("$alerts{'thwa'}");
return;
}
else {
document.$formname.elements[numcourse].name = "act"+coursename;
var numnewsec = getIndex(document.$formname.newsec);
if (numnewsec != "-1") {
document.$formname.elements[numnewsec].name = "sec"+coursename;
document.$formname.elements[numnewsec].value = section;
}
var numstart = getIndex(document.$formname.start);
if (numstart != "-1") {
document.$formname.elements[numstart].name = "start"+coursename;
}
var numend = getIndex(document.$formname.end);
if (numend != "-1") {
document.$formname.elements[numend].name = "end"+coursename
}
}
}
var authcheck = auth_check();
if (authcheck == 'ok') {
document.$formname.submit();
}
}
ENDSCRIPT
} else {
$dc_setcourse_code .= "
document.$formname.sections.value = section;
}
return 'ok';
}
";
}
$dc_setcourse_code .= (<<"ENDSCRIPT");
function getIndex(caller) {
for (var i=0;i 0) {
var loginpicked = 0;
for (var i=0; i 'You must select a course in the current domain',
inea => 'In each course, each user may only have one student role at a time',
youh => 'You had selected',
sect => 'sections',
plsm => 'Please modify your selections so they include no more than one section',
mayn => 'may not be used as the name for a section, as it is a reserved word',
plsc => 'Please choose a different section name',
mayt => 'may not be used as the name for a section, as it is the name of a course group',
secn => 'Section names and group names must be distinct',
secd => 'Section designations do not apply to ',
role => 'roles',
accr => 'role will be added with access to all sections',
thwa => 'There was a problem with your course selection'
);
return %alerts;
}
sub authcheck_alerts {
my %alerts =
&Apache::lonlocal::texthash(
authen => 'You must choose an authentication type.',
krb => 'You need to specify the Kerberos domain.',
ipass => 'You need to specify the initial password.',
);
return %alerts;
}
1;