--- loncom/interface/lonuserutils.pm 2010/11/15 18:50:37 1.97.2.25 +++ loncom/interface/lonuserutils.pm 2010/09/20 00:26:44 1.109.2.5 @@ -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.109.2.5 2010/09/20 00:26:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,6 +36,7 @@ use Apache::loncommon(); use Apache::lonhtmlcommon; use Apache::lonlocal; use Apache::longroup; +use Apache::lonnavmaps; use LONCAPA qw(:DEFAULT :match); ############################################################### @@ -47,8 +48,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); @@ -296,7 +296,7 @@ sub hidden_input { } sub print_upload_manager_header { - my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission,$crstype, + my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission,$crstype,$formname, $can_assign)=@_; my $javascript; # @@ -327,9 +327,32 @@ sub print_upload_manager_header { $password_choice = 'int'; } # - my $groupslist; + my ($sectionjs,$groupslist); if ($context eq 'course') { $groupslist = &get_groupslist(); + if ($env{'form.caller'} eq 'requestcrs') { + $sectionjs = <<"ENDJS"; + +function toggleSectionsDefault() { + var usingsecs; + if (document.$formname.usesection.length > 1) { + for (var i=0; i\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('Enter as many fields as you can.').'
'. + &mt('The system will inform you and bring you back to this page,'). + '
'.&mt('if the data selected are insufficient to add users.')."
\n"); $r->print(&hidden_input('action','upload'). &hidden_input('state','got_file'). &hidden_input('associate',''). &hidden_input('datatoken',$datatoken). &hidden_input('fileupload',$env{'form.fileupload'}). &hidden_input('upfiletype',$env{'form.upfiletype'}). - &hidden_input('upfile_associate',$env{'form.upfile_associate'})); + &hidden_input('upfile_associate',$env{'form.upfile_associate'}). + &hidden_input('caller',$env{'form.caller'})); $r->print('

'); $r->print('
print("

\n". ''); } @@ -389,9 +415,13 @@ sub javascript_validations { if ($context eq 'course') { if ($env{'request.course.sec'} eq '') { $setsection_call = 'setSections(document.'.$param{'formname'}.",'$crstype'".');'; - $setsections_js = - &setsections_javascript($param{'formname'},$groupslist, - $mode,'',$crstype); + if ($env{'form.caller'} eq 'requestcrs') { + $setsections_js = &newsections_javascript($param{'formname'}); + } else { + $setsections_js = + &setsections_javascript($param{'formname'},$groupslist, + $mode,'',$crstype); + } } else { $setsection_call = "'ok'"; } @@ -519,7 +549,9 @@ END END } else { $section_checks = §ion_check_js(); - $optional_checks = (<{'krb4'} || $can_assign->{'krb5'}) { - $argreset .= " vf.krbarg.value='';\n"; - $numbuttons ++ ; - } - if ($can_assign->{'int'}) { - $argreset .= " vf.intarg.value='';\n"; - $numbuttons ++; - } - if ($can_assign->{'loc'}) { - $argreset .= " vf.locarg.value='';\n"; - $numbuttons ++; - } - if (!$can_assign->{'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'). - &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 - // (see bug 6368). - if (nw==9) { - eval('vf.f'+tf+'.selectedIndex=0;') - alert('$warning'); - } -END - } elsif ($numbuttons > 1) { + if (keys(%{$can_assign}) > 1) { $auth_update = <<"END"; // If we set the password, make the password form below correspond to // the new value. if (nw==9) { changed_radio('int',document.studentform); set_auth_radio_buttons('int',document.studentform); -$argreset - } - END } + if ($can_assign->{'krb'}) { + $auth_update .= " vf.krbarg.value='';\n"; + } + if ($can_assign->{'int'}) { + $auth_update .= " vf.intarg.value='';\n"; + } + if ($can_assign->{'loc'}) { + $auth_update .= " vf.locarg.value='';\n"; + } + $auth_update .= " + }\n"; } return(<{'krb4'} || $can_assign->{'krb5'}) { - $argreset .= " vf.krbarg.value='';\n"; - $numbuttons ++ ; + if (keys(%{$can_assign}) > 1) { + $auth_update = <<"END"; + // initial password specified, pick internal authentication + if (tf==8 && nw!=0) { + changed_radio('int',document.studentform); + set_auth_radio_buttons('int',document.studentform); +END + } + if ($can_assign->{'krb'}) { + $auth_update .= " vf.krbarg.value='';\n"; } if ($can_assign->{'int'}) { - $argreset .= " vf.intarg.value='';\n"; - $numbuttons ++; + $auth_update .= " vf.intarg.value='';\n"; } if ($can_assign->{'loc'}) { - $argreset .= " vf.locarg.value='';\n"; - $numbuttons ++; - } - 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.'); - $auth_update = <<"END"; - // Currently the initial password field is only supported for internal auth - // (see bug 6368). - if (tf==8 && nw!=0) { - eval('vf.f'+tf+'.selectedIndex=0;') - alert('$warning'); - } -END - } elsif ($numbuttons > 1) { - $auth_update = <<"END"; - // initial password specified, pick internal authentication - if (tf==8 && nw!=0) { - changed_radio('int',document.studentform); - set_auth_radio_buttons('int',document.studentform); -$argreset - } - -END + $auth_update .= " vf.locarg.value='';\n"; } + $auth_update .= " + }\n"; } - return(<' .&Apache::lonhtmlcommon::start_pick_box(); - - $Str .= &Apache::lonhtmlcommon::row_title(&mt('Login Type')); + if ($env{'form.caller'} eq 'requestcrs') { + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Default password')); + } else { + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Login Type')); + } if ($context eq 'domain') { $Str .= '

