--- loncom/interface/lonuserutils.pm 2007/12/24 05:26:31 1.33 +++ loncom/interface/lonuserutils.pm 2010/01/20 16:46:23 1.114 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Utility functions for managing LON-CAPA user accounts # -# $Id: lonuserutils.pm,v 1.33 2007/12/24 05:26:31 raeburn Exp $ +# $Id: lonuserutils.pm,v 1.114 2010/01/20 16:46:23 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -42,7 +42,7 @@ use LONCAPA qw(:DEFAULT :match); ############################################################### # Drop student from all sections of a course, except optional $csec sub modifystudent { - my ($udom,$unam,$courseid,$csec,$desiredhost)=@_; + my ($udom,$unam,$courseid,$csec,$desiredhost,$context)=@_; # if $csec is undefined, drop the student from all the courses matching # this one. If $csec is defined, drop them from all other sections of # this course and add them to section $csec @@ -69,14 +69,14 @@ sub modifystudent { # dom name id mode pass f m l g ($udom,$unam,'', '', '',undef,undef,undef,undef, $section,time,undef,undef,$desiredhost,'','manual', - '',$courseid); + '',$courseid,'',$context); $result .= $reply.':'; } } } } if ($result eq '') { - $result = 'Unable to find section for this student'; + $result = &mt('Unable to find section for this student'); } else { $result =~ s/(ok:)+/ok/g; } @@ -86,12 +86,12 @@ sub modifystudent { sub modifyuserrole { my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass, $first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role, - $end,$start,$checkid) = @_; + $end,$start,$checkid,$inststatus) = @_; my ($scope,$userresult,$authresult,$roleresult,$idresult); if ($setting eq 'course' || $context eq 'course') { $scope = '/'.$cid; $scope =~ s/\_/\//g; - if ($role ne 'cc' && $sec ne '') { + if (($role ne 'cc') && ($role ne 'co') && ($sec ne '')) { $scope .='/'.$sec; } } elsif ($context eq 'domain') { @@ -124,12 +124,13 @@ sub modifyuserrole { $userresult = &Apache::lonnet::modifyuser($udom,$uname,$uid,$umode,$upass,$first, $middle,$last,$gene,$forceid,$desiredhome, - $email,$role,$start,$end); + $email,$inststatus); if ($userresult eq 'ok') { if ($role ne '') { $role =~ s/_/\//g; $roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope, - $role,$end,$start); + $role,$end,$start,'', + '',$context); } } return ($userresult,$authresult,$roleresult,$idresult); @@ -168,7 +169,7 @@ sub propagate_id_change { } sub update_classlist { - my ($cdom,$cnum,$udom,$uname,$user) = @_; + my ($cdom,$cnum,$udom,$uname,$user,$newend) = @_; my ($uid,$classlistentry); my $fullname = &Apache::lonnet::format_name($user->{'firstname'},$user->{'middlename'}, @@ -179,15 +180,37 @@ sub update_classlist { my @classinfo = split(/:/,$classhash{$uname.':'.$udom}); my $ididx=&Apache::loncoursedata::CL_ID() - 2; my $nameidx=&Apache::loncoursedata::CL_FULLNAME() - 2; + my $endidx = &Apache::loncoursedata::CL_END() - 2; + my $startidx = &Apache::loncoursedata::CL_START() - 2; for (my $i=0; $i<@classinfo; $i++) { - if ($i == $ididx) { + if ($i == $endidx) { + if ($newend ne '') { + $classlistentry .= $newend.':'; + } else { + $classlistentry .= $classinfo[$i].':'; + } + } elsif ($i == $startidx) { + if ($newend ne '') { + if ($classinfo[$i] > $newend) { + $classlistentry .= $newend.':'; + } else { + $classlistentry .= $classinfo[$i].':'; + } + } else { + $classlistentry .= $classinfo[$i].':'; + } + } elsif ($i == $ididx) { if (defined($user->{'id'})) { $classlistentry .= $user->{'id'}.':'; } else { $classlistentry .= $classinfo[$i].':'; } } elsif ($i == $nameidx) { - $classlistentry .= $fullname.':'; + if (defined($user->{'lastname'})) { + $classlistentry .= $fullname.':'; + } else { + $classlistentry .= $classinfo[$i].':'; + } } else { $classlistentry .= $classinfo[$i].':'; } @@ -212,7 +235,7 @@ sub domain_roles_select { # domain context # # Role types - my @roletypes = ('domain','author','course'); + my @roletypes = ('domain','author','course','community'); my %lt = &role_type_names(); # # build up the menu information to be passed to @@ -224,6 +247,10 @@ sub domain_roles_select { foreach my $roletype (@roletypes) { # set up the text for this domain $select_menus{$roletype}->{'text'}= $lt{$roletype}; + my $crstype; + if ($roletype eq 'community') { + $crstype = 'Community'; + } # we want a choice of 'default' as the default in the second menu if ($env{'form.roletype'} ne '') { $select_menus{$roletype}->{'default'} = $env{'form.showrole'}; @@ -238,7 +265,7 @@ sub domain_roles_select { @roles = &construction_space_roles(); } else { my $custom = 1; - @roles = &course_roles('domain',undef,$custom); + @roles = &course_roles('domain',undef,$custom,$roletype); } my $order = ['Any',@roles]; $select_menus{$roletype}->{'order'} = $order; @@ -248,14 +275,15 @@ sub domain_roles_select { &mt('Custom role'); } else { $select_menus{$roletype}->{'select2'}->{$role} = - &Apache::lonnet::plaintext($role); + &Apache::lonnet::plaintext($role,$crstype); } } $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any'); } my $result = &Apache::loncommon::linked_select_forms ('studentform',(' 'x3).&mt('Role: '),$env{'form.roletype'}, - 'roletype','showrole',\%select_menus,['domain','author','course']); + 'roletype','showrole',\%select_menus, + ['domain','author','course','community']); return $result; } @@ -267,7 +295,7 @@ sub hidden_input { } sub print_upload_manager_header { - my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_; + my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission,$crstype)=@_; my $javascript; # if (! exists($env{'form.upfile_associate'})) { @@ -304,10 +332,12 @@ sub print_upload_manager_header { my $javascript_validations = &javascript_validations('upload',$krbdefdom,$password_choice,undef, $env{'request.role.domain'},$context, - $groupslist); - my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':''); - $r->print(&mt('Total number of records found in file: [_1].',$distotal). - "
\n"); + $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"); @@ -318,32 +348,30 @@ 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(''); + $r->print('

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

\n". ''); + '// '."\n". + ''); } ############################################################### ############################################################### sub javascript_validations { my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain, - $context,$groupslist)=@_; - + $context,$groupslist,$crstype)=@_; my %param = ( kerb_def_dom => $krbdefdom, curr_authtype => $curr_authtype, ); - if ($mode eq 'createuser') { - $param{'formname'} = 'cu'; - } elsif ($mode eq 'upload') { + if ($mode eq 'upload') { $param{'formname'} = 'studentform'; - } elsif ($mode eq 'singlestudent') { - $param{'formname'} = 'cu'; } elsif ($mode eq 'createcourse') { $param{'formname'} = 'ccrs'; } elsif ($mode eq 'modifycourse') { @@ -358,16 +386,16 @@ sub javascript_validations { if (($context eq 'course') || ($context eq 'domain')) { if ($context eq 'course') { if ($env{'request.course.sec'} eq '') { - $setsection_call = 'setSections(document.'.$param{'formname'}.');'; + $setsection_call = 'setSections(document.'.$param{'formname'}.",'$crstype'".');'; $setsections_js = &setsections_javascript($param{'formname'},$groupslist, - $mode); + $mode,'',$crstype); } else { $setsection_call = "'ok'"; } } elsif ($context eq 'domain') { $setsection_call = 'setCourse()'; - $setsections_js = &dc_setcourse_js($param{'formname'},$mode); + $setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context); } $finish = " var checkSec = $setsection_call\n". " if (checkSec == 'ok') {\n". @@ -383,17 +411,20 @@ sub javascript_validations { krb => 'You need to specify the Kerberos domain.', ipass => 'You need to specify the initial password.', name => 'The optional name field was not specified.', - snum => 'The optional ID number field was not specified.', + snum => 'The optional student/employee ID field was not specified.', section => 'The optional section field was not specified.', - email => 'The optional email address field was not specified.', + email => 'The optional e-mail address field was not specified.', role => 'The optional role field was not specified.', + domain => 'The optional domain field was not specified.', continue => 'Continue adding users?', ); - - my $function_name =(<'; $Str .= &hidden_input('nfields',$i); $Str .= &hidden_input('keyfields',$keyfields); - $Str .= "

".&mt('Login Type')."

\n"; + + $Str .= '

'.&mt('Options').'

' + .&Apache::lonhtmlcommon::start_pick_box(); + + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Login Type')); if ($context eq 'domain') { - $Str .= '

'.&mt('Change authentication for existing users to these settings?').'   

'; + $Str .= '

' + .&mt('Change authentication for existing users in domain "[_1]" to these settings?' + ,$defdom) + .' ' + .'  ' + .'

'; } else { - $Str .= "

\n". - &mt('Note: this will not take effect if the user already exists'). + $Str .= '

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

\n"; } $Str .= &set_login($defdom,$krbform,$intform,$locform); + my ($home_server_pick,$numlib) = &Apache::loncommon::home_server_form_item($defdom,'lcserver', 'default','hide'); if ($numlib > 1) { - $Str .= '

'.&mt('LON-CAPA Home Server for New Users')."

\n". - &mt('LON-CAPA domain: [_1] with home server: [_2]',$defdom, - $home_server_pick).'
'; - } else { - $Str .= $home_server_pick; - } - $Str .= '

'.&mt('Starting and Ending Dates'). - "

\n"; - $Str .= "

\n".$date_table."

\n"; + $Str .= &Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title( + &mt('LON-CAPA Home Server for New Users')) + .&mt('LON-CAPA domain: [_1] with home server:','"'.$defdom.'"') + .$home_server_pick + .&Apache::lonhtmlcommon::row_closure(); + } else { + $Str .= $home_server_pick. + &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(); + if ($context eq 'domain') { - $Str .= '

'.&mt('Settings for assigning roles:').'

'."\n". - &mt('Pick the action to take on roles for these users:').'
      '; - } - if ($context eq 'author') { - $Str .= '

'.&mt('Default role')."

\n". - &mt('Choose the role to assign to users without a value specified in the uploaded file'); + $Str .= &Apache::lonhtmlcommon::row_title( + &mt('Settings for assigning roles')) + .&mt('Pick the action to take on roles for these users:').'
' + .'' + .'   ' + .'   ' + .''; + } elsif ($context eq 'author') { + $Str .= &Apache::lonhtmlcommon::row_title( + &mt('Default role')) + .&mt('Choose the role to assign to users without a value specified in the uploaded file.') } elsif ($context eq 'course') { - $Str .= '

'.&mt('Default role and section')."

\n". - &mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file'); - } else { - $Str .= '

'.&mt('Default role and/or section(s)')."
\n". - &mt('Role and/or section(s) for users without values specified in the uploaded file.'); + $Str .= &Apache::lonhtmlcommon::row_title( + &mt('Default role and section')) + .&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)')) + .&mt('Role and/or section(s) for users without values specified in the uploaded file.'); } - $Str .= '
'; if (($context eq 'domain') || ($context eq 'author')) { + $Str .= '
'; my ($options,$cb_script,$coursepick) = &default_role_selector($context,1); if ($context eq 'domain') { - $Str .= ''.&mt('Domain Level').'
'.$options.'

'.&mt('Course Level').'
'.$cb_script.$coursepick; + $Str .= '

' + .''.&mt('Domain Level').'
' + .$options + .'

' + .''.&mt('Course Level').'' + .'

' + .$cb_script.$coursepick + .&Apache::lonhtmlcommon::row_closure(); } elsif ($context eq 'author') { - $Str .= $options; + $Str .= $options + .&Apache::lonhtmlcommon::row_closure(1); # last row in pick_box } } else { my ($cnum,$cdom) = &get_course_identity(); my $rowtitle = &mt('section'); my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle, - $permission,$context,'upload'); - $Str .= $secbox."

".&mt('Full Update')."

\n". - '

\n"; + $permission,$context,'upload',$crstype); + $Str .= $secbox + .&Apache::lonhtmlcommon::row_closure(); + my %lt; + if ($crstype eq 'Community') { + %lt = &Apache::lonlocal::texthash ( + disp => 'Display members with current/future access who are not in the uploaded file', + stus => 'Members selected from this list can be dropped.' + ); + } else { + %lt = &Apache::lonlocal::texthash ( + disp => 'Display students with current/future access who are not in the uploaded file', + stus => 'Students selected from this list can be dropped.' + ); + } + $Str .= &Apache::lonhtmlcommon::row_title(&mt('Full Update')) + .'
' + .$lt{'stus'} + .&Apache::lonhtmlcommon::row_closure(); } if ($context eq 'course' || $context eq 'domain') { $Str .= &forceid_change($context); } - $Str .= '
'; + + # Footer + $Str .= ''; $r->print($Str); return; } @@ -782,25 +914,25 @@ sub print_upload_manager_footer { sub forceid_change { my ($context) = @_; my $output = - "

".&mt('ID/Student Number')."

\n". - "

\n".'
'."\n". - &mt('(only do if you know what you are doing.)')."\n"; + &Apache::lonhtmlcommon::row_title(&mt('Student/Employee ID')) + .'
'."\n" + .&mt('(only do if you know what you are doing.)')."\n"; if ($context eq 'domain') { $output .= '
'."\n"; } - $output .= '

'; + $output .= &Apache::lonhtmlcommon::row_closure(1); # last row in pick_box return $output; } ############################################################### ############################################################### sub print_upload_manager_form { - my ($r,$context,$permission) = @_; + my ($r,$context,$permission,$crstype) = @_; my $firstLine; my $datatoken; if (!$env{'form.datatoken'}) { @@ -830,6 +962,8 @@ sub print_upload_manager_form { 'ipwd_choice' => 'scalar', 'email_choice' => 'scalar', 'role_choice' => 'scalar', + 'domain_choice' => 'scalar', + 'inststatus_choice' => 'scalar', }; my $defdom = $env{'request.role.domain'}; if ($context eq 'course') { @@ -845,7 +979,7 @@ sub print_upload_manager_form { &Apache::loncommon::get_kerberos_defaults($defdom); # &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context, - $permission); + $permission,$crstype); my $i; my $keyfields; if ($total>=0) { @@ -856,11 +990,13 @@ sub print_upload_manager_form { ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}], ['lname',&mt('Last Name'), $env{'form.lname_choice'}], ['gen', &mt('Generation'), $env{'form.gen_choice'}], - ['id', &mt('ID/Student Number'),$env{'form.id_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'}]); + ['role',&mt('Role'), $env{'form.role_choice'}], + ['domain',&mt('Domain'), $env{'form.domain_choice'}], + ['inststatus',&mt('Affiliation'), $env{'form.inststatus_choice'}]); if ($env{'form.upfile_associate'} eq 'reverse') { &Apache::loncommon::csv_print_samples($r,\@records); $i=&Apache::loncommon::csv_print_select_table($r,\@records, @@ -879,7 +1015,7 @@ sub print_upload_manager_form { } $r->print(''); &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear, - $context,$permission); + $context,$permission,$crstype); } sub setup_date_selectors { @@ -937,8 +1073,15 @@ sub setup_date_selectors { sub get_dates_from_form { - my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate'); - my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate'); + my ($startname,$endname) = @_; + if ($startname eq '') { + $startname = 'startdate'; + } + if ($endname eq '') { + $endname = 'enddate'; + } + my $startdate = &Apache::lonhtmlcommon::get_date_from_form($startname); + my $enddate = &Apache::lonhtmlcommon::get_date_from_form($endname); if ($env{'form.no_end_date'}) { $enddate = 0; } @@ -946,7 +1089,7 @@ sub get_dates_from_form { } sub date_setting_table { - my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission) = @_; + my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission,$crstype) = @_; my $nolink; if ($bulkaction) { $nolink = 1; @@ -963,15 +1106,19 @@ sub date_setting_table { ($env{'form.action'} eq 'upload')) { if ($env{'request.course.sec'} eq '') { $dateDefault = ''. - ''; + ''; } } } my $perpetual = ''; if ($mode eq 'create_enrolldates') { @@ -994,7 +1141,7 @@ sub date_setting_table { } sub make_dates_default { - my ($startdate,$enddate,$context) = @_; + my ($startdate,$enddate,$context,$crstype) = @_; my $result = ''; if ($context eq 'course') { my ($cnum,$cdom) = &get_course_identity(); @@ -1002,26 +1149,34 @@ sub make_dates_default { {'default_enrollment_start_date'=>$startdate, 'default_enrollment_end_date' =>$enddate},$cdom,$cnum); if ($put_result eq 'ok') { - $result .= &mt('Set default start and end access dates for course.'). - '
'."\n"; + if ($crstype eq 'Community') { + $result .= &mt('Set default start and end access dates for community.'); + } else { + $result .= &mt('Set default start and end access dates for course.'); + } + $result .= '
'."\n"; # # Refresh the course environment &Apache::lonnet::coursedescription($env{'request.course.id'}, {'freshen_cache' => 1}); } else { - $result .= &mt('Unable to set default access dates for course.').":".$put_result. - '
'; + if ($crstype eq 'Community') { + $result .= &mt('Unable to set default access dates for community'); + } else { + $result .= &mt('Unable to set default access dates for course'); + } + $result .= ':'.$put_result.'
'; } } return $result; } sub default_role_selector { - my ($context,$checkpriv) = @_; + my ($context,$checkpriv,$crstype) = @_; my %customroles; my ($options,$coursepick,$cb_jscript); if ($context ne 'author') { - %customroles = &my_custom_roles(); + %customroles = &my_custom_roles($crstype); } my %lt=&Apache::lonlocal::texthash( @@ -1033,7 +1188,7 @@ sub default_role_selector { $options = ''."\n". + ''."\n". ''. ''. '
'. @@ -1074,6 +1229,7 @@ sub default_role_selector { $env{'request.role.domain'}.'" />'. ''. ''. + ''. '
'. &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table()."\n"; @@ -1083,13 +1239,13 @@ sub default_role_selector { } sub default_course_roles { - my ($context,$checkpriv,%customroles) = @_; + my ($context,$checkpriv,$crstype,%customroles) = @_; my $output; my $custom = 1; - my @roles = &course_roles($context,$checkpriv,$custom); + my @roles = &course_roles($context,$checkpriv,$custom,lc($crstype)); foreach my $role (@roles) { if ($role ne 'cr') { - my $plrole=&Apache::lonnet::plaintext($role); + my $plrole=&Apache::lonnet::plaintext($role,$crstype); $output .= ' '; } } @@ -1138,8 +1294,14 @@ sub domain_roles { } sub course_roles { - my ($context,$checkpriv,$custom) = @_; - my @allroles = &roles_by_context('course',$custom); + my ($context,$checkpriv,$custom,$roletype) = @_; + my $crstype; + if ($roletype eq 'community') { + $crstype = 'Community' ; + } else { + $crstype = 'Course'; + } + my @allroles = &roles_by_context('course',$custom,$crstype); my @roles; if ($context eq 'domain') { @roles = @allroles; @@ -1150,7 +1312,7 @@ sub course_roles { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) { push(@roles,$role); } else { - if ($role ne 'cc' && $env{'request.course.sec'} ne '') { + if ((($role ne 'cc') && ($role ne 'co')) && ($env{'request.course.sec'} ne '')) { if (&Apache::lonnet::allowed('c'.$role, $env{'request.course.id'}.'/'. $env{'request.course.sec'})) { @@ -1168,19 +1330,19 @@ sub course_roles { } sub curr_role_permissions { - my ($context,$setting,$checkpriv) = @_; + my ($context,$setting,$checkpriv,$type) = @_; my $custom = 1; my @roles; if ($context eq 'author') { @roles = &construction_space_roles($checkpriv); } elsif ($context eq 'domain') { if ($setting eq 'course') { - @roles = &course_roles($context,$checkpriv,$custom); + @roles = &course_roles($context,$checkpriv,$custom,$type); } else { @roles = &domain_roles($checkpriv); } } elsif ($context eq 'course') { - @roles = &course_roles($context,$checkpriv,$custom); + @roles = &course_roles($context,$checkpriv,$custom,$type); } return @roles; } @@ -1188,10 +1350,14 @@ sub curr_role_permissions { # ======================================================= Existing Custom Roles sub my_custom_roles { + my ($crstype) = @_; my %returnhash=(); my %rolehash=&Apache::lonnet::dump('roles'); - foreach my $key (keys %rolehash) { + foreach my $key (keys(%rolehash)) { if ($key=~/^rolesdef\_(\w+)$/) { + if ($crstype eq 'Community') { + next if ($rolehash{$key} =~ /bre\&S/); + } $returnhash{$1}=$1; } } @@ -1249,70 +1415,81 @@ sub print_userlist { 'html' => 'HTML'); my $output_selector = ''; - $r->print(''.(' 'x3)); - } - $r->print(''.(' 'x3)."\n"); + $r->print(''.(' 'x3)); + } + $r->print(''.(' 'x3)."\n"); my $roleselected = ''; if ($env{'form.showrole'} eq 'Any') { - $roleselected = ' selected="selected" '; + $roleselected = ' selected="selected"'; } - my ($role_select,$cnum,$cdom); - if ($context eq 'domain') { - $role_select = &domain_roles_select(); - $r->print(''); - } else { - $role_select = ''; - $r->print(''); - if ($context eq 'course') { - ($cnum,$cdom) = &get_course_identity(); - $r->print(§ion_group_filter($cnum,$cdom)); - } + my ($cnum,$cdom); + $r->print(&role_filter($context)); + if ($context eq 'course') { + ($cnum,$cdom) = &get_course_identity(); + $r->print(§ion_group_filter($cnum,$cdom)); + } + if ($env{'form.phase'} eq '') { + $r->print('

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

