--- loncom/interface/loncoursegroups.pm 2006/11/02 21:06:06 1.63 +++ loncom/interface/loncoursegroups.pm 2006/11/20 23:49:49 1.64 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: loncoursegroups.pm,v 1.63 2006/11/02 21:06:06 albertel Exp $ +# $Id: loncoursegroups.pm,v 1.64 2006/11/20 23:49:49 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -92,12 +92,13 @@ sub handler { my $action = $env{'form.action'}; my $state = $env{'form.state'}; - if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify')) { + if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify') || ($action eq 'delete')) { if (!defined($state)) { $state = 'view'; } } - if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { + if ($action eq 'create' || $action eq 'modify' || $action eq 'view' || + $action eq 'delete') { if ($view_permission || $manage_permission) { if ($state eq 'view') { &print_main_menu($r,$cdom,$cnum,\%functions,\%idx, @@ -165,7 +166,7 @@ sub display_groups { $env{'form.refpage'}.'&state=pick_task&groupname=', view => ' 'Modify', @@ -305,7 +306,9 @@ END if (($manage_permission) && ($env{'form.refpage'} ne 'enrl')) { $link .= '  '.$actionlinks{'modify'}. - $group.'">'.$lt{'modify'}.''; + $group.'">'.$lt{'modify'}.''. + '  '.$actionlinks{'delete'}. + $group.'">'.$lt{'delete'}.''; } } $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense'). @@ -808,6 +811,7 @@ function changeSort(caller) { my %branchstates = (); @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result'); @{$states{'modify'}} = ('pick_task'); + @{$states{'delete'}} = ('verify','result'); @{$branchstates{'noprivs'}} = ('result'); @{$branchstates{'settings'}} = ('change_settings','chgresult'); @{$branchstates{'members'}} = ('change_members','change_privs','memresult'); @@ -818,7 +822,7 @@ function changeSort(caller) { push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}}); } - if (($action eq 'create') || ($action eq 'modify')) { + if (($action eq 'create') || ($action eq 'modify') || ($action eq 'delete')) { my $done = 0; my $i=0; while ($i<@{$states{$action}} && !$done) { @@ -839,9 +843,9 @@ function changeSort(caller) { ({href=>"/adm/dropadd", text=>"Enrollment Manager", faq=>9,bug=>'Instructor Interface',}); - if ($action eq 'modify') { + if ($action eq 'modify' || $action eq 'delete') { &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/coursegroups?refpage=enrl&action=modify", + ({href=>"/adm/coursegroups?refpage=enrl&action=$action", text=>"Groups", faq=>9,bug=>'Instructor Interface',}); } @@ -877,6 +881,10 @@ function changeSort(caller) { memresult => 'Modifications Complete', addresult => 'Additions Complete', ); + %{$trail{'delete'}} = &Apache::lonlocal::texthash( + verify => 'Verify deletion', + result => 'Deletion Complete' + ); my %navbuttons = &Apache::lonlocal::texthash( gtns => 'Go to next step', gtps => 'Go to previous step', @@ -885,7 +893,7 @@ function changeSort(caller) { gtpp => 'Go to previous page', adme => 'Add members', ); - if ((($action eq 'create') || ($action eq 'modify')) && + if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete')) && ($manage_permission)) { for (my $i=0; $i<@{$states{$action}}; $i++) { if ($state eq $states{$action}[$i]) { @@ -903,16 +911,18 @@ function changeSort(caller) { $crstype); last; } else { - if (($state eq 'result') && ($i > 0)) { - &Apache::lonhtmlcommon::add_breadcrumb( + if (($action eq 'create') || ($action eq 'modify')) { + if (($state eq 'result') && ($i > 0)) { + &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[0]')", text=>"$trail{$action}{$states{$action}[$i]}"}); - } else { - &Apache::lonhtmlcommon::add_breadcrumb( + } else { + &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')", text=>"$trail{$action}{$states{$action}[$i]}"}); + } } - } + } } } elsif (($action eq 'view') && ($view_permission)) { &Apache::lonhtmlcommon::add_breadcrumb( @@ -922,7 +932,6 @@ function changeSort(caller) { &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission, $manage_permission,$action,$state,$gpterm,$ucgpterm, $crstype); - } $r->print(&footer()); return; @@ -1069,7 +1078,138 @@ sub display_control { $sections,$states,$navbuttons,$memchg, $sectioncount,$stored,$gpterm,$ucgpterm,$crstype); } + } elsif ($action eq 'delete') { + my %stored = &retrieve_settings($cdom,$cnum,$groupname); + if ($state eq 'verify') { + &verify_delete($r,$groupname,$state,$action,$page,$states, + \%stored); + } elsif ($state eq 'result') { + &delete_group($r,$cdom,$cnum,$groupname); + } + } +} + +sub verify_delete { + my ($r,$groupname,$formname,$action,$page,$states,$stored) = @_; + $r->print(&Apache::lonhtmlcommon::echo_form_input([])); + $r->print(&mt("You have requested deletion of the following group: ").''. + $stored->{'description'}.''. + '