' .&mt('Change authentication for existing users in domain "[_1]" to these settings?' @@ -858,12 +871,17 @@ sub print_upload_manager_footer { .'

'; } else { $Str .= '

'."\n". - &mt('This will not take effect if the user already exists.'). - &Apache::loncommon::help_open_topic('Auth_Options'). - "

\n"; + &mt('This will not take effect if the user already exists.'); + my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($defdom); + if ($authnum > 1) { + $Str .= &Apache::loncommon::help_open_topic('Auth_Options'); + } + $Str .= "

\n"; } $Str .= &set_login($defdom,$krbform,$intform,$locform); - + if ($env{'form.caller'} eq 'requestcrs') { + $Str .= ''; + } my ($home_server_pick,$numlib) = &Apache::loncommon::home_server_form_item($defdom,'lcserver', 'default','hide'); @@ -879,14 +897,14 @@ sub print_upload_manager_footer { &Apache::lonhtmlcommon::row_closure(); } - $Str .= &Apache::lonhtmlcommon::row_title(&mt('Default domain')) - .&Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1) - .&Apache::lonhtmlcommon::row_closure(); - - $Str .= &Apache::lonhtmlcommon::row_title(&mt('Starting and Ending Dates')) - ."

\n".$date_table."

\n" - .&Apache::lonhtmlcommon::row_closure(); - + unless ($env{'form.caller'} eq 'requestcrs') { + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Default domain')) + .&Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1) + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Starting and Ending Dates')) + ."

\n".$date_table."