\n". + ''); + return; } - if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) { - $r->print(' '.&list_submit_button(&mt('Update Display')). - "\n

\n"); + 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" + ); } my ($indexhash,$keylist) = &make_keylist_array(); - my (%userlist,%userinfo); - if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { + my (%userlist,%userinfo,$clearcoursepick); + if (($context eq 'domain') && + ($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community')) { + my ($crstype,$numcodes,$title,$warning); + if ($env{'form.roletype'} eq 'course') { + $crstype = 'Course'; + $numcodes = $totcodes; + $title = &mt('Select Courses'); + $warning = &mt('Warning: data retrieval for multiple courses can take considerable time, as this operation is not currently optimized.'); + } elsif ($env{'form.roletype'} eq 'community') { + $crstype = 'Community'; + $numcodes = 0; + $title = &mt('Select Communities'); + $warning = &mt('Warning: data retrieval for multiple communities can take considerable time, as this operation is not currently optimized.'); + } my $courseform = - &Apache::lonhtmlcommon::course_selection($formname,$totcodes, - $codetitles,$idlist,$idlist_titles); + &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(&mt('Select Course(s)'), - 'LC_oddrow_value')."\n". + &Apache::lonhtmlcommon::row_title($title,'LC_oddrow_value')."\n". $courseform."\n". &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::end_pick_box().'

'. - '

'.&list_submit_button(&mt('Update Display')). - "\n

\n"); - if ($env{'form.coursepick'}) { + '

'. + &list_submit_button(&mt('Update Display')). + "\n".'

'.$warning.''."\n"); + $clearcoursepick = 0; + if (($env{'form.origroletype'} ne '') && + ($env{'form.origroletype'} ne $env{'form.roletype'})) { + $clearcoursepick = 1; + } + if (($env{'form.coursepick'}) && (!$clearcoursepick)) { $r->print('
'.&mt('Searching').' ...
 
'); } } else { @@ -1320,32 +1497,26 @@ sub print_userlist { } $r->rflush(); if ($context eq 'course') { - my $classlist = &Apache::loncoursedata::get_classlist(); - my $secidx = &Apache::loncoursedata::CL_SECTION(); - my $viewablesec = &viewable_section($permission); - foreach my $student (keys(%{$classlist})) { - my $section = $classlist->{$student}[$secidx]; - if ($viewablesec ne '') { - if ($section ne $viewablesec) { - next; - } else { - $userlist{$student} = $classlist->{$student}; - } - } else { - $userlist{$student} = $classlist->{$student}; + if (($env{'form.showrole'} eq 'st') || ($env{'form.showrole'} eq 'Any')) { + my $classlist = &Apache::loncoursedata::get_classlist(); + if (ref($classlist) eq 'HASH') { + %userlist = %{$classlist}; } } - my $showroles; - if ($env{'form.showrole'} ne 'Any') { - $showroles = [$env{'form.showrole'}]; - } else { - $showroles = undef; + if ($env{'form.showrole'} ne 'st') { + my $showroles; + if ($env{'form.showrole'} ne 'Any') { + $showroles = [$env{'form.showrole'}]; + } else { + $showroles = undef; + } + my $withsec = 1; + my $hidepriv = 1; + my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, + \@statuses,$showroles,undef,$withsec,$hidepriv); + &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo, + \%advrolehash,$permission); } - my $withsec = 1; - my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, - \@statuses,$showroles,undef,$withsec); - &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo, - \%advrolehash,$permission); } else { my (%cstr_roles,%dom_roles); if ($context eq 'author') { @@ -1391,10 +1562,12 @@ sub print_userlist { } } } - } elsif ($env{'form.roletype'} eq 'course') { - if ($env{'form.coursepick'}) { + } elsif (($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community')) { + if (($env{'form.coursepick'}) && (!$clearcoursepick)) { my %courses = &process_coursepick(); - my %allusers; + my %allusers; + my $hidepriv = 1; foreach my $cid (keys(%courses)) { my ($cnum,$cdom,$cdesc) = &get_course_identity($cid); next if ($cnum eq '' || $cdom eq ''); @@ -1402,7 +1575,8 @@ sub print_userlist { my (@roles,@sections,%access,%users,%userdata, %statushash); if ($env{'form.showrole'} eq 'Any') { - @roles = &course_roles($context,undef,$custom); + @roles = &course_roles($context,undef,$custom, + $env{'form.roletype'}); } else { @roles = ($env{'form.showrole'}); } @@ -1412,7 +1586,7 @@ sub print_userlist { foreach my $type (@statuses) { $access{$type} = $type; } - &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users,\%userdata,\%statushash); + &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users,\%userdata,\%statushash,$hidepriv); foreach my $user (keys(%userdata)) { next if (ref($userinfo{$user}) eq 'HASH'); foreach my $item ('fullname','id') { @@ -1448,6 +1622,8 @@ sub print_userlist { $r->print(&mt('There are no authors or co-authors to display.')."\n"); } elsif ($env{'form.roletype'} eq 'course') { $r->print(&mt('There are no course users to display')."\n"); + } elsif ($env{'form.roletype'} eq 'community') { + $r->print(&mt('There are no community users to display')."\n"); } } elsif ($context eq 'course') { $r->print(&mt('There are no course users to display.')."\n"); @@ -1463,13 +1639,64 @@ sub print_userlist { $permission,$env{'form.Status'},\%userlist,$keylist); } if (!$usercount) { - $r->print('
'.&mt('There are no users matching the search criteria.')); + $r->print('
' + .&mt('There are no users matching the search criteria.') + .'' + ); } } $r->print(''); } +sub role_filter { + my ($context) = @_; + my $output; + my $roleselected = ''; + if ($env{'form.showrole'} eq 'Any') { + $roleselected = ' selected="selected"'; + } + my ($role_select); + if ($context eq 'domain') { + $role_select = &domain_roles_select(); + $output = ''; + } else { + $role_select = ''; + $output = ' '; + } + return $output; +} + sub section_group_filter { my ($cnum,$cdom) = @_; my @filters; @@ -1487,14 +1714,14 @@ sub section_group_filter { all => 'all', none => 'none', ); - my ($output,@options); + my $output; foreach my $item (@filters) { - my $markup; + my ($markup,@options); if ($env{'form.'.$name{$item}} eq '') { $env{'form.'.$name{$item}} = 'all'; } if ($item eq 'sec') { - if ($env{'form.showrole'} eq 'cc') { + if (($env{'form.showrole'} eq 'cc') || ($env{'form.showrole'} eq 'co')) { $env{'form.'.$name{$item}} = 'none'; } my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); @@ -1505,11 +1732,11 @@ 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) { - $currsel = ' selected="selected" '; + $currsel = ' selected="selected"'; } $markup .= ' '."\n"; } $markup .= ''."\n"; - $output .= (' 'x3).''; + $output .= (' 'x3).'' + .'' + .' '; } } return $output; @@ -1533,6 +1762,10 @@ sub list_submit_button { sub gather_userinfo { my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_; + my $viewablesec; + if ($context eq 'course') { + $viewablesec = &viewable_section($permission); + } foreach my $item (keys(%{$rolehash})) { my %userdata; if ($context eq 'author') { @@ -1542,7 +1775,6 @@ sub gather_userinfo { &build_user_record($context,\%userdata,$userinfo,$indexhash, $item,$userlist); } elsif ($context eq 'course') { - my $viewablesec = &viewable_section($permission); ($userdata{'username'},$userdata{'domain'},$userdata{'role'}, $userdata{'section'}) = split(/:/,$item,-1); ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item}); @@ -1570,7 +1802,8 @@ sub gather_userinfo { $indexhash,$uniqid,$userlist); } } - } elsif ($env{'form.roletype'} eq 'course') { + } elsif (($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community')) { ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) = split(/:/,$item); if (ref($rolehash->{$item}) eq 'HASH') { @@ -1620,7 +1853,8 @@ sub gather_userinfo { sub build_user_record { my ($context,$userdata,$userinfo,$indexhash,$record_key,$userlist) = @_; next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1'); - if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) { + if (!(($context eq 'domain') && (($env{'form.roletype'} eq 'course') + && ($env{'form.roletype'} eq 'community')))) { &process_date_info($userdata); } my $username = $userdata->{'username'}; @@ -1735,13 +1969,17 @@ sub process_coursepick { my $coursefilter = $env{'form.coursepick'}; my $cdom = $env{'request.role.domain'}; my %courses; + my $crssrch = 'Course'; + if ($env{'form.roletype'} eq 'community') { + $crssrch = 'Community'; + } if ($coursefilter eq 'all') { %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.', - undef,undef,'Course'); + undef,undef,$crssrch); } elsif ($coursefilter eq 'category') { my $instcode = &instcode_from_coursefilter(); %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.', - undef,undef,'Course'); + undef,undef,$crssrch); } elsif ($coursefilter eq 'specific') { if ($env{'form.coursetotal'} > 1) { my @course_ids = split(/&&/,$env{'form.courselist'}); @@ -1810,6 +2048,8 @@ sub make_keylist_array { $index->{'email'} = &Apache::loncoursedata::CL_PERMANENTEMAIL(); $index->{'role'} = &Apache::loncoursedata::CL_ROLE(); $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT(); + $index->{'photo'} = &Apache::loncoursedata::CL_PHOTO(); + $index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL(); foreach my $key (keys(%{$index})) { $keylist->[$index->{$key}] = $key; } @@ -1858,7 +2098,10 @@ sub process_date_info { } sub show_users_list { - my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist)=@_; + my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_; + if ($formname eq '') { + $formname = 'studentform'; + } # # Variables for excel output my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format); @@ -1873,13 +2116,17 @@ sub show_users_list { } else { push(@sortable,'extent'); } + if ($mode eq 'pickauthor') { + @sortable = ('username','fullname','email','status'); + } if (!grep(/^\Q$sortby\E$/,@sortable)) { $sortby = 'username'; } my $setting = $env{'form.roletype'}; - my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$secfilter,$grpfilter); + my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype); if ($context eq 'course') { $cid = $env{'request.course.id'}; + $crstype = &Apache::loncommon::course_type(); ($cnum,$cdom) = &get_course_identity($cid); ($classgroups) = &Apache::loncoursedata::get_group_memberships( $userlist,$keylist,$cdom,$cnum); @@ -1897,6 +2144,7 @@ sub show_users_list { if ($env{'course.'.$cid.'.internal.showphoto'}) { $r->print(' '); } @@ -1912,69 +2161,71 @@ function photowindow(photolink) { END } + } elsif ($context eq 'domain') { + if ($setting eq 'community') { + $crstype = 'Community'; + } elsif ($setting eq 'course') { + $crstype = 'Course'; + } } - if ($mode ne 'autoenroll') { + if ($mode ne 'autoenroll' && $mode ne 'pickauthor') { my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript(); - my $alert = &mt("You must select at least one user by checking a user's 'Select' checkbox"); - my $singconfirm = &mt(' for a single user?'); - my $multconfirm = &mt(' for multiple users?'); - my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode); + my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode); + my $verify_action_js = &bulkaction_javascript($formname); $r->print(< +// 0) { - for (i = 0; i < field.length; i++) { - if (field[i].checked == true) { - numchecked ++; - } - } - } else { - if (field.checked == true) { - numchecked ++; - } - } - if (numchecked == 0) { - alert("$alert"); - } - else { - var message = document.studentform.bulkaction[document.studentform.bulkaction.selectedIndex].text; - if (numchecked == 1) { - message += singconf; - } - else { - message += multconf; - } - if (confirm(message)) { - document.studentform.phase.value = 'bulkchange'; - document.studentform.submit(); - } - } -} +$verify_action_js function username_display_launch(username,domain) { var target; - for (var i=0; i $date_sec_selector @@ -1996,63 +2247,79 @@ END 'status' => "status", 'role' => "role", 'type' => "enroll type/action", - 'email' => "email address", - 'clicker' => "clicker id", + 'email' => "e-mail address", 'photo' => "photo", 'extent' => "extent", 'pr' => "Proceed", 'ca' => "check all", 'ua' => "uncheck all", 'ac' => "Action to take for selected users", - 'link' => "Behavior of username links", - 'aboutme' => "Display a user's personal page", + '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 = ('username','domain','id','fullname'); - if ($context eq 'course') { - push(@cols,'section'); - } - if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) { - 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')) { - push (@cols,'extent'); - } - if (($statusmode eq 'Any') && - (!($context eq 'domain' && $env{'form.roletype'} eq 'course'))) { - push(@cols,'status'); - } - if ($context eq 'course') { - push(@cols,'groups'); + 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'); } - push(@cols,'email'); my $rolefilter = $env{'form.showrole'}; if ($env{'form.showrole'} eq 'cr') { $rolefilter = &mt('custom'); } elsif ($env{'form.showrole'} ne 'Any') { - $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'}); + $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'},$crstype); } my $results_description; if ($mode ne 'autoenroll') { $results_description = &results_header_row($rolefilter,$statusmode, - $context,$permission,$mode); - $r->print(''.$results_description.'
'); + $context,$permission,$mode,$crstype); + $r->print(''.$results_description.'

'); } my ($output,$actionselect,%canchange,%canchangesec); - if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') { - if ($mode ne 'autoenroll') { + if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { + if ($mode ne 'autoenroll' && $mode ne 'pickauthor') { if ($permission->{'cusr'}) { - $actionselect = &select_actions($context,$setting,$statusmode); + unless (($context eq 'domain') && + (($setting eq 'course') || ($setting eq 'community'))) { + $actionselect = + &select_actions($context,$setting,$statusmode,$formname); + } } $r->print(< @@ -2061,39 +2328,20 @@ END END - $output = '

'; - my @linkdests = ('aboutme'); - if ($permission->{'cusr'}) { - push (@linkdests,'modify'); - $output .= ''.$lt{'link'}.': '; - my $usernamelink = $env{'form.usernamelink'}; - if ($usernamelink eq '') { - $usernamelink = 'aboutme'; - } - foreach my $item (@linkdests) { - my $checkedstr = ''; - if ($item eq $usernamelink) { - $checkedstr = ' checked="checked" '; - } - $output .= '  '; - } - $output .= '
'; - } else { - $output .= &mt("Click on a username to view the user's personal page.").'
'; - } if ($actionselect) { - $output .= <<"END"; -$lt{'ac'}: $actionselect

-

  - + $output .= <<"END"; +

$lt{'ac'} +$actionselect +

  +
END my @allroles; if ($env{'form.showrole'} eq 'Any') { my $custom = 1; if ($context eq 'domain') { - @allroles = &roles_by_context($setting,$custom); + @allroles = &roles_by_context($setting,$custom,$crstype); } else { - @allroles = &roles_by_context($context,$custom); + @allroles = &roles_by_context($context,$custom,$crstype); } } else { @allroles = ($env{'form.showrole'}); @@ -2127,40 +2375,70 @@ END } } } + $output .= '
'.$lt{'link'}.''. + ''; + my @linkdests = ('aboutme'); + if ($permission->{'cusr'}) { + unshift (@linkdests,'modify'); + } + if (&Apache::lonnet::allowed('vsa', $env{'request.course.id'}) || + &Apache::lonnet::allowed('vsa', $env{'request.course.id'}.'/'. + $env{'request.course.sec'})) { + push(@linkdests,'track'); + } + + $output .= '
'; + my $usernamelink = $env{'form.usernamelink'}; + if ($usernamelink eq '') { + $usernamelink = 'aboutme'; + } + foreach my $item (@linkdests) { + my $checkedstr = ''; + if ($item eq $usernamelink) { + $checkedstr = ' checked="checked"'; + } + $output .= '
'; + } + my $checkwin; + if ($env{'form.userwin'}) { + $checkwin = ' checked="checked"'; + } + $output .= '
'.$lt{'owin'}.'
'; } - $output .= "\n

\n". + $output .= "\n".'

'."\n". &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(); if ($mode eq 'autoenroll') { $output .= " - $lt{'type'} + $lt{'type'} "; } else { - $output .= "\n".''.&mt('Count').''."\n"; + $output .= "\n".' '."\n"; if ($actionselect) { $output .= ''.&mt('Select').''."\n"; } } foreach my $item (@cols) { - $output .= "$lt{$item}\n"; + $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 = &Apache::lonlocal::texthash( - 'on' => 'Show', - 'off' => 'Hide', - ); + my %clicker_options = ( + 'on' => 'Show', + 'off' => 'Hide', + ); my $clickerchg = 'on'; if ($displayclickers eq 'on') { $clickerchg = 'off'; } - $output .= ' '."\n".' '. - ''. - $clicker_options{$clickerchg}.' '.$lt{'clicker'}."\n". - ' '."\n"; + $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'}) { @@ -2173,8 +2451,8 @@ END $photochg = 'off'; } $output .= ' '."\n".' '. - ''. + ''. $photo_options{$photochg}.' '.$lt{'photo'}."\n". ' '."\n"; } @@ -2190,18 +2468,24 @@ END time.'_'.rand(1000000000).'.csv'; unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) { $r->log_error("Couldn't open $CSVfilename for output $!"); - $r->print("Problems occured in writing the csv file. ". - "This error has been logged. ". - "Please alert your LON-CAPA administrator."); + $r->print( + '

' + .&mt('Problems occurred in writing the CSV file.') + .' '.&mt('This error has been logged.') + .' '.&mt('Please alert your LON-CAPA administrator.') + .'

' + ); $CSVfile = undef; } # + push @cols,'clicker'; # Write headers and data to file print $CSVfile '"'.$results_description.'"'."\n"; print $CSVfile '"'.join('","',map { &Apache::loncommon::csv_translate($lt{$_}) - } (@cols)).'"'."\n"; + } (@cols))."\"\n"; } elsif ($mode eq 'excel') { + push @cols,'clicker'; # Create the excel spreadsheet ($excel_workbook,$excel_filename,$format) = &Apache::loncommon::create_workbook($r); @@ -2210,11 +2494,11 @@ END $excel_sheet->write($row++,0,$results_description,$format->{'h2'}); # my @colnames = map {$lt{$_}} (@cols); + $excel_sheet->write($row++,0,\@colnames,$format->{'bold'}); } # Done with header lines in all formats - my %index; my $i; foreach my $idx (@$keylist) { @@ -2232,9 +2516,18 @@ END $grpfilter = 'all'; } } + my %ltstatus = &Apache::lonlocal::texthash( + Active => 'Active', + Future => 'Future', + Expired => 'Expired', + ); # Get groups, role, permanent e-mail so we can sort on them if # necessary. foreach my $user (keys(%{$userlist})) { + if ($user eq '' ) { + delete($userlist->{$user}); + next; + } if ($context eq 'domain' && $user eq $env{'request.role.domain'}.'-domainconfig:'.$env{'request.role.domain'}) { delete($userlist->{$user}); next; @@ -2255,7 +2548,8 @@ END } } elsif ($env{'form.roletype'} eq 'author') { ($uname,$udom,$role) = split(/:/,$user,-1); - } elsif ($env{'form.roletype'} eq 'course') { + } elsif (($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community')) { ($uname,$udom,$role) = split(/:/,$user); } } else { @@ -2280,6 +2574,13 @@ END } if ($mode ne 'autoenroll') { my $section = $userlist->{$user}->[$index{'section'}]; + if (($env{'request.course.sec'} ne '') && + ($section ne $env{'request.course.sec'})) { + if ($role eq 'st') { + delete($userlist->{$user}); + next; + } + } if ($secfilter eq 'none') { if ($section ne '') { delete($userlist->{$user}); @@ -2302,6 +2603,15 @@ END next; } } + if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { + if (($displayphotos eq 'on') && ($role eq 'st')) { + $userlist->{$user}->[$index{'photo'}] = + &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg'); + $userlist->{$user}->[$index{'thumbnail'}] = + &Apache::lonnet::retrievestudentphoto($udom,$uname, + 'gif','thumbnail'); + } + } } } my %emails = &Apache::loncommon::getemails($uname,$udom); @@ -2342,8 +2652,11 @@ END foreach my $item (@{$keylist}) { $in{$item} = $sdata->[$index{$item}]; } - my $role = $in{'role'}; - $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]); + my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1]; + if ($clickers!~/\w/) { $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 { @@ -2354,7 +2667,7 @@ END } else { $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); } - if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::start_data_table_row()); my $checkval; if ($mode eq 'autoenroll') { @@ -2363,7 +2676,7 @@ END $cellentry = ''.&mt('auto').' '; $autocount ++; } else { - $cellentry = '
'.&mt('manual').'
'; + $cellentry = '
'.&mt('manual').'
'; $manualcount ++; if ($in{'lockedtype'}) { $cellentry .= ''; @@ -2372,12 +2685,13 @@ END $cellentry .= ''; $lockcount ++; } - $cellentry .= '
'; + $cellentry .= '
'; } $r->print("$cellentry\n"); } else { - $r->print("$rowcount\n"); - $checkval; + if ($mode ne 'pickauthor') { + $r->print("$rowcount\n"); + } if ($actionselect) { my $showcheckbox; if ($role =~ /^cr\//) { @@ -2407,18 +2721,25 @@ END } } $r->print(''); + 'actionlist" value="'.$checkval.'" />'); } else { $r->print(' '); } + } elsif ($mode eq 'pickauthor') { + $r->print(''); } } foreach my $item (@cols) { if ($item eq 'username') { - $r->print(''.&print_username_link($mode,$permission, - \%in).''); + $r->print(''.&print_username_link($mode,\%in).''); } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) { $r->print(''.$in{$item}.''."\n"); + } elsif ($item eq 'status') { + my $showitem = $in{$item}; + if (defined($ltstatus{$in{$item}})) { + $showitem = $ltstatus{$in{$item}}; + } + $r->print(''.$showitem.''."\n"); } else { $r->print(''.$in{$item}.''."\n"); } @@ -2434,11 +2755,8 @@ END $r->print('   '); } if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { - if ($displayphotos eq 'on' && $sdata->[$index{'role'}] eq 'st') { - my $imgurl = - &Apache::lonnet::retrievestudentphoto($in{'domain'},$in{'username'}, - 'gif','thumbnail'); - $r->print(' '); + if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') { + $r->print(' '); } else { $r->print('   '); } @@ -2463,7 +2781,7 @@ END foreach my $item (@cols) { push @line,&Apache::loncommon::csv_translate($in{$item}); } - print $CSVfile '"'.join('","',@line).'"'."\n"; + print $CSVfile '"'.join('","',@line)."\"\n"; } elsif ($mode eq 'excel') { my $col = 0; foreach my $item (@cols) { @@ -2482,17 +2800,14 @@ END $row++; } } - if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::end_data_table().'
'); } elsif ($mode eq 'excel') { $excel_workbook->close(); - $r->print('

'. - &mt('Your Excel spreadsheet').' '.&mt('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('Your CSV file').' is ready for download.'. - "\n"); + $r->print(&mt('[_1]Your CSV file[_2] is ready for download.', '

','')."

\n"); $r->rflush(); } if ($mode eq 'autoenroll') { @@ -2502,18 +2817,133 @@ END } } +sub bulkaction_javascript { + my ($formname,$caller) = @_; + my $docstart = 'document'; + if ($caller eq 'popup') { + $docstart = 'opener.document'; + } + my %lt = &Apache::lonlocal::texthash( + acwi => 'Access will be set to start immediately', + asyo => 'as you did not select an end date in the pop-up window', + accw => 'Access will be set to continue indefinitely', + asyd => 'as you did not select an end date in the pop-up window', + sewi => "Sections will be switched to 'No section'", + ayes => "as you either selected the 'No section' option", + oryo => 'or you did not select a section in the pop-up window', + arol => 'A role with no section will be added', + swbs => 'Sections will be switched to:', + rwba => 'Roles will be added for section(s):', + ); + my $alert = &mt("You must select at least one user by checking a user's 'Select' checkbox"); + my $noaction = &mt("You need to select an action to take for the user(s) you have selected"); + my $singconfirm = &mt(' for a single user?'); + my $multconfirm = &mt(' for multiple users?'); + my $output = <<"ENDJS"; +function verify_action (field) { + var numchecked = 0; + var singconf = '$singconfirm'; + var multconf = '$multconfirm'; + if ($docstart.$formname.elements[field].length > 0) { + for (i=0; i<$docstart.$formname.elements[field].length; i++) { + if ($docstart.$formname.elements[field][i].checked == true) { + numchecked ++; + } + } + } else { + if ($docstart.$formname.elements[field].checked == true) { + numchecked ++; + } + } + if (numchecked == 0) { + alert("$alert"); + return; + } else { + var message = $docstart.$formname.bulkaction[$docstart.$formname.bulkaction.selectedIndex].text; + var choice = $docstart.$formname.bulkaction[$docstart.$formname.bulkaction.selectedIndex].value; + if (choice == '') { + alert("$noaction"); + return; + } else { + if (numchecked == 1) { + message += singconf; + } else { + message += multconf; + } +ENDJS + if ($caller ne 'popup') { + $output .= <<"NEWWIN"; + if (choice == 'chgdates' || choice == 'reenable' || choice == 'activate' || choice == 'chgsec') { + opendatebrowser(document.$formname,'$formname','go'); + return; + + } else { + if (confirm(message)) { + document.$formname.phase.value = 'bulkchange'; + document.$formname.submit(); + return; + } + } +NEWWIN + } else { + $output .= <<"POPUP"; + if (choice == 'chgdates' || choice == 'reenable' || choice == 'activate') { + var datemsg = ''; + if (($docstart.$formname.startdate_month.value == '') && + ($docstart.$formname.startdate_day.value == '') && + ($docstart.$formname.startdate_year.value == '')) { + datemsg = "\\n$lt{'acwi'},\\n$lt{'asyo'}.\\n"; + } + if (($docstart.$formname.enddate_month.value == '') && + ($docstart.$formname.enddate_day.value == '') && + ($docstart.$formname.enddate_year.value == '')) { + datemsg += "\\n$lt{'accw'},\\n$lt{'asyd'}.\\n"; + } + if (datemsg != '') { + message += "\\n"+datemsg; + } + } + if (choice == 'chgsec') { + var rolefilter = $docstart.$formname.showrole.options[$docstart.$formname.showrole.selectedIndex].value; + var retained = $docstart.$formname.retainsec.value; + var secshow = $docstart.$formname.newsecs.value; + if (secshow == '') { + if (rolefilter == 'st' || retained == 0 || retained == "") { + message += "\\n\\n$lt{'sewi'},\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n"; + } else { + message += "\\n\\n$lt{'arol'}\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n"; + } + } else { + if (rolefilter == 'st' || retained == 0 || retained == "") { + message += "\\n\\n$lt{'swbs'} "+secshow+".\\n"; + } else { + message += "\\n\\n$lt{'rwba'} "+secshow+".\\n"; + } + } + } + if (confirm(message)) { + $docstart.$formname.phase.value = 'bulkchange'; + $docstart.$formname.submit(); + window.close(); + } +POPUP + } + $output .= ' + } + } +} +'; + return $output; +} + sub print_username_link { - my ($mode,$permission,$in) = @_; + my ($mode,$in) = @_; my $output; if ($mode eq 'autoenroll') { $output = $in->{'username'}; - } elsif (!$permission->{'cusr'}) { - $output = &Apache::loncommon::aboutmewrapper($in->{'username'}, - $in->{'username'}, - $in->{'domain'}); } else { $output = '{'username'}','$in->{'domain'}'".')" />'. + "'$in->{'username'}','$in->{'domain'}'".')">'. $in->{'username'}.''; } return $output; @@ -2524,12 +2954,13 @@ sub role_type_names { 'domain' => 'Domain Roles', 'author' => 'Co-Author Roles', 'course' => 'Course Roles', + 'community' => 'Community Roles', ); return %lt; } sub select_actions { - my ($context,$setting,$statusmode) = @_; + my ($context,$setting,$statusmode,$formname) = @_; my %lt = &Apache::lonlocal::texthash( revoke => "Revoke user roles", delete => "Delete user roles", @@ -2590,7 +3021,7 @@ sub select_actions { } } if ($options) { - $output = ''."\n". ''."\n".$options."\n".''; if ($choices{'dates'}) { @@ -2606,14 +3037,15 @@ sub select_actions { ''."\n". ''."\n". ''."\n". - ''."\n"; + ''."\n". + ''."\n"; if ($context eq 'course') { $output .= ''."\n"; } } if ($choices{'sections'}) { - $output .= ''."\n". - ''."\n"; + $output .= ''."\n". + ''."\n"; } } return $output; @@ -2621,21 +3053,17 @@ sub select_actions { sub date_section_javascript { my ($context,$setting) = @_; - my $title; - if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) { - $title = &mt('Date and Section selector'); - } else { - $title = &mt('Date selector'); - } - my $output = ' + my $title = 'Date_And_Section_Selector'; + my %nopopup = &Apache::lonlocal::texthash ( + revoke => "Check the boxes for any users for whom roles are to be revoked, and click 'Proceed'", + delete => "Check the boxes for any users for whom roles are to be deleted, and click 'Proceed'", + none => "Choose an action to take for selected users", + ); + my $output = <<"ENDONE"; ENDTWO return $output; } sub date_section_selector { - my ($context,$permission) = @_; + my ($context,$permission,$crstype) = @_; my $callingform = $env{'form.callingform'}; my $formname = 'dateselect'; my $groupslist = &get_groupslist(); my $sec_js = &setsections_javascript($formname,$groupslist); my $output = <<"END"; -'; +ENDJS my %lt = &Apache::lonlocal::texthash ( chac => 'Access dates to apply for selected users', chse => 'Changes in section affiliation to apply to selected users', fors => 'For student roles changing the section, will result in a section switch as students may only be in one section of a course at a time.', forn => 'For a role in a course that is not a student role, a user may have roles in more than one section of a course at a time.', reta => "Retain each user's current section affiliations?", - dnap => '(Does not apply to student roles).', + dnap => '(Does not apply to student roles).', ); my ($date_items,$headertext); if ($env{'form.bulkaction'} eq 'chgsec') { @@ -2744,13 +3190,18 @@ END } $date_items = &date_setting_table($starttime,undef,$context, $env{'form.bulkaction'},$formname, - $permission); + $permission,$crstype); } $output .= '

'.$headertext.'

'. '
'."\n". $date_items; if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') { my ($cnum,$cdom) = &get_course_identity(); + 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 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; if ($env{'form.showrole'} eq 'st') { $output .= '

'.$lt{'fors'}.'

'; @@ -2776,25 +3227,24 @@ END $info = ''; } my $rowtitle = &mt('New section to assign'); - my $secbox = §ion_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,$permission,$context); + my $secbox = §ion_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,$permission,$context,'',$crstype); $output .= $info.$secbox; } $output .= '

'. -&mt('Use "Save" to update the main window with your selections.').'

'. '

'."\n". '
'; return $output; } sub section_picker { - my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_; + my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode,$crstype) = @_; my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); my $sections_select .= &course_sections(\%sections_count,$role); my $secbox = '

'.&Apache::lonhtmlcommon::start_pick_box()."\n"; if ($mode eq 'upload') { my ($options,$cb_script,$coursepick) = - &default_role_selector($context,1); - $secbox .= &Apache::lonhtmlcommon::row_title('role','LC_oddrow_value'). + &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"; @@ -2817,26 +3267,50 @@ sub section_picker { } sub results_header_row { - my ($rolefilter,$statusmode,$context,$permission,$mode) = @_; + my ($rolefilter,$statusmode,$context,$permission,$mode,$crstype) = @_; my ($description,$showfilter); if ($rolefilter ne 'Any') { $showfilter = $rolefilter; } if ($context eq 'course') { if ($mode eq 'csv' || $mode eq 'excel') { - $description = &mt('Course - ').$env{'course.'.$env{'request.course.id'}.'.description'}.': '; + if ($crstype eq 'Community') { + $description = &mt('Community - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' '; + } else { + $description = &mt('Course - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' '; + } } if ($statusmode eq 'Expired') { - $description .= &mt('Users in course with expired [_1] roles',$showfilter); + if ($crstype eq 'Community') { + $description .= &mt('Users in community with expired [_1] roles',$showfilter); + } else { + $description .= &mt('Users in course with expired [_1] roles',$showfilter); + } } elsif ($statusmode eq 'Future') { - $description .= &mt('Users in course with future [_1] roles',$showfilter); + if ($crstype eq 'Community') { + $description .= &mt('Users in community with future [_1] roles',$showfilter); + } else { + $description .= &mt('Users in course with future [_1] roles',$showfilter); + } } elsif ($statusmode eq 'Active') { - $description .= &mt('Users in course with active [_1] roles',$showfilter); + if ($crstype eq 'Community') { + $description .= &mt('Users in community with active [_1] roles',$showfilter); + } else { + $description .= &mt('Users in course with active [_1] roles',$showfilter); + } } else { if ($rolefilter eq 'Any') { - $description .= &mt('All users in course'); + if ($crstype eq 'Community') { + $description .= &mt('All users in community'); + } else { + $description .= &mt('All users in course'); + } } else { - $description .= &mt('All users in course with [_1] roles',$rolefilter); + if ($crstype eq 'Community') { + $description .= &mt('All users in community with [_1] roles',$rolefilter); + } else { + $description .= &mt('All users in course with [_1] roles',$rolefilter); + } } } my $constraint; @@ -2844,7 +3318,7 @@ sub results_header_row { if ($viewablesec ne '') { if ($env{'form.showrole'} eq 'st') { $constraint = &mt('only users in section "[_1]"',$viewablesec); - } elsif ($env{'form.showrole'} ne 'cc') { + } elsif (($env{'form.showrole'} ne 'cc') && ($env{'form.showrole'} ne 'co')) { $constraint = &mt('only users affiliated with no section or section "[_1]"',$viewablesec); } if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) { @@ -2883,8 +3357,11 @@ sub results_header_row { } } elsif ($context eq 'author') { $description = - &mt('Author space for [_1]', - &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'})).':  '; + &mt('Author space for [_1]' + ,'' + .&Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}) + .'') + .':  '; if ($statusmode eq 'Expired') { $description .= &mt('Co-authors with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { @@ -2900,7 +3377,7 @@ sub results_header_row { } } elsif ($context eq 'domain') { my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description'); - $description = &mt('Domain - ').$domdesc.': '; + $description = &mt('Domain - [_1]:',$domdesc).' '; if ($env{'form.roletype'} eq 'domain') { if ($statusmode eq 'Expired') { $description .= &mt('Users in domain with expired [_1] roles',$showfilter); @@ -2929,19 +3406,28 @@ sub results_header_row { $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter); } } - } elsif ($env{'form.roletype'} eq 'course') { + } elsif (($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community')) { my $coursefilter = $env{'form.coursepick'}; - if ($coursefilter eq 'category') { - my $instcode = &instcode_from_coursefilter(); - if ($instcode eq '.') { + if ($env{'form.roletype'} eq 'course') { + if ($coursefilter eq 'category') { + my $instcode = &instcode_from_coursefilter(); + if ($instcode eq '.') { + $description .= &mt('All courses in domain').' - '; + } else { + $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - '; + } + } elsif ($coursefilter eq 'selected') { + $description .= &mt('Selected courses in domain').' - '; + } elsif ($coursefilter eq 'all') { $description .= &mt('All courses in domain').' - '; - } else { - $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - '; } - } elsif ($coursefilter eq 'selected') { - $description .= &mt('Selected courses in domain').' - '; - } elsif ($coursefilter eq 'all') { - $description .= &mt('All courses in domain').' - '; + } elsif ($env{'form.roletype'} eq 'community') { + if ($coursefilter eq 'selected') { + $description .= &mt('Selected communities in domain').' - '; + } elsif ($coursefilter eq 'all') { + $description .= &mt('All communities in domain').' - '; + } } if ($statusmode eq 'Expired') { $description .= &mt('users with expired [_1] roles',$showfilter); @@ -2978,7 +3464,7 @@ sub viewable_section { ################################################# ################################################# sub show_drop_list { - my ($r,$classlist,$nosort,$permission) = @_; + my ($r,$classlist,$nosort,$permission,$crstype) = @_; my $cid = $env{'request.course.id'}; my ($cnum,$cdom) = &get_course_identity($cid); if (! exists($env{'form.sortby'})) { @@ -2996,10 +3482,12 @@ sub show_drop_list {

- + END my ($indexhash,$keylist) = &make_keylist_array(); my $studentcount = 0; @@ -3022,7 +3510,11 @@ END } } if (!$studentcount) { - $r->print(&mt('There are no students to drop.')); + if ($crstype eq 'Community') { + $r->print(&mt('There are no members to drop.')); + } else { + $r->print(&mt('There are no students to drop.')); + } return; } my ($classgroups) = &Apache::loncoursedata::get_group_memberships( @@ -3030,11 +3522,16 @@ END my %lt=&Apache::lonlocal::texthash('usrn' => "username", 'dom' => "domain", 'sn' => "student name", + 'mn' => "member name", 'sec' => "section", 'start' => "start date", 'end' => "end date", 'groups' => "active groups", ); + my $nametitle = $lt{'sn'}; + if ($crstype eq 'Community') { + $nametitle = $lt{'mn'}; + } if ($nosort) { $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); @@ -3043,7 +3540,7 @@ END $lt{'usrn'} $lt{'dom'} ID - $lt{'sn'} + $nametitle $lt{'sec'} $lt{'start'} $lt{'end'} @@ -3062,7 +3559,7 @@ END ID - $lt{'sn'} + $nametitle $lt{'sec'} @@ -3117,7 +3614,7 @@ END # $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); - + $username $domain $id @@ -3132,14 +3629,23 @@ END $r->print(&Apache::loncommon::end_data_table().'
'); %lt=&Apache::lonlocal::texthash( 'dp' => "Drop Students", + 'dm' => "Drop Members", 'ca' => "check all", 'ua' => "uncheck all", ); + my $btn = $lt{'dp'}; + if ($crstype eq 'Community') { + $btn = $lt{'dm'}; + } $r->print(<<"END"); -

-   - -

+

+

+   + +

+

+ +

END return; } @@ -3150,23 +3656,43 @@ END sub print_first_users_upload_form { my ($r,$context) = @_; my $str; - $str = ''; + $str = ''; $str .= ''; - $str .= ''; - $str .= "

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

\n"; - $str .= &Apache::loncommon::upfile_select_html(); - $str .= "

\n"; - $str .= ''."\n"; - $str .= '

\n"; - $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List", - &mt("How do I create a users list from a spreadsheet")). - "
\n"; - $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV", - &mt("How do I create a CSV file from a spreadsheet")). - "
\n"; - $str .= &Apache::loncommon::end_page(); + $str .= ''; + + $str .= '

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