'.&mt('When a group is deleted the following occurs:').''.&mt('Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same course in the future.')); + my $prevtext = &mt('Go back'); + my $nexttext = &mt('Delete group'); + my $prev; + if ($env{'form.refpage'} eq 'enrl') { + $prev = 'view'; + } + &display_navbuttons($r,$formname,$prev,$prevtext, + $$states{$action}[$page+1],$nexttext); + return; +} + +sub delete_group { + my ($r,$cdom,$cnum,$groupname) = @_; + my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, + $groupname); + my $now = time; + my $num_users = 0; + my $num_fail = 0; + my $num_ok = 0; + my @deleted; + my @undeleted; + my %usersettings; + foreach my $key (sort(keys(%membership))) { + if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { + my $user = $1; + my($end,$start,@userprivs) = split(/:/,$membership{$key}); + if ($start != -1) { + $num_users ++; + $usersettings{$groupname.':'.$user} = $now.':-1:'; + if (&Apache::lonnet::modify_group_roles($cdom,$cnum, + $groupname,$user, + $now,'-1','') + eq 'ok') { + $num_ok ++; + push(@deleted,$user); + } else { + push(@undeleted,$user); + $num_fail ++; + } + } + } + } + if ($num_ok > 0) { + my $roster_result = + &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum, + \%usersettings); + } + if ($num_fail > 0) { + $r->print(&mt('Group deletion failed because deletion of [_1] out of [_2] members failed',$num_fail,$num_users)); + + } else { + my ($result,$message) = + &Apache::lonnet::delete_coursegroup($cdom,$cnum,$groupname); + if ($result eq 'ok') { + my $outcome = &modify_folders($cdom,$cnum,$groupname); + if ($outcome eq '') { + $r->print(&mt('Group successfully deleted')); + } else { + $r->print(&mt("Although the group was deleted, an error ([_1]) occurred when removing the group's folder from the 'Course Groups' folder.",$outcome)); + } + } else { + $r->print(&mt('Group deletion failed')); + } } + return; +} + +sub modify_folders { + my ($cdom,$cnum,$groupname) = @_; + my $outcome; + my $navmap = Apache::lonnavmaps::navmap->new(); + my $groupmap = '/uploaded/'.$cdom.'/'.$cnum.'/'.'group_folder_'. + $groupname.'.sequence'; + my $groupmapres = $navmap->getResourceByUrl($groupmap); + if ($groupmapres) { + my ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb()); + $map = '/'.$map; + my ($errtext,$fatal) = &LONCAPA::map::mapread($map); + if ($fatal) { + $outcome=&mt('Error reading contents of parent folder to group'). + " ($map): $errtext".'
'; + } else { + my $idx = 0; + my $grpidx; + foreach my $item (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$item]); + $url=&LONCAPA::map::qtescape($url); + if ($url eq $groupmap) { + $grpidx = $idx; + last; + } else { + $idx++; + } + } + + if ($grpidx ne '') { + &LONCAPA::map::makezombie($LONCAPA::map::order[$grpidx]); + for (my $i=$grpidx;$i<$#LONCAPA::map::order;$i++) { + $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1]; + } + $#LONCAPA::map::order--; + my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1); + if ($outtext) { + $outcome = &mt('Error storing updated parent folder to group'). " ($map): $errtext".'
'; + return; + } + } + } + } + undef($navmap); + return $outcome; } sub header { @@ -1543,6 +1683,11 @@ sub display_navbuttons {    '); + } elsif ($prevtext) { + $r->print(' + +    '); } if ($next) { $r->print(' @@ -3458,7 +3603,7 @@ sub map_updater { ':false:normal:res'; $LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx; my ($outtext,$errtext) = &LONCAPA::map::storemap($parentmap,1); - if ($errtext) { + if ($outtext) { $outcome = &mt('Error storing updated parent folder')." ($parentmap): $errtext".'
'; return $outcome; } @@ -3568,7 +3713,11 @@ sub validate_groupname { my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_; my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum); my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum); - + my %deleted_groups = &Apache::lonnet::get_deleted_groups($cdom,$cnum); + if (my $tmp = &Apache::lonnet::error(%deleted_groups)) { + undef(%deleted_groups); + &Apache::lonnet::logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom); + } my %lt = &Apache::lonlocal::texthash ( igna => "Invalid $gpterm name", tgne => "The $gpterm name entered ", @@ -3595,12 +3744,14 @@ sub validate_groupname { return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}. '
'.$lt{'grna'}; } - if ($action eq 'create' - && exists($curr_groups{$groupname})) { - - return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm). - $lt{'inth'}.'
'.$lt{'grna'}; - + if ($action eq 'create') { + if (exists($curr_groups{$groupname})) { + return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm). + $lt{'inth'}.'.
'.$lt{'grna'}; + } elsif (exists($deleted_groups{$groupname})) { + return $exitmsg.$lt{'cnnb'}.&mt('a [_1] which previously existed',$gpterm). + $lt{'inth'}.'.
'.$lt{'grna'}; + } } elsif ($action eq 'modify') { unless(exists($curr_groups{$groupname})) { $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}.