\n" + .&Apache::lonhtmlcommon::row_closure(); + } if ($context eq 'domain') { $Str .= &Apache::lonhtmlcommon::row_title( &mt('Settings for assigning roles')) @@ -906,9 +924,22 @@ 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 ($env{'form.caller'} eq 'requestcrs') { + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Default section')). + &mt('Students can be assigned to different sections.').'
'. + &mt('Will you be using sections?').' '. + ''. + ' '.&mt('Yes').''. + '   '; + } 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)')) @@ -932,11 +963,22 @@ sub print_upload_manager_footer { } } else { my ($cnum,$cdom) = &get_course_identity(); - my $rowtitle = &mt('section'); + my ($rowtitle,$closure); + if ($env{'form.caller'} eq 'requestcrs') { + $closure = 1; + $rowtitle = &mt('default section name (letters/numbers only)'); + } else { + $rowtitle = &mt('section'); + } my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle, - $permission,$context,'upload',$crstype); - $Str .= $secbox - .&Apache::lonhtmlcommon::row_closure(); + $permission,$context,'upload',$crstype, + $env{'form.caller'}). + &Apache::lonhtmlcommon::row_closure($closure); + if ($env{'form.caller'} eq 'requestcrs') { + $Str .= ''; + } else { + $Str .= $secbox; + } my %lt; if ($crstype eq 'Community') { %lt = &Apache::lonlocal::texthash ( @@ -949,15 +991,19 @@ sub print_upload_manager_footer { stus => 'Students selected from this list can be dropped.' ); } - $Str .= &Apache::lonhtmlcommon::row_title(&mt('Full Update')) - .'
' - .$lt{'stus'} - .&Apache::lonhtmlcommon::row_closure(); + unless ($env{'form.caller'} eq 'requestcrs') { + $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); + unless ($env{'form.caller'} eq 'requestcrs') { + $Str .= &forceid_change($context); + } } $Str .= &Apache::lonhtmlcommon::end_pick_box(); @@ -1001,7 +1047,7 @@ sub forceid_change { ############################################################### ############################################################### sub print_upload_manager_form { - my ($r,$context,$permission,$crstype) = @_; + my ($r,$context,$permission,$crstype,$formname) = @_; my $firstLine; my $datatoken; if (!$env{'form.datatoken'}) { @@ -1049,12 +1095,13 @@ sub print_upload_manager_form { # my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($defdom); &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context, - $permission,$crstype,\%can_assign); + $permission,$crstype,$formname,\%can_assign); my $i; my $keyfields; if ($total>=0) { my @field= (['username',&mt('Username'), $env{'form.username_choice'}], + ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}], ['names',&mt('Last Name, First Names'),$env{'form.names_choice'}], ['fname',&mt('First Name'), $env{'form.fname_choice'}], ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}], @@ -1062,7 +1109,6 @@ sub print_upload_manager_form { ['gen', &mt('Generation'), $env{'form.gen_choice'}], ['id', &mt('Student/Employee ID'),$env{'form.id_choice'}], ['sec', &mt('Section'), $env{'form.sec_choice'}], - ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}], ['email',&mt('E-mail Address'), $env{'form.email_choice'}], ['role',&mt('Role'), $env{'form.role_choice'}], ['domain',&mt('Domain'), $env{'form.domain_choice'}], @@ -1255,8 +1301,10 @@ sub default_role_selector { 'exs' => "Existing sections", 'new' => "New section", ); - $options = ''."\n"; + unless (($context eq 'course') && (&Apache::loncommon::needs_gci_custom())) { + $options .= ' '."\n"; + } if ($context eq 'course') { $options .= &default_course_roles($context,$checkpriv,$crstype,%customroles); } elsif ($context eq 'author') { @@ -1517,18 +1565,14 @@ sub print_userlist { 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

\n"); } my ($indexhash,$keylist) = &make_keylist_array(); my (%userlist,%userinfo,$clearcoursepick); 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') { @@ -1802,7 +1846,7 @@ sub section_group_filter { } if (@options > 0) { my $currsel; - $markup = ''."\n"; foreach my $option ('all','none',@options) { $currsel = ''; if ($env{'form.'.$name{$item}} eq $option) { @@ -1817,9 +1861,7 @@ sub section_group_filter { $markup .= ''."\n"; } $markup .= ''."\n"; - $output .= (' 'x3).'' - .'' - .' '; + $output .= (' 'x3).''; } } return $output; @@ -2169,6 +2211,7 @@ sub process_date_info { sub show_users_list { my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_; + my $custommenu; if ($formname eq '') { $formname = 'studentform'; } @@ -2193,11 +2236,17 @@ sub show_users_list { $sortby = 'username'; } my $setting = $env{'form.roletype'}; - my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype); + my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype, + $clickersupport,$displaygroups); if ($context eq 'course') { $cid = $env{'request.course.id'}; $crstype = &Apache::loncommon::course_type(); ($cnum,$cdom) = &get_course_identity($cid); + $custommenu = &Apache::loncommon::needs_gci_custom(); + unless ($custommenu) { + $clickersupport = 1; + $displaygroups = 1; + } ($classgroups) = &Apache::loncoursedata::get_group_memberships( $userlist,$keylist,$cdom,$cnum); if ($mode eq 'autoenroll') { @@ -2318,6 +2367,8 @@ END 'role' => "role", 'type' => "enroll type/action", 'email' => "e-mail address", + 'lastlogin' => "last login", + 'submissions' => "test status", 'photo' => "photo", 'extent' => "extent", 'pr' => "Proceed", @@ -2347,7 +2398,7 @@ END push(@cols,'section'); } if (!($context eq 'domain' && ($env{'form.roletype'} eq 'course') - && ($env{'form.roletype'} eq 'community'))) { + && ($env{'form.roletype'} eq 'community'))) { push(@cols,('start','end')); } if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') { @@ -2358,15 +2409,25 @@ END $env{'form.roletype'} eq 'community')) { push (@cols,'extent'); } - if (($statusmode eq 'Any') && + 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'); + if ($displaygroups) { + push(@cols,'groups'); + } } push(@cols,'email'); + if ($context eq 'course') { + if ($custommenu) { + push(@cols,'lastlogin'); + if (($env{'form.showrole'} eq 'Any') || ($env{'form.showrole'} eq 'st')) { + push(@cols,'submissions'); + } + } + } } my $rolefilter = $env{'form.showrole'}; @@ -2379,7 +2440,6 @@ END if ($mode ne 'autoenroll') { $results_description = &results_header_row($rolefilter,$statusmode, $context,$permission,$mode,$crstype); - $r->print(''.$results_description.'

'); } my ($output,$actionselect,%canchange,%canchangesec); @@ -2401,7 +2461,7 @@ END END if ($actionselect) { $output .= <<"END"; -
$lt{'ac'} +
$lt{'ac'} $actionselect

 
@@ -2446,7 +2506,7 @@ END } } } - $output .= '
'.$lt{'link'}.''. + $output .= '
'.$lt{'link'}.''. ''; my @linkdests = ('aboutme'); if ($permission->{'cusr'}) { @@ -2457,6 +2517,7 @@ END $env{'request.course.sec'})) { push(@linkdests,'track'); } + $output .= '
'; my $usernamelink = $env{'form.usernamelink'}; if ($usernamelink eq '') { @@ -2473,7 +2534,7 @@ END if ($env{'form.userwin'}) { $checkwin = ' checked="checked"'; } - $output .= ''.$lt{'owin'}.'
'; + $output .= ''.$lt{'owin'}.'
'; } $output .= "\n".''."\n". &Apache::loncommon::start_data_table(). @@ -2489,27 +2550,32 @@ END } } foreach my $item (@cols) { - $output .= "$lt{$item}\n"; + if (grep(/^\Q$item\E$/,@sortable)) { + $output .= "$lt{$item}\n"; + } else { + $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' + if ($clickersupport) { + 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( @@ -2548,14 +2614,18 @@ END $CSVfile = undef; } # - push @cols,'clicker'; + if ($clickersupport) { + 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'; + if ($clickersupport) { + push @cols,'clicker'; + } # Create the excel spreadsheet ($excel_workbook,$excel_filename,$format) = &Apache::loncommon::create_workbook($r); @@ -2591,6 +2661,40 @@ END Future => 'Future', Expired => 'Expired', ); + # If this is for a single course get last course "log-in" and submissions. + my (%crslogins,%stusubmissions,%elapsed,$numparts,%nummultipart,$multipart); + my $now = time; + if ($context eq 'course') { + if ($custommenu) { + %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum); + %stusubmissions=&Apache::lonnet::dump('nohist_submissiontracker',$cdom,$cnum); + %elapsed = &Apache::lonlocal::texthash( + -1 => 'more than a month ago', + 2592000 => 'within last 30 days', + 604800 => 'within last 7 days', + 86400 => 'within last 24 hours', + ); + my $navmap = Apache::lonnavmaps::navmap->new(); + if (defined($navmap)) { + my @allres=$navmap->retrieveResources('/uploaded/'.$cdom.'/'.$cnum.'/default_1261144274.sequence',sub { $_[0]->is_problem() },0); + foreach my $resource (@allres) { + my @parts = $resource->parts(); + my $count = scalar(@parts); + if ($count > 1) { + $nummultipart{$count} ++; + } + $numparts += $count; + } + if (keys(%nummultipart) > 0) { + $multipart = '
'.'contains'; + foreach my $key (sort {$a <=> $b} keys(%nummultipart)) { + $multipart .= " nummultipart{$key} multipart questions (with $key parts)"; + } + } + } + } + } + # Get groups, role, permanent e-mail so we can sort on them if # necessary. foreach my $user (keys(%{$userlist})) { @@ -2726,7 +2830,7 @@ END if ($clickers!~/\w/) { $clickers='-'; } $in{'clicker'} = $clickers; my $role = $in{'role'}; - $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype); + $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype); if (! defined($in{'start'}) || $in{'start'} == 0) { $in{'start'} = &mt('none'); } else { @@ -2737,6 +2841,34 @@ END } else { $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); } + if ($context eq 'course') { + if ($custommenu) { + my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role}; + if ($lastlogin ne '') { + my $sincelogin = $now - $lastlogin; + if ($sincelogin < 86400) { + $in{'lastlogin'} = $elapsed{'86400'}; + } elsif ($sincelogin < 604800) { + $in{'lastlogin'} = $elapsed{'604800'}; + } elsif ($sincelogin < 2592000 ) { + $in{'lastlogin'} = $elapsed{'2592000'}; + } else { + $in{'lastlogin'} = $elapsed{'-1'}; + } + } + } + if ($role eq 'st') { + my $numsub = $stusubmissions{$in{'username'}.':'.$in{'domain'}."\0attempts"} + + $stusubmissions{$in{'username'}.':'.$in{'domain'}."\0surveysubs"}; + if (!$numsub) { + $in{'submissions'} = 'not attempted'; + } elsif ($numsub < $numparts) { + $in{'submissions'} = 'incomplete ('.$numsub.'/'.$numparts.')'; + } else { + $in{'submissions'} = 'completed'; + } + } + } if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::start_data_table_row()); my $checkval; @@ -2810,19 +2942,27 @@ END $showitem = $ltstatus{$in{$item}}; } $r->print(''.$showitem.''."\n"); + } elsif ($item eq 'submissions') { + if ($in{$item} =~ /^incomplete/) { + $r->print(''.$in{$item}.$multipart.''); + } else { + $r->print(''.$in{$item}.''."\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 = + if ($clickersupport) { + if ($displayclickers eq 'on') { + my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1]; - if ($clickers!~/\w/) { $clickers='-'; } - $r->print(''.$clickers.''); - } else { - $r->print('   '); + 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 '') { @@ -3013,7 +3153,7 @@ sub print_username_link { $output = $in->{'username'}; } else { $output = '{'username'}','$in->{'domain'}'".')">'. + "'$in->{'username'}','$in->{'domain'}'".')" />'. $in->{'username'}.''; } return $output; @@ -3243,8 +3383,8 @@ 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 course role that is not "student", users may have roles in more than one section at a time.', + 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).', ); @@ -3263,13 +3403,14 @@ ENDJS $permission,$crstype); } $output .= '

