--- loncom/interface/lonuserutils.pm 2010/11/15 18:50:37 1.97.2.25 +++ loncom/interface/lonuserutils.pm 2014/04/04 23:06:31 1.166 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Utility functions for managing LON-CAPA user accounts # -# $Id: lonuserutils.pm,v 1.97.2.25 2010/11/15 18:50:37 raeburn Exp $ +# $Id: lonuserutils.pm,v 1.166 2014/04/04 23:06:31 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -47,8 +47,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); @@ -238,6 +237,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 +285,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,13 +338,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.
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" + ); $r->print(&hidden_input('action','upload'). &hidden_input('state','got_file'). &hidden_input('associate',''). @@ -350,17 +361,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('

'); - $r->print('
print( + '
'. + '
'.&mt('Functions').''. + ''. + ' '); - $r->print("

\n". - ''); + 'onclick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />'. + '

' + ); + $r->print( + '' + ); } ############################################################### @@ -382,6 +399,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') { @@ -391,13 +414,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); } $finish = " var checkSec = $setsection_call\n". " if (checkSec == 'ok') {\n". @@ -420,13 +444,16 @@ 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'); } 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; @@ -483,6 +510,7 @@ END return; } } +/* regexp here to check for non \d \. in credits */ END } else { $auth_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.'); $auth_update = <<"END"; // Currently the initial password field is only supported for internal auth @@ -639,6 +677,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'); @@ -651,8 +690,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); } // @@ -675,6 +715,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'); @@ -772,6 +813,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'); @@ -784,8 +826,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) { @@ -817,7 +860,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) = @@ -906,9 +950,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)')) @@ -916,7 +966,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').'
' @@ -933,8 +984,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; @@ -957,7 +1013,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(); @@ -980,28 +1038,64 @@ 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')) - .'
'."\n" - .&mt('(only do if you know what you are doing.)')."\n"; + ''.&Apache::loncommon::help_open_topic('ForceIDChange')."\n"; if ($context eq 'domain') { - $output .= '
'."\n"; + $output .= + '
' + .''."\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'}) { @@ -1034,7 +1128,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); @@ -1042,6 +1138,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) = @@ -1067,6 +1164,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, @@ -1083,9 +1184,8 @@ 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); } sub setup_date_selectors { @@ -1242,7 +1342,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') { @@ -1254,6 +1354,7 @@ sub default_role_selector { 'grs' => "Section", 'exs' => "Existing sections", 'new' => "New section", + 'crd' => "Credits", ); $options = ''; + } $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". @@ -1286,9 +1393,9 @@ sub default_role_selector { &default_course_roles($context,$checkpriv,'Course',%customroles)."\n". ''. ''. - ''. ''. '
'. + '
'. $lt{'exs'}.'
  '.$lt{'new'}.'
'. @@ -1300,7 +1407,7 @@ sub default_role_selector { ''. ''. ''. - '
'. + ''.$creditsinput. &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table()."\n"; } @@ -1422,6 +1529,7 @@ sub curr_role_permissions { sub my_custom_roles { my ($crstype) = @_; my %returnhash=(); + my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1}); my %rolehash=&Apache::lonnet::dump('roles'); foreach my $key (keys(%rolehash)) { if ($key=~/^rolesdef\_(\w+)$/) { @@ -1436,7 +1544,7 @@ 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'; @@ -1444,8 +1552,9 @@ sub print_userlist { 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') { @@ -1470,20 +1579,16 @@ sub print_userlist { @statuses = ('future'); } -# if ($context eq 'course') { -# $r->print(&display_adv_courseroles()); -# } - # # Interface output $r->print('
'."\n". ''); - $r->print("

\n"); + $r->print('

'."\n"); if ($env{'form.action'} ne 'modifystudent') { my %lt=&Apache::lonlocal::texthash('csv' => "CSV", 'excel' => "Excel", 'html' => 'HTML'); - my $output_selector = ''; foreach my $outputformat ('html','csv','excel') { my $option = '
'. + &column_checkboxes($context,$mode,$formname,$showcredits). + '
'); if ($env{'form.phase'} eq '') { - $r->print('

'.&list_submit_button(&mt('Display List of Users')). - "\n

\n". + $r->print('
'. + &list_submit_button(&mt('Display List of Users'))."\n". '
'); 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" - ); + (($env{'form.roletype'} eq 'course') || ($env{'form.roletype'} eq 'community')))) { + $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 'course') || ($env{'form.roletype'} eq 'community')) { my ($crstype,$numcodes,$title,$warning); if ($env{'form.roletype'} eq 'course') { @@ -1542,15 +1654,15 @@ sub print_userlist { $title = &mt('Select Communities'); $warning = &mt('Warning: data retrieval for multiple communities can take considerable time, as this operation is not currently optimized.'); } + my @standardnames = &Apache::loncommon::get_standard_codeitems(); my $courseform = &Apache::lonhtmlcommon::course_selection($formname,$numcodes, - $codetitles,$idlist,$idlist_titles,$crstype); - $r->print('

'.&Apache::lonhtmlcommon::start_pick_box()."\n". - &Apache::lonhtmlcommon::start_pick_box()."\n". - &Apache::lonhtmlcommon::row_title($title,'LC_oddrow_value')."\n". + $codetitles,$idlist,$idlist_titles,$crstype, + \@standardnames); + $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"); @@ -1560,10 +1672,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') { @@ -1598,6 +1710,12 @@ sub print_userlist { \%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') { @@ -1683,33 +1801,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.') .'' ); @@ -1717,6 +1839,7 @@ sub print_userlist { } $r->print(''); + return; } sub role_filter { @@ -1729,11 +1852,11 @@ sub role_filter { my ($role_select); if ($context eq 'domain') { $role_select = &domain_roles_select(); - $output = ''; + .'
'; } else { - $role_select = ''."\n". ''; my ($roletype,$crstype); @@ -1760,9 +1883,9 @@ sub role_filter { $role_select .= ''; } $role_select .= ''; - $output = ''; + .''; } return $output; } @@ -1825,11 +1948,200 @@ 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')); + } + } + return @cols; +} + +sub column_checkboxes { + my ($context,$mode,$formname,$showcredits) = @_; + 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; + } + } elsif ($context eq 'domain') { + $unchecked{'extent'} = 1; + } + $unchecked{'start'} = 1; + $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; + } + } + } + my $numposs = scalar(@cols); + my $numinrow = 7; + my %lt = &get_column_names($context); + my $output = '
'.&mt('Information to show').''."\n".''. + ''. + (' 'x3). + ''. + ''; + + for (my $i=0; $i<$numposs; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $output .= ''; + } + $output .= ''; + } + my $checked; + if ($env{'form.phase'} eq '') { + $checked = ' checked="checked"'; + if ($unchecked{$cols[$i]}) { + $checked = ''; + } + if ($disabledchk{$cols[$i]}) { + $checked = ' disabled="disabled"'; + } + } elsif (grep(/^\Q$cols[$i]\E$/,@showncols)) { + $checked = ' checked="checked"'; + } elsif ($disabledchk{$cols[$i]}) { + $checked = ' disabled="disabled"'; + } + if ($i == $numposs-1) { + my $colsleft = $numinrow-$rem; + if ($colsleft > 1) { + $output .= ''; + } + $output .= '
'; + } else { + $output .= ''; + } + } else { + $output .= ''; + } + my $style; + if ($cols[$i] eq 'extent') { + if (($env{'form.roletype'} eq 'domain') || ($env{'form.roletype'} eq '')) { + $style = ' style="display: none;"'; + } + } elsif (($cols[$i] eq 'authorusage') || ($cols[$i] eq 'authorquota')) { + if ($env{'form.roletype'} ne 'domain') { + $style = ' style="display: none;"'; + } + } + $output .= '
'; + 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", + ); + 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; @@ -1993,7 +2305,7 @@ function setCourseCat(formname) { if (formname.Year.options[formname.Year.selectedIndex].value == -1) { return; } - courseSet('Year'); + courseSet('$codetitles[0]'); for (var j=0; j'.$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(); @@ -2120,6 +2409,9 @@ 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->{'authorquota'} = &Apache::loncoursedata::CL_AUTHORQUOTA(); + $index->{'authorusage'} = &Apache::loncoursedata::CL_AUTHORUSAGE(); foreach my $key (keys(%{$index})) { $keylist->[$index->{$key}] = $key; } @@ -2168,10 +2460,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); @@ -2183,34 +2477,36 @@ 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 ($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') { @@ -2239,14 +2531,12 @@ 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", - '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", ); - 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'); - } - + my %lt = (%coltxt,%acttxt); my $rolefilter = $env{'form.showrole'}; if ($env{'form.showrole'} eq 'cr') { $rolefilter = &mt('custom'); @@ -2379,8 +2616,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') { @@ -2401,7 +2637,7 @@ END END if ($actionselect) { $output .= <<"END"; -
$lt{'ac'} +
$lt{'ac'} $actionselect

 
@@ -2442,11 +2678,17 @@ 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; + } } } } } - $output .= '
'.$lt{'link'}.''. + $output .= '
'.$lt{'link'}.''. ''; my @linkdests = ('aboutme'); if ($permission->{'cusr'}) { @@ -2457,6 +2699,7 @@ END $env{'request.course.sec'})) { push(@linkdests,'track'); } + $output .= '
'; my $usernamelink = $env{'form.usernamelink'}; if ($usernamelink eq '') { @@ -2473,9 +2716,13 @@ END if ($env{'form.userwin'}) { $checkwin = ' checked="checked"'; } - $output .= ''.$lt{'owin'}.'
'; + $output .= + '' + .'
'; } - $output .= "\n".''."\n". + $output .= "\n".'
'."\n". &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(); if ($mode eq 'autoenroll') { @@ -2485,49 +2732,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') { @@ -2548,14 +2765,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); @@ -2591,6 +2806,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})) { @@ -2674,7 +2894,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'}] = @@ -2682,12 +2902,37 @@ 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); 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; @@ -2708,12 +2953,20 @@ 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; foreach my $user (@sorted_users) { my %in; @@ -2724,18 +2977,26 @@ 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); - 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()); @@ -2743,10 +3004,10 @@ END if ($mode eq 'autoenroll') { my $cellentry; if ($in{'type'} eq 'auto') { - $cellentry = ''.&mt('auto').' '; + $cellentry = ''.&mt('auto').' '; $autocount ++; } else { - $cellentry = '
'.&mt('manual').'
'; + $cellentry = ''); + } else { + $r->print(''); } - $r->print(''); } else { $r->print(''); } @@ -2810,43 +3081,36 @@ END $showitem = $ltstatus{$in{$item}}; } $r->print(''."\n"); - } else { - $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(''); - } 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(''); } else { - $r->print(' '); - } + $r->print(''."\n"); + } } + } elsif (($item eq 'authorquota') || ($item eq 'authorusage')) { + $r->print(''."\n"); + } else { + $r->print(''."\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}); @@ -2856,9 +3120,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'); @@ -2874,10 +3138,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') { @@ -3039,6 +3303,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') { @@ -3046,15 +3311,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; + } } } } @@ -3161,11 +3431,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(); @@ -3581,17 +3862,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", @@ -3610,7 +3894,7 @@ END - + @@ -3624,21 +3908,21 @@ END $r->print(<  END $r->print(&Apache::loncommon::end_data_table_header_row()); @@ -3709,7 +3993,6 @@ END $btn = $lt{'dm'}; } $r->print(<<"END"); -

  @@ -3731,19 +4014,27 @@ 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')) - .&Apache::loncommon::upfile_select_html() + .&Apache::lonhtmlcommon::row_title(&mt('File')); + if (&Apache::lonlocal::current_language() ne 'en') { + if ($context eq 'course') { + $str .= '

'."\n" + .&mt('Please upload an UTF8 encoded file to ensure a correct character encoding in your classlist.')."\n" + .'

'."\n"; + } + } + $str .= &Apache::loncommon::upfile_select_html() .&Apache::lonhtmlcommon::row_closure() .&Apache::lonhtmlcommon::row_title( '
'.&mt('manual').'
'; $manualcount ++; if ($in{'lockedtype'}) { $cellentry .= ''; @@ -2781,17 +3042,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('  '.$showitem.''.$in{$item}.' '.$clickers.' '.$clickers.'  '.$in{$item}.''.$in{$item}.'  $lt{'usrn'} $lt{'dom'}ID$lt{'id'} $nametitle $lt{'sec'} $lt{'start'} - $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'}