--- loncom/interface/lonuserutils.pm 2012/02/08 19:35:20 1.136.6.2
+++ loncom/interface/lonuserutils.pm 2024/09/01 02:33:40 1.184.4.10.2.9
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
-# $Id: lonuserutils.pm,v 1.136.6.2 2012/02/08 19:35:20 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.184.4.10.2.9 2024/09/01 02:33:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -30,12 +30,29 @@
package Apache::lonuserutils;
+=pod
+
+=head1 NAME
+
+Apache::lonuserutils.pm
+
+=head1 SYNOPSIS
+
+ Utilities for management of users and custom roles
+
+ Provides subroutines called by loncreateuser.pm
+
+=head1 OVERVIEW
+
+=cut
+
use strict;
use Apache::lonnet;
use Apache::loncommon();
use Apache::lonhtmlcommon;
use Apache::lonlocal;
use Apache::longroup;
+use HTML::Entities;
use LONCAPA qw(:DEFAULT :match);
###############################################################
@@ -47,8 +64,7 @@ sub modifystudent {
# 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 $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
- my %roles = &Apache::lonnet::dump('roles',$udom,$unam,'.',undef,$extra);
+ 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);
@@ -87,7 +103,7 @@ sub modifystudent {
sub modifyuserrole {
my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass,
$first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role,
- $end,$start,$checkid,$inststatus) = @_;
+ $end,$start,$checkid,$inststatus,$emptyok) = @_;
my ($scope,$userresult,$authresult,$roleresult,$idresult);
if ($setting eq 'course' || $context eq 'course') {
$scope = '/'.$cid;
@@ -98,7 +114,11 @@ sub modifyuserrole {
} elsif ($context eq 'domain') {
$scope = '/'.$env{'request.role.domain'}.'/';
} elsif ($context eq 'author') {
- $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
+ if ($env{'request.role'} =~ m{^ca\.(/$match_domain/$match_username)$}) {
+ $scope = $1;
+ } else {
+ $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
+ }
}
if ($context eq 'domain') {
my $uhome = &Apache::lonnet::homeserver($uname,$udom);
@@ -118,6 +138,25 @@ sub modifyuserrole {
generation => $gene,
id => $uid,
);
+
+ # When "Update ID in user's course(s)" and "Force change of existing ID"
+ # checkboxes both checked, prevent replacement of name information
+ # in classlist.db file(s) for the user's course(s) with blank(s),
+ # in the case where the uploaded csv file was without column(s) for
+ # the particular field. Fields are: First Name, Middle Names/Initials,
+ # Last Name (or the composite: Last Name, First Names), and Generation.
+
+ my %emptyallowed;
+ if ((ref($emptyok) eq 'HASH') && (keys(%{$emptyok}) > 0)) {
+ %emptyallowed = %{$emptyok};
+ }
+ foreach my $field (keys(%userupdate)) {
+ if ($userupdate{$field} eq '') {
+ unless ($emptyallowed{$field}) {
+ delete($userupdate{$field});
+ }
+ }
+ }
$idresult = &propagate_id_change($uname,$udom,\%userupdate);
}
}
@@ -238,6 +277,8 @@ sub domain_roles_select {
# Role types
my @roletypes = ('domain','author','course','community');
my %lt = &role_type_names();
+ my $onchangefirst = "updateCols('showrole')";
+ my $onchangesecond = "updateCols('showrole')";
#
# build up the menu information to be passed to
# &Apache::loncommon::linked_select_forms
@@ -284,7 +325,8 @@ sub domain_roles_select {
my $result = &Apache::loncommon::linked_select_forms
('studentform',(' 'x3).&mt('Role: '),$env{'form.roletype'},
'roletype','showrole',\%select_menus,
- ['domain','author','course','community']);
+ ['domain','author','course','community'],$onchangefirst,
+ $onchangesecond);
return $result;
}
@@ -336,14 +378,22 @@ sub print_upload_manager_header {
$env{'request.role.domain'},$context,
$groupslist,$crstype);
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.').'
'.
- &mt('The system will inform you and bring you back to this page, [_1]if the data selected are insufficient to add users.','
')."
\n");
+ $r->print(
+ '
'.&mt('Identify fields in uploaded list')." \n".
+ '
'.
+ &mt('Total number of records found in file: [_1]'
+ ,''.$distotal.' ').
+ "
\n"
+ );
+ if ($distotal == 0) {
+ $r->print('
'.&mt('None found').'
');
+ }
+ $r->print(
+ '
'.
+ &mt('Enter as many fields as you can.').' '.
+ &mt('The system will inform you and bring you back to this page,[_1]if the data selected are insufficient to add users.',' ').
+ "
\n"
+ );
$r->print(&hidden_input('action','upload').
&hidden_input('state','got_file').
&hidden_input('associate','').
@@ -351,17 +401,23 @@ sub print_upload_manager_header {
&hidden_input('fileupload',$env{'form.fileupload'}).
&hidden_input('upfiletype',$env{'form.upfiletype'}).
&hidden_input('upfile_associate',$env{'form.upfile_associate'}));
- $r->print('
'.
- &mt('Ignore First Line').'');
- $r->print('
print(
+ '
'.
+ '
'.&mt('Functions').' '.
+ ' '.
+ &mt('Ignore First Line').' '.
+ ' ');
- $r->print(" \n".
- '');
+ 'onclick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />'.
+ ''
+ );
+ $r->print(
+ ''
+ );
}
###############################################################
@@ -383,6 +439,12 @@ sub javascript_validations {
$param{'curr_autharg'} = $curr_authfield;
}
+ my $showcredits;
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
+ if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
+ $showcredits = 1;
+ }
+
my ($setsection_call,$setsections_js);
my $finish = " vf.submit();\n";
if ($mode eq 'upload') {
@@ -392,13 +454,14 @@ sub javascript_validations {
$setsection_call = 'setSections(document.'.$param{'formname'}.",'$crstype'".');';
$setsections_js =
&setsections_javascript($param{'formname'},$groupslist,
- $mode,'',$crstype);
+ $mode,'',$crstype,$showcredits);
} else {
$setsection_call = "'ok'";
}
} elsif ($context eq 'domain') {
$setsection_call = 'setCourse()';
- $setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context);
+ $setsections_js = &dc_setcourse_js($param{'formname'},$mode,
+ $context,$showcredits,$domain);
}
$finish = " var checkSec = $setsection_call\n".
" if (checkSec == 'ok') {\n".
@@ -421,13 +484,17 @@ sub javascript_validations {
domain => 'The optional domain field was not specified.',
continue => 'Continue adding users?',
);
+ if ($showcredits) {
+ $alert{'credits'} = &mt('The optional credits field was not specified');
+ }
if (($mode eq 'upload') && ($context eq 'domain')) {
$alert{'inststatus'} = &mt('The optional affiliation field was not specified');
}
+ &js_escape(\%alert);
my $function_name = <<"END";
$setsections_js
-function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus) {
+function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits) {
END
my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($domain);
my $auth_checks;
@@ -466,7 +533,7 @@ END
";
} elsif ($mode eq 'modifycourse') {
$auth_checks .= "
- if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') {
+ if ((current.argfield !== null) && (current.argfield !== undefined) && (current.argfield !== '') && (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '')) {
";
}
if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
@@ -484,21 +551,28 @@ END
return;
}
}
+/* regexp here to check for non \d \. in credits */
END
} else {
+ my ($numrules,$intargjs) =
+ &Apache::loncommon::passwd_validation_js('vf.elements[current.argfield].value',$domain);
$auth_checks .= (<
0) {
+$intargjs
+ }
}
END
}
@@ -556,6 +634,16 @@ END
message+='$alert{'domain'}';
}
END
+ if ($showcredits) {
+ $optional_checks .= <{'int'}) {
- my $warning = &mt('You may not specify an initial password for each user, as this is only available when new users use LON-CAPA internal authentication.\n').
+ my $warning = &mt('You may not specify an initial password for each user, as this is only available when new users use LON-CAPA internal authentication.')."\n".
&mt('Your current role does not have rights to create users with that authentication type.');
+ &js_escape(\$warning);
$auth_update = <<"END";
// Currently the initial password field is only supported for internal auth
// (see bug 6368).
@@ -640,6 +730,7 @@ function verify(vf,sec_caller) {
var foundrole=0;
var founddomain=0;
var foundinststatus=0;
+ var foundcredits=0;
var tw;
for (i=0;i<=vf.nfields.value;i++) {
tw=eval('vf.f'+i+'.selectedIndex');
@@ -652,8 +743,9 @@ function verify(vf,sec_caller) {
if (tw==11) { foundrole=1; }
if (tw==12) { founddomain=1; }
if (tw==13) { foundinststatus=1; }
+ if (tw==14) { foundcredits=1; }
}
- verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus);
+ verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits);
}
//
@@ -676,6 +768,7 @@ function verify(vf,sec_caller) {
// 11 = role
// 12 = domain
// 13 = inststatus
+// 14 = foundcredits
function flip(vf,tf) {
var nw=eval('vf.f'+tf+'.selectedIndex');
@@ -741,6 +834,7 @@ sub upload_manager_javascript_reverse_as
if (!$can_assign->{'int'}) {
my $warning = &mt('You may not specify an initial password, as this is only available when new users use LON-CAPA internal authentication.\n').
&mt('Your current role does not have rights to create users with that authentication type.');
+ &js_escape(\$warning);
$auth_update = <<"END";
// Currently the initial password field is only supported for internal auth
// (see bug 6368).
@@ -773,6 +867,7 @@ function verify(vf,sec_caller) {
var foundrole=0;
var founddomain=0;
var foundinststatus=0;
+ var foundcredits=0;
var tw;
for (i=0;i<=vf.nfields.value;i++) {
tw=eval('vf.f'+i+'.selectedIndex');
@@ -785,8 +880,9 @@ function verify(vf,sec_caller) {
if (i==10 && tw!=0) { foundrole=1; }
if (i==11 && tw!=0) { founddomain=1; }
if (i==12 && tw!=0) { foundinstatus=1; }
+ if (i==13 && tw!=0) { foundcredits=1; }
}
- verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus);
+ verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain,foundinststatus,foundcredits);
}
function flip(vf,tf) {
@@ -818,7 +914,8 @@ ENDPICK
###############################################################
###############################################################
sub print_upload_manager_footer {
- my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission,$crstype) = @_;
+ my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission,$crstype,
+ $showcredits) = @_;
my $form = 'document.studentform';
my $formname = 'studentform';
my ($krbdef,$krbdefdom) =
@@ -907,9 +1004,15 @@ sub print_upload_manager_footer {
&mt('Default role'))
.&mt('Choose the role to assign to users without a value specified in the uploaded file.')
} elsif ($context eq 'course') {
- $Str .= &Apache::lonhtmlcommon::row_title(
+ if ($showcredits) {
+ $Str .= &Apache::lonhtmlcommon::row_title(
+ &mt('Default role, section and credits'))
+ .&mt('Choose the role and/or section(s) and/or credits to assign to users without values specified in the uploaded file.');
+ } else {
+ $Str .= &Apache::lonhtmlcommon::row_title(
&mt('Default role and section'))
- .&mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file.');
+ .&mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file.');
+ }
} else {
$Str .= &Apache::lonhtmlcommon::row_title(
&mt('Default role and/or section(s)'))
@@ -917,7 +1020,8 @@ sub print_upload_manager_footer {
}
if (($context eq 'domain') || ($context eq 'author')) {
$Str .= ' ';
- my ($options,$cb_script,$coursepick) = &default_role_selector($context,1);
+ my ($options,$cb_script,$coursepick) =
+ &default_role_selector($context,1,'',$showcredits);
if ($context eq 'domain') {
$Str .= ''
.''.&mt('Domain Level').' '
@@ -934,8 +1038,13 @@ sub print_upload_manager_footer {
} else {
my ($cnum,$cdom) = &get_course_identity();
my $rowtitle = &mt('section');
- my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle,
- $permission,$context,'upload',$crstype);
+ my $defaultcredits;
+ if ($showcredits) {
+ $defaultcredits = &get_defaultcredits();
+ }
+ my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle,$permission,
+ $context,'upload',$crstype,$showcredits,
+ $defaultcredits);
$Str .= $secbox
.&Apache::lonhtmlcommon::row_closure();
my %lt;
@@ -958,7 +1067,9 @@ sub print_upload_manager_footer {
.&Apache::lonhtmlcommon::row_closure();
}
if ($context eq 'course' || $context eq 'domain') {
- $Str .= &forceid_change($context);
+ $Str .= &Apache::lonhtmlcommon::row_title(&mt('Student/Employee ID'))
+ .&forceid_change($context)
+ .&Apache::lonhtmlcommon::row_closure(1); # last row in pick_box
}
$Str .= &Apache::lonhtmlcommon::end_pick_box();
@@ -981,35 +1092,78 @@ sub print_upload_manager_footer {
return;
}
+sub get_defaultcredits {
+ my ($cdom,$cnum) = @_;
+
+ if ($cdom eq '' || $cnum eq '') {
+ return unless ($env{'request.course.id'});
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ }
+ return unless(($cdom =~ /^$match_domain$/) && ($cnum =~ /^$match_courseid$/));
+ my ($defaultcredits,$domdefcredits);
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
+ if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
+ my $instcode = $env{'course.'.$cdom.'_'.$cnum.'.internal.coursecode'};
+ if ($instcode) {
+ $domdefcredits = $domdefaults{'officialcredits'};
+ } elsif ($env{'course.'.$cdom.'_'.$cnum.'.internal.textbook'}) {
+ $domdefcredits = $domdefaults{'textbookcredits'};
+ } else {
+ $domdefcredits = $domdefaults{'unofficialcredits'};
+ }
+ } else {
+ return;
+ }
+
+ if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
+ $defaultcredits = $env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'};
+ } elsif (exists($env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'})) {
+ $defaultcredits = $env{'course.'.$cdom.'_'.$cnum.'.internal.defaultcredits'};
+ } else {
+ my %crsinfo =
+ &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1});
+ $defaultcredits = $crsinfo{'internal.defaultcredits'};
+ }
+ if ($defaultcredits eq '') {
+ $defaultcredits = $domdefcredits;
+ }
+ return $defaultcredits;
+}
+
sub forceid_change {
my ($context) = @_;
my $output =
- &Apache::lonhtmlcommon::row_title(&mt('Student/Employee ID'))
- .' '
- .&mt('Disable Student/Employee ID Safeguard and force change of conflicting IDs')
- .' '."\n"
- .&mt('(only do if you know what you are doing.)')."\n";
+ ' '
+ .&mt('Force change of existing ID')
+ .' '.&Apache::loncommon::help_open_topic('ForceIDChange')."\n";
if ($context eq 'domain') {
- $output .= ' '.
- &mt('Update student/employee ID in courses in which user is active/future student,[_1](if forcing change).',' ').
- ' '."\n";
+ $output .=
+ ' '
+ .' '
+ .&mt("Update ID in user's course(s).").' '."\n";
}
- $output .= &Apache::lonhtmlcommon::row_closure(1); # last row in pick_box
return $output;
}
###############################################################
###############################################################
sub print_upload_manager_form {
- my ($r,$context,$permission,$crstype) = @_;
+ my ($r,$context,$permission,$crstype,$showcredits) = @_;
my $firstLine;
my $datatoken;
if (!$env{'form.datatoken'}) {
$datatoken=&Apache::loncommon::upfile_store($r);
} else {
- $datatoken=$env{'form.datatoken'};
- &Apache::loncommon::load_tmp_file($r);
+ $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
+ if ($datatoken ne '') {
+ &Apache::loncommon::load_tmp_file($r,$datatoken);
+ }
+ }
+ if ($datatoken eq '') {
+ $r->print('
'.&mt('Error').': '.
+ &mt('Invalid datatoken').'
');
+ return 'missingdata';
}
my @records=&Apache::loncommon::upfile_record_sep();
if($env{'form.noFirstLine'}){
@@ -1035,7 +1189,9 @@ sub print_upload_manager_form {
'domain_choice' => 'scalar',
'inststatus_choice' => 'scalar',
};
- my $defdom = $env{'request.role.domain'};
+ if ($showcredits) {
+ $col_setting_names->{'credits_choice'} = 'scalar';
+ }
if ($context eq 'course') {
&Apache::loncommon::restore_course_settings('enrollment_upload',
$col_setting_names);
@@ -1043,6 +1199,7 @@ sub print_upload_manager_form {
&Apache::loncommon::restore_settings($context,'user_upload',
$col_setting_names);
}
+ my $defdom = $env{'request.role.domain'};
#
# Determine kerberos parameters as appropriate
my ($krbdef,$krbdefdom) =
@@ -1068,6 +1225,10 @@ sub print_upload_manager_form {
['role',&mt('Role'), $env{'form.role_choice'}],
['domain',&mt('Domain'), $env{'form.domain_choice'}],
['inststatus',&mt('Affiliation'), $env{'form.inststatus_choice'}]);
+ if ($showcredits) {
+ push(@field,
+ ['credits',&mt('Student Credits'), $env{'form.credits_choice'}]);
+ }
if ($env{'form.upfile_associate'} eq 'reverse') {
&Apache::loncommon::csv_print_samples($r,\@records);
$i=&Apache::loncommon::csv_print_select_table($r,\@records,
@@ -1084,9 +1245,9 @@ sub print_upload_manager_form {
$keyfields=join(',',sort(keys(%sone)));
}
}
- $r->print(' ');
&print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
- $context,$permission,$crstype);
+ $context,$permission,$crstype,$showcredits);
+ return 'ok';
}
sub setup_date_selectors {
@@ -1243,7 +1404,7 @@ sub make_dates_default {
}
sub default_role_selector {
- my ($context,$checkpriv,$crstype) = @_;
+ my ($context,$checkpriv,$crstype,$showcredits) = @_;
my %customroles;
my ($options,$coursepick,$cb_jscript);
if ($context ne 'author') {
@@ -1255,6 +1416,7 @@ sub default_role_selector {
'grs' => "Section",
'exs' => "Existing sections",
'new' => "New section",
+ 'crd' => "Credits",
);
$options = ''."\n".
' '.&mt('Please select').' '."\n";
@@ -1274,12 +1436,18 @@ sub default_role_selector {
}
my $courseform = &Apache::loncommon::selectcourse_link
('studentform','dccourse','dcdomain','coursedesc',"$env{'request.role.domain'}",undef,'Course/Community');
+ my ($credit_elem,$creditsinput);
+ if ($showcredits) {
+ $credit_elem = 'credits';
+ $creditsinput = ' ';
+ }
$cb_jscript =
- &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'currsec','studentform','courserole','Course/Community');
+ &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'currsec','studentform','courserole','Course/Community',$credit_elem);
$coursepick = &Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row().
''.$courseform.' '.$lt{'rol'}.' '.
''.$lt{'grs'}.' '.
+ ''.$lt{'crd'}.' '.
&Apache::loncommon::end_data_table_header_row().
&Apache::loncommon::start_data_table_row()."\n".
' '."\n".
@@ -1287,9 +1455,9 @@ sub default_role_selector {
&default_course_roles($context,$checkpriv,'Course',%customroles)."\n".
' '.
''.
- ''.
+ ' '.
$lt{'exs'}.''.
- ' <--'.&mt('Pick course first').
+ ' <--'.&mt('Pick course first').
' '.
' '.
''.$lt{'new'}.' '.
@@ -1301,7 +1469,7 @@ sub default_role_selector {
' '.
' '.
' '.
- '
'.
+ ''.$creditsinput.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table()."\n";
}
@@ -1340,6 +1508,14 @@ sub construction_space_roles {
foreach my $role (@allroles) {
if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) {
push(@roles,$role);
+ } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) {
+ my ($audom,$auname) = ($1,$2);
+ if (($role eq 'ca') || ($role eq 'aa')) {
+ if ((&Apache::lonnet::allowed('v'.$role,,$audom.'/'.$auname)) &&
+ ($env{"environment.internal.manager./$audom/$auname"})) {
+ push(@roles,$role);
+ }
+ }
}
}
return @roles;
@@ -1421,9 +1597,10 @@ sub curr_role_permissions {
# ======================================================= Existing Custom Roles
sub my_custom_roles {
- my ($crstype) = @_;
+ my ($crstype,$udom,$uname) = @_;
my %returnhash=();
- my %rolehash=&Apache::lonnet::dump('roles');
+ my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
+ my %rolehash=&Apache::lonnet::dump('roles',$udom,$uname);
foreach my $key (keys(%rolehash)) {
if ($key=~/^rolesdef\_(\w+)$/) {
if ($crstype eq 'Community') {
@@ -1437,16 +1614,35 @@ sub my_custom_roles {
sub print_userlist {
my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,
- $idlist,$idlist_titles) = @_;
+ $idlist,$idlist_titles,$showcredits) = @_;
my $format = $env{'form.output'};
if (! exists($env{'form.sortby'})) {
$env{'form.sortby'} = 'username';
}
+ my ($showstart,$showend);
+ if (($env{'form.Status'} eq '') && ($env{'form.phase'} eq '') &&
+ ($env{'form.showrole'} eq '') && ($context eq 'course') &&
+ ($env{'request.course.id'} ne '') &&
+ ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'} ne '')) {
+ my $now = time;
+ my $startaccess = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'};
+ my $endaccess = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'};
+ if (($startaccess) && ($startaccess > $now)) {
+ $env{'form.Status'} = 'Future';
+ $showstart = 1;
+ }
+ if (($endaccess ne '') && ($endaccess != 0) && ($endaccess < $now)) {
+ $env{'form.Status'} = 'Expired';
+ undef($showstart);
+ $showend = 1;
+ }
+ }
if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
$env{'form.Status'} = 'Active';
}
+ my $onchange = "javascript:updateCols('Status');";
my $status_select = &Apache::lonhtmlcommon::StatusOptions
- ($env{'form.Status'});
+ ($env{'form.Status'},undef,undef,$onchange);
if ($env{'form.showrole'} eq '') {
if ($context eq 'course') {
@@ -1471,20 +1667,16 @@ sub print_userlist {
@statuses = ('future');
}
-# if ($context eq 'course') {
-# $r->print(&display_adv_courseroles());
-# }
- #
# Interface output
$r->print('');
return;
}
if (!(($context eq 'domain') &&
(($env{'form.roletype'} eq 'course') || ($env{'form.roletype'} eq 'community')))) {
- $r->print(
- "\n\n"
- .''
- .&list_submit_button(&mt('Update Display'))
- ."
\n"
- );
+ $r->print(' '.
+ &list_submit_button(&mt('Update Display'))."\n");
+ }
+
+ my @cols = &infocolumns($context,$mode,$showcredits);
+ if (!@cols) {
+ $r->print(''.
+ &mt('No user information selected for display.').' '.
+ ' '."\n");
+ return;
}
my ($indexhash,$keylist) = &make_keylist_array();
- my (%userlist,%userinfo,$clearcoursepick);
+ my (%userlist,%userinfo,$clearcoursepick,$needauthorquota,$needauthorusage);
if (($context eq 'domain') &&
($env{'form.roletype'} eq 'course') ||
($env{'form.roletype'} eq 'community')) {
@@ -1548,12 +1747,10 @@ sub print_userlist {
&Apache::lonhtmlcommon::course_selection($formname,$numcodes,
$codetitles,$idlist,$idlist_titles,$crstype,
\@standardnames);
- $r->print(''.&Apache::lonhtmlcommon::start_pick_box()."\n".
- &Apache::lonhtmlcommon::start_pick_box()."\n".
- &Apache::lonhtmlcommon::row_title($title,'LC_oddrow_value')."\n".
+ $r->print('
'.
+ '
'.$title.' '."\n".
$courseform."\n".
- &Apache::lonhtmlcommon::row_closure(1).
- &Apache::lonhtmlcommon::end_pick_box().''.
+ ' '.
' '.
&list_submit_button(&mt('Update Display')).
"\n".'
'.$warning.' '."\n");
@@ -1563,10 +1760,10 @@ sub print_userlist {
$clearcoursepick = 1;
}
if (($env{'form.coursepick'}) && (!$clearcoursepick)) {
- $r->print(' '.&mt('Searching').' ... ');
+ $r->print(' '.&mt('Searching ...').' ');
}
} else {
- $r->print(' '.&mt('Searching').' ... ');
+ $r->print(''.&mt('Searching ...').'
');
}
$r->rflush();
if ($context eq 'course') {
@@ -1593,14 +1790,39 @@ sub print_userlist {
} else {
my (%cstr_roles,%dom_roles);
if ($context eq 'author') {
- # List co-authors and assistant co-authors
my @possroles = &roles_by_context($context);
- %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
- \@statuses,\@possroles);
- &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
- \%cstr_roles,$permission);
+ my @allowedroles;
+ # List co-authors and assistant co-authors
+ my ($auname,$audom);
+ if ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) {
+ ($audom,$auname) = ($1,$2);
+ foreach my $role (@possroles) {
+ if ((&Apache::lonnet::allowed('v'.$role,"$audom/$auname")) ||
+ (&Apache::lonnet::allowed('c'.$role,"$audom/$auname"))) {
+ push(@allowedroles,$role);
+ }
+ }
+ } elsif ($env{'request.role'} =~ m{^au\./($match_domain)/}) {
+ if ($1 eq $env{'user.domain'}) {
+ $auname = $env{'user.name'};
+ $audom = $env{'user.domain'};
+ }
+ @allowedroles = @possroles;
+ }
+ if (($auname ne '') && ($audom ne '')) {
+ %cstr_roles = &Apache::lonnet::get_my_roles($auname,$audom,undef,
+ \@statuses,\@allowedroles);
+ &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
+ \%cstr_roles,$permission);
+ }
} elsif ($context eq 'domain') {
if ($env{'form.roletype'} eq 'domain') {
+ if (grep(/^authorusage$/,@cols)) {
+ $needauthorusage = 1;
+ }
+ if (grep(/^authorquota$/,@cols)) {
+ $needauthorquota = 1;
+ }
%dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'});
foreach my $key (keys(%dom_roles)) {
if (ref($dom_roles{$key}) eq 'HASH') {
@@ -1686,33 +1908,37 @@ sub print_userlist {
}
}
if (keys(%userlist) == 0) {
+ my $msg = '';
if ($context eq 'author') {
- $r->print(&mt('There are no co-authors to display.')."\n");
+ $msg = &mt('There are no co-authors to display.');
} elsif ($context eq 'domain') {
if ($env{'form.roletype'} eq 'domain') {
- $r->print(&mt('There are no users with domain roles to display.')."\n");
+ $msg = &mt('There are no users with domain roles to display.');
} elsif ($env{'form.roletype'} eq 'author') {
- $r->print(&mt('There are no authors or co-authors to display.')."\n");
+ $msg = &mt('There are no authors or co-authors to display.');
} elsif ($env{'form.roletype'} eq 'course') {
- $r->print(&mt('There are no course users to display')."\n");
+ $msg = &mt('There are no course users to display');
} elsif ($env{'form.roletype'} eq 'community') {
- $r->print(&mt('There are no community users to display')."\n");
+ $msg = &mt('There are no community users to display');
}
} elsif ($context eq 'course') {
$r->print(&mt('There are no course users to display.')."\n");
}
+ $r->print(''.$msg.'
'."\n") if $msg;
} else {
# Print out the available choices
my $usercount;
if ($env{'form.action'} eq 'modifystudent') {
($usercount) = &show_users_list($r,$context,'view',$permission,
- $env{'form.Status'},\%userlist,$keylist);
+ $env{'form.Status'},\%userlist,$keylist,'',
+ $showcredits);
} else {
($usercount) = &show_users_list($r,$context,$env{'form.output'},
- $permission,$env{'form.Status'},\%userlist,$keylist);
+ $permission,$env{'form.Status'},\%userlist,
+ $keylist,'',$showcredits,$needauthorquota,$needauthorusage);
}
if (!$usercount) {
- $r->print(''
+ $r->print(''
.&mt('There are no users matching the search criteria.')
.' '
);
@@ -1720,6 +1946,7 @@ sub print_userlist {
}
$r->print(' ');
+ return;
}
sub role_filter {
@@ -1732,11 +1959,11 @@ sub role_filter {
my ($role_select);
if ($context eq 'domain') {
$role_select = &domain_roles_select();
- $output = ''
+ $output = ''
.&mt('Role Type: [_1]',$role_select)
- .' ';
+ .' ';
} else {
- $role_select = ''."\n".
+ $role_select = ''."\n".
''.
&mt('Any role').' ';
my ($roletype,$crstype);
@@ -1763,9 +1990,9 @@ sub role_filter {
$role_select .= ''.$plrole.' ';
}
$role_select .= ' ';
- $output = ''
+ $output = ''
.&mt('Role: [_1]',$role_select)
- .' ';
+ .'';
}
return $output;
}
@@ -1828,11 +2055,219 @@ sub section_group_filter {
return $output;
}
+sub infocolumns {
+ my ($context,$mode,$showcredits) = @_;
+ my @cols;
+ if (($mode eq 'pickauthor') || ($mode eq 'autoenroll')) {
+ @cols = &get_cols_array($context,$mode,$showcredits);
+ } else {
+ my @posscols = &get_cols_array($context,$mode,$showcredits);
+ if ($env{'form.phase'} ne '') {
+ my @checkedcols = &Apache::loncommon::get_env_multiple('form.showcol');
+ foreach my $col (@checkedcols) {
+ if (grep(/^$col$/,@posscols)) {
+ push(@cols,$col);
+ }
+ }
+ } else {
+ @cols = @posscols;
+ }
+ }
+ return @cols;
+}
+
+sub get_cols_array {
+ my ($context,$mode,$showcredits) = @_;
+ my @cols;
+ if ($mode eq 'pickauthor') {
+ @cols = ('username','fullname','status','email');
+ } else {
+ @cols = ('username','domain','id','fullname');
+ if ($context eq 'course') {
+ push(@cols,'section');
+ }
+ push(@cols,('start','end','role'));
+ unless (($mode eq 'autoenroll') && ($env{'form.Status'} ne 'Any')) {
+ push(@cols,'status');
+ }
+ if ($context eq 'course') {
+ push(@cols,'groups');
+ }
+ push(@cols,'email');
+ if (($context eq 'course') && ($mode ne 'autoenroll')) {
+ if ($showcredits) {
+ push(@cols,'credits');
+ }
+ push(@cols,'lastlogin','clicker');
+ }
+ if (($context eq 'course') && ($mode ne 'autoenroll') &&
+ ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) {
+ push(@cols,'photo');
+ }
+ if ($context eq 'domain') {
+ push(@cols,('authorusage','authorquota','extent'));
+ }
+ if ($context eq 'author') {
+ push(@cols,'manager');
+ }
+ }
+ return @cols;
+}
+
+sub column_checkboxes {
+ my ($context,$mode,$formname,$showcredits,$showstart,$showend) = @_;
+ my @cols = &get_cols_array($context,$mode,$showcredits);
+ my @showncols = &Apache::loncommon::get_env_multiple('form.showcol');
+ my (%disabledchk,%unchecked);
+ if ($env{'form.phase'} eq '') {
+ $disabledchk{'status'} = 1;
+ if ($context eq 'course') {
+ $disabledchk{'role'} = 1;
+ $unchecked{'photo'} = 1;
+ $unchecked{'clicker'} = 1;
+ if ($showcredits) {
+ $unchecked{'credits'} = 1;
+ }
+ my %curr_groups = &Apache::longroup::coursegroups();
+ unless (keys(%curr_groups)) {
+ $unchecked{'groups'} = 1;
+ }
+ } elsif ($context eq 'domain') {
+ $unchecked{'extent'} = 1;
+ }
+ if ($showstart) {
+ $unchecked{'lastlogin'} = 1;
+ } else {
+ $unchecked{'start'} = 1;
+ }
+ unless ($showend) {
+ $unchecked{'end'} = 1;
+ }
+ } else {
+ if ($env{'form.Status'} ne 'Any') {
+ $disabledchk{'status'} = 1;
+ }
+ if (($env{'form.showrole'} ne 'Any') && ($env{'form.showrole'} ne 'cr')) {
+ $disabledchk{'role'} = 1;
+ }
+ if ($context eq 'domain') {
+ if (($env{'form.roletype'} eq 'course') ||
+ ($env{'form.roletype'} eq 'community')) {
+ $disabledchk{'status'} = 1;
+ $disabledchk{'authorusage'} = 1;
+ $disabledchk{'authorquota'} = 1;
+ } elsif ($env{'form.roletype'} eq 'domain') {
+ $disabledchk{'extent'} = 1;
+ }
+ } elsif ($context eq 'author') {
+ if (($env{'form.Status'} eq 'Expired') ||
+ ($env{'form.showrole'} eq 'aa')) {
+ $disabledchk{'manager'} = 1;
+ }
+ }
+ }
+ my $numposs = scalar(@cols);
+ my $numinrow = 7;
+ my %lt = &get_column_names($context);
+ my $output = ''.&mt('Information to show').' '."\n".''.
+ ' '.
+ (' 'x3).
+ ' '.
+ ' ';
+ return $output;
+}
+
sub list_submit_button {
my ($text) = @_;
return ' ';
}
+sub get_column_names {
+ my ($context) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ 'username' => "username",
+ 'domain' => "domain",
+ 'id' => 'ID',
+ 'fullname' => "name",
+ 'section' => "section",
+ 'groups' => "active groups",
+ 'start' => "start date",
+ 'end' => "end date",
+ 'status' => "status",
+ 'role' => "role",
+ 'credits' => "credits",
+ 'type' => "enroll type/action",
+ 'email' => "e-mail address",
+ 'photo' => "photo",
+ 'lastlogin' => "last login",
+ 'extent' => "extent",
+ 'authorusage' => "disk usage (%)",
+ 'authorquota' => "disk quota (MB)",
+ 'ca' => "check all",
+ 'ua' => "uncheck all",
+ 'clicker' => "clicker-ID",
+ 'manager' => "co-author manager",
+ );
+ if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
+ $lt{'extent'} = &mt('course(s): description, section(s), status');
+ } elsif ($context eq 'domain' && $env{'form.roletype'} eq 'community') {
+ $lt{'extent'} = &mt('community(s): description, section(s), status');
+ } elsif (($context eq 'author') ||
+ ($context eq 'domain' && $env{'form.roletype'} eq 'author')) {
+ $lt{'extent'} = &mt('author');
+ }
+ return %lt;
+}
+
sub gather_userinfo {
my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_;
my $viewablesec;
@@ -1845,6 +2280,7 @@ sub gather_userinfo {
($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
split(/:/,$item);
($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item});
+ next if (($userdata{'username'} eq '') && ($userdata{'domain'} eq ''));
&build_user_record($context,\%userdata,$userinfo,$indexhash,
$item,$userlist);
} elsif ($context eq 'course') {
@@ -1950,7 +2386,6 @@ sub build_user_record {
sub courses_selector {
my ($cdom,$formname) = @_;
- my %coursecodes = ();
my %codes = ();
my @codetitles = ();
my %cat_titles = ();
@@ -1963,14 +2398,15 @@ sub courses_selector {
my $jscript = '';
my $totcodes = 0;
- $totcodes =
- &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,
- $cdom,$totcodes);
- if ($totcodes > 0) {
- $format_reply =
- &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,
- \%codes,\@codetitles,\%cat_titles,\%cat_order);
- if ($format_reply eq 'ok') {
+ my $instcats = &Apache::lonnet::get_dom_instcats($cdom);
+ if (ref($instcats) eq 'HASH') {
+ if ((ref($instcats->{'codetitles'}) eq 'ARRAY') && (ref($instcats->{'codes'}) eq 'HASH') &&
+ (ref($instcats->{'cat_titles'}) eq 'HASH') && (ref($instcats->{'cat_order'}) eq 'HASH')) {
+ %codes = %{$instcats->{'codes'}};
+ @codetitles = @{$instcats->{'codetitles'}};
+ %cat_titles = %{$instcats->{'cat_titles'}};
+ %cat_order = %{$instcats->{'cat_order'}};
+ $totcodes = scalar(keys(%codes));
my $numtypes = @codetitles;
&Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);
@@ -1978,7 +2414,7 @@ sub courses_selector {
my $allidlist = $idlist{$codetitles[0]};
$jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist);
$jscript .= $scripttext;
- $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,@codetitles);
+ $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,\@codetitles);
}
}
my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
@@ -2007,7 +2443,8 @@ function setCourseCat(formname) {
}
courseSet('$codetitles[1]');
for (var j=0; j '.&Apache::loncommon::start_data_table();
- foreach my $role (sort(keys(%coursepersonnel))) {
- next if ($role =~ /^\s*$/);
- $output .= &Apache::loncommon::start_data_table_row().
- ''.$role.' ';
- foreach my $user (split(',',$coursepersonnel{$role})) {
- my ($puname,$pudom)=split(':',$user);
- $output .= ' '.&Apache::loncommon::aboutmewrapper(
- &Apache::loncommon::plainname($puname,$pudom),
- $puname,$pudom);
- }
- $output .= ' '.&Apache::loncommon::end_data_table_row();
- }
- $output .= &Apache::loncommon::end_data_table();
-}
-
sub make_keylist_array {
my ($index,$keylist);
$index->{'domain'} = &Apache::loncoursedata::CL_SDOM();
@@ -2123,6 +2537,11 @@ sub make_keylist_array {
$index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();
$index->{'photo'} = &Apache::loncoursedata::CL_PHOTO();
$index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL();
+ $index->{'credits'} = &Apache::loncoursedata::CL_CREDITS();
+ $index->{'instsec'} = &Apache::loncoursedata::CL_INSTSEC();
+ $index->{'authorquota'} = &Apache::loncoursedata::CL_AUTHORQUOTA();
+ $index->{'authorusage'} = &Apache::loncoursedata::CL_AUTHORUSAGE();
+ $index->{'manager'} = &Apache::loncoursedata::CL_CAMANAGER();
foreach my $key (keys(%{$index})) {
$keylist->[$index->{$key}] = $key;
}
@@ -2171,10 +2590,12 @@ sub process_date_info {
}
sub show_users_list {
- my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_;
+ my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname,
+ $showcredits,$needauthorquota,$needauthorusage)=@_;
if ($formname eq '') {
$formname = 'studentform';
}
+ my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
#
# Variables for excel output
my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
@@ -2186,34 +2607,39 @@ sub show_users_list {
my @sortable = ('username','domain','id','fullname','start','end','email','role');
if ($context eq 'course') {
push(@sortable,('section','groups','type'));
+ if ($showcredits) {
+ push(@sortable,'credits');
+ }
} else {
push(@sortable,'extent');
+ if (($context eq 'domain') && ($env{'form.roletype'} eq 'domain') &&
+ (($env{'form.showrole'} eq 'Any') || ($env{'form.showrole'} eq 'au'))) {
+ push(@sortable,('authorusage','authorquota'));
+ }
+ if ($context eq 'author') {
+ push(@sortable,'manager');
+ }
}
if ($mode eq 'pickauthor') {
@sortable = ('username','fullname','email','status');
}
- if (!grep(/^\Q$sortby\E$/,@sortable)) {
+ my %is_sortable;
+ map { $is_sortable{$_} = 1; } @sortable;
+ unless ($is_sortable{$sortby}) {
$sortby = 'username';
}
my $setting = $env{'form.roletype'};
- my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype);
+ my ($cid,$cdom,$cnum,$classgroups,$crstype,$defaultcredits);
if ($context eq 'course') {
$cid = $env{'request.course.id'};
$crstype = &Apache::loncommon::course_type();
($cnum,$cdom) = &get_course_identity($cid);
+ $defaultcredits = $env{'course.'.$cid.'.internal.defaultcredits'};
($classgroups) = &Apache::loncoursedata::get_group_memberships(
$userlist,$keylist,$cdom,$cnum);
if ($mode eq 'autoenroll') {
$env{'form.showrole'} = 'st';
} else {
- if (! exists($env{'form.displayphotos'})) {
- $env{'form.displayphotos'} = 'off';
- }
- $displayphotos = $env{'form.displayphotos'};
- if (! exists($env{'form.displayclickers'})) {
- $env{'form.displayclickers'} = 'off';
- }
- $displayclickers = $env{'form.displayclickers'};
if ($env{'course.'.$cid.'.internal.showphoto'}) {
$r->print('
');
}
- $r->print(<
-
-END
}
} elsif ($context eq 'domain') {
if ($setting eq 'community') {
@@ -2242,27 +2664,33 @@ END
}
}
if ($mode ne 'autoenroll' && $mode ne 'pickauthor') {
- my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode);
my $verify_action_js = &bulkaction_javascript($formname);
$r->print(<
// print(<
END
-
- my %lt=&Apache::lonlocal::texthash(
- 'username' => "username",
- 'domain' => "domain",
- 'id' => 'ID',
- 'fullname' => "name",
- 'section' => "section",
- 'groups' => "active groups",
- 'start' => "start date",
- 'end' => "end date",
- 'status' => "status",
- 'role' => "role",
- 'type' => "enroll type/action",
- 'email' => "e-mail address",
- 'photo' => "photo",
- 'lastlogin' => "last login"
- 'extent' => "extent",
+ my @cols = &infocolumns($context,$mode,$showcredits);
+ my %coltxt = &get_column_names($context);
+ my %acttxt = &Apache::lonlocal::texthash(
'pr' => "Proceed",
- 'ca' => "check all",
- 'ua' => "uncheck all",
'ac' => "Action to take for selected users",
'link' => "Behavior of clickable username link for each user",
'aboutme' => "Display a user's personal information page",
'owin' => "Open in a new window",
'modify' => "Modify a user's information",
'track' => "View a user's recent activity",
- 'clicker' => "Clicker-ID",
+ 'activity' => "View a user's access log",
);
- if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
- $lt{'extent'} = &mt('Course(s): description, section(s), status');
- } elsif ($context eq 'domain' && $env{'form.roletype'} eq 'community') {
- $lt{'extent'} = &mt('Communities: description, section(s), status');
- } elsif ($context eq 'author') {
- $lt{'extent'} = &mt('Author');
- }
- my @cols;
- if ($mode eq 'pickauthor') {
- @cols = ('username','fullname','status','email');
- } else {
- @cols = ('username','domain','id','fullname');
- if ($context eq 'course') {
- push(@cols,'section');
- }
- if (!($context eq 'domain' && ($env{'form.roletype'} eq 'course')
- && ($env{'form.roletype'} eq 'community'))) {
- push(@cols,('start','end'));
- }
- if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') {
- push(@cols,'role');
- }
- if ($context eq 'domain' && ($env{'form.roletype'} eq 'author' ||
- $env{'form.roletype'} eq 'course' ||
- $env{'form.roletype'} eq 'community')) {
- push (@cols,'extent');
- }
- if (($statusmode eq 'Any') &&
- (!($context eq 'domain' && (($env{'form.roletype'} eq 'course')
- || ($env{'form.roletype'} eq 'community'))))) {
- push(@cols,'status');
- }
- if ($context eq 'course') {
- push(@cols,'groups');
- }
- push(@cols,'email');
- if ($context eq 'course') {
- push(@cols,'lastlogin');
- }
- }
-
+ my %lt = (%coltxt,%acttxt);
my $rolefilter = $env{'form.showrole'};
if ($env{'form.showrole'} eq 'cr') {
$rolefilter = &mt('custom');
@@ -2386,7 +2758,7 @@ END
if ($mode ne 'autoenroll') {
$results_description = &results_header_row($rolefilter,$statusmode,
$context,$permission,$mode,$crstype);
- $r->print(''.$results_description.' ');
+ $r->print(''.$results_description.' ');
}
my ($output,$actionselect,%canchange,%canchangesec);
if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
@@ -2448,6 +2820,12 @@ END
if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
$canchangesec{$role} = $env{'request.course.sec'};
}
+ } elsif ((($role eq 'co') && ($crstype eq 'Community')) ||
+ (($role eq 'cc') && ($crstype eq 'Course'))) {
+ if (&is_courseowner($env{'request.course.id'},
+ $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) {
+ $canchange{$role} = 1;
+ }
}
}
}
@@ -2458,12 +2836,17 @@ END
if ($permission->{'cusr'}) {
unshift (@linkdests,'modify');
}
- if (&Apache::lonnet::allowed('vsa', $env{'request.course.id'}) ||
- &Apache::lonnet::allowed('vsa', $env{'request.course.id'}.'/'.
- $env{'request.course.sec'})) {
- push(@linkdests,'track');
+ if ($context eq 'course') {
+ if (&Apache::lonnet::allowed('vsa', $env{'request.course.id'}) ||
+ &Apache::lonnet::allowed('vsa', $env{'request.course.id'}.'/'.
+ $env{'request.course.sec'})) {
+ push(@linkdests,'track');
+ }
+ } elsif ($context eq 'domain') {
+ if (&Apache::lonnet::allowed('vac',$env{'request.role.domain'})) {
+ push(@linkdests,'activity');
+ }
}
-
$output .= '';
my $usernamelink = $env{'form.usernamelink'};
if ($usernamelink eq '') {
@@ -2480,9 +2863,13 @@ END
if ($env{'form.userwin'}) {
$checkwin = ' checked="checked"';
}
- $output .= ' '.$lt{'owin'}.' ';
+ $output .=
+ ''
+ .''
+ .' '.$lt{'owin'}
+ .' ';
}
- $output .= "\n".''."\n".
+ $output .= "\n".'
'."\n".
&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row();
if ($mode eq 'autoenroll') {
@@ -2492,49 +2879,19 @@ END
} else {
$output .= "\n".' '."\n";
if ($actionselect) {
- $output .= ''.&mt('Select').' '."\n";
+ $output .= ''.&mt('Select').' '."\n";
}
}
foreach my $item (@cols) {
- $output .= "$lt{$item} \n";
- }
- my %role_types = &role_type_names();
- if ($context eq 'course' && $mode ne 'autoenroll') {
- if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
- # Clicker display on or off?
- my %clicker_options = (
- 'on' => 'Show',
- 'off' => 'Hide',
- );
- my $clickerchg = 'on';
- if ($displayclickers eq 'on') {
- $clickerchg = 'off';
- }
- $output .= ' '."\n".' '
- .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id'
- ,''
- ,' ')
- ."\n".' '."\n";
-
- # Photo display on or off?
- if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
- my %photo_options = &Apache::lonlocal::texthash(
- 'on' => 'Show',
- 'off' => 'Hide',
- );
- my $photochg = 'on';
- if ($displayphotos eq 'on') {
- $photochg = 'off';
- }
- $output .= ' '."\n".' '.
- ''.
- $photo_options{$photochg}.' '.$lt{'photo'}."\n".
- ' '."\n";
- }
+ $output .= '';
+ if ($is_sortable{$item}) {
+ $output .= "$lt{$item} ▼ ";
+ } else {
+ $output .= $lt{$item};
}
+ $output .= " \n";
}
+ my %role_types = &role_type_names();
$output .= &Apache::loncommon::end_data_table_header_row();
# Done with the HTML header line
} elsif ($mode eq 'csv') {
@@ -2555,14 +2912,12 @@ END
$CSVfile = undef;
}
#
- push @cols,'clicker';
# Write headers and data to file
print $CSVfile '"'.$results_description.'"'."\n";
print $CSVfile '"'.join('","',map {
&Apache::loncommon::csv_translate($lt{$_})
} (@cols))."\"\n";
} elsif ($mode eq 'excel') {
- push @cols,'clicker';
# Create the excel spreadsheet
($excel_workbook,$excel_filename,$format) =
&Apache::loncommon::create_workbook($r);
@@ -2581,6 +2936,7 @@ END
foreach my $idx (@$keylist) {
$index{$idx} = $i++;
}
+ my $now = time;
my $usercount = 0;
my ($secfilter,$grpfilter);
if ($context eq 'course') {
@@ -2598,10 +2954,21 @@ END
Future => 'Future',
Expired => 'Expired',
);
- # If this is for a single course get last course "log-in".
- my %crslogins;
+ my (%crslogins,%camanagers);
if ($context eq 'course') {
+ # If this is for a single course get last course "log-in".
%crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum);
+ } elsif ($context eq 'author') {
+ my $authormanagers;
+ if ($env{'request.role'} =~ m{^(?:ca|aa)\./($match_domain)/($match_username)$}) {
+ my %envhash = &Apache::lonnet::userenvironment($1,$2,'authormanagers');
+ $authormanagers = $envhash{'authormanagers'};
+ } else {
+ $authormanagers = $env{'environment.authormanagers'};
+ }
+ if ($authormanagers ne '') {
+ map { $camanagers{$_.':ca'} = 1; } split(/,/,$authormanagers);
+ }
}
# Get groups, role, permanent e-mail so we can sort on them if
# necessary.
@@ -2686,7 +3053,7 @@ END
}
}
if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
- if (($displayphotos eq 'on') && ($role eq 'st')) {
+ if ((grep/^photo$/,@cols) && ($role eq 'st')) {
$userlist->{$user}->[$index{'photo'}] =
&Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg');
$userlist->{$user}->[$index{'thumbnail'}] =
@@ -2694,12 +3061,47 @@ END
'gif','thumbnail');
}
}
+ if (($role eq 'st') && ($defaultcredits)) {
+ if ($userlist->{$user}->[$index{'credits'}] eq '') {
+ $userlist->{$user}->[$index{'credits'}] = $defaultcredits;
+ }
+ }
+ }
+ }
+ if ($context eq 'author') {
+ if (($camanagers{$user}) &&
+ ((!defined($userlist->{$user}->[$index{'end'}])) ||
+ ($userlist->{$user}->[$index{'end'}] == 0) ||
+ ($userlist->{$user}->[$index{'end'}] > $now))) {
+ $userlist->{$user}->[$index{'manager'}] = &mt('Yes');
+ } else {
+ $userlist->{$user}->[$index{'manager'}] = &mt('No');
}
}
my %emails = &Apache::loncommon::getemails($uname,$udom);
if ($emails{'permanentemail'} =~ /\S/) {
$userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'};
}
+ if (($context eq 'domain') && ($env{'form.roletype'} eq 'domain') &&
+ ($role eq 'au')) {
+ my ($disk_quota,$current_disk_usage,$percent);
+ if (($needauthorusage) || ($needauthorquota)) {
+ $disk_quota = &Apache::loncommon::get_user_quota($uname,$udom,'author');
+ }
+ if ($needauthorusage) {
+ $current_disk_usage =
+ &Apache::lonnet::diskusage($udom,$uname,"$londocroot/priv/$udom/$uname");
+ if ($disk_quota == 0) {
+ $percent = 100.0;
+ } else {
+ $percent = $current_disk_usage/(10 * $disk_quota);
+ }
+ $userlist->{$user}->[$index{'authorusage'}] = sprintf("%.0f",$percent);
+ }
+ if ($needauthorquota) {
+ $userlist->{$user}->[$index{'authorquota'}] = sprintf("%.2f",$disk_quota);
+ }
+ }
$usercount ++;
}
my $autocount = 0;
@@ -2720,13 +3122,27 @@ END
my $index = $index{$sortby};
my $second = $index{'username'};
my $third = $index{'domain'};
- my @sorted_users = sort {
- lc($userlist->{$a}->[$index]) cmp lc($userlist->{$b}->[$index])
- ||
- lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
- lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
- } (keys(%$userlist));
+ my @sorted_users;
+ if (($sortby eq 'authorquota') || ($sortby eq 'authorusage')) {
+ @sorted_users = sort {
+ $userlist->{$b}->[$index] <=> $userlist->{$a}->[$index] ||
+ lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
+ lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
+ } (keys(%$userlist));
+ } else {
+ @sorted_users = sort {
+ lc($userlist->{$a}->[$index]) cmp lc($userlist->{$b}->[$index]) ||
+ lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
+ lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
+ } (keys(%$userlist));
+ }
my $rowcount = 0;
+ my $disabled;
+ if ($mode eq 'autoenroll') {
+ unless ($permission->{'cusr'}) {
+ $disabled = ' disabled="disabled"';
+ }
+ }
foreach my $user (@sorted_users) {
my %in;
my $sdata = $userlist->{$user};
@@ -2736,7 +3152,7 @@ END
}
my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
if ($clickers!~/\w/) { $clickers='-'; }
- $in{'clicker'} = $clickers;
+ $in{'clicker'} = $clickers;
my $role = $in{'role'};
$in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype);
unless ($mode eq 'excel') {
@@ -2763,16 +3179,16 @@ END
if ($mode eq 'autoenroll') {
my $cellentry;
if ($in{'type'} eq 'auto') {
- $cellentry = ''.&mt('auto').' Change ';
+ $cellentry = ''.&mt('auto').' '.&mt('Change').' ';
$autocount ++;
} else {
- $cellentry = ''.&mt('manual').' Change';
+ $cellentry = '';
@@ -2801,17 +3217,35 @@ END
if ($showcheckbox) {
$checkval = $user;
if ($context eq 'course') {
- if ($role eq 'st') {
- $checkval .= ':st';
- }
- $checkval .= ':'.$in{'section'};
- if ($role eq 'st') {
- $checkval .= ':'.$in{'type'}.':'.
- $in{'lockedtype'};
+ if (($role eq 'co' || $role eq 'cc') &&
+ ($user =~ /^\Q$env{'user.name'}:$env{'user.domain'}:$role\E/)) {
+ $showcheckbox = 0;
+ } else {
+ if ($role eq 'st') {
+ $checkval .= ':st';
+ }
+ $checkval .= ':'.$in{'section'};
+ if ($role eq 'st') {
+ $checkval .= ':'.$in{'type'}.':'.
+ $in{'lockedtype'}.':'.
+ $in{'credits'}.':'.
+ &escape($in{'instsec'});
+ }
+ }
+ }
+ if ($showcheckbox) {
+ $r->print(' ');
+ foreach my $item ('start','end') {
+ $r->print(' ');
}
+ $r->print(' ');
+ } else {
+ $r->print(' ');
}
- $r->print(' ');
} else {
$r->print(' ');
}
@@ -2822,35 +3256,36 @@ END
foreach my $item (@cols) {
if ($item eq 'username') {
$r->print(''.&print_username_link($mode,\%in).' ');
- } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) {
- $r->print(''.$in{$item}.' '."\n");
} elsif ($item eq 'status') {
my $showitem = $in{$item};
if (defined($ltstatus{$in{$item}})) {
$showitem = $ltstatus{$in{$item}};
}
$r->print(''.$showitem.' '."\n");
- } else {
- $r->print(''.$in{$item}.' '."\n");
- }
- }
- if (($context eq 'course') && ($mode ne 'autoenroll')) {
- if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
- if ($displayclickers eq 'on') {
- my $clickers =
+ } elsif ($item eq 'photo') {
+ if (($context eq 'course') && ($mode ne 'autoenroll') &&
+ ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) {
+ if ($role eq 'st') {
+ $r->print(' ');
+ } else {
+ $r->print(' ');
+ }
+ }
+ } elsif ($item eq 'clicker') {
+ if (($context eq 'course') && ($mode ne 'autoenroll')) {
+ if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
+ my $clickers =
(&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
- if ($clickers!~/\w/) { $clickers='-'; }
- $r->print(''.$clickers.' ');
- } else {
- $r->print(' ');
- }
- if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
- if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') {
- $r->print(' ');
+ if ($clickers!~/\w/) { $clickers='-'; }
+ $r->print(''.$clickers.' ');
} else {
- $r->print(' ');
- }
+ $r->print(' '."\n");
+ }
}
+ } elsif (($item eq 'authorquota') || ($item eq 'authorusage')) {
+ $r->print(''.$in{$item}.' '."\n");
+ } else {
+ $r->print(''.$in{$item}.' '."\n");
}
}
$r->print(&Apache::loncommon::end_data_table_row());
@@ -2884,10 +3319,10 @@ END
$r->print(&Apache::loncommon::end_data_table().' ');
} elsif ($mode eq 'excel') {
$excel_workbook->close();
- $r->print(&mt('[_1]Your Excel spreadsheet[_2] is ready for download.', '',' ')."
\n");
+ $r->print(''.&mt('[_1]Your Excel spreadsheet[_2] is ready for download.', '',' ')."
\n");
} elsif ($mode eq 'csv') {
close($CSVfile);
- $r->print(&mt('[_1]Your CSV file[_2] is ready for download.', '',' ')."
\n");
+ $r->print(''.&mt('[_1]Your CSV file[_2] is ready for download.', '',' ')."
\n");
$r->rflush();
}
if ($mode eq 'autoenroll') {
@@ -2919,6 +3354,10 @@ sub bulkaction_javascript {
my $noaction = &mt("You need to select an action to take for the user(s) you have selected");
my $singconfirm = &mt(' for a single user?');
my $multconfirm = &mt(' for multiple users?');
+ &js_escape(\$alert);
+ &js_escape(\$noaction);
+ &js_escape(\$singconfirm);
+ &js_escape(\$multconfirm);
my $output = <<"ENDJS";
function verify_action (field) {
var numchecked = 0;
@@ -3049,6 +3488,7 @@ sub select_actions {
chgdates => "Change starting/ending dates",
chgsec => "Change section associated with user roles",
);
+ # FIXME Add an option to change credits for student roles.
my ($output,$options,%choices);
# FIXME Disable actions for now for roletype=course in domain context
if ($context eq 'domain' && $setting eq 'course') {
@@ -3056,15 +3496,20 @@ sub select_actions {
}
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;
- }
- }
+ my $showactions;
+ if (&Apache::lonnet::allowed('c'.$env{'form.showrole'},
+ $env{'request.course.id'})) {
+ $showactions = 1;
+ } elsif ($env{'request.course.sec'} ne '') {
+ if (&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
+ $showactions = 1;
+ }
+ }
+ unless ($showactions) {
+ unless (&is_courseowner($env{'request.course.id'},
+ $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) {
+ return;
+ }
}
}
}
@@ -3171,11 +3616,13 @@ ENDTWO
}
sub date_section_selector {
- my ($context,$permission,$crstype) = @_;
+ my ($context,$permission,$crstype,$showcredits) = @_;
my $callingform = $env{'form.callingform'};
my $formname = 'dateselect';
my $groupslist = &get_groupslist();
- my $sec_js = &setsections_javascript($formname,$groupslist);
+ my $sec_js =
+ &setsections_javascript($formname,$groupslist,undef,undef,$crstype,
+ $showcredits);
my $output = <<"END";
-
END
my ($indexhash,$keylist) = &make_keylist_array();
@@ -3590,17 +4055,20 @@ END
}
}
if (!$studentcount) {
+ my $msg = '';
if ($crstype eq 'Community') {
- $r->print(&mt('There are no members to drop.'));
+ $msg = &mt('There are no members to drop.');
} else {
- $r->print(&mt('There are no students to drop.'));
+ $msg = &mt('There are no students to drop.');
}
+ $r->print('
'.$msg.'
');
return;
}
my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
$classlist,$keylist,$cdom,$cnum);
my %lt=&Apache::lonlocal::texthash('usrn' => "username",
'dom' => "domain",
+ 'id' => "ID",
'sn' => "student name",
'mn' => "member name",
'sec' => "section",
@@ -3619,7 +4087,7 @@ END
$lt{'usrn'}
$lt{'dom'}
- ID
+ $lt{'id'}
$nametitle
$lt{'sec'}
$lt{'start'}
@@ -3633,21 +4101,21 @@ END
$r->print(<
- $lt{'usrn'}
+ $lt{'usrn'}
- $lt{'dom'}
+ $lt{'dom'}
- ID
+ $lt{'id'}
- $nametitle
+ $nametitle
- $lt{'sec'}
+ $lt{'sec'}
- $lt{'start'}
+ $lt{'start'}
- $lt{'end'}
+ $lt{'end'}
- $lt{'groups'}
+ $lt{'groups'}
END
$r->print(&Apache::loncommon::end_data_table_header_row());
@@ -3718,7 +4186,6 @@ END
$btn = $lt{'dm'};
}
$r->print(<<"END");
-
@@ -3740,16 +4207,17 @@ sub print_first_users_upload_form {
$str .= ' ';
$str .= ' ';
+ $str .= &Apache::grades::checkforfile_js();
+
$str .= '
'.&mt('Upload a file containing information about users').' '."\n";
# Excel and CSV Help
- $str .= ''
+ $str .= '
'
.&Apache::loncommon::help_open_topic("Course_Create_Class_List",
&mt("How do I create a users list from a spreadsheet"))
- .'
'."\n"
- .&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
+ .' '.&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
&mt("How do I create a CSV file from a spreadsheet"))
- .'
'."\n";
+ ."
\n";
$str .= &Apache::lonhtmlcommon::start_pick_box()
.&Apache::lonhtmlcommon::row_title(&mt('File'));
if (&Apache::lonlocal::current_language() ne 'en') {
@@ -3770,7 +4238,8 @@ sub print_first_users_upload_form {
.&Apache::lonhtmlcommon::end_pick_box();
$str .= ''
- .' '
+ .' '
.'
';
$r->print($str);
@@ -3779,8 +4248,11 @@ sub print_first_users_upload_form {
# ================================================= Drop/Add from uploaded file
sub upfile_drop_add {
- my ($r,$context,$permission) = @_;
- &Apache::loncommon::load_tmp_file($r);
+ my ($r,$context,$permission,$showcredits) = @_;
+ my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
+ if ($datatoken ne '') {
+ &Apache::loncommon::load_tmp_file($r,$datatoken);
+ }
my @userdata=&Apache::loncommon::upfile_record_sep();
if($env{'form.noFirstLine'}){shift(@userdata);}
my @keyfields = split(/\,/,$env{'form.keyfields'});
@@ -3794,42 +4266,55 @@ sub upfile_drop_add {
$fields{$env{'form.f'.$i}}=$keyfields[$i];
}
}
- if ($env{'form.fullup'} ne 'yes') {
- $r->print(''.
- ' '.
+ $r->print(''.
&mt('There are no students with current/future access to the course.').
- ''."\n");
+ '
'."\n");
} elsif (ref($classlist) eq 'HASH') {
# Remove the students we just added from the list of students.
foreach my $line (@userdata) {
@@ -4429,9 +5086,7 @@ sub upfile_drop_add {
}
}
} # end of unless
- if ($env{'form.fullup'} ne 'yes') {
- $r->print('');
- }
+ return 'ok';
}
sub print_namespacing_alerts {
@@ -4474,15 +5129,52 @@ sub print_namespacing_alerts {
}
}
+sub passwdrule_alerts {
+ my ($domain,$passwdrules) = @_;
+ my $warning;
+ if (ref($passwdrules) eq 'HASH') {
+ my %showrules = %{$passwdrules};
+ if (keys(%showrules)) {
+ my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
+ $warning = ''.&mt('Password requirement(s) unmet for one or more users:').' ';
+ if ($showrules{'min'}) {
+ my $min = $passwdconf{'min'};
+ if ($min eq '') {
+ $min = $Apache::lonnet::passwdmin;
+ }
+ $warning .= ''.&mt('minimum [quant,_1,character]',$min).' ';
+ }
+ if ($showrules{'max'}) {
+ $warning .= ''.&mt('maximum [quant,_1,character]',$passwdconf{'max'}).' ';
+ }
+ if ($showrules{'uc'}) {
+ $warning .= ''.&mt('contain at least one upper case letter').' ';
+ }
+ if ($showrules{'lc'}) {
+ $warning .= ''.&mt('contain at least one lower case letter').' ';
+ }
+ if ($showrules{'num'}) {
+ $warning .= ''.&mt('contain at least one number').' ';
+ }
+ if ($showrules{'spec'}) {
+ $warning .= ''.&mt('contain at least one non-alphanumeric').' ';
+ }
+ $warning .= ' ';
+ }
+ }
+ return $warning;
+}
+
sub user_change_result {
my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
$username,$userdomain,$userchg) = @_;
my $okresult = 0;
+ my @status;
if ($userresult ne 'ok') {
if ($userresult =~ /^error:(.+)$/) {
my $error = $1;
- $r->print(' '.
- &mt('[_1]: Unable to add/modify: [_2]',''.$username.':'.$userdomain.' ',$error));
+ push(@status,
+ &mt('[_1]: Unable to add/modify: [_2]',''.$username.':'.$userdomain.' ',$error));
}
} else {
$counts->{'user'} ++;
@@ -4491,8 +5183,8 @@ sub user_change_result {
if ($authresult ne 'ok') {
if ($authresult =~ /^error:(.+)$/) {
my $error = $1;
- $r->print(' '.
- &mt('[_1]: Unable to modify authentication: [_2]',''.$username.':'.$userdomain.' ',$error));
+ push(@status,
+ &mt('[_1]: Unable to modify authentication: [_2]',''.$username.':'.$userdomain.' ',$error));
}
} else {
$counts->{'auth'} ++;
@@ -4501,8 +5193,8 @@ sub user_change_result {
if ($roleresult ne 'ok') {
if ($roleresult =~ /^error:(.+)$/) {
my $error = $1;
- $r->print(' '.
- &mt('[_1]: Unable to add role: [_2]',''.$username.':'.$userdomain.' ',$error));
+ push(@status,
+ &mt('[_1]: Unable to add role: [_2]',''.$username.':'.$userdomain.' ',$error));
}
} else {
$counts->{'role'} ++;
@@ -4511,14 +5203,16 @@ sub user_change_result {
if ($okresult) {
$flushc++;
$userchg->{$username.':'.$userdomain}=1;
- $r->print('. ');
if ($flushc>15) {
$r->rflush;
$flushc=0;
}
}
if ($idresult) {
- $r->print($idresult);
+ push(@status,$idresult);
+ }
+ if (@status) {
+ $r->print(''.join(' ',@status).' ');
}
return $flushc;
}
@@ -4533,18 +5227,20 @@ sub print_drop_menu {
$heading = &mt("Drop Students");
}
$r->print(''.$heading.' '."\n".
- ''. &Apache::loncommon::end_page());
+ $r->print('');
return;
}
@@ -4587,7 +5283,7 @@ sub update_user_list {
foreach my $item (@changelist) {
my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,
@sections,$scopestem,$singlesec,$showsecs,$warn_singlesec,
- $nothingtodo,$keepnosection);
+ $nothingtodo,$keepnosection,$credits,$instsec);
if ($choice eq 'drop') {
($uname,$udom,$sec) = split(/:/,$item,-1);
$role = 'st';
@@ -4600,7 +5296,9 @@ sub update_user_list {
$scope = $scopestem.'/'.$sec;
}
} elsif ($context eq 'course') {
- ($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1);
+ ($uname,$udom,$role,$sec,$type,$locktype,$credits,$instsec) =
+ split(/\:/,$item,8);
+ $instsec = &unescape($instsec);
$cid = $env{'request.course.id'};
$scopestem = '/'.$cid;
$scopestem =~s/\_/\//g;
@@ -4619,8 +5317,9 @@ sub update_user_list {
} elsif ($setting eq 'author') {
($uname,$udom,$role,$scope) = split(/\:/,$item);
} elsif ($setting eq 'course') {
- ($uname,$udom,$role,$cid,$sec,$type,$locktype) =
- split(/\:/,$item);
+ ($uname,$udom,$role,$cid,$sec,$type,$locktype,$credits,$instsec) =
+ split(/\:/,$item,9);
+ $instsec = &unescape($instsec);
$scope = '/'.$cid;
$scope =~s/\_/\//g;
if ($sec ne '') {
@@ -4642,7 +5341,7 @@ sub update_user_list {
$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,'',$context);
+ &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
} else {
$result =
&Apache::lonnet::revokerole($udom,$uname,$scope,$role,
@@ -4650,7 +5349,7 @@ sub update_user_list {
}
} 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,'',$context);
+ &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
}
$result =
&Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,
@@ -4663,7 +5362,7 @@ sub update_user_list {
}
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,'',$context);
+ $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
} else {
$result =
&Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
@@ -4671,14 +5370,14 @@ sub update_user_list {
}
} 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,'',$context);
+ $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
} else {
$result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
$now,'','',$context);
}
} 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,'',$context);
+ $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
} else {
$result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
$start,'','',$context);
@@ -4748,7 +5447,7 @@ sub update_user_list {
} else {
if ($role eq 'st') {
$result =
- &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context);
+ &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
} else {
my $newscope = $scopestem;
$result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context);
@@ -4762,7 +5461,7 @@ sub update_user_list {
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,'',$context);
+ $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context,$credits,$instsec);
if (@newsecs > 1) {
my $showsingle;
if ($newsec eq '') {
@@ -4873,7 +5572,7 @@ sub update_user_list {
}
}
}
- $r->print(''.&mt("$result_text{'ok'}{$choice} for [quant,_1,user role,user roles,no user roles].",$count).'
');
+ $r->print(''.&mt("$result_text{'ok'}{$choice} [quant,_1,user role,user roles,no user roles].",$count).'
');
if ($count > 0) {
if ($choice eq 'revoke' || $choice eq 'drop') {
$r->print(''.&mt('Re-enabling will re-activate data for the role.').'
');
@@ -4890,7 +5589,10 @@ sub update_user_list {
if ($choice eq 'drop') {
$linktext = &mt('Display current class roster');
}
- $r->print(''.$linktext.' '."\n");
+ $r->print(
+ &Apache::lonhtmlcommon::actionbox(
+ [''.$linktext.' '])
+ .''."\n");
}
sub dates_feedback {
@@ -4898,7 +5600,7 @@ sub dates_feedback {
my $dates;
if ($start < $now) {
if ($end == 0) {
- $dates .= &mt('role(s) active now; no end date');
+ $dates = &mt('role(s) active now; no end date');
} elsif ($end > $now) {
$dates = &mt('role(s) active now; ends [_1].',&Apache::lonlocal::locallocaltime($end));
} else {
@@ -4937,18 +5639,25 @@ sub active_student_roles {
sub section_check_js {
my $groupslist= &get_groupslist();
+ my %js_lt = &Apache::lonlocal::texthash(
+ 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.',
+ );
+ &js_escape(\%js_lt);
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.");
+ alert("'"+secname+"' $js_lt{'mayn'}\\n$js_lt{'plch'}");
return 'error';
}
if (secname != '') {
for (var k=0; k $b} keys %{$sections_count});
+ my @sections = (sort {$a <=> $b} keys(%{$sections_count}));
my $numsec = scalar(@sections);
my $is_selected = ' selected="selected"';
if ($numsec <= 1) {
- $output = ''."\n".
+ $output = ''."\n".
' '.&mt('Select').' '."\n";
if ($current_sec eq 'none') {
$output .=
@@ -5016,7 +5725,7 @@ sub course_sections {
my $multiple = 4;
if (scalar(@sections) < 4) { $multiple = scalar(@sections); }
if ($role eq 'st') {
- $output .= '>'."\n".
+ $output .= $disabled.'>'."\n".
' '.&mt('Select').' '."\n";
if ($current_sec eq 'none') {
$output .=
@@ -5026,7 +5735,7 @@ sub course_sections {
' '.&mt('No section')." \n";
}
} else {
- $output .= 'multiple="multiple" size="'.$multiple.'">'."\n";
+ $output .= 'multiple="multiple" size="'.$multiple.'"'.$disabled.'>'."\n";
}
foreach my $sec (@sections) {
if ($current_sec eq $sec) {
@@ -5051,14 +5760,18 @@ sub get_groupslist {
}
sub setsections_javascript {
- my ($formname,$groupslist,$mode,$checkauth,$crstype) = @_;
+ my ($formname,$groupslist,$mode,$checkauth,$crstype,$showcredits) = @_;
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 (($crstype eq 'Course') && ($showcredits)) {
+ $checkincluded = "((role == 'st') && (formname.elements[i-2].checked == true)) || ((role != 'st') && (formname.elements[i-1].checked == true))";
+ } else {
+ $checkincluded = 'formname.elements[i-1].checked == true';
+ }
if ($checkauth) {
$finish = "var authcheck = auth_check();\n".
" if (authcheck == 'ok') {\n".
@@ -5069,7 +5782,7 @@ sub setsections_javascript {
}
$rolecode = "var match = str.split('_');
var role = match[3];\n";
- } elsif ($formname eq 'enrollstudent') {
+ } elsif (($formname eq 'enrollstudent') || ($formname eq 'selfenroll')) {
$checkincluded = 'formname.name == "'.$formname.'"';
if ($checkauth) {
$finish = "var authcheck = auth_check();\n".
@@ -5095,7 +5808,7 @@ sub setsections_javascript {
acor => 'A 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.',
inco => 'In each community, each user may only have one member role at a time.',
- youh => 'You had selected ',
+ 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.',
@@ -5103,7 +5816,8 @@ sub setsections_javascript {
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.',
nonw => 'Section names may only contain letters or numbers.',
- );
+ );
+ &js_escape(\%alerts);
$setsection_js .= <<"ENDSECCODE";
function setSections(formname,crstype) {
@@ -5114,11 +5828,14 @@ function setSections(formname,crstype) {
var groups = new Array($groupslist);
for (var i=0;i{'mip'}) &&
+ ($udom eq $env{'request.role.domain'})) {
+ unless ($env{'course.'.$env{'request.course.id'}.'.internal.nopasswdchg'}) {
+ my ($cnum,$cdom) = &get_course_identity();
+ if ((&Apache::lonnet::is_course_owner($cdom,$cnum)) && ($udom eq $env{'user.domain'})) {
+ my @userstatuses = ('default');
+ my %userenv = &Apache::lonnet::userenvironment($udom,$uname,'inststatus');
+ if ($userenv{'inststatus'} ne '') {
+ @userstatuses = split(/:/,$userenv{'inststatus'});
+ }
+ my $noupdate = 1;
+ my %passwdconf = &Apache::lonnet::get_passwdconf($cdom);
+ if (ref($passwdconf{'crsownerchg'}) eq 'HASH') {
+ if (ref($passwdconf{'crsownerchg'}{'for'}) eq 'ARRAY') {
+ foreach my $status (@userstatuses) {
+ if (grep(/^\Q$status\E$/,@{$passwdconf{'crsownerchg'}{'for'}})) {
+ undef($noupdate);
+ last;
+ }
+ }
+ }
+ }
+ if ($noupdate) {
+ return;
+ }
+ my %owned = &Apache::lonnet::courseiddump($cdom,'.',1,'.',
+ $env{'user.name'}.':'.$env{'user.domain'},
+ undef,undef,undef,'.');
+ my %roleshash = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',
+ ['active','future']);
+ foreach my $key (keys(%roleshash)) {
+ my ($name,$domain,$role) = split(/:/,$key);
+ if ($role eq 'st') {
+ next if (($name eq $cnum) && ($domain eq $cdom));
+ if ($owned{$domain.'_'.$name}) {
+ if (ref($owned{$domain.'_'.$name}) eq 'HASH') {
+ if ($owned{$domain.'_'.$name}{'nopasswdchg'}) {
+ $noupdate = 1;
+ last;
+ }
+ }
+ } else {
+ $noupdate = 1;
+ last;
+ }
+ } else {
+ $noupdate = 1;
+ last;
+ }
+ }
+ unless ($noupdate) {
+ $canchange = 1;
+ }
+ }
+ }
+ }
+ return $canchange;
+}
+
sub check_usertype {
my ($dom,$uname,$rules,$curr_rules,$got_rules) = @_;
my $usertype;
@@ -5377,7 +6165,7 @@ sub roles_by_context {
} elsif ($context eq 'author') {
@allroles = ('ca','aa');
} elsif ($context eq 'domain') {
- @allroles = ('li','ad','dg','sc','au','dc');
+ @allroles = ('li','ad','dg','dh','da','sc','au','dc');
}
return @allroles;
}
@@ -5419,9 +6207,60 @@ sub get_permission {
if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
$permission{'grp_manage'} = 1;
}
+ if ($permission{'cusr'}) {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my %coursehash = (
+ 'internal.selfenrollmgrdc' => $env{'course.'.$env{'request.course.id'}.'.internal.selfenrollmgrdc'},
+ 'internal.selfenrollmgrcc' => $env{'course.'.$env{'request.course.id'}.'.internal.selfenrollmgrcc'},
+ 'internal.coursecode' => $env{'course.'.$env{'request.course.id'}.'.internal.coursecode'},
+ 'internal.textbook' =>$env{'course.'.$env{'request.course.id'}.'.internal.textbook'},
+ );
+ my ($managed_by_cc,$managed_by_dc) = &selfenrollment_administration($cdom,$cnum,$crstype,\%coursehash);
+ if (ref($managed_by_cc) eq 'ARRAY') {
+ if (@{$managed_by_cc}) {
+ $permission{'selfenrolladmin'} = 1;
+ }
+ }
+ unless ($permission{'selfenrolladmin'}) {
+ $permission{'selfenrollview'} = 1;
+ }
+ }
+ if ($env{'request.course.id'}) {
+ my $user;
+ if (($env{'user.name'} ne '') && ($env{'user.domain'} ne '')) {
+ $user = $env{'user.name'}.':'.$env{'user.domain'};
+ }
+ if (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.courseowner'} eq
+ $user)) {
+ $permission{'owner'} = 1;
+ if (&Apache::lonnet::allowed('mip',$env{'request.course.id'})) {
+ $permission{'mip'} = 1;
+ }
+ } elsif (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.co-owners'} ne '')) {
+ if (grep(/^\Q$user\E$/,split(/,/,$env{'course.'.$env{'request.course.id'}.'.internal.co-owners'}))) {
+ $permission{'co-owner'} = 1;
+ }
+ }
+ }
} elsif ($context eq 'author') {
- $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'});
- $permission{'view'} = $permission{'cusr'};
+ my $audom = $env{'request.role.domain'};
+ my $auname = $env{'user.name'};
+ if ((&Apache::lonnet::allowed('cca',"$audom/$auname")) ||
+ (&Apache::lonnet::allowed('caa',"$audom/$auname"))) {
+ $permission{'author'} = 1;
+ $permission{'cusr'} = 1;
+ $permission{'view'} = 1;
+ }
+ } elsif ($context eq 'coauthor') {
+ my ($audom,$auname) = ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$});
+ if ((&Apache::lonnet::allowed('vca',"$audom/$auname")) ||
+ (&Apache::lonnet::allowed('vaa',"$audom/$auname"))) {
+ if ($env{"environment.internal.manager./$audom/$auname"}) {
+ $permission{'cusr'} = 1;
+ $permission{'view'} = 1;
+ }
+ }
} else {
my @allroles = &roles_by_context($context);
foreach my $role (@allroles) {
@@ -5438,11 +6277,20 @@ sub get_permission {
if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {
$permission{'custom'} = 1;
}
- $permission{'view'} = $permission{'cusr'};
+ if (&Apache::lonnet::allowed('vac',$env{'request.role.domain'})) {
+ $permission{'activity'} = 1;
+ }
+ if (&Apache::lonnet::allowed('vur',$env{'request.role.domain'})) {
+ $permission{'view'} = 1;
+ }
+ if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
+ $permission{'owner'} = 1;
+ }
}
my $allowed = 0;
- foreach my $perm (values(%permission)) {
- if ($perm) { $allowed=1; last; }
+ foreach my $key (keys(%permission)) {
+ next if (($key eq 'owner') || ($key eq 'co-owner') || ($key eq 'author'));
+ if ($permission{$key}) { $allowed=1; last; }
}
return (\%permission,$allowed);
}
@@ -5455,6 +6303,18 @@ sub authorpriv {
|| (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; } return 1;
}
+sub coauthorpriv {
+ my ($auname,$audom)=@_;
+ my $uname = $env{'user.name'};
+ my $udom = $env{'user.domain'};
+ if (((&Apache::lonnet::allowed('vca',"$udom/$uname")) ||
+ (&Apache::lonnet::allowed('vaa',"$udom/$uname"))) &&
+ ($env{"environment.internal.manager./$audom/$auname"})) {
+ return 1;
+ }
+ return '';
+}
+
sub roles_on_upload {
my ($context,$setting,$crstype,%customroles) = @_;
my (@possible_roles,@permitted_roles);
@@ -5491,7 +6351,7 @@ sub get_course_identity {
}
sub dc_setcourse_js {
- my ($formname,$mode,$context) = @_;
+ my ($formname,$mode,$context,$showcredits,$domain) = @_;
my ($dc_setcourse_code,$authen_check);
my $cctext = &Apache::lonnet::plaintext('cc');
my $cotext = &Apache::lonnet::plaintext('co');
@@ -5500,7 +6360,7 @@ sub dc_setcourse_js {
if ($mode eq 'upload') {
$role = 'courserole';
} else {
- $authen_check = &verify_authen($formname,$context);
+ $authen_check = &verify_authen($formname,$context,$domain);
}
$dc_setcourse_code = (<<"SCRIPTTOP");
$authen_check
@@ -5577,7 +6437,7 @@ function setCourse() {
}
SCRIPTTOP
if ($mode ne 'upload') {
- $dc_setcourse_code .= (<<"ENDSCRIPT");
+ $dc_setcourse_code .= (<<"SCRIPTMID");
var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole
var numcourse = getIndex(document.$formname.dccourse);
if (numcourse == "-1") {
@@ -5603,6 +6463,16 @@ SCRIPTTOP
if (numend != "-1") {
document.$formname.elements[numend].name = "end"+coursename
}
+SCRIPTMID
+ if ($showcredits) {
+ $dc_setcourse_code .= < 0) {
+$intargjs
+ }
}
$finish
}
@@ -5711,6 +6589,7 @@ sub sectioncheck_alerts {
thwa => 'There was a problem with your course selection',
thwc => 'There was a problem with your community selection',
);
+ &js_escape(\%alerts);
return %alerts;
}
@@ -5721,8 +6600,589 @@ sub authcheck_alerts {
krb => 'You need to specify the Kerberos domain.',
ipass => 'You need to specify the initial password.',
);
+ &js_escape(\%alerts);
return %alerts;
}
+sub is_courseowner {
+ my ($thiscourse,$courseowner) = @_;
+ if ($courseowner eq '') {
+ if ($env{'request.course.id'} eq $thiscourse) {
+ $courseowner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
+ }
+ }
+ if ($courseowner ne '') {
+ if ($courseowner eq $env{'user.name'}.':'.$env{'user.domain'}) {
+ return 1;
+ }
+ }
+ return;
+}
+
+sub get_selfenroll_titles {
+ my @row = ('types','registered','enroll_dates','access_dates','section',
+ 'approval','limit');
+ my %lt = &Apache::lonlocal::texthash (
+ types => 'Users allowed to self-enroll',
+ registered => 'Registration status (official courses)' ,
+ enroll_dates => 'Dates self-enrollment available',
+ access_dates => 'Access dates for self-enrolling users',
+ section => "Self-enrolling users' section",
+ approval => 'Processing of requests',
+ limit => 'Enrollment limit',
+ );
+ return (\@row,\%lt);
+}
+
+sub selfenroll_default_descs {
+ my %desc = (
+ types => {
+ dom => &mt('Course domain'),
+ all => &mt('Any domain'),
+ '' => &mt('None'),
+ },
+ limit => {
+ none => &mt('No limit'),
+ allstudents => &mt('Limit by total students'),
+ selfenrolled => &mt('Limit by total self-enrolled'),
+ },
+ approval => {
+ '0' => &mt('Processed automatically'),
+ '1' => &mt('Queued for approval'),
+ '2' => &mt('Queued, pending validation'),
+ },
+ registered => {
+ 0 => 'No registration required',
+ 1 => 'Registered students only',
+ },
+ );
+ return %desc;
+}
+
+sub selfenroll_validation_types {
+ my @items = ('url','fields','button','markup');
+ my %names = &Apache::lonlocal::texthash (
+ url => 'Web address of validation server/script',
+ fields => 'Form fields to send to validator',
+ button => 'Text for validation button',
+ markup => 'Validation description (HTML)',
+ );
+ my @fields = ('username','domain','uniquecode','course','coursetype','description');
+ return (\@items,\%names,\@fields);
+}
+
+sub get_extended_type {
+ my ($cdom,$cnum,$crstype,$current) = @_;
+ my $type = 'unofficial';
+ my %settings;
+ if (ref($current) eq 'HASH') {
+ %settings = %{$current};
+ } else {
+ %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.textbook'],$cdom,$cnum);
+ }
+ if ($crstype eq 'Community') {
+ $type = 'community';
+ } elsif ($crstype eq 'Placement') {
+ $type = 'placement';
+ } elsif ($settings{'internal.coursecode'}) {
+ $type = 'official';
+ } elsif ($settings{'internal.textbook'}) {
+ $type = 'textbook';
+ }
+ return $type;
+}
+
+sub selfenrollment_administration {
+ my ($cdom,$cnum,$crstype,$coursehash) = @_;
+ my %settings;
+ if (ref($coursehash) eq 'HASH') {
+ %settings = %{$coursehash};
+ } else {
+ %settings = &Apache::lonnet::get('environment',
+ ['internal.selfenrollmgrdc','internal.selfenrollmgrcc',
+ 'internal.coursecode','internal.textbook'],$cdom,$cnum);
+ }
+ my ($possconfigs) = &get_selfenroll_titles();
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
+ my $selfenrolltype = &get_extended_type($cdom,$cnum,$crstype,\%settings);
+
+ my (@in_course,@in_domain);
+ if ($settings{'internal.selfenrollmgrcc'} ne '') {
+ @in_course = split(/,/,$settings{'internal.selfenrollmgrcc'});
+ my @diffs = &Apache::loncommon::compare_arrays($possconfigs,\@in_course);
+ unless (@diffs) {
+ return (\@in_course,\@in_domain);
+ }
+ }
+ if ($settings{'internal.selfenrollmgrdc'} ne '') {
+ @in_domain = split(/,/,$settings{'internal.selfenrollmgrdc'});
+ my @diffs = &Apache::loncommon::compare_arrays(\@in_domain,$possconfigs);
+ unless (@diffs) {
+ return (\@in_course,\@in_domain);
+ }
+ }
+ my @combined = @in_course;
+ push(@combined,@in_domain);
+ my @diffs = &Apache::loncommon::compare_arrays(\@combined,$possconfigs);
+ unless (@diffs) {
+ return (\@in_course,\@in_domain);
+ }
+ if ($domdefaults{$selfenrolltype.'selfenrolladmdc'} eq '') {
+ push(@in_course,@diffs);
+ } else {
+ my @defaultdc = split(/,/,$domdefaults{$selfenrolltype.'selfenrolladmdc'});
+ foreach my $item (@diffs) {
+ if (grep(/^\Q$item\E$/,@defaultdc)) {
+ push(@in_domain,$item);
+ } else {
+ push(@in_course,$item);
+ }
+ }
+ }
+ return (\@in_course,\@in_domain);
+}
+
+sub custom_role_header {
+ my ($context,$crstype,$templaterolerefs,$prefix) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ sele => 'Select a Template',
+ );
+ my ($context_code,$button_code);
+ if ($context eq 'domain') {
+ $context_code = &custom_coursetype_switch($crstype,$prefix);
+ }
+ if (ref($templaterolerefs) eq 'ARRAY') {
+ foreach my $role (@{$templaterolerefs}) {
+ my $display = 'inline';
+ if (($context eq 'domain') && ($role eq 'co')) {
+ $display = 'none';
+ }
+ $button_code .= &make_button_code($role,$crstype,$display,$prefix).' ';
+ }
+ }
+ return <<"END";
+
+
+$lt{'sele'}
+$button_code
+
+$context_code
+
+END
+}
+
+sub custom_coursetype_switch {
+ my ($crstype,$prefix) = @_;
+ my ($checkedcourse,$checkedcommunity);
+ if ($crstype eq 'Community') {
+ $checkedcommunity = ' checked="checked"';
+ } else {
+ $checkedcourse = ' checked="checked"';
+ }
+ my %lt = &Apache::lonlocal::texthash(
+ cont => 'Context',
+ cour => 'Course',
+ comm => 'Community',
+ );
+ return <<"END";
+
+
+$lt{'cont'}
+
+
+$lt{'cour'}
+
+
+
+$lt{'comm'}
+
+
+
+END
+}
+
+sub custom_role_table {
+ my ($crstype,$full,$levels,$levelscurrent,$prefix,$add_class,$id) = @_;
+ return unless ((ref($full) eq 'HASH') && (ref($levels) eq 'HASH') &&
+ (ref($levelscurrent) eq 'HASH'));
+ my %lt=&Apache::lonlocal::texthash (
+ 'prv' => "Privilege",
+ 'crl' => "Course Level",
+ 'dml' => "Domain Level",
+ 'ssl' => "System Level");
+ my %cr = (
+ course => '_c',
+ domain => '_d',
+ system => '_s',
+ );
+
+ my $output=&Apache::loncommon::start_data_table($add_class,$id).
+ &Apache::loncommon::start_data_table_header_row().
+ ''.$lt{'prv'}.' '.$lt{'crl'}.' '.$lt{'dml'}.
+ ' '.$lt{'ssl'}.' '.
+ &Apache::loncommon::end_data_table_header_row();
+ foreach my $priv (sort(keys(%{$full}))) {
+ my $privtext = &Apache::lonnet::plaintext($priv,$crstype);
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$privtext.' ';
+ foreach my $type ('course','domain','system') {
+ if (($type eq 'system') && ($priv eq 'bre') && ($crstype eq 'Community')) {
+ $output .= ' ';
+ } else {
+ $output .= ''.
+ ($levels->{$type}{$priv}?' {$type}{$priv}?' checked="checked"':'').' />':' ').
+ ' ';
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table_row();
+ }
+ $output .= &Apache::loncommon::end_data_table();
+ return $output;
+}
+
+sub custom_role_privs {
+ my ($privs,$full,$levels,$levelscurrent)= @_;
+ return unless ((ref($privs) eq 'HASH') && (ref($full) eq 'HASH') &&
+ (ref($levels) eq 'HASH') && (ref($levelscurrent) eq 'HASH'));
+ my %cr = (
+ course => 'cr:c',
+ domain => 'cr:d',
+ system => 'cr:s',
+ );
+ foreach my $type ('course','domain','system') {
+ foreach my $item (split(/\:/,$Apache::lonnet::pr{$cr{$type}})) {
+ my ($priv,$restrict)=split(/\&/,$item);
+ if (!$restrict) { $restrict='F'; }
+ $levels->{$type}->{$priv}=$restrict;
+ if ($privs->{$type}=~/\:$priv/) {
+ $levelscurrent->{$type}->{$priv}=1;
+ }
+ $full->{$priv}=1;
+ }
+ }
+ return;
+}
+
+sub custom_template_roles {
+ my ($context,$crstype) = @_;
+ my @template_roles = ("in","ta","ep");
+ if (($context eq 'domain') || ($context eq 'domprefs')) {
+ push(@template_roles,"ad");
+ }
+ push(@template_roles,"st");
+ if ($context eq 'domain') {
+ unshift(@template_roles,('co','cc'));
+ } else {
+ if ($crstype eq 'Community') {
+ unshift(@template_roles,'co');
+ } else {
+ unshift(@template_roles,'cc');
+ }
+ }
+ return @template_roles;
+}
+
+sub custom_roledefs_js {
+ my ($context,$crstype,$formname,$full,$templaterolesref,$jsback) = @_;
+ my $button_code = "\n";
+ my $head_script = "\n";
+ my (%roletitlestr,$rolenamestr);
+ my %role_titles = (
+ Course => [],
+ Community => [],
+ );
+ $head_script .= ''."\n";
+ return $head_script;
+}
+
+# --------------------------------------------------------
+sub make_script_template {
+ my ($role,$crstype,$formname) = @_;
+ my $return_script = 'function set_'.$role.'(prefix) {'."\n";
+ my (%full_by_level,%role_priv);
+ foreach my $level ('c','d','s') {
+ foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:'.$level})) {
+ next if (($level eq 's') && ($crstype eq 'Community') && ($item eq 'bre&S'));
+ my ($priv,$restrict)=split(/\&/,$item);
+ $full_by_level{$level}{$priv}=1;
+ }
+ $role_priv{$level} = {};
+ my @temp = split(/:/,$Apache::lonnet::pr{$role.':'.$level});
+ foreach my $priv (@temp) {
+ my ($priv_item, $dummy) = split(/\&/,$priv);
+ $role_priv{$level}{$priv_item} = 1;
+ }
+ }
+ my %to_check = (
+ c => ['c','d','s'],
+ d => ['d','s'],
+ s => ['s'],
+ );
+ foreach my $level ('c','d','s') {
+ if (ref($full_by_level{$level}) eq 'HASH') {
+ foreach my $priv (keys(%{$full_by_level{$level}})) {
+ my $value = 'false';
+ if (ref($to_check{$level}) eq 'ARRAY') {
+ foreach my $lett (@{$to_check{$level}}) {
+ if (exists($role_priv{$lett}{$priv})) {
+ $value = 'true';
+ last;
+ }
+ }
+ $return_script .= "document.$formname.elements[prefix+'".$priv."_".$level."'].checked = $value;\n";
+ }
+ }
+ }
+ }
+ $return_script .= '}'."\n";
+ return ($return_script);
+}
+# ----------------------------------------------------------
+sub make_button_code {
+ my ($role,$crstype,$display,$prefix) = @_;
+ my $label = &Apache::lonnet::plaintext($role,$crstype);
+ my $button_code = ' ';
+ return ($button_code);
+}
+
+sub custom_role_update {
+ my ($rolename,$prefix) = @_;
+# ------------------------------------------------------- What can be assigned?
+ my %privs = (
+ c => '',
+ d => '',
+ s => '',
+ );
+ foreach my $level (keys(%privs)) {
+ foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:'.$level})) {
+ my ($priv,$restrict)=split(/\&/,$item);
+ if (!$restrict) { $restrict=''; }
+ if ($env{'form.'.$prefix.$priv.'_'.$level}) {
+ $privs{$level} .=':'.$item;
+ }
+ }
+ }
+ return %privs;
+}
+
+sub adhoc_status_types {
+ my ($cdom,$context,$role,$selectedref,$othertitle,$usertypes,$types,$disabled) = @_;
+ my $output = &Apache::loncommon::start_data_table();
+ my $numinrow = 3;
+ my $rem;
+ if (ref($types) eq 'ARRAY') {
+ for (my $i=0; $i<@{$types}; $i++) {
+ if (defined($usertypes->{$types->[$i]})) {
+ my $rem = $i%($numinrow);
+ if ($rem == 0) {
+ if ($i > 0) {
+ $output .= &Apache::loncommon::end_data_table_row();
+ }
+ $output .= &Apache::loncommon::start_data_table_row();
+ }
+ my $check;
+ if (ref($selectedref) eq 'ARRAY') {
+ if (grep(/^\Q$types->[$i]\E$/,@{$selectedref})) {
+ $check = ' checked="checked"';
+ }
+ }
+ $output .= ''.
+ ''.
+ ' [$i].'"'.$check.$disabled.' />'.
+ $usertypes->{$types->[$i]}.' ';
+ }
+ }
+ $rem = @{$types}%($numinrow);
+ }
+ my $colsleft = $numinrow - $rem;
+ if (($rem == 0) && (@{$types} > 0)) {
+ $output .= &Apache::loncommon::start_data_table_row();
+ }
+ if ($colsleft > 1) {
+ $output .= '';
+ } else {
+ $output .= ' ';
+ }
+ my $defcheck;
+ if (ref($selectedref) eq 'ARRAY') {
+ if (grep(/^default$/,@{$selectedref})) {
+ $defcheck = ' checked="checked"';
+ }
+ }
+ $output .= ''.
+ ' '.
+ $othertitle.' '.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ return $output;
+}
+
+sub adhoc_staff {
+ my ($access,$context,$role,$selectedref,$adhocref,$disabled) = @_;
+ my $output;
+ if (ref($adhocref) eq 'HASH') {
+ my %by_fullname;
+ my $numinrow = 4;
+ my $rem;
+ my @personnel = keys(%{$adhocref});
+ if (@personnel) {
+ foreach my $person (@personnel) {
+ my ($uname,$udom) = split(/:/,$person);
+ my $fullname = &Apache::loncommon::plainname($uname,$udom,'lastname');
+ $by_fullname{$fullname} = $person;
+ }
+ my @sorted = sort(keys(%by_fullname));
+ my $count = scalar(@sorted);
+ $output = &Apache::loncommon::start_data_table();
+ for (my $i=0; $i<$count; $i++) {
+ my $rem = $i%($numinrow);
+ if ($rem == 0) {
+ if ($i > 0) {
+ $output .= &Apache::loncommon::end_data_table_row();
+ }
+ $output .= &Apache::loncommon::start_data_table_row();
+ }
+ my $check;
+ my $user = $by_fullname{$sorted[$i]};
+ if (ref($selectedref) eq 'ARRAY') {
+ if (grep(/^\Q$user\E$/,@{$selectedref})) {
+ $check = ' checked="checked"';
+ }
+ }
+ if ($i == $count-1) {
+ my $colsleft = $numinrow - $rem;
+ if ($colsleft > 1) {
+ $output .= '';
+ } else {
+ $output .= ' ';
+ }
+ } else {
+ $output .= ' ';
+ }
+ $output .= ''.
+ ' '.$sorted[$i].
+ ' ';
+ if ($i == $count-1) {
+ $output .= &Apache::loncommon::end_data_table_row();
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table();
+ }
+ }
+ return $output;
+}
+
+
1;