'.$headertext.'

'. - '
'."\n". + ''."\n". $date_items; if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') { my ($cnum,$cdom) = &get_course_identity(); + my $crstype = &Apache::loncommon::course_type(); if ($crstype eq 'Community') { - $lt{'fors'} = &mt('For member roles, changing the section will result in a section switch, as members may only be in one section of a community at a time.'); - $lt{'forn'} = &mt('For a community role that is not "member", users may have roles in more than one section at a time.'); + $lt{'fors'} = &mt('For member roles changing the section, will result in a section switch as members may only be in one section of a community at a time.'); + $lt{'forn'} = &mt('For a role in a community that is not a member role, a user may have roles in more than one section of a community at a time.'); $lt{'dnap'} = &mt('(Does not apply to member roles).'); } my $info; @@ -3307,23 +3448,27 @@ ENDJS } sub section_picker { - my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode,$crstype) = @_; + my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode,$crstype,$caller) = @_; my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); my $sections_select .= &course_sections(\%sections_count,$role); - my $secbox = '
'.&Apache::lonhtmlcommon::start_pick_box()."\n"; - if ($mode eq 'upload') { + my $secbox = '

'.&Apache::lonhtmlcommon::start_pick_box()."\n"; + if ($mode eq 'upload' && $caller ne 'requestcrs') { my ($options,$cb_script,$coursepick) = &default_role_selector($context,1,$crstype); $secbox .= &Apache::lonhtmlcommon::row_title(&mt('role'),'LC_oddrow_value'). $options. &Apache::lonhtmlcommon::row_closure(1)."\n"; } $secbox .= &Apache::lonhtmlcommon::row_title($rowtitle,'LC_oddrow_value')."\n"; - if ($env{'request.course.sec'} eq '') { + if ($caller eq 'requestcrs') { + $secbox .= ''."\n". + ''."\n". + ''."\n"; + } elsif ($env{'request.course.sec'} eq '') { $secbox .= ''."\n". '
'.&mt('Existing sections')."\n". '
'.$sections_select.'
'. &mt('New section').'
'."\n". - ''."\n". + ''."\n". ''."\n". '
'."\n"; } else { @@ -3332,7 +3477,7 @@ sub section_picker { $env{'request.course.sec'}; } $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n". - &Apache::lonhtmlcommon::end_pick_box().'