'."\n"; + + # Excel and CSV Help + $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", + &mt("How do I create a CSV file from a spreadsheet")) + .'

'."\n"; + $str .= &Apache::lonhtmlcommon::start_pick_box() + .&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( + '') + .'' + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box(); + + $str .= '

' + .'' + .'

'; + $r->print($str); return; } @@ -3195,7 +3721,7 @@ sub upfile_drop_add { # # Store the field choices away foreach my $field (qw/username names - fname mname lname gen id sec ipwd email role/) { + fname mname lname gen id sec ipwd email role domain/) { $env{'form.'.$field.'_choice'}=$fields{$field}; } &Apache::loncommon::store_course_settings('enrollment_upload', @@ -3209,19 +3735,40 @@ sub upfile_drop_add { 'sec_choice' => 'scalar', 'ipwd_choice' => 'scalar', 'email_choice' => 'scalar', - 'role_choice' => 'scalar' }); + 'role_choice' => 'scalar', + 'domain_choice' => 'scalar', + 'inststatus_choice' => 'scalar'}); # + my ($cid,$crstype,$setting); + if ($context eq 'domain') { + $setting = $env{'form.roleaction'}; + } + if ($env{'request.course.id'} ne '') { + $cid = $env{'request.course.id'}; + $crstype = &Apache::loncommon::course_type(); + } elsif ($setting eq 'course') { + if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) { + $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'}; + $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)); + $r->print(&make_dates_default($startdate,$enddate,$context,$crstype)); } # Determine domain and desired host (home server) - my $domain=$env{'request.role.domain'}; + my $defdom=$env{'request.role.domain'}; + my $domain; + if ($env{'form.defaultdomain'} ne '') { + $domain = $env{'form.defaultdomain'}; + } else { + $domain = $defdom; + } my $desiredhost = $env{'form.lcserver'}; if (lc($desiredhost) eq 'default') { $desiredhost = undef; } else { - my %home_servers = &Apache::lonnet::get_servers($domain,'library'); + my %home_servers = &Apache::lonnet::get_servers($defdom,'library'); if (! exists($home_servers{$desiredhost})) { $r->print(''.&mt('Error'). &mt('Invalid home server specified').''); @@ -3259,9 +3806,8 @@ sub upfile_drop_add { $amode = ''; # This causes the loop below to be skipped } } - my ($cid,$defaultsec,$defaultrole,$setting); + my ($defaultsec,$defaultrole); if ($context eq 'domain') { - $setting = $env{'form.roleaction'}; if ($setting eq 'domain') { $defaultrole = $env{'form.defaultrole'}; } elsif ($setting eq 'course') { @@ -3274,28 +3820,22 @@ sub upfile_drop_add { $defaultrole = $env{'form.defaultrole'}; $defaultsec = $env{'form.sections'}; } - if ($env{'request.course.id'} ne '') { - $cid = $env{'request.course.id'}; - } elsif ($setting eq 'course') { - if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) { - $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'}; - } - } # Check to see if user information can be changed my @userinfo = ('firstname','middlename','lastname','generation', 'permanentemail','id'); my %canmodify; if (&Apache::lonnet::allowed('mau',$domain)) { + push(@userinfo,'inststatus'); foreach my $field (@userinfo) { $canmodify{$field} = 1; } } my (%userlist,%modifiable_fields,@poss_roles); my $secidx = &Apache::loncoursedata::CL_SECTION(); - my @courseroles = &roles_by_context('course',1); + my @courseroles = &roles_by_context('course',1,$crstype); if (!&Apache::lonnet::allowed('mau',$domain)) { if ($context eq 'course' || $context eq 'author') { - @poss_roles = &curr_role_permissions($context); + @poss_roles = &curr_role_permissions($context,'','',$crstype); my @statuses = ('active','future'); my ($indexhash,$keylist) = &make_keylist_array(); my %info; @@ -3306,7 +3846,9 @@ sub upfile_drop_add { if ($context eq 'course') { my ($cnum,$cdom) = &get_course_identity(); my $roster = &Apache::loncoursedata::get_classlist(); - %userlist = %{$roster}; + if (ref($roster) eq 'HASH') { + %userlist = %{$roster}; + } my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, \@statuses,\@poss_roles); &gather_userinfo($context,'view',\%userlist,$indexhash,\%info, @@ -3332,6 +3874,8 @@ sub upfile_drop_add { } else { $r->print('

