--- loncom/interface/lonuserutils.pm 2007/12/22 17:33:26 1.27 +++ loncom/interface/lonuserutils.pm 2007/12/23 03:21:28 1.31 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Utility functions for managing LON-CAPA user accounts # -# $Id: lonuserutils.pm,v 1.27 2007/12/22 17:33:26 raeburn Exp $ +# $Id: lonuserutils.pm,v 1.31 2007/12/23 03:21:28 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -2047,6 +2047,11 @@ END $env{'request.role.domain'})) { $canchange{$role} = 1; } + } elsif ($setting eq 'author') { + if (&Apache::lonnet::allowed('c'.$role, + $env{'request.role.domain'})) { + $canchange{$role} = 1; + } } } elsif ($context eq 'author') { if (&Apache::lonnet::allowed('c'.$role, @@ -2841,8 +2846,8 @@ sub viewable_section { ################################################# ################################################# sub show_drop_list { - my ($r,$classlist,$keylist,$nosort,$permission)=@_; - my $cid=$env{'request.course.id'}; + my ($r,$classlist,$nosort,$permission) = @_; + my $cid = $env{'request.course.id'}; my ($cnum,$cdom) = &get_course_identity($cid); if (! exists($env{'form.sortby'})) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, @@ -2852,9 +2857,6 @@ sub show_drop_list { if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) { $sortby = 'username'; } - my ($classgroups) = &Apache::loncoursedata::get_group_memberships( - $classlist,$keylist,$cdom,$cnum); - # my $action = "drop"; my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript(); $r->print(< END - -my %lt=&Apache::lonlocal::texthash('usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", - 'start' => "start date", - 'end' => "end date", - 'groups' => "active groups", - ); + my ($indexhash,$keylist) = &make_keylist_array(); + my $studentcount = 0; + if (ref($classlist) eq 'HASH') { + foreach my $student (keys(%{$classlist})) { + my $sdata = $classlist->{$student}; + my $status = $sdata->[$indexhash->{'status'}]; + my $section = $sdata->[$indexhash->{'section'}]; + if ($status ne 'Active') { + delete($classlist->{$student}); + next; + } + if ($env{'request.course.sec'} ne '') { + if ($section ne $env{'request.course.sec'}) { + delete($classlist->{$student}); + next; + } + } + $studentcount ++; + } + } + if (!$studentcount) { + $r->print(&mt('There are no students to drop.')); + return; + } + my ($classgroups) = &Apache::loncoursedata::get_group_memberships( + $classlist,$keylist,$cdom,$cnum); + my %lt=&Apache::lonlocal::texthash('usrn' => "username", + 'dom' => "domain", + 'sn' => "student name", + 'sec' => "section", + 'start' => "start date", + 'end' => "end date", + 'groups' => "active groups", + ); if ($nosort) { $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); @@ -2918,32 +2945,26 @@ END } # # Sort the students - my %index; - my $i; - foreach (@$keylist) { - $index{$_} = $i++; - } - $index{'groups'} = scalar(@$keylist); - my $index = $index{$sortby}; - my $second = $index{'username'}; - my $third = $index{'domain'}; + my $index = $indexhash->{$sortby}; + my $second = $indexhash->{'username'}; + my $third = $indexhash->{'domain'}; my @Sorted_Students = sort { lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index]) || lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second]) || lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third]) - } (keys(%$classlist)); + } (keys(%{$classlist})); foreach my $student (@Sorted_Students) { my $error; my $sdata = $classlist->{$student}; - my $username = $sdata->[$index{'username'}]; - my $domain = $sdata->[$index{'domain'}]; - my $section = $sdata->[$index{'section'}]; - my $name = $sdata->[$index{'fullname'}]; - my $id = $sdata->[$index{'id'}]; - my $start = $sdata->[$index{'start'}]; - my $end = $sdata->[$index{'end'}]; + my $username = $sdata->[$indexhash->{'username'}]; + my $domain = $sdata->[$indexhash->{'domain'}]; + my $section = $sdata->[$indexhash->{'section'}]; + my $name = $sdata->[$indexhash->{'fullname'}]; + my $id = $sdata->[$indexhash->{'id'}]; + my $start = $sdata->[$indexhash->{'start'}]; + my $end = $sdata->[$indexhash->{'end'}]; my $groups = $classgroups->{$student}; my $active_groups; if (ref($groups->{active}) eq 'HASH') { @@ -2959,25 +2980,18 @@ END } else { $end = &Apache::lonlocal::locallocaltime($end); } - my $status = $sdata->[$index{'status'}]; - next if ($status ne 'Active'); - if ($env{'request.course.sec'} ne '') { - if ($section ne $env{'request.course.sec'}) { - next; - } - } my $studentkey = $student.':'.$section; - my $startitem = ''; + my $startitem = ''; # $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); - + $username $domain $id $name $section - $start + $start $startitem $end $active_groups END @@ -2985,7 +2999,7 @@ END } $r->print(&Apache::loncommon::end_data_table().'
'); %lt=&Apache::lonlocal::texthash( - 'dp' => "Expire Users' Roles", + 'dp' => "Drop Students", 'ca' => "check all", 'ua' => "uncheck all", ); @@ -3042,6 +3056,10 @@ sub upfile_drop_add { $fields{$env{'form.f'.$i}}=$keyfields[$i]; } } + if ($env{'form.fullup'} ne 'yes') { + $r->print('
'."\n". + ''); + } # # Store the field choices away foreach my $field (qw/username names @@ -3467,7 +3485,7 @@ sub upfile_drop_add { } } if (!$multiple) { - ($userresult,$authresult,$roleresult) = + ($userresult,$authresult,$roleresult,$idresult) = &modifyuserrole($context,$setting, $changeauth,$cid,$domain,$username, $id,$amode,$password,$fname, @@ -3487,8 +3505,8 @@ sub upfile_drop_add { } else { $flushc = &user_change_result($r,$userresult,$authresult, - $roleresult,\%counts,$flushc, - $username,%userchg); + $roleresult,$idresult,\%counts,$flushc, + $username,\%userchg); } } else { if ($context eq 'course') { @@ -3510,11 +3528,13 @@ sub upfile_drop_add { } # end of foreach (@userdata) # Flush the course logs so reverse user roles immediately updated &Apache::lonnet::flushcourselogs(); - $r->print("