'; + &Apache::lonhtmlcommon::end_pick_box().'

'; return $secbox; } @@ -3473,12 +3618,11 @@ sub results_header_row { if ($rolefilter eq 'Any') { $description .= &mt('All users with co-author roles in domain',$showfilter); } else { - $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter); + $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter); } } } elsif (($env{'form.roletype'} eq 'course') || ($env{'form.roletype'} eq 'community')) { - my $coursefilter = $env{'form.coursepick'}; if ($env{'form.roletype'} eq 'course') { if ($coursefilter eq 'category') { @@ -3538,6 +3682,10 @@ sub show_drop_list { my ($r,$classlist,$nosort,$permission,$crstype) = @_; my $cid = $env{'request.course.id'}; my ($cnum,$cdom) = &get_course_identity($cid); + my $displaygroups; + unless (&Apache::loncommon::needs_gci_custom()) { + $displaygroups = 1; + } if (! exists($env{'form.sortby'})) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['sortby']); @@ -3615,8 +3763,10 @@ END $lt{'sec'} $lt{'start'} $lt{'end'} - $lt{'groups'} END + if ($displaygroups) { + $r->print(" $lt{'groups'}\n"); + } $r->print(&Apache::loncommon::end_data_table_header_row()); } else { $r->print(&Apache::loncommon::start_data_table(). @@ -3637,10 +3787,13 @@ END $lt{'start'} $lt{'end'} - - $lt{'groups'} END + if ($displaygroups) { + $r->print(" + $lt{'groups'} + \n"); + } $r->print(&Apache::loncommon::end_data_table_header_row()); } # @@ -3693,8 +3846,10 @@ END $section $start $startitem $end - $active_groups END + if ($displaygroups) { + $r->print(" $active_groups\n"); + } $r->print(&Apache::loncommon::end_data_table_row()); } $r->print(&Apache::loncommon::end_data_table().'
'); @@ -3725,13 +3880,15 @@ END # Print out the initial form to get the file containing a list of users # sub print_first_users_upload_form { - my ($r,$context) = @_; + my ($r,$context,$noheader,$caller) = @_; my $str; $str = ''; $str .= ''; $str .= ''; - $str .= '

'.&mt('Upload a file containing information about users').'

'."\n"; + unless ($noheader) { + $str .= '

'.&mt('Upload a file containing information about users').'

'."\n"; + } # Excel and CSV Help $str .= '
' @@ -3745,15 +3902,15 @@ sub print_first_users_upload_form { .&Apache::lonhtmlcommon::row_title(&mt('File')) .&Apache::loncommon::upfile_select_html() .&Apache::lonhtmlcommon::row_closure() - .&Apache::lonhtmlcommon::row_title( - '') - .'' + .&Apache::lonhtmlcommon::row_title(&mt('Ignore First Line, e.g., contains column titles')) + .'' + .'   ' + .'' .&Apache::lonhtmlcommon::row_closure(1) .&Apache::lonhtmlcommon::end_pick_box(); $str .= '

' + .'' .'' .'