'.&mt('Adding/Modifying Users')."

\n

\n"); } + $r->rflush; + my %counts = ( user => 0, auth => 0, @@ -3339,7 +3883,7 @@ sub upfile_drop_add { ); my $flushc=0; my %student=(); - my (%curr_groups,@sections,@cleansec,@secs,$defaultwarn,$groupwarn); + my (%curr_groups,@sections,@cleansec,$defaultwarn,$groupwarn); my %userchg; if ($context eq 'course' || $setting eq 'course') { if ($context eq 'course') { @@ -3377,11 +3921,12 @@ sub upfile_drop_add { } } my (%curr_rules,%got_rules,%alerts); - my %customroles = &my_custom_roles(); - my ($custom_ok,@permitted_roles) = - &roles_on_upload($context,%customroles); + my %customroles = &my_custom_roles($crstype); + my @permitted_roles = + &roles_on_upload($context,$setting,$crstype,%customroles); # Get new users list foreach my $line (@userdata) { + my @secs; my %entries=&Apache::loncommon::record_sep($line); # Determine user name unless (($entries{$fields{'username'}} eq '') || @@ -3407,21 +3952,30 @@ sub upfile_drop_add { if ($entries{$fields{'username'}} ne &LONCAPA::clean_username($entries{$fields{'username'}})) { $r->print('
'. - &mt('[_1]: Unacceptable username for user [_2] [_3] [_4] [_5]', - $entries{$fields{'username'}},$fname,$mname,$lname,$gen). - ''); + &mt('[_1]: Unacceptable username for user [_2] [_3] [_4] [_5]', + ''.$entries{$fields{'username'}}.'',$fname,$mname,$lname,$gen)); next; } else { + if ($entries{$fields{'domain'}} + ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) { + $r->print('
'. ''.$entries{$fields{'domain'}}. + ': '.&mt('Unacceptable domain for user [_2] [_3] [_4] [_5]',$fname,$mname,$lname,$gen)); + next; + } my $username = $entries{$fields{'username'}}; + my $userdomain = $entries{$fields{'domain'}}; + if ($userdomain eq '') { + $userdomain = $domain; + } if (defined($fields{'sec'})) { if (defined($entries{$fields{'sec'}})) { + $entries{$fields{'sec'}} =~ s/\W//g; my $item = $entries{$fields{'sec'}}; - $item =~ s/(\s+$|^\s+)//g; if ($item eq "none" || $item eq 'all') { - $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.',$username,$fname,$mname,$lname,$gen,$item)); + $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.',''.$username.'',$fname,$mname,$lname,$gen,$item)); next; } elsif (exists($curr_groups{$item})) { - $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.',$username,$fname,$mname,$lname,$gen,$item).' '.&mt('Section names and group names must be distinct.')); + $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.',''.$username.'',$fname,$mname,$lname,$gen,$item).' '.&mt('Section names and group names must be distinct.')); next; } else { push(@secs,$item); @@ -3430,10 +3984,10 @@ sub upfile_drop_add { } if ($env{'request.course.sec'} ne '') { @secs = ($env{'request.course.sec'}); - if (ref($userlist{$username.':'.$domain}) eq 'ARRAY') { - my $currsec = $userlist{$username.':'.$domain}[$secidx]; + if (ref($userlist{$username.':'.$userdomain}) eq 'ARRAY') { + my $currsec = $userlist{$username.':'.$userdomain}[$secidx]; if ($currsec ne $env{'request.course.sec'}) { - $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".',$username,$fname,$mname,$lname,$gen,$secs[0]).'
'); + $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".',''.$username.'',$fname,$mname,$lname,$gen,$secs[0]).'
'); if ($currsec eq '') { $r->print(&mt('This user already has an active/future student role in the course, unaffiliated to any section.')); @@ -3462,7 +4016,15 @@ sub upfile_drop_add { if (defined($fields{'email'})) { if (defined($entries{$fields{'email'}})) { $email=$entries{$fields{'email'}}; - unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } } + unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } + } + } + # determine affiliation + my $inststatus=''; + if (defined($fields{'inststatus'})) { + if (defined($entries{$fields{'inststatus'}})) { + $inststatus=$entries{$fields{'inststatus'}}; + } } # determine user password my $password = $genpwd; @@ -3475,19 +4037,21 @@ sub upfile_drop_add { my $role = ''; if (defined($fields{'role'})) { if ($entries{$fields{'role'}}) { - if (grep(/^\Q$entries{$fields{'role'}}\E$/,@permitted_roles)) { - $role=$entries{$fields{'role'}}; - $role =~ s/(\s+$|^\s+)//g; - } - if ($custom_ok) { - if ($customroles{$role}) { - $role = 'cr_'.$env{'user.domain'}.'_'.$env{'user.name'}.'_'.$entries{$fields{'role'}}; + $entries{$fields{'role'}} =~ s/(\s+$|^\s+)//g; + if ($entries{$fields{'role'}} ne '') { + if (grep(/^\Q$entries{$fields{'role'}}\E$/,@permitted_roles)) { + $role = $entries{$fields{'role'}}; } } if ($role eq '') { my $rolestr = join(', ',@permitted_roles); - $r->print('
'. - &mt('[_1]: You do not have permission to add the requested role [_2] for the user.',$entries{$fields{'username'}},$entries{$fields{'role'}}).'
'.&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n"); + $r->print('
' + .&mt('[_1]: You do not have permission to add the requested role [_2] for the user.' + ,''.$entries{$fields{'username'}}.'' + ,$entries{$fields{'role'}}) + .'
' + .&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n" + ); next; } } @@ -3496,16 +4060,16 @@ sub upfile_drop_add { $role = $defaultrole; } # Clean up whitespace - foreach (\$domain,\$username,\$id,\$fname,\$mname, - \$lname,\$gen) { + foreach (\$id,\$fname,\$mname,\$lname,\$gen) { $$_ =~ s/(\s+$|^\s+)//g; } # check against rules my $checkid = 0; my $newuser = 0; my (%rulematch,%inst_results,%idinst_results); - my $uhome=&Apache::lonnet::homeserver($username,$domain); + my $uhome=&Apache::lonnet::homeserver($username,$userdomain); if ($uhome eq 'no_host') { + next if ($userdomain ne $domain); $checkid = 1; $newuser = 1; my $checkhash; @@ -3521,38 +4085,40 @@ sub upfile_drop_add { } } else { if ($context eq 'course' || $context eq 'author') { - if ($role eq '') { - my @checkroles; - foreach my $role (@poss_roles) { - my $endkey; - if ($role ne 'st') { - $endkey = ':'.$role; - } - if (exists($userlist{$username.':'.$domain.$endkey})) { - if (!grep(/^\Q$role\E$/,@checkroles)) { - push(@checkroles,$role); + if ($userdomain eq $domain ) { + if ($role eq '') { + my @checkroles; + foreach my $role (@poss_roles) { + my $endkey; + if ($role ne 'st') { + $endkey = ':'.$role; + } + if (exists($userlist{$username.':'.$userdomain.$endkey})) { + if (!grep(/^\Q$role\E$/,@checkroles)) { + push(@checkroles,$role); + } } } + if (@checkroles > 0) { + %canmodify = &can_modify_userinfo($context,$domain,\@userinfo,\@checkroles); + } + } elsif (ref($modifiable_fields{$role}) eq 'HASH') { + %canmodify = %{$modifiable_fields{$role}}; } - if (@checkroles > 0) { - %canmodify = &can_modify_userinfo($context,$domain,\@userinfo,\@checkroles); - } - } elsif (ref($modifiable_fields{$role}) eq 'HASH') { - %canmodify = %{$modifiable_fields{$role}}; } - } - my @newinfo = (\$fname,\$mname,\$lname,\$gen,\$email,\$id); - for (my $i=0; $i<@userinfo; $i++) { - if (${$newinfo[$i]} ne '') { - if (!$canmodify{$userinfo[$i]}) { - ${$newinfo[$i]} = ''; + my @newinfo = (\$fname,\$mname,\$lname,\$gen,\$email,\$id); + for (my $i=0; $i<@newinfo; $i++) { + if (${$newinfo[$i]} ne '') { + if (!$canmodify{$userinfo[$i]}) { + ${$newinfo[$i]} = ''; + } } } } } if ($id ne '') { if (!$newuser) { - my %idhash = &Apache::lonnet::idrget($domain,($username)); + my %idhash = &Apache::lonnet::idrget($userdomain,($username)); if ($idhash{$username} ne $id) { $checkid = 1; } @@ -3560,14 +4126,14 @@ sub upfile_drop_add { if ($checkid) { my $checkhash; my $checks = { 'id' => 1 }; - $checkhash->{$username.':'.$domain} = { 'newuser' => $newuser, + $checkhash->{$username.':'.$userdomain} = { 'newuser' => $newuser, 'id' => $id }; &Apache::loncommon::user_rule_check($checkhash,$checks, \%alerts,\%rulematch,\%idinst_results,\%curr_rules, \%got_rules); if (ref($alerts{'id'}) eq 'HASH') { - if (ref($alerts{'id'}{$domain}) eq 'HASH') { - next if ($alerts{'id'}{$domain}{$id}); + if (ref($alerts{'id'}{$userdomain}) eq 'HASH') { + next if ($alerts{'id'}{$userdomain}{$id}); } } } @@ -3576,82 +4142,85 @@ sub upfile_drop_add { my $multiple = 0; my ($userresult,$authresult,$roleresult,$idresult); my (%userres,%authres,%roleres,%idres); + my $singlesec = ''; if ($role eq 'st') { my $sec; - if ($cid) { - if (@secs > 0) { - $sec = $secs[0]; - } - &modifystudent($domain,$username,$cid,$sec, - $desiredhost); - $roleresult = - &Apache::lonnet::modifystudent - ($domain,$username,$id,$amode,$password, - $fname,$mname,$lname,$gen,$sec,$enddate, - $startdate,$env{'form.forceid'}, - $desiredhost,$email,'manual','',$cid); - $userresult = $roleresult; + if (@secs > 0) { + $sec = $secs[0]; } + &modifystudent($userdomain,$username,$cid,$sec, + $desiredhost,$context); + $roleresult = + &Apache::lonnet::modifystudent + ($userdomain,$username,$id,$amode,$password, + $fname,$mname,$lname,$gen,$sec,$enddate, + $startdate,$env{'form.forceid'}, + $desiredhost,$email,'manual','',$cid, + '',$context,$inststatus); + $userresult = $roleresult; } else { - if (($context eq 'course') || - (grep(/^\Q$role\E$/,@courseroles))) { - if (!$cid) { - next; - } - } - my $singlesec; - if ((grep(/^\Q$role\E$/,@courseroles)) && ($role ne 'cc')) { - if (@secs > 1) { - $multiple = 1; - foreach my $sec (@secs) { - ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) = - &modifyuserrole($context,$setting, - $changeauth,$cid,$domain,$username, - $id,$amode,$password,$fname, - $mname,$lname,$gen,$sec, - $env{'form.forceid'},$desiredhost, - $email,$role,$enddate,$startdate,$checkid); + if ($role ne '') { + if ($context eq 'course' || $setting eq 'course') { + if ($customroles{$role}) { + $role = 'cr_'.$env{'user.domain'}.'_'. + $env{'user.name'}.'_'.$role; + } + if (($role ne 'cc') && ($role ne 'co')) { + if (@secs > 1) { + $multiple = 1; + foreach my $sec (@secs) { + ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) = + &modifyuserrole($context,$setting, + $changeauth,$cid,$userdomain,$username, + $id,$amode,$password,$fname, + $mname,$lname,$gen,$sec, + $env{'form.forceid'},$desiredhost, + $email,$role,$enddate, + $startdate,$checkid,$inststatus); + } + } elsif (@secs > 0) { + $singlesec = $secs[0]; + } } - } elsif (@secs > 0) { - $singlesec = $secs[0]; } } if (!$multiple) { ($userresult,$authresult,$roleresult,$idresult) = &modifyuserrole($context,$setting, - $changeauth,$cid,$domain,$username, - $id,$amode,$password,$fname, - $mname,$lname,$gen,$singlesec, - $env{'form.forceid'},$desiredhost, - $email,$role,$enddate,$startdate,$checkid); + $changeauth,$cid,$userdomain,$username, + $id,$amode,$password,$fname, + $mname,$lname,$gen,$singlesec, + $env{'form.forceid'},$desiredhost, + $email,$role,$enddate,$startdate, + $checkid,$inststatus); } } if ($multiple) { foreach my $sec (sort(keys(%userres))) { - $flushc = + $flushc = &user_change_result($r,$userres{$sec},$authres{$sec}, $roleres{$sec},$idres{$sec},\%counts,$flushc, - $username,\%userchg); + $username,$userdomain,\%userchg); } } else { $flushc = &user_change_result($r,$userresult,$authresult, $roleresult,$idresult,\%counts,$flushc, - $username,\%userchg); + $username,$userdomain,\%userchg); } } else { if ($context eq 'course') { $r->print('
'. - &mt('[_1]: Unable to enroll. No password specified.',$username) + &mt('[_1]: Unable to enroll. No password specified.',''.$username.'') ); } elsif ($context eq 'author') { $r->print('
'. - &mt('[_1]: Unable to add co-author. No password specified.',$username) + &mt('[_1]: Unable to add co-author. No password specified.',''.$username.'') ); } else { $r->print('
'. - &mt('[_1]: Unable to add user. No password specified.',$username) + &mt('[_1]: Unable to add user. No password specified.',''.$username.'') ); } } @@ -3686,7 +4255,7 @@ sub upfile_drop_add { ''. &mt('There are no students with current/future access to the course.'). ''."\n"); - } else { + } elsif (ref($classlist) eq 'HASH') { # Remove the students we just added from the list of students. foreach my $line (@userdata) { my %entries=&Apache::loncommon::record_sep($line); @@ -3748,13 +4317,13 @@ sub print_namespacing_alerts { sub user_change_result { my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc, - $username,$userchg) = @_; + $username,$userdomain,$userchg) = @_; my $okresult = 0; if ($userresult ne 'ok') { if ($userresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. - &mt('[_1]: Unable to add/modify: [_2]',$username,$error)); + &mt('[_1]: Unable to add/modify: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'user'} ++; @@ -3764,7 +4333,7 @@ sub user_change_result { if ($authresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. - &mt('[_1]: Unable to modify authentication: [_2]',$username,$error)); + &mt('[_1]: Unable to modify authentication: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'auth'} ++; @@ -3774,7 +4343,7 @@ sub user_change_result { if ($roleresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. - &mt('[_1]: Unable to add role: [_2]',$username,$error)); + &mt('[_1]: Unable to add role: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'role'} ++; @@ -3782,7 +4351,7 @@ sub user_change_result { } if ($okresult) { $flushc++; - $userchg->{$username}=1; + $userchg->{$username.':'.$userdomain}=1; $r->print('. '); if ($flushc>15) { $r->rflush; @@ -3797,14 +4366,24 @@ sub user_change_result { # ========================================================= Menu Phase Two Drop sub print_drop_menu { - my ($r,$context,$permission) = @_; - $r->print('

'.&mt("Drop Students").'

'."\n". + my ($r,$context,$permission,$crstype) = @_; + my $heading; + if ($crstype eq 'Community') { + $heading = &mt("Drop Members"); + } else { + $heading = &mt("Drop Students"); + } + $r->print('

'.$heading.'

'."\n". '
'."\n"); my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { - $r->print(&mt('There are no students currently enrolled.')."\n"); + if ($crstype eq 'Community') { + $r->print(&mt('There are no members currently enrolled.')."\n"); + } else { + $r->print(&mt('There are no students currently enrolled.')."\n"); + } } else { - &show_drop_list($r,$classlist,'nosort',$permission); + &show_drop_list($r,$classlist,'nosort',$permission,$crstype); } $r->print('
'. &Apache::loncommon::end_page()); return; @@ -3816,6 +4395,10 @@ sub update_user_list { my ($r,$context,$setting,$choice) = @_; my $now = time; my $count=0; + my $crstype; + if ($context eq 'course') { + $crstype = &Apache::loncommon::course_type(); + } my @changelist; if ($choice eq 'drop') { @changelist = &Apache::loncommon::get_env_multiple('form.droplist'); @@ -3886,7 +4469,7 @@ sub update_user_list { } } } - my $plrole = &Apache::lonnet::plaintext($role); + my $plrole = &Apache::lonnet::plaintext($role,$crstype); my $start = $env{'form.'.$item.'_start'}; my $end = $env{'form.'.$item.'_end'}; if ($choice eq 'drop') { @@ -3894,24 +4477,25 @@ sub update_user_list { $end = $now; $type = 'manual'; $result = - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } elsif ($choice eq 'revoke') { # revoke or delete user role $end = $now; if ($role eq 'st') { $result = - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = - &Apache::lonnet::revokerole($udom,$uname,$scope,$role); + &Apache::lonnet::revokerole($udom,$uname,$scope,$role, + '','',$context); } } elsif ($choice eq 'delete') { if ($role eq 'st') { - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid); + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context); } $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now, - $start,1); + $start,1,'',$context); } else { #reenable, activate, change access dates or change section if ($choice ne 'chgsec') { @@ -3920,29 +4504,29 @@ sub update_user_list { } if ($choice eq 'reenable') { if ($role eq 'st') { - $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); + $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, - $now); + $now,'','',$context); } } elsif ($choice eq 'activate') { if ($role eq 'st') { - $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); + $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, - $now); + $now,'','',$context); } } elsif ($choice eq 'chgdates') { if ($role eq 'st') { - $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); + $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, - $start); + $start,'','',$context); } } elsif ($choice eq 'chgsec') { my (@newsecs,$revresult,$nochg,@retained); - if ($role ne 'cc') { + if (($role ne 'cc') && ($role ne 'co')) { @newsecs = split(/,/,$env{'form.newsecs'}); } # remove existing section if not to be retained. @@ -3951,7 +4535,12 @@ sub update_user_list { if (@newsecs == 0) { $result = &mt('No change in section assignment (none)'); $nochg = 1; - } + } else { + $revresult = + &Apache::lonnet::revokerole($udom,$uname, + $scope,$role, + '','',$context); + } } else { if (@newsecs > 0) { if (grep(/^\Q$sec\E$/,@newsecs)) { @@ -3959,12 +4548,14 @@ sub update_user_list { } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, - $scope,$role); + $scope,$role, + '','',$context); } } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, - $scope,$role); + $scope,$role, + '','',$context); } } } else { @@ -3979,17 +4570,17 @@ sub update_user_list { 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); + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context); } else { my $newscope = $scopestem; - $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start); + $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context); } } } 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); + $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context); } else { my $newscope = $scopestem; if ($newsec ne '') { @@ -4036,14 +4627,14 @@ sub update_user_list { $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.

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

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

'); } # Flush the course logs so reverse user roles immediately updated &Apache::lonnet::flushcourselogs(); } if ($env{'form.makedatesdefault'}) { if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') { - $r->print(&make_dates_default($startdate,$enddate,$context)); + $r->print(&make_dates_default($startdate,$enddate,$context,$crstype)); } } my $linktext = &mt('Display User Lists'); @@ -4057,11 +4648,9 @@ sub classlist_drop { my ($scope,$uname,$udom,$now) = @_; my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)}); if (&Apache::lonnet::is_course($cdom,$cnum)) { - my $user = $uname.':'.$udom; if (!&active_student_roles($cnum,$cdom,$uname,$udom)) { - my $result = - &Apache::lonnet::cput('classlist', - { $user => $now },$cdom,$cnum); + my %user; + my $result = &update_classlist($cdom,$cnum,$udom,$uname,\%user,$now); return &mt('Drop from classlist: [_1]', ''.$result.'').'
'; } @@ -4128,17 +4717,29 @@ sub set_login { } sub course_sections { - my ($sections_count,$role) = @_; + my ($sections_count,$role,$current_sec) = @_; my $output = ''; my @sections = (sort {$a <=> $b} keys %{$sections_count}); my $numsec = scalar(@sections); + my $is_selected = ' selected="selected"'; if ($numsec <= 1) { $output = ''.&mt('Select').''."\n". + ' '."\n"; + if ($current_sec eq 'none') { + $output .= + ' \n"; + } else { + $output .= ' \n"; + } } else { $output .= 'multiple="multiple" size="'.$multiple.'">'."\n"; } foreach my $sec (@sections) { - $output .= '\n"; + if ($current_sec eq $sec) { + $output .= '\n"; + } else { + $output .= '\n"; + } } } $output .= ''; @@ -4170,7 +4781,7 @@ sub get_groupslist { } sub setsections_javascript { - my ($formname,$groupslist,$mode) = @_; + my ($formname,$groupslist,$mode,$checkauth,$crstype) = @_; my ($checkincluded,$finish,$rolecode,$setsection_js); if ($mode eq 'upload') { $checkincluded = 'formname.name == "'.$formname.'"'; @@ -4178,12 +4789,26 @@ sub setsections_javascript { $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n"; } elsif ($formname eq 'cu') { $checkincluded = 'formname.elements[i-1].checked == true'; - $finish = 'formname.submit()'; + if ($checkauth) { + $finish = "var authcheck = auth_check();\n". + " if (authcheck == 'ok') {\n". + " formname.submit();\n". + " }\n"; + } else { + $finish = 'formname.submit()'; + } $rolecode = "var match = str.split('_'); var role = match[3];\n"; } elsif ($formname eq 'enrollstudent') { $checkincluded = 'formname.name == "'.$formname.'"'; - $finish = 'formname.submit()'; + if ($checkauth) { + $finish = "var authcheck = auth_check();\n". + " if (authcheck == 'ok') {\n". + " formname.submit();\n". + " }\n"; + } else { + $finish = 'formname.submit()'; + } $rolecode = "var match = str.split('_'); var role = match[1];\n"; } else { @@ -4195,8 +4820,11 @@ sub setsections_javascript { } my %alerts = &Apache::lonlocal::texthash( secd => 'Section designations do not apply to Course Coordinator roles.', + sedn => 'Section designations do not apply to Coordinator roles.', 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.', + inec => '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.', @@ -4204,11 +4832,13 @@ 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) { +function setSections(formname,crstype) { var re1 = /^currsec_/; + var re2 =/\\W/; var groups = new Array($groupslist); for (var i=0;i 0) { + alert("$alerts{'nonw'}\\n$alerts{'plch'}"); + return; + } + numsec = numsec + validsecs.length; } if ((role == 'st') && (numsec > 1)) { - alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}") + if (crstype == 'Community') { + alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}"); + } else { + alert("$alerts{'inco'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}"); + } return; } else { @@ -4295,7 +4945,7 @@ sub can_create_user { } if (ref($domconf{'usercreation'}) eq 'HASH') { if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') { - if ($context eq 'course' || $context eq 'author') { + if ($context eq 'course' || $context eq 'author' || $context eq 'requestcrs') { my $creation = $domconf{'usercreation'}{'cancreate'}{$context}; if ($creation eq 'none') { $cancreate = 0; @@ -4329,10 +4979,14 @@ sub can_modify_userinfo { if (ref($userroles) eq 'ARRAY') { foreach my $role (@{$userroles}) { my $testrole; - if ($role =~ /^cr\//) { - $testrole = 'cr'; - } else { + if ($context eq 'selfcreate') { $testrole = $role; + } else { + if ($role =~ /^cr\//) { + $testrole = 'cr'; + } else { + $testrole = $role; + } } if (ref($domconfig{'usermodification'}{$context}{$testrole}) eq 'HASH') { if ($domconfig{'usermodification'}{$context}{$testrole}{$field}) { @@ -4389,27 +5043,36 @@ sub check_usertype { } sub roles_by_context { - my ($context,$custom) = @_; + my ($context,$custom,$crstype) = @_; my @allroles; if ($context eq 'course') { - @allroles = ('st','ad','ta','ep','in','cc'); + @allroles = ('st'); + if ($env{'request.role'} =~ m{^dc\./}) { + push(@allroles,'ad'); + } + push(@allroles,('ta','ep','in')); + if ($crstype eq 'Community') { + push(@allroles,'co'); + } else { + push(@allroles,'cc'); + } if ($custom) { push(@allroles,'cr'); } } elsif ($context eq 'author') { @allroles = ('ca','aa'); } elsif ($context eq 'domain') { - @allroles = ('li','dg','sc','au','dc'); + @allroles = ('li','ad','dg','sc','au','dc'); } return @allroles; } sub get_permission { - my ($context,$roles) = @_; + my ($context,$crstype) = @_; my %permission; if ($context eq 'course') { my $custom = 1; - my @allroles = &roles_by_context($context,$custom); + my @allroles = &roles_by_context($context,$custom,$crstype); foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) { $permission{'cusr'} = 1; @@ -4478,24 +5141,17 @@ sub authorpriv { } sub roles_on_upload { - my ($context,%customroles) = @_; + my ($context,$setting,$crstype,%customroles) = @_; my (@possible_roles,@permitted_roles); - if ($context eq 'domain') { - @possible_roles = &curr_role_permissions($context,undef,1); - push(@possible_roles,&curr_role_permissions($context,'course',1)); - } else { - @possible_roles = &curr_role_permissions($context,undef,1); - } - my $custom_ok = 0; + @possible_roles = &curr_role_permissions($context,$setting,1,$crstype); foreach my $role (@possible_roles) { if ($role eq 'cr') { - $custom_ok = 1; push(@permitted_roles,keys(%customroles)); } else { push(@permitted_roles,$role); } } - return ($custom_ok,@permitted_roles); + return @permitted_roles; } sub get_course_identity { @@ -4520,15 +5176,20 @@ sub get_course_identity { } sub dc_setcourse_js { - my ($formname,$mode) = @_; - my $dc_setcourse_code; + my ($formname,$mode,$context) = @_; + my ($dc_setcourse_code,$authen_check); my $cctext = &Apache::lonnet::plaintext('cc'); + my $cotext = &Apache::lonnet::plaintext('co'); my %alerts = §ioncheck_alerts(); my $role = 'role'; if ($mode eq 'upload') { $role = 'courserole'; + } else { + $authen_check = &verify_authen($formname,$context); } $dc_setcourse_code = (<<"SCRIPTTOP"); +$authen_check + function setCourse() { var course = document.$formname.dccourse.value; if (course != "") { @@ -4565,7 +5226,11 @@ function setCourse() { numsections = numsections + newsecs.length; } if ((userrole == 'st') && (numsections > 1)) { - alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.") + if (document.$formname.crstype.value == 'Community') { + alert("$alerts{'inco'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.") + } else { + alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.") + } return; } for (var j=0; j 0)) { + alert("$alerts{'secd'} $cotext $alerts{'role'}.\\n$alerts{'accr'}."); + section = ""; + } SCRIPTTOP if ($mode ne 'upload') { $dc_setcourse_code .= (<<"ENDSCRIPT"); var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole var numcourse = getIndex(document.$formname.dccourse); if (numcourse == "-1") { - alert("$alerts{'thwa'}"); + if (document.$formname.type == 'Community') { + alert("$alerts{'thwc'}"); + } else { + alert("$alerts{'thwa'}"); + } return; } else { @@ -4613,9 +5290,11 @@ SCRIPTTOP } } } - document.$formname.submit(); + var authcheck = auth_check(); + if (authcheck == 'ok') { + document.$formname.submit(); + } } - ENDSCRIPT } else { $dc_setcourse_code .= " @@ -4636,26 +5315,99 @@ ENDSCRIPT return -1; } ENDSCRIPT + return $dc_setcourse_code; +} + +sub verify_authen { + my ($formname,$context) = @_; + my %alerts = &authcheck_alerts(); + my $finish = "return 'ok';"; + if ($context eq 'author') { + $finish = "document.$formname.submit();"; + } + my $outcome = <<"ENDSCRIPT"; + +function auth_check() { + var logintype; + if (document.$formname.login.length) { + if (document.$formname.login.length > 0) { + var loginpicked = 0; + for (var i=0; i 'You must select a course in the current domain', + curd => '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', youh => 'You had selected', sect => 'sections', plsm => 'Please modify your selections so they include no more than one section', mayn => 'may not be used as the name for a section, as it is a reserved word', plsc => 'Please choose a different section name', mayt => 'may not be used as the name for a section, as it is the name of a course group', + mayc => 'may not be used as the name for a section, as it is the name of a community group', secn => 'Section names and group names must be distinct', secd => 'Section designations do not apply to ', role => 'roles', accr => 'role will be added with access to all sections', - thwa => 'There was a problem with your course selection' + thwa => 'There was a problem with your course selection', + thwc => 'There was a problem with your community selection', ); return %alerts; } +sub authcheck_alerts { + my %alerts = + &Apache::lonlocal::texthash( + authen => 'You must choose an authentication type.', + krb => 'You need to specify the Kerberos domain.', + ipass => 'You need to specify the initial password.', + ); + return %alerts; +} + 1;