\n

\n".&mt('Processed [_1] user(s).',$counts{'user'}). + $r->print("

\n

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

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

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

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

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

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

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

\n". @@ -3522,23 +3542,22 @@ sub upfile_drop_add { $counts{'auth'})."

\n"); } $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules)); - $r->print(''); - $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','prevphase','currstate'])); - $r->print('
'); ##################################### - # Drop students # + # Display list of students to drop # ##################################### if ($env{'form.fullup'} eq 'yes') { - $r->print('

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

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

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

\n"); # Get current classlist - my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); + my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { - $r->print(&mt('There are no students currently enrolled.'). - "\n"); + $r->print('
'. + ''. + &mt('There are no students with current/future access to the course.'). + '
'."\n"); } else { # Remove the students we just added from the list of students. - foreach (@userdata) { - my %entries=&Apache::loncommon::record_sep($_); + foreach my $line (@userdata) { + my %entries=&Apache::loncommon::record_sep($line); unless (($entries{$fields{'username'}} eq '') || (!defined($entries{$fields{'username'}}))) { delete($classlist->{$entries{$fields{'username'}}. @@ -3546,10 +3565,13 @@ sub upfile_drop_add { } } # Print out list of dropped students. - &show_drop_list($r,$classlist,$keylist,'nosort'); + &show_drop_list($r,$classlist,'nosort',$permission); } } } # end of unless + if ($env{'form.fullup'} ne 'yes') { + $r->print(''); + } } sub print_namespacing_alerts { @@ -3593,8 +3615,8 @@ sub print_namespacing_alerts { } sub user_change_result { - my ($r,$userresult,$authresult,$roleresult,$counts,$flushc,$username, - $userchg) = @_; + my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc, + $username,$userchg) = @_; my $okresult = 0; if ($userresult ne 'ok') { if ($userresult =~ /^error:(.+)$/) { @@ -3635,6 +3657,9 @@ sub user_change_result { $flushc=0; } } + if ($idresult) { + $r->print($idresult); + } return $flushc; } @@ -3643,14 +3668,12 @@ sub print_drop_menu { my ($r,$context,$permission) = @_; $r->print('

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

'."\n". '
'."\n"); - my $cid=$env{'request.course.id'}; - my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist(); + my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { $r->print(&mt('There are no students currently enrolled.')."\n"); - return; + } else { + &show_drop_list($r,$classlist,'nosort',$permission); } - # Print out the available choices - &show_drop_list($r,$classlist,$keylist,$permission); $r->print('
'. &Apache::loncommon::end_page()); return; } @@ -3662,10 +3685,10 @@ sub update_user_list { my $now = time; my $count=0; my @changelist; - if ($choice ne '') { - @changelist = &Apache::loncommon::get_env_multiple('form.actionlist'); - } else { + if ($choice eq 'drop') { @changelist = &Apache::loncommon::get_env_multiple('form.droplist'); + } else { + @changelist = &Apache::loncommon::get_env_multiple('form.actionlist'); } my %result_text = ( ok => { 'revoke' => 'Revoked', 'delete' => 'Deleted', @@ -3732,7 +3755,6 @@ sub update_user_list { } } my $plrole = &Apache::lonnet::plaintext($role); - my ($uid,$first,$middle,$last,$gene,$sec); my $start = $env{'form.'.$item.'_start'}; my $end = $env{'form.'.$item.'_end'}; if ($choice eq 'drop') { @@ -3752,16 +3774,12 @@ sub update_user_list { &Apache::lonnet::revokerole($udom,$uname,$scope,$role); } } elsif ($choice eq 'delete') { - $start = -1; - $end = -1; if ($role eq 'st') { -# FIXME - how does role deletion affect classlist? - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid); - } else { - $result = - &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now, - 0,1); - } + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid); + } + $result = + &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now, + $start,1); } else { #reenable, activate, change access dates or change section if ($choice ne 'chgsec') { @@ -3803,27 +3821,36 @@ sub update_user_list { $nochg = 1; } } else { - if (!grep(/^\Q$sec\E$/,@newsecs)) { - $revresult = - &Apache::lonnet::revokerole($udom,$uname,$scope,$role); + if (@newsecs > 0) { + if (grep(/^\Q$sec\E$/,@newsecs)) { + push(@retained,$sec); + } else { + $revresult = + &Apache::lonnet::revokerole($udom,$uname, + $scope,$role); + } } else { - push(@retained,$sec); + $revresult = + &Apache::lonnet::revokerole($udom,$uname, + $scope,$role); } } } else { - push(@retained,$sec); + if ($sec eq '') { + $nochg = 1; + } else { + push(@retained,$sec); + } } # add new sections if (@newsecs == 0) { if (!$nochg) { - if ($sec ne '') { - if ($role eq 'st') { - $result = - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid); - } else { - my $newscope = $scopestem; - $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start); - } + if ($role eq 'st') { + $result = + &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid); + } else { + my $newscope = $scopestem; + $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start); } } } else { @@ -3857,11 +3884,11 @@ sub update_user_list { $count++; } else { $r->print( - &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]:[_4]", + &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].", $plrole,$extent,$uname.':'.$udom,$result).'
'); } } - $r->print('