'; @@ -3816,9 +3973,15 @@ sub upfile_drop_add { $crstype = &Apache::loncommon::course_type($cid); } } - my ($startdate,$enddate) = &get_dates_from_form(); - if ($env{'form.makedatesdefault'}) { - $r->print(&make_dates_default($startdate,$enddate,$context,$crstype)); + my ($startdate,$enddate); + if ($env{'form.caller'} eq 'requestcrs') { + $startdate = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'}; + $enddate = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'}; + } else { + ($startdate,$enddate) = &get_dates_from_form(); + if ($env{'form.makedatesdefault'}) { + $r->print(&make_dates_default($startdate,$enddate,$context,$crstype)); + } } # Determine domain and desired host (home server) my $defdom=$env{'request.role.domain'}; @@ -3877,7 +4040,7 @@ sub upfile_drop_add { } elsif ($setting eq 'course') { $defaultrole = $env{'form.courserole'}; $defaultsec = $env{'form.sections'}; - } + } } elsif ($context eq 'author') { $defaultrole = $env{'form.defaultrole'}; } elsif ($context eq 'course') { @@ -3998,7 +4161,6 @@ sub upfile_drop_add { my @secs; my %entries=&Apache::loncommon::record_sep($line); # Determine user name - $entries{$fields{'username'}} =~ s/^\s+|\s+$//g; unless (($entries{$fields{'username'}} eq '') || (!defined($entries{$fields{'username'}}))) { my ($fname, $mname, $lname,$gen) = ('','','',''); @@ -4021,17 +4183,11 @@ sub upfile_drop_add { } if ($entries{$fields{'username'}} ne &LONCAPA::clean_username($entries{$fields{'username'}})) { - my $nowhitespace; - if ($entries{$fields{'username'}} =~ /\s/) { - $nowhitespace = ' - '.&mt('usernames may not contain spaces.'); - } $r->print('
'. &mt('[_1]: Unacceptable username for user [_2] [_3] [_4] [_5]', - ''.$entries{$fields{'username'}}.'',$fname,$mname,$lname,$gen). - $nowhitespace); + ''.$entries{$fields{'username'}}.'',$fname,$mname,$lname,$gen)); next; } else { - $entries{$fields{'domain'}} =~ s/^\s+|\s+$//g; if ($entries{$fields{'domain'}} ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) { $r->print('
'. ''.$entries{$fields{'domain'}}. @@ -4090,7 +4246,6 @@ sub upfile_drop_add { # determine email address my $email=''; if (defined($fields{'email'})) { - $entries{$fields{'email'}} =~ s/^\s+|\s+$//g; if (defined($entries{$fields{'email'}})) { $email=$entries{$fields{'email'}}; unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } @@ -4137,7 +4292,7 @@ sub upfile_drop_add { $role = $defaultrole; } # Clean up whitespace - foreach (\$id,\$fname,\$mname,\$lname,\$gen,\$inststatus) { + foreach (\$id,\$fname,\$mname,\$lname,\$gen) { $$_ =~ s/(\s+$|^\s+)//g; } # check against rules @@ -4148,17 +4303,41 @@ sub upfile_drop_add { if ($uhome eq 'no_host') { if ($userdomain ne $domain) { $r->print('
'. - &mt('[_1]: The domain specified ([_2]) is different to that of the course.', - ''.$username.'',$userdomain).'
'. - &mt('The user does not already exist, and you may not create a new user in a different domain.')); + &mt('[_1]: The domain specified ([_2]) is different to that of the course.', + ''.$username.'',$userdomain).'
'. + &mt('The user does not already exist, and you may not create a new user in a different domain.')); next; } $checkid = 1; $newuser = 1; my $user = $username.':'.$domain; + if ($username =~/^[^\@]+\@[^\@]+$/) { + if ($email eq '') { + $email = $username; + } + if (&Apache::loncommon::needs_gci_custom()) { + my $lc_email; + if ($username eq $email) { + $lc_email = lc($email); + } + my $lc_username = lc($username); + if ($lc_username ne $username) { + if ($username eq $email) { + $email = $lc_username; + } + $username = $lc_username; + $uhome=&Apache::lonnet::homeserver($username,$userdomain); + if ($uhome ne 'no_host') { + $newuser = 0; + } + } + } + } + } + if ($newuser) { my $checkhash; my $checks = { 'username' => 1 }; - $checkhash->{$username.':'.$domain} = { 'newuser' => 1, }; + $checkhash->{$user} = { 'newuser' => 1, }; &Apache::loncommon::user_rule_check($checkhash,$checks, \%alerts,\%rulematch,\%inst_results,\%curr_rules, \%got_rules); @@ -4172,18 +4351,18 @@ sub upfile_drop_add { } } } - my $usertype = 'unofficial'; - if (ref($rulematch{$user}) eq 'HASH') { - if ($rulematch{$user}{'username'}) { - $usertype = 'official'; - } - } - unless ($cancreate{$usertype}) { - my $showtype = $longtypes{$usertype}; - $r->print('
'. - &mt('[_1]: The user does not exist, and you are not permitted to create users of type: [_2].',''.$username.'',$showtype)); - next; + } + my $usertype = 'unofficial'; + if (ref($rulematch{$user}) eq 'HASH') { + if ($rulematch{$user}{'username'}) { + $usertype = 'official'; } + } + if (!$cancreate{$usertype}) { + r->print('
'. + &mt("[_1]: The user does not exist, and you are not permitted to create users of type: $longtypes{$usertype}.",''.$username.'')); + next; + } } else { if ($context eq 'course' || $context eq 'author') { if ($userdomain eq $domain ) { @@ -4271,7 +4450,7 @@ sub upfile_drop_add { $role = 'cr_'.$env{'user.domain'}.'_'. $env{'user.name'}.'_'.$role; } - if (($role ne 'cc') && ($role ne 'co')) { + if (($role ne 'cc') && ($role ne 'co')) { if (@secs > 1) { $multiple = 1; foreach my $sec (@secs) { @@ -4334,14 +4513,24 @@ sub upfile_drop_add { } } # end of foreach (@userdata) # Flush the course logs so reverse user roles immediately updated - $r->register_cleanup(\&Apache::lonnet::flushcourselogs); + &Apache::lonnet::flushcourselogs(); $r->print("

\n

\n".&mt('Processed [quant,_1,user].',$counts{'user'}). "

\n"); if ($counts{'role'} > 0) { - $r->print("

\n". - &mt('Roles added for [quant,_1,user].',$counts{'role'}).' '.&mt('If a user is currently logged-in to LON-CAPA, any new roles which are active will be available when the user next logs in.')."

