--- loncom/interface/lonuserutils.pm 2009/06/05 12:49:50 1.94
+++ loncom/interface/lonuserutils.pm 2013/07/15 14:55:14 1.153
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
-# $Id: lonuserutils.pm,v 1.94 2009/06/05 12:49:50 bisitz Exp $
+# $Id: lonuserutils.pm,v 1.153 2013/07/15 14:55:14 bisitz Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -91,7 +91,7 @@ sub modifyuserrole {
if ($setting eq 'course' || $context eq 'course') {
$scope = '/'.$cid;
$scope =~ s/\_/\//g;
- if ($role ne 'cc' && $sec ne '') {
+ if (($role ne 'cc') && ($role ne 'co') && ($sec ne '')) {
$scope .='/'.$sec;
}
} elsif ($context eq 'domain') {
@@ -235,8 +235,10 @@ sub domain_roles_select {
# domain context
#
# Role types
- my @roletypes = ('domain','author','course');
+ 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
@@ -247,6 +249,10 @@ sub domain_roles_select {
foreach my $roletype (@roletypes) {
# set up the text for this domain
$select_menus{$roletype}->{'text'}= $lt{$roletype};
+ my $crstype;
+ if ($roletype eq 'community') {
+ $crstype = 'Community';
+ }
# 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'};
@@ -261,7 +267,7 @@ sub domain_roles_select {
@roles = &construction_space_roles();
} else {
my $custom = 1;
- @roles = &course_roles('domain',undef,$custom);
+ @roles = &course_roles('domain',undef,$custom,$roletype);
}
my $order = ['Any',@roles];
$select_menus{$roletype}->{'order'} = $order;
@@ -271,14 +277,16 @@ sub domain_roles_select {
&mt('Custom role');
} else {
$select_menus{$roletype}->{'select2'}->{$role} =
- &Apache::lonnet::plaintext($role);
+ &Apache::lonnet::plaintext($role,$crstype);
}
}
$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']);
+ 'roletype','showrole',\%select_menus,
+ ['domain','author','course','community'],$onchangefirst,
+ $onchangesecond);
return $result;
}
@@ -290,7 +298,8 @@ sub hidden_input {
}
sub print_upload_manager_header {
- my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_;
+ my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission,$crstype,
+ $can_assign)=@_;
my $javascript;
#
if (! exists($env{'form.upfile_associate'})) {
@@ -304,9 +313,9 @@ sub print_upload_manager_header {
}
}
if ($env{'form.upfile_associate'} eq 'reverse') {
- $javascript=&upload_manager_javascript_reverse_associate();
+ $javascript=&upload_manager_javascript_reverse_associate($can_assign);
} else {
- $javascript=&upload_manager_javascript_forward_associate();
+ $javascript=&upload_manager_javascript_forward_associate($can_assign);
}
#
# Deal with restored settings
@@ -327,13 +336,24 @@ sub print_upload_manager_header {
my $javascript_validations =
&javascript_validations('upload',$krbdefdom,$password_choice,undef,
$env{'request.role.domain'},$context,
- $groupslist);
+ $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. The system will inform you and bring you back to this page, 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".
- &mt('Pick the action to take on roles for these users:').' ';
- }
- if ($context eq 'author') {
- $Str .= '
'.&mt('Default role')."
\n".
- &mt('Choose the role to assign to users without a value specified in the uploaded file');
+ $Str .= &Apache::lonhtmlcommon::row_title(
+ &mt('Settings for assigning roles'))
+ .&mt('Pick the action to take on roles for these users:').' '
+ .''
+ .' '
+ .' '
+ .'';
+ } elsif ($context eq 'author') {
+ $Str .= &Apache::lonhtmlcommon::row_title(
+ &mt('Default role'))
+ .&mt('Choose the role to assign to users without a value specified in the uploaded file.')
} elsif ($context eq 'course') {
- $Str .= '
'.&mt('Default role and section')."
\n".
- &mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file');
+ 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.');
+ }
} else {
- $Str .= '
'.&mt('Default role and/or section(s)')." \n".
- &mt('Role and/or section(s) for users without values specified in the uploaded file.');
+ $Str .= &Apache::lonhtmlcommon::row_title(
+ &mt('Default role and/or section(s)'))
+ .&mt('Role and/or section(s) for users without values specified in the uploaded file.');
}
- $Str .= ' ';
if (($context eq 'domain') || ($context eq 'author')) {
- my ($options,$cb_script,$coursepick) = &default_role_selector($context,1);
+ $Str .= ' ';
+ my ($options,$cb_script,$coursepick) =
+ &default_role_selector($context,1,'',$showcredits);
if ($context eq 'domain') {
- $Str .= ''.&mt('Domain Level').' '.$options.'
'
+ .$cb_script.$coursepick
+ .&Apache::lonhtmlcommon::row_closure();
} elsif ($context eq 'author') {
- $Str .= $options;
+ $Str .= $options
+ .&Apache::lonhtmlcommon::row_closure(1); # last row in pick_box
}
} else {
my ($cnum,$cdom) = &get_course_identity();
my $rowtitle = &mt('section');
- my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle,
- $permission,$context,'upload');
- $Str .= $secbox."
".&mt('Full Update')."
\n".
- '
'.&mt('Students selected from this list can be dropped.').'
'."\n";
+ 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;
+ if ($crstype eq 'Community') {
+ %lt = &Apache::lonlocal::texthash (
+ disp => 'Display members with current/future access who are not in the uploaded file',
+ stus => 'Members selected from this list can be dropped.'
+ );
+ } else {
+ %lt = &Apache::lonlocal::texthash (
+ disp => 'Display students with current/future access who are not in the uploaded file',
+ stus => 'Students selected from this list can be dropped.'
+ );
+ }
+ $Str .= &Apache::lonhtmlcommon::row_title(&mt('Full Update'))
+ .' '
+ .$lt{'stus'}
+ .&Apache::lonhtmlcommon::row_closure();
}
if ($context eq 'course' || $context eq 'domain') {
$Str .= &forceid_change($context);
}
+
+ $Str .= &Apache::lonhtmlcommon::end_pick_box();
$Str .= '
';
- $Str .= '');
&print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
- $context,$permission);
+ $context,$permission,$crstype,$showcredits);
}
sub setup_date_selectors {
@@ -1012,7 +1258,7 @@ sub get_dates_from_form {
}
sub date_setting_table {
- my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission) = @_;
+ my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission,$crstype) = @_;
my $nolink;
if ($bulkaction) {
$nolink = 1;
@@ -1029,9 +1275,13 @@ sub date_setting_table {
($env{'form.action'} eq 'upload')) {
if ($env{'request.course.sec'} eq '') {
$dateDefault = ''.
- '';
+ '';
}
}
}
@@ -1060,7 +1310,7 @@ sub date_setting_table {
}
sub make_dates_default {
- my ($startdate,$enddate,$context) = @_;
+ my ($startdate,$enddate,$context,$crstype) = @_;
my $result = '';
if ($context eq 'course') {
my ($cnum,$cdom) = &get_course_identity();
@@ -1068,26 +1318,34 @@ sub make_dates_default {
{'default_enrollment_start_date'=>$startdate,
'default_enrollment_end_date' =>$enddate},$cdom,$cnum);
if ($put_result eq 'ok') {
- $result .= &mt('Set default start and end access dates for course.').
- ' '."\n";
+ if ($crstype eq 'Community') {
+ $result .= &mt('Set default start and end access dates for community.');
+ } else {
+ $result .= &mt('Set default start and end access dates for course.');
+ }
+ $result .= ' '."\n";
#
# Refresh the course environment
&Apache::lonnet::coursedescription($env{'request.course.id'},
{'freshen_cache' => 1});
} else {
- $result .= &mt('Unable to set default access dates for course.').":".$put_result.
- ' ';
+ if ($crstype eq 'Community') {
+ $result .= &mt('Unable to set default access dates for community');
+ } else {
+ $result .= &mt('Unable to set default access dates for course');
+ }
+ $result .= ':'.$put_result.' ';
}
}
return $result;
}
sub default_role_selector {
- my ($context,$checkpriv) = @_;
+ my ($context,$checkpriv,$crstype,$showcredits) = @_;
my %customroles;
my ($options,$coursepick,$cb_jscript);
if ($context ne 'author') {
- %customroles = &my_custom_roles();
+ %customroles = &my_custom_roles($crstype);
}
my %lt=&Apache::lonlocal::texthash(
@@ -1095,11 +1353,12 @@ sub default_role_selector {
'grs' => "Section",
'exs' => "Existing sections",
'new' => "New section",
+ 'crd' => "Credits",
);
$options = '
'."\n";
- }
- }
- }
$output .= &Apache::loncommon::end_data_table_header_row();
# Done with the HTML header line
} elsif ($mode eq 'csv') {
@@ -2289,20 +2725,22 @@ END
time.'_'.rand(1000000000).'.csv';
unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
$r->log_error("Couldn't open $CSVfilename for output $!");
- $r->print(&mt('Problems occurred in writing the CSV file. '
- .'This error has been logged. '
- .'Please alert your LON-CAPA administrator.'));
+ $r->print(
+ '
'
+ .&mt('Problems occurred in writing the CSV file.')
+ .' '.&mt('This error has been logged.')
+ .' '.&mt('Please alert your LON-CAPA administrator.')
+ .'
'
+ );
$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);
@@ -2338,6 +2776,11 @@ END
Future => 'Future',
Expired => 'Expired',
);
+ # If this is for a single course get last course "log-in".
+ my %crslogins;
+ if ($context eq 'course') {
+ %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum);
+ }
# Get groups, role, permanent e-mail so we can sort on them if
# necessary.
foreach my $user (keys(%{$userlist})) {
@@ -2365,7 +2808,8 @@ END
}
} elsif ($env{'form.roletype'} eq 'author') {
($uname,$udom,$role) = split(/:/,$user,-1);
- } elsif ($env{'form.roletype'} eq 'course') {
+ } elsif (($env{'form.roletype'} eq 'course') ||
+ ($env{'form.roletype'} eq 'community')) {
($uname,$udom,$role) = split(/:/,$user);
}
} else {
@@ -2420,7 +2864,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'}] =
@@ -2428,6 +2872,11 @@ END
'gif','thumbnail');
}
}
+ if (($role eq 'st') && ($defaultcredits)) {
+ if ($userlist->{$user}->[$index{'credits'}] eq '') {
+ $userlist->{$user}->[$index{'credits'}] = $defaultcredits;
+ }
+ }
}
}
my %emails = &Apache::loncommon::getemails($uname,$udom);
@@ -2472,16 +2921,24 @@ END
if ($clickers!~/\w/) { $clickers='-'; }
$in{'clicker'} = $clickers;
my $role = $in{'role'};
- $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]);
- if (! defined($in{'start'}) || $in{'start'} == 0) {
- $in{'start'} = &mt('none');
- } else {
- $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
+ $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype);
+ unless ($mode eq 'excel') {
+ if (! defined($in{'start'}) || $in{'start'} == 0) {
+ $in{'start'} = &mt('none');
+ } else {
+ $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
+ }
+ if (! defined($in{'end'}) || $in{'end'} == 0) {
+ $in{'end'} = &mt('none');
+ } else {
+ $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
+ }
}
- if (! defined($in{'end'}) || $in{'end'} == 0) {
- $in{'end'} = &mt('none');
- } else {
- $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
+ if ($context eq 'course') {
+ my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role};
+ if ($lastlogin ne '') {
+ $in{'lastlogin'} = &Apache::lonlocal::locallocaltime($lastlogin);
+ }
}
if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
$r->print(&Apache::loncommon::start_data_table_row());
@@ -2527,17 +2984,27 @@ 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'};
+ }
+ }
+ }
+ if ($showcheckbox) {
+ $r->print('
'."\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");
+ }
}
+ } else {
+ $r->print('
'.$in{$item}.'
'."\n");
}
}
$r->print(&Apache::loncommon::end_data_table_row());
} elsif ($mode eq 'csv') {
next if (! defined($CSVfile));
# no need to bother with $linkto
- if (! defined($in{'start'}) || $in{'start'} == 0) {
- $in{'start'} = &mt('none');
- } else {
- $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
- }
- if (! defined($in{'end'}) || $in{'end'} == 0) {
- $in{'end'} = &mt('none');
- } else {
- $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
- }
my @line = ();
foreach my $item (@cols) {
push @line,&Apache::loncommon::csv_translate($in{$item});
@@ -2602,9 +3060,9 @@ END
my $col = 0;
foreach my $item (@cols) {
if ($item eq 'start' || $item eq 'end') {
- if (defined($item) && $item != 0) {
+ if ((defined($in{$item})) && ($in{$item} != 0)) {
$excel_sheet->write($row,$col++,
- &Apache::lonstathelpers::calc_serial($in{item}),
+ &Apache::lonstathelpers::calc_serial($in{$item}),
$format->{'date'});
} else {
$excel_sheet->write($row,$col++,'none');
@@ -2759,7 +3217,7 @@ sub print_username_link {
$output = $in->{'username'};
} else {
$output = '{'username'}','$in->{'domain'}'".')" />'.
+ "'$in->{'username'}','$in->{'domain'}'".')">'.
$in->{'username'}.'';
}
return $output;
@@ -2770,6 +3228,7 @@ sub role_type_names {
'domain' => 'Domain Roles',
'author' => 'Co-Author Roles',
'course' => 'Course Roles',
+ 'community' => 'Community Roles',
);
return %lt;
}
@@ -2784,6 +3243,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') {
@@ -2791,15 +3251,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;
+ }
}
}
}
@@ -2874,9 +3339,9 @@ sub date_section_javascript {
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 ($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";
ENDJS
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).',
+ 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 course role that is not "student", users may have roles in more than one section 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') {
@@ -3002,13 +3472,18 @@ ENDJS
}
$date_items = &date_setting_table($starttime,undef,$context,
$env{'form.bulkaction'},$formname,
- $permission);
+ $permission,$crstype);
}
$output .= '