'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,users].",$count).'

'); + $r->print('

'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,no users].",$count).'

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

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

')); @@ -3871,23 +3898,20 @@ sub update_user_list { } if ($env{'form.makedatesdefault'}) { if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') { - $r->print(&make_dates_default($startdate,$enddate)); + $r->print(&make_dates_default($startdate,$enddate,$context)); } } } sub classlist_drop { - my ($scope,$uname,$udom,$now,$action) = @_; + my ($scope,$uname,$udom,$now) = @_; my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)}); - my $cid=$cdom.'_'.$cnum; - my $user = $uname.':'.$udom; - if ($action eq 'drop') { + 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 }, - $env{'course.'.$cid.'.domain'}, - $env{'course.'.$cid.'.num'}); + { $user => $now },$cdom,$cnum); return &mt('Drop from classlist: [_1]', ''.$result.'').'
'; } @@ -3957,16 +3981,26 @@ sub course_sections { my ($sections_count,$role) = @_; my $output = ''; my @sections = (sort {$a <=> $b} keys %{$sections_count}); - if (scalar(@sections) == 1) { + my $numsec = scalar(@sections); + if ($numsec <= 1) { $output = ''."\n"; + if ($role eq 'st') { + $output .= '>'."\n". + ' '."\n". + ' \n"; + } else { + $output .= 'multiple="multiple" size="'.$multiple.'">'."\n"; + } foreach my $sec (@sections) { $output .= '\n"; } @@ -3986,16 +4020,27 @@ sub get_groupslist { } sub setsections_javascript { - my ($form,$groupslist) = @_; - my ($checkincluded,$finish,$roleplace,$setsection_js); - if ($form eq 'cu') { + my ($formname,$groupslist,$mode) = @_; + my ($checkincluded,$finish,$rolecode,$setsection_js); + if ($mode eq 'upload') { + $checkincluded = 'formname.name == "'.$formname.'"'; + $finish = "return 'ok';"; + $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n"; + } elsif ($formname eq 'cu') { $checkincluded = 'formname.elements[i-1].checked == true'; $finish = 'formname.submit()'; - $roleplace = 3; + $rolecode = "var match = str.split('_'); + var role = match[3];\n"; + } elsif ($formname eq 'enrollstudent') { + $checkincluded = 'formname.name == "'.$formname.'"'; + $finish = 'formname.submit()'; + $rolecode = "var match = str.split('_'); + var role = match[1];\n"; } else { - $checkincluded = 'formname.name == "'.$form.'"'; + $checkincluded = 'formname.name == "'.$formname.'"'; $finish = "seccheck = 'ok';"; - $roleplace = 1; + $rolecode = "var match = str.split('_'); + var role = match[1];\n"; $setsection_js = "var seccheck = 'alert';"; } my %alerts = &Apache::lonlocal::texthash( @@ -4020,8 +4065,7 @@ function setSections(formname) { var checkcurr = str.match(re1); if (checkcurr != null) { if ($checkincluded) { - var match = str.split('_'); - var role = match[$roleplace]; + $rolecode if (role == 'cc') { alert("$alerts{'secd'}\\n$alerts{'accr'}"); } @@ -4096,6 +4140,9 @@ sub can_create_user { my ($dom,$context,$usertype) = @_; my %domconf = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); my $cancreate = 1; + if (&Apache::lonnet::allowed('mau',$dom)) { + return $cancreate; + } if (ref($domconf{'usercreation'}) eq 'HASH') { if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') { if ($context eq 'course' || $context eq 'author') { @@ -4250,7 +4297,8 @@ sub get_permission { } else { my @allroles = &roles_by_context($context); foreach my $role (@allroles) { - if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) { $permission{'cusr'} = 1; + if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) { + $permission{'cusr'} = 1; last; } } @@ -4459,6 +4507,5 @@ sub sectioncheck_alerts { return %alerts; } - 1;