\n"); + if (&Apache::loncommon::needs_gci_custom()) { + $r->print("

\n". + &mt('[quant,_1,student] enrolled in Concept Test.',$counts{'role'}). + "

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

\n". + &mt('Roles added for [quant,_1,user].',$counts{'role'}).' '.&mt('If a user is currently logged-in to LON-CAPA, any new roles which are active will be available when the user next logs in.')."

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

'.&mt('No roles added').'

'); + if (&Apache::loncommon::needs_gci_custom()) { + $r->print('

'.&mt('No students enrolled').'

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

'.&mt('No roles added').'

'); + } } if ($counts{'auth'} > 0) { $r->print("

\n". @@ -4498,9 +4687,10 @@ sub print_drop_menu { # ================================================================== Phase four sub update_user_list { - my ($r,$context,$setting,$choice,$crstype) = @_; + my ($r,$context,$setting,$choice) = @_; my $now = time; my $count=0; + my $crstype; if ($context eq 'course') { $crstype = &Apache::loncommon::course_type(); } @@ -4515,7 +4705,7 @@ sub update_user_list { 'reenable' => 'Re-enabled', 'activate' => 'Activated', 'chgdates' => 'Changed Access Dates for', - 'chgsec' => 'Changed section(s) for', + 'chgsec' => 'Changed section for', 'drop' => 'Dropped', }, error => {'revoke' => 'revoking', @@ -4532,9 +4722,8 @@ sub update_user_list { ($startdate,$enddate) = &get_dates_from_form(); } foreach my $item (@changelist) { - my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype, - @sections,$scopestem,$singlesec,$showsecs,$warn_singlesec, - $nothingtodo,$keepnosection); + my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections, + $scopestem); if ($choice eq 'drop') { ($uname,$udom,$sec) = split(/:/,$item,-1); $role = 'st'; @@ -4633,23 +4822,14 @@ sub update_user_list { } elsif ($choice eq 'chgsec') { my (@newsecs,$revresult,$nochg,@retained); if (($role ne 'cc') && ($role ne 'co')) { - my @secs = sort(split(/,/,$env{'form.newsecs'})); - if (@secs) { - my %curr_groups = &Apache::longroup::coursegroups(); - foreach my $sec (@secs) { - next if (($sec =~ /\W/) || ($sec eq 'none') || - (exists($curr_groups{$sec}))); - push(@newsecs,$sec); - } - } + @newsecs = split(/,/,$env{'form.newsecs'}); } # remove existing section if not to be retained. - if (!$env{'form.retainsec'} || ($role eq 'st')) { + if (!$env{'form.retainsec'}) { if ($sec eq '') { if (@newsecs == 0) { - $result = 'ok'; + $result = &mt('No change in section assignment (none)'); $nochg = 1; - $nothingtodo = 1; } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, @@ -4676,23 +4856,13 @@ sub update_user_list { } else { if ($sec eq '') { $nochg = 1; - $keepnosection = 1; } else { push(@retained,$sec); } } # add new sections - my (@diffs,@shownew); - if (@retained) { - @diffs = &Apache::loncommon::compare_arrays(\@retained,\@newsecs); - } else { - @diffs = @newsecs; - } if (@newsecs == 0) { - if ($nochg) { - $result = 'ok'; - $nothingtodo = 1; - } else { + if (!$nochg) { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context); @@ -4701,41 +4871,15 @@ sub update_user_list { $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context); } } - $showsecs = &mt('No section'); - } elsif (@diffs == 0) { - $result = 'ok'; - $nothingtodo = 1; } else { foreach my $newsec (@newsecs) { if (!grep(/^\Q$newsec\E$/,@retained)) { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context); - if (@newsecs > 1) { - my $showsingle; - if ($newsec eq '') { - $showsingle = &mt('No section'); - } else { - $showsingle = $newsec; - } - if ($crstype eq 'Community') { - $warn_singlesec = &mt('Although more than one section was indicated, a role was only added for the first section - [_1], as each community member may only be in one section at a time.',''.$showsingle.''); - } else { - $warn_singlesec = &mt('Although more than one section was indicated, a role was only added for the first section - [_1], as each student may only be in one section of a course at a time.',''.$showsingle.''); - } - $showsecs = $showsingle; - last; - } else { - if ($newsec eq '') { - $showsecs = &mt('No section'); - } else { - $showsecs = $newsec; - } - } } else { my $newscope = $scopestem; if ($newsec ne '') { $newscope .= '/'.$newsec; - push(@shownew,$newsec); } $result = &Apache::lonnet::assignrole($udom,$uname, $newscope,$role,$end,$start); @@ -4743,15 +4887,6 @@ sub update_user_list { } } } - unless ($role eq 'st') { - unless ($showsecs) { - my @tolist = sort(@shownew,@retained); - if ($keepnosection) { - push(@tolist,&mt('No section')); - } - $showsecs = join(', ',@tolist); - } - } } } my $extent = $scope; @@ -4762,48 +4897,13 @@ sub update_user_list { } } if ($result eq 'ok' || $result eq 'ok:') { - my $dates; - if (($choice eq 'chgsec') || ($choice eq 'chgdates')) { - $dates = &dates_feedback($start,$end,$now); - } - if ($choice eq 'chgsec') { - if ($nothingtodo) { - $r->print(&mt("Section assignment for role of '[_1]' in [_2] for '[_3]' unchanged.",$plrole,$extent,''. - &Apache::loncommon::plainname($uname,$udom). - '').' '); - if ($sec eq '') { - $r->print(&mt('[_1]No section[_2] - [_3]','','',$dates)); - } else { - $r->print(&mt('Section(s): [_1] - [_2]', - ''.$showsecs.'',$dates)); - } - $r->print('
'); - } else { - $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]' to [_4] - [_5]",$plrole,$extent, - ''.&Apache::loncommon::plainname($uname,$udom).'', - ''.$showsecs.'',$dates).'
'); - $count ++; - } - if ($warn_singlesec) { - $r->print('

'.$warn_singlesec.'
'); - } - } elsif ($choice eq 'chgdates') { - $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]' - [_4]",$plrole,$extent, - ''.&Apache::loncommon::plainname($uname,$udom).'', - $dates).'
'); - $count ++; - } else { - $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for '[_3]'.",$plrole,$extent, - ''.&Apache::loncommon::plainname($uname,$udom).''). - '
'); - $count ++; - } + $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]", + $plrole,$extent,$uname.':'.$udom).'
'); + $count++; } else { $r->print( - &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for '[_3]': [_4].", - $plrole,$extent, - ''.&Apache::loncommon::plainname($uname,$udom).'', - $result).'
'); + &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].", + $plrole,$extent,$uname.':'.$udom,$result).'
'); } } $r->print(''."\n"); @@ -4819,13 +4919,13 @@ 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} role(s) for [quant,_1,user,users,no users].",$count).'

'); if ($count > 0) { if ($choice eq 'revoke' || $choice eq 'drop') { $r->print('

'.&mt('Re-enabling will re-activate data for the role.').'

'); } # Flush the course logs so reverse user roles immediately updated - $r->register_cleanup(\&Apache::lonnet::flushcourselogs); + &Apache::lonnet::flushcourselogs(); } if ($env{'form.makedatesdefault'}) { if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') { @@ -4839,27 +4939,6 @@ sub update_user_list { $r->print(''.$linktext.''."\n"); } -sub dates_feedback { - my ($start,$end,$now) = @_; - my $dates; - if ($start < $now) { - if ($end == 0) { - $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 { - $dates = &mt('role(s) expired: [_1].',&Apache::lonlocal::locallocaltime($end)); - } - } else { - if ($end == 0 || $end > $now) { - $dates = &mt('future role(s); starts: [_1].',&Apache::lonlocal::locallocaltime($start)); - } else { - $dates = &mt('role(s) expired: [_1].',&Apache::lonlocal::locallocaltime($end)); - } - } - return $dates; -} - sub classlist_drop { my ($scope,$uname,$udom,$now) = @_; my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)}); @@ -5040,7 +5119,7 @@ sub setsections_javascript { accr => 'A course coordinator role will be added with access to all sections.', 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.', + inco => 'In each community, each user may only have on member role at a time.', youh => 'You had selected ', secs => 'sections.', plmo => 'Please modify your selections so they include no more than one section.', @@ -5048,21 +5127,16 @@ sub setsections_javascript { 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.', - nonw => 'Section names may only contain letters or numbers.', ); $setsection_js .= <<"ENDSECCODE"; function setSections(formname,crstype) { var re1 = /^currsec_/; - var re2 =/\\W/; - var trimleading = /^\\s+/; - var trimtrailing = /\\s+\$/; var groups = new Array($groupslist); for (var i=0;i 0) { - alert("$alerts{'nonw'}\\n$alerts{'plch'}"); - return; + } + if (numsec > 0) { + if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) { + sections = sections + "," + formname.elements[i+1].value; } - numsec = numsec + validsecs.length; } + else { + sections = formname.elements[i+1].value; + } + var newsecs = formname.elements[i+1].value; + var numsplit; + if (newsecs != null && newsecs != "") { + numsplit = newsecs.split(/,/g); + numsec = numsec + numsplit.length; + } + if ((role == 'st') && (numsec > 1)) { if (crstype == 'Community') { alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}"); @@ -5135,36 +5187,25 @@ function setSections(formname,crstype) { alert("$alerts{'inco'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}"); } return; - } else { - if (validsecs != null) { - for (var j=0; j 'In each course, each user may only have one student role at a time.', + youh => 'You had selected ', + secs => 'sections.', + plmo => 'Please modify your selections so they include no more than one section.', + mayn => 'may not be used as the name for a section, as it is a reserved word.', + plch => 'Please choose a different section name.', + ); + my $setsection_js = <<"ENDSECCODE"; + +function setSections(formname) { + var newsecs = formname.newsec.value; + var numsplit = 0; + var numsec = 0; + if (newsecs != null && newsecs != "") { + numsplit = newsecs.split(/,/g); + numsec = numsplit.length; + } + if (numsec > 1) { + alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}"); + } else { + if (numsplit > 0) { + for (var j=0; j 'You must select a course or community in the current domain', 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', + inco => 'In each community, each user may only have one member role at a time', youh => 'You had selected', sect => 'sections', plsm => 'Please modify your selections so they include no more than one section',