Diff for /loncom/interface/loncoursegroups.pm between versions 1.54 and 1.70

version 1.54, 2006/07/20 03:11:52 version 1.70, 2007/05/02 01:33:48
Line 29  package Apache::loncoursegroups; Line 29  package Apache::loncoursegroups;
   
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon;  use Apache::loncommon();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnavmaps;  use Apache::lonnavmaps();
 use Apache::longroup;  use Apache::longroup();
 use Apache::portfolio;  use Apache::portfolio();
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
   use LONCAPA::map();
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA;  use LONCAPA;
   
Line 91  sub handler { Line 92  sub handler {
   
     my $action = $env{'form.action'};      my $action = $env{'form.action'};
     my $state = $env{'form.state'};      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') || ($action eq 'reenable')) {
         if (!defined($state)) {          if (!defined($state)) {
             $state = 'view';              $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' || $action eq 'reenable') { 
         if ($view_permission || $manage_permission) {          if ($view_permission || $manage_permission) {
             if ($state eq 'view') {              if ($state eq 'view') {
                 &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,                  &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,
Line 127  sub print_main_menu { Line 129  sub print_main_menu {
 function changeSort(caller) {  function changeSort(caller) {
     document.$state.sortby.value = caller;      document.$state.sortby.value = caller;
     document.$state.submit();      document.$state.submit();
   }
   function openGroupRoster(group,status) {
       var url = '/adm/grouproster?';
       url += 'group='+group+'&status='+status+'&ref=popup';
       var title = 'Group Membership';
       var options = 'scrollbars=1,resizable=1,menubar=0';
       options += ',width=700,height=600';
       rosterbrowser = open(url,title,options,'1');
       rosterbrowser.focus();
 }\n|;  }\n|;
     $r->print(&header('Groups',$jscript,$action,$state));      $r->print(&header('Groups',$jscript,$action,$state));
     if ($env{'form.refpage'} eq 'enrl') {      if ($env{'form.refpage'} eq 'enrl') {
Line 155  sub display_groups { Line 166  sub display_groups {
                          $env{'form.refpage'}.'&state=pick_task&groupname=',                           $env{'form.refpage'}.'&state=pick_task&groupname=',
       view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',        view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',
       delete => '<a href="/adm/coursegroups?action=delete&refpage='.        delete => '<a href="/adm/coursegroups?action=delete&refpage='.
                          $env{'form.refpage'}.'&groupname=',                           $env{'form.refpage'}.'&state=verify&groupname=',
         reenable => '<a href="/adm/coursegroups?action=reenable&refpage='.
                            $env{'form.refpage'}.'&state=verify&groupname=',
     );      );
     my %lt = &Apache::lonlocal::texthash(       my %lt = &Apache::lonlocal::texthash( 
                           modify => 'Modify',                            modify => 'Modify',
                           view   => 'View',                            view   => 'View',
                           delete => 'Delete',                            delete => 'Delete',
                             reenable => 'Re-enable',
                           act    => 'Action',                            act    => 'Action',
                           gname  => 'Group Name',                            gname  => 'Group Name',
                           desc   => 'Group Title',                            desc   => 'Group Title',
Line 176  sub display_groups { Line 190  sub display_groups {
                           nogr   => 'No groups exist.',                            nogr   => 'No groups exist.',
                           crng   => 'Create a new group',                            crng   => 'Create a new group',
                           alth   => 'Although your current role has privileges'.                            alth   => 'Although your current role has privileges'.
                                     ' to view any existing groups in this'.                                      ' to view any existing groups in this '.
                                     lc($crstype).', you do not have privileges'.                                      lc($crstype).', you do not have privileges '.
                                     'to create new groups.',                                      'to create new groups.',
                      );                       );
     if ($view_permission) {      if ($view_permission) {
         if (!defined($action)) {          if (!defined($action)) {
             $action = 'view';              $action = 'view';
         }          }
         my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);          my $status;
           if ($action eq 'reenable') {
               $status = 'deleted_groups';
           }
           my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
                                                             $status);
         if (%curr_groups) {          if (%curr_groups) {
             if ($manage_permission) {              if ($manage_permission) {
                 if (!exists($env{'form.refpage'})) {                   if (!exists($env{'form.refpage'})) { 
Line 282  END Line 301  END
                         $functionality = &mt('None available');                          $functionality = &mt('None available');
                     }                      }
                     my $link = $actionlinks{$action};                      my $link = $actionlinks{$action};
                     if ($action eq 'modify' || $action eq 'delete') {                      if ($action eq 'modify' || $action eq 'delete' || 
                           $action eq 'reenable') {
                         $link .= $group;                          $link .= $group;
                     } else {                      } else {
                         $link .= $group.'/smppg?ref=grouplist';                          $link .= $group.'/smppg?ref=grouplist';
Line 295  END Line 315  END
                         if (($manage_permission) &&                           if (($manage_permission) && 
                             ($env{'form.refpage'} ne 'enrl')) {                              ($env{'form.refpage'} ne 'enrl')) {
                             $link .= '&nbsp;&nbsp;'.$actionlinks{'modify'}.                              $link .= '&nbsp;&nbsp;'.$actionlinks{'modify'}.
                                       $group.'">'.$lt{'modify'}.'</a>';                                        $group.'">'.$lt{'modify'}.'</a>'.
                                        '&nbsp;&nbsp;'.$actionlinks{'delete'}.
                                         $group.'">'.$lt{'delete'}.'</a>';
                         }                          }
                     }                      }
                     $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').                      $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
Line 420  sub group_administration { Line 442  sub group_administration {
                 $state = 'pick_task';                  $state = 'pick_task';
             }              }
         } else {          } else {
             %stored = &retrieve_settings($cdom,$cnum,$groupname);              %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
             if (ref($stored{'types'}) eq 'ARRAY') {              if (ref($stored{'types'}) eq 'ARRAY') {
                 @types = @{$stored{'types'}};                  @types = @{$stored{'types'}};
             }              }
Line 798  function changeSort(caller) { Line 820  function changeSort(caller) {
     my %branchstates = ();      my %branchstates = ();
     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');      @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
     @{$states{'modify'}} = ('pick_task');      @{$states{'modify'}} = ('pick_task');
       @{$states{'delete'}} = ('verify','result');
       @{$states{'reenable'}} = ('verify','result');
     @{$branchstates{'noprivs'}} = ('result');      @{$branchstates{'noprivs'}} = ('result');
     @{$branchstates{'settings'}} = ('change_settings','chgresult');      @{$branchstates{'settings'}} = ('change_settings','chgresult');
     @{$branchstates{'members'}} = ('change_members','change_privs','memresult');      @{$branchstates{'members'}} = ('change_members','change_privs','memresult');
Line 808  function changeSort(caller) { Line 832  function changeSort(caller) {
         push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});          push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});
     }      }
   
     if (($action eq 'create') || ($action eq 'modify')) {      if (($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
         my $done = 0;          my $done = 0;
         my $i=0;          my $i=0;
         while ($i<@{$states{$action}} && !$done) {          while ($i<@{$states{$action}} && !$done) {
Line 829  function changeSort(caller) { Line 853  function changeSort(caller) {
         ({href=>"/adm/dropadd",          ({href=>"/adm/dropadd",
           text=>"Enrollment Manager",            text=>"Enrollment Manager",
           faq=>9,bug=>'Instructor Interface',});            faq=>9,bug=>'Instructor Interface',});
         if ($action eq 'modify') {          if ($action eq 'modify' || $action eq 'delete') {
             &Apache::lonhtmlcommon::add_breadcrumb              &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>"/adm/coursegroups?refpage=enrl&action=modify",              ({href=>"/adm/coursegroups?refpage=enrl&action=$action",
               text=>"Groups",                text=>"Groups",
               faq=>9,bug=>'Instructor Interface',});                faq=>9,bug=>'Instructor Interface',});
         }          }
Line 867  function changeSort(caller) { Line 891  function changeSort(caller) {
                             memresult => 'Modifications Complete',                              memresult => 'Modifications Complete',
                             addresult => 'Additions Complete',                              addresult => 'Additions Complete',
                           );                            );
       %{$trail{'delete'}} = &Apache::lonlocal::texthash(
                               verify => 'Verify deletion',
                               result => 'Deletion Complete'
                             );
       %{$trail{'reenable'}} = &Apache::lonlocal::texthash(
                               verify => 'Verify Re-enable',
                               result => 'Re-enabled'
                             );
     my %navbuttons = &Apache::lonlocal::texthash(      my %navbuttons = &Apache::lonlocal::texthash(
                              gtns => 'Go to next step',                               gtns => 'Go to next step',
                              gtps => 'Go to previous step',                               gtps => 'Go to previous step',
Line 875  function changeSort(caller) { Line 907  function changeSort(caller) {
                              gtpp => 'Go to previous page',                               gtpp => 'Go to previous page',
                              adme => 'Add members',                               adme => 'Add members',
     );      );
     if ((($action eq 'create') || ($action eq 'modify')) &&      if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) &&
               ($manage_permission)) {                ($manage_permission)) {
         for (my $i=0; $i<@{$states{$action}}; $i++) {          for (my $i=0; $i<@{$states{$action}}; $i++) {
             if ($state eq $states{$action}[$i]) {              if ($state eq $states{$action}[$i]) {
                 &Apache::lonhtmlcommon::add_breadcrumb(                  &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"$trail{$action}{$state}"});                     {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs                  $r->print(&Apache::lonhtmlcommon::breadcrumbs
   ("Groups Manager"));    ("Groups Manager","Creating_Groups"));
                 &display_control($r,$cdom,$cnum,$action,$state,$page,                  &display_control($r,$cdom,$cnum,$action,$state,$page,
                        \%sectioncount,$groupname,$description,$functions,                         \%sectioncount,$groupname,$description,$functions,
                        \@tools,$toolprivs,$fixedprivs,$startdate,$enddate,                         \@tools,$toolprivs,$fixedprivs,$startdate,$enddate,
Line 893  function changeSort(caller) { Line 925  function changeSort(caller) {
  $crstype);   $crstype);
                 last;                  last;
             } else {              } else {
                 if (($state eq 'result') && ($i > 0)) {                  if (($action eq 'create') || ($action eq 'modify')) {
                     &Apache::lonhtmlcommon::add_breadcrumb(                      if (($state eq 'result') && ($i > 0)) {
                           &Apache::lonhtmlcommon::add_breadcrumb(
     {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",      {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});        text=>"$trail{$action}{$states{$action}[$i]}"});
                 } else {                       } else { 
                     &Apache::lonhtmlcommon::add_breadcrumb(                          &Apache::lonhtmlcommon::add_breadcrumb(
      {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",       {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});        text=>"$trail{$action}{$states{$action}[$i]}"});
                       }
                 }                  }
             }              }             
         }          }
     } elsif (($action eq 'view') && ($view_permission)) {      } elsif (($action eq 'view') && ($view_permission)) {
                         &Apache::lonhtmlcommon::add_breadcrumb(                          &Apache::lonhtmlcommon::add_breadcrumb(
Line 912  function changeSort(caller) { Line 946  function changeSort(caller) {
         &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,          &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
  $manage_permission,$action,$state,$gpterm,$ucgpterm,   $manage_permission,$action,$state,$gpterm,$ucgpterm,
  $crstype);   $crstype);
   
     }      }
     $r->print(&footer());      $r->print(&footer());
     return;      return;
 }  }
   
 sub retrieve_settings {  sub retrieve_settings {
     my ($cdom,$cnum,$groupname) = @_;      my ($cdom,$cnum,$groupname,$action) = @_;
     my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname);      my %curr_groups;
       my $namespace;
       if ($action eq 'reenable') {
           $namespace = 'deleted_groups';
       } else {
           $namespace = 'coursegroups';
       }
       %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
                                                      $namespace);
   
     return if (!%curr_groups);      return if (!%curr_groups);
   
Line 965  sub retrieve_settings { Line 1006  sub retrieve_settings {
  foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {   foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {
             if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') {              if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') {
         foreach my $section (@{$groupinfo{'autosec'}{$role}}) {          foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
   
             push (@{$stored{'sec_'.$role}},$section);              push (@{$stored{'sec_'.$role}},$section);
         }          }
         if (@{$groupinfo{'autosec'}{$role}} > 0) {          if (@{$groupinfo{'autosec'}{$role}} > 0) {
Line 1026  sub display_control { Line 1068  sub display_control {
                                  $userdata,$granularity,$quota,$specificity,                                   $userdata,$granularity,$quota,$specificity,
                                  $idx,$states,$navbuttons,$gpterm,$ucgpterm);                                   $idx,$states,$navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'add_members') {          } elsif ($state eq 'add_members') {
             &add_members_form($r,$action,$state,$page,$startdate,              &add_members_form($r,$cdom,$cnum,$action,$state,$page,$startdate,
                               $enddate,$groupname,$description,$granularity,                                $enddate,$groupname,$description,$granularity,
                               $quota,$sectioncount,$tools,$functions,$stored,                                $quota,$sectioncount,$tools,$functions,$stored,
                               $states,$navbuttons,$gpterm,$ucgpterm);                                $states,$navbuttons,$gpterm,$ucgpterm);
Line 1058  sub display_control { Line 1100  sub display_control {
                              $sections,$states,$navbuttons,$memchg,                               $sections,$states,$navbuttons,$memchg,
                              $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);                               $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
         }          }
       } elsif ($action eq 'delete') {
           my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
           if ($state eq 'verify') {
               &verify_delete($r,$groupname,$state,$action,$page,$states,
                              \%stored);
           } elsif ($state eq 'result') {
               &delete_group($r,$cdom,$cnum,$groupname);
           }
       } elsif ($action eq 'reenable') {
           my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
           if ($state eq 'verify') {
               &verify_reenable($r,$groupname,$state,$action,$page,$states,
                              \%stored);
           } elsif ($state eq 'result') {
               &reenable_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: ").'<i>'.
                 $stored->{'description'}.'</i>'.
                 '<br /><br />'.&mt('When a group is deleted the following occurs:').'<ul>'.
                 '<li>'.&mt('All group membership is terminated.').'</li>'.
                 '<li>'.&mt('The group ceases to be available either for viewing or for modification of group settings and membership.').'</li>'.
                 '<li>'.&mt('The group folder is removed from the folder containing it - normally this is the "Course Groups" folder which contains folders for all groups in the course.').'</li>'.
                 '</ul>'.&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},3);
               if ($start != -1) {
                   $num_users ++;
                   $usersettings{$groupname.':'.$user} = $now.':-1:'.$userprivs;
                   if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
                                                           $groupname,$user,
                                                           $now,'-1',$userprivs)
                       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::toggle_coursegroup_status($cdom,$cnum,
                                                           $groupname,'delete');
           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 reenable_folder {
       my ($cdom,$cnum,$groupname,$description) = @_;
       my $outcome;
       my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
       my $allgrpsmap = $crspath.'group_allfolders.sequence';
       my $foldertitle = &mt('Course Folder -').$description;
       my $mapurl = $crspath.'group_folder_'.
                      $groupname.'.sequence';
       my ($errtext,$fatal)=&LONCAPA::map::mapread($allgrpsmap);
       if ($fatal) {
           $outcome=&mt('Error reading contents of parent folder to group').
                        " ($allgrpsmap): $errtext".'<br />';
       } else {
           my $idx=&LONCAPA::map::getresidx($mapurl);
           $LONCAPA::map::resources[$idx] = $foldertitle.':'.$mapurl.
                                            ':false:normal:res';
           $LONCAPA::map::order[1+$#LONCAPA::map::order]=$idx;
           my ($outtext,$errtext) = &LONCAPA::map::storemap($allgrpsmap,1);
           if ($errtext) {
               $outcome = &mt('Error saving updated parent folder to group').
                              "- $allgrpsmap - $errtext".'<br />';
           } else {
               my ($furl,$ferr) =
                        &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
           }
       }
       return $outcome;
   }
   
   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);
       my ($map,$id,$src);
       if ($groupmapres) {
           ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb());
       }
       undef($navmap);
       if ($map) {
           $map = '/'.$map;
           my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
           if ($fatal) {
               $outcome=&mt('Error reading contents of parent folder to group').
                            " ($map): $errtext".'<br />';
           } 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 ($errtext) {
                       $outcome = &mt('Error saving updated parent folder to group'). "- $map - $errtext".'<br />';
                   } else {
                       my ($furl,$ferr) =
                           &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                   }  
               }
           }
       }
       return $outcome;
   }
   
   sub verify_reenable {
       my ($r,$groupname,$formname,$action,$page,$states,$stored) = @_;
       $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
       $r->print(&mt("You have requested enabling the following previously deleted group: ").'<i>'.
                 $stored->{'description'}.'</i>'.
                 '<br /><br />'.&mt('When a deleted group is re-enabled the following occurs:').'<ul>'.
                 '<li>'.&mt('Group settings and membership at the time the group was deleted are reinstated.').'</li>'.
                 '<li>'.&mt('A group folder is added to the "Course Groups" folder which contains folders for all groups in the course.').'</li></ul>');
       my $prevtext = &mt('Go back');
       my $nexttext = &mt('Reenable group');
       my $prev;
       if ($env{'form.refpage'} eq 'enrl')  {
           $prev = 'view';
       }
       &display_navbuttons($r,$formname,$prev,$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       return;
   }
   
   sub reenable_group {
       my ($r,$cdom,$cnum,$groupname) = @_;
       my %groups = 
           &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
                                           'deleted_groups');
       if (keys(%groups) == 0) {
           $r->print(&mt('The group ([_1]) was not re-enabled, because it is not a deleted group.<br />Perhaps it has already been re-enabled?',$groupname));
           return;
       }
       my %groupinfo = 
           &Apache::longroup::get_group_settings($groups{$groupname});
       my $defstart = $groupinfo{'startdate'};
       my $defend = $groupinfo{'enddate'};
       my $showstart = &Apache::lonlocal::locallocaltime($defstart);
       my $showend;
       if ($defend == 0) {
           $showend = &mt('No end date set');
       } else {
           $showend = &Apache::lonlocal::locallocaltime($defend);
       }
       my $description = &unescape($groupinfo{'description'});
       my $num_users = 0;
       my $num_ok = 0;
       my $num_fail = 0;
       my (%usersettings,@enabled,@unenabled);
       my ($result,$message) =
             &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,$groupname,
                                                        'reenable');
       if ($result eq 'ok') {
           my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                              $groupname);
           foreach my $key (sort(keys(%membership))) {
               if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
                   my $user = $1;
                   my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
                   if (($start == -1) && ($end == $groupinfo{'modified'})) {
                       $num_users ++;
                       $usersettings{$groupname.':'.$user} = $defend.':'.
                                                             $defstart.':'.
                                                             $userprivs;
                       if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
                                                               $groupname,$user,
                                                               $defend,$defstart,
                                                               $userprivs) eq 'ok') {
                           $num_ok ++;
                           push(@enabled,$user);
                       } else {
                           push(@unenabled,$user);
                           $num_fail ++;
                       }
                   }
               }
           }
           if ($num_users > 0) {
               if ($num_ok > 0) {
                   my $roster_result =
           &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
                                                          \%usersettings);
                   if ($roster_result eq 'ok') {
                       $r->print(&mt('Membership reinstated for [_1] users, each with start and end dates for group access set to defaults: [_2] and [_3]',$num_ok,$showstart,$showend).'<br />');
                   }
               } else {
                   $r->print(&mt('A problem occurred when trying to reinstate [_1] of the [_2] members of the pre-existing group.',$num_fail,$num_users).'<br />');
               }
           } else {
               $r->print(&mt('There were no group members to reinstate, as none were removed when the group was deleted.').'<br />');
           }
           my $outcome = &reenable_folder($cdom,$cnum,$groupname,$description);
           if ($outcome eq '') {
               $r->print(&mt('Group successfully re-enabled.'));
           } else {
               $r->print(&mt("Although the group was re-enabled, an error ([_1]) occurred when adding the group's folder to the 'Course Groups' folder.",$outcome));
           }
       } else {
           $r->print(&mt('Re-enabling group failed'));
       }
       return;
 }  }
   
 sub header {  sub header {
Line 1150  sub group_members { Line 1464  sub group_members {
     my ($cdom,$cnum,$group,$group_info) = @_;      my ($cdom,$cnum,$group,$group_info) = @_;
     my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);      my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
     my $now = time;      my $now = time;
     my ($tmp)=keys(%memberhash);      my %lt = &Apache::lonlocal::texthash (
     if ($tmp=~/^error:/) {                                            active => 'active',
         $$group_info{'totalmembers'} = 'Unknown - an error occurred';                                            previous => 'previous',
         return $tmp;                                            future => 'future',
     }      );
       my %membercounts = (  
                            active => 0,
                            previous => 0,
                            future => 0,
                          );
     my $totalmembers = 0;      my $totalmembers = 0;
     my $active = 0;  
     my $previous = 0;  
     my $future = 0;  
     foreach my $member (keys %memberhash) {      foreach my $member (keys %memberhash) {
         $totalmembers ++;          $totalmembers ++;
         my ($end,$start) = split(/:/,$memberhash{$member});          my ($end,$start) = split(/:/,$memberhash{$member});
         unless ($start == -1) {          unless ($start == -1) {
             if (($end!=0) && ($end<$now)) {              if (($end!=0) && ($end<$now)) {
                 $previous ++;                  $membercounts{previous} ++;
             } elsif (($start!=0) && ($start>$now)) {              } elsif (($start!=0) && ($start>$now)) {
                 $future ++;                  $membercounts{future} ++;
             } else {              } else {
                $active ++;                  $membercounts{active} ++;
             }              }
         }          }
     }      }
     if ($totalmembers == 0) {      if ($totalmembers == 0) {
         $$group_info{$group}{'totalmembers'} = 'None';          $$group_info{$group}{'totalmembers'} = 'None';
     } else {      } else {
         $$group_info{$group}{'totalmembers'} = '<nobr>'.$active.          foreach my $type ('active','previous','future') {
             '&nbsp;-&nbsp;active</nobr><br /><nobr>'.$previous.              $$group_info{$group}{'totalmembers'} .= 
             '&nbsp;-&nbsp;previous</nobr><br /><nobr>'.$future.                 &open_list_window($group,$type,$membercounts{$type},$lt{$type});
             '&nbsp;-&nbsp;future</nobr>';          }
     }      }
     return 'ok';      return 'ok';
 }  }
   
   sub open_list_window {
       my ($group,$status,$count,$text) = @_;
       my $entry;
       if ($count > 0) {
           $entry = '<nobr><a href="javascript:openGroupRoster('.
                    "'$group','$status'".')">'.$text.'</a>&nbsp;-&nbsp;'.$count.
                    '</nobr><br />';
       } else {
           $entry = '<nobr>'.$text.'&nbsp;-&nbsp;'.$count.'</nobr><br />';
       }
       return $entry;
   }
   
   
 sub general_settings_form {  sub general_settings_form {
     my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools,      my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools,
Line 1193  sub general_settings_form { Line 1522  sub general_settings_form {
                            $gpterm,$ucgpterm,$crstype);                             $gpterm,$ucgpterm,$crstype);
     &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm);      &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm);
     if ($action eq 'create') {      if ($action eq 'create') {
         &membership_options($r,$action,$formname,$sectioncount,3,$gpterm,          &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,3,
     $ucgpterm);                              $gpterm,$ucgpterm);
         $nexttext = $$navbuttons{'gtns'};          $nexttext = $$navbuttons{'gtns'};
     } else {      } else {
         my @available = ();          my @available = ();
Line 1206  sub general_settings_form { Line 1535  sub general_settings_form {
        $gpterm,$ucgpterm);         $gpterm,$ucgpterm);
         &mapping_options($r,$action,$formname,$page,$sectioncount,          &mapping_options($r,$action,$formname,$page,$sectioncount,
                          $states,$stored,$navbuttons,4,5,                           $states,$stored,$navbuttons,4,5,
  $gpterm,$ucgpterm,$crstype);   $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
         $nexttext = $$navbuttons{'mose'};          $nexttext = $$navbuttons{'mose'};
     }      }
     $prevtext = $$navbuttons{'gtpp'};      $prevtext = $$navbuttons{'gtpp'};
Line 1342  sub get_quota_constraints { Line 1671  sub get_quota_constraints {
 }  }
   
 sub membership_options {  sub membership_options {
     my ($r,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm) = @_;      my ($r,$cdom,$cnum,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm)=@_;
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                 'pipa' => 'Build a list of users for selection of group members',                  'pipa' => 'Build a list of users for selection of group members',
Line 1364  sub membership_options { Line 1693  sub membership_options {
                    future => &mt('Will have future access'),                     future => &mt('Will have future access'),
                    );                     );
   
     #FIXME need to plumb around for the various cr roles defined by the user      my @roles = ('st','cc','in','ta','ep','cr');
     my @roles = ('st','cc','in','ta','ep');  
   
     my @sections = keys(%{$sectioncount});      my @sections = keys(%{$sectioncount});
   
Line 1388  sub membership_options { Line 1716  sub membership_options {
       </tr><tr><td>');        </tr><tr><td>');
     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));      $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
     $r->print('</td><td>');      $r->print('</td><td>');
     $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));      $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles,undef,undef,1,$cdom,$cnum));
     if (@sections > 0) {      if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;          @sections = sort {$a cmp $b} @sections;
         unshift(@sections,'none'); # Put 'no sections' next          unshift(@sections,'none'); # Put 'no sections' next
Line 1518  sub display_navbuttons { Line 1846  sub display_navbuttons {
       <input type="button" name="previous" value = "'.$prevtext.'"        <input type="button" name="previous" value = "'.$prevtext.'"
     onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>      onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
    &nbsp;&nbsp;&nbsp;');     &nbsp;&nbsp;&nbsp;');
       } elsif ($prevtext) {
           $r->print('
         <input type="button" name="previous" value = "'.$prevtext.'"
       onclick="javascript:history.back()"/>
      &nbsp;&nbsp;&nbsp;');
     }      }
     if ($next) {      if ($next) {
         $r->print('          $r->print('
Line 1825  sub privilege_specificity { Line 2158  sub privilege_specificity {
     }      }
     &topic_bar($r,$img,$lt{'uprv'});      &topic_bar($r,$img,$lt{'uprv'});
     if ((($action eq 'create') && (@{$available} > 0)) ||       if ((($action eq 'create') && (@{$available} > 0)) || 
         (($action eq 'modify') && ($formname eq 'change_settings'))) {            (($action eq 'modify') && ($formname eq 'change_settings'))) {
         my %specific = (          my %specific = (
                       'No'  => 'checked="checked"',                        'No'  => 'checked="checked"',
                       'Yes' => '',                        'Yes' => '',
Line 1882  sub privilege_specificity { Line 2215  sub privilege_specificity {
     } else {      } else {
         if ($action eq 'create') {          if ($action eq 'create') {
             $r->print($lt{'asyo'});              $r->print($lt{'asyo'});
               $r->print('<input type="hidden" name="specificity" value="No" />');
         } elsif ($action eq 'modify' && $formname eq 'pick_members') {          } elsif ($action eq 'modify' && $formname eq 'pick_members') {
             my @defprivs;              my @defprivs;
             if (ref($$stored{'defpriv'}) eq 'ARRAY') {              if (ref($$stored{'defpriv'}) eq 'ARRAY') {
Line 2362  sub change_privs_form { Line 2696  sub change_privs_form {
 }  }
   
 sub add_members_form {  sub add_members_form {
     my ($r,$action,$formname,$page,$startdate,$enddate,$groupname,      my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,$groupname,
         $description,$granularity,$quota,$sectioncount,$tools,$functions,          $description,$granularity,$quota,$sectioncount,$tools,$functions,
         $stored,$states,$navbuttons,$gpterm,$ucgpterm)=@_;           $stored,$states,$navbuttons,$gpterm,$ucgpterm)=@_; 
     $r->print(' <br />');      $r->print(' <br />');
Line 2372  sub add_members_form { Line 2706  sub add_members_form {
     &print_current_settings($r,$action,$functions,$startdate,$enddate,      &print_current_settings($r,$action,$functions,$startdate,$enddate,
     $groupname,$description,$granularity,$quota,      $groupname,$description,$granularity,$quota,
     \@available,\@unavailable,$gpterm,$ucgpterm);      \@available,\@unavailable,$gpterm,$ucgpterm);
     &membership_options($r,$action,$formname,$sectioncount,1,$gpterm,$ucgpterm);      &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,1,$gpterm,
                           $ucgpterm);
     my $nexttext = $$navbuttons{'gtns'};      my $nexttext = $$navbuttons{'gtns'};
     my $prevtext = $$navbuttons{'gtpp'};      my $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
Line 2412  sub choose_privs_form { Line 2747  sub choose_privs_form {
         my $img2 = 8;          my $img2 = 8;
         &mapping_options($r,$action,$formname,$page,$sectioncount,          &mapping_options($r,$action,$formname,$page,$sectioncount,
                          $states,$stored,$navbuttons,$img1,$img2,                           $states,$stored,$navbuttons,$img1,$img2,
                          $gpterm,$ucgpterm,$crstype);                           $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
     }      }
     my $prevtext = $$navbuttons{'gtps'};      my $prevtext = $$navbuttons{'gtps'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
Line 2804  sub write_group_data { Line 3139  sub write_group_data {
                                            $description,$tools,\%groupinfo,                                             $description,$tools,\%groupinfo,
                                            $gpterm,$ucgpterm,$crstype);                                             $gpterm,$ucgpterm,$crstype);
             if ($result ne 'ok') {              if ($result ne 'ok') {
                 $r->print(&mt('A problem occurred when creating folders for the new [_1]. [_2].<br />',$gpterm,$result));                  $r->print(&mt('A problem occurred when creating folders for the new [_1].<br />[_2]<br />',$gpterm,$result));
             }              }
             $r->print(&mt('[_1] [_2] was created.<br />',$ucgpterm,$groupname));              $r->print(&mt('[_1] [_2] was created.<br />',$ucgpterm,$groupname));
         } else {          } elsif ($action eq 'modify') {
               my (@oldtools,@newtools); 
               if (ref($$stored{'tool'}) eq 'ARRAY') {
                   @oldtools = @{$$stored{'tool'}};
               }
               if (ref($tools) eq 'ARRAY') {
                   @newtools = @{$tools};
               }
               if (!grep(/^discussion$/,@oldtools) && 
                    grep(/^discussion$/,@newtools)) {
                   my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
                   my $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
                   my $navmap = Apache::lonnavmaps::navmap->new();
                   my $bbmapres = $navmap->getResourceByUrl($boardsmap);
                   undef($navmap);
                   if (!$bbmapres) {
                       my $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
                       my $disctitle = &mt('Discussion Boards');
                       my $outcome = &map_updater($cdom,$cnum,'group_boards_'.
                                                  $groupname.'.sequence','bbseq',
                                                  $disctitle,$grpmap);
                       my ($furl,$ferr) = 
                           &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                       $navmap = Apache::lonnavmaps::navmap->new();
                       # modify parameter
                       if ($outcome eq 'ok') {
                           my $parm_result = &parm_setter($navmap,$cdom,$boardsmap,
                                                          $groupname);
                           if ($parm_result) {
                               $r->print(&mt('Error while setting parameters '.
                                             'for Discussion Boards folder: '.
                                             '[_1]<br />.',$parm_result));
                           } else {
                               $r->print(&mt('Discussion Boards Folder created.<br />'));
                           }
                       } else {
                           $r->print($outcome);
                       }
                       undef($navmap);
                   }
               }
             $r->print(&mt('[_1] [_2] was updated.<br />',$ucgpterm,$groupname));              $r->print(&mt('[_1] [_2] was updated.<br />',$ucgpterm,$groupname));
         }          }
     } else {      } else {
Line 3036  sub process_membership { Line 3411  sub process_membership {
   
 sub mapping_options {  sub mapping_options {
     my ($r,$action,$formname,$page,$sectioncount,$states,$stored,      my ($r,$action,$formname,$page,$sectioncount,$states,$stored,
         $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype) = @_;          $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype,$cdom,$cnum) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'auto' => "Settings for automatic $gpterm enrollment",          'auto' => "Settings for automatic $gpterm enrollment",
         'gmma' => "$ucgpterm membership mapping to specific sections/roles",          'gmma' => "$ucgpterm membership mapping to specific sections/roles",
Line 3053  sub mapping_options { Line 3428  sub mapping_options {
         'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.",          'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.",
     );      );
     &automapping($r,$action,$stored,\%lt,$img1);      &automapping($r,$action,$stored,\%lt,$img1);
     &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype);      &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype,$cdom,$cnum,
                         $action);
     return;      return;
 }  }
   
Line 3086  sub automapping { Line 3462  sub automapping {
 }  }
   
 sub mapping_settings {  sub mapping_settings {
     my ($r,$sectioncount,$lt,$stored,$image,$crstype) = @_;      my ($r,$sectioncount,$lt,$stored,$image,$crstype,$cdom,$cnum,$action) = @_;
     my @sections = keys(%{$sectioncount});      my @sections = keys(%{$sectioncount});
     if (@sections > 0) {      if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;          @sections = sort {$a cmp $b} @sections;
Line 3097  sub mapping_settings { Line 3473  sub mapping_settings {
     }      }
     &topic_bar($r,$image,$$lt{'pirs'});      &topic_bar($r,$image,$$lt{'pirs'});
     my @roles = &standard_roles();      my @roles = &standard_roles();
     my %customroles = &my_custom_roles();      my %customroles = &Apache::lonhtmlcommon::course_custom_roles($cdom,$cnum);
     $r->print(&Apache::loncommon::start_data_table().      $r->print(&Apache::loncommon::start_data_table().
       &Apache::loncommon::start_data_table_header_row());        &Apache::loncommon::start_data_table_header_row());
     $r->print('      $r->print('
Line 3108  sub mapping_settings { Line 3484  sub mapping_settings {
     }      }
     $r->print(&Apache::loncommon::end_data_table_header_row()."\n");      $r->print(&Apache::loncommon::end_data_table_header_row()."\n");
     foreach my $role (@roles) {      foreach my $role (@roles) {
         my $plrole=&Apache::lonnet::plaintext($role,$crstype);          my $roletitle=&Apache::lonnet::plaintext($role,$crstype);
         my $sections_sel;          $r->print(&print_autorole_item($role,$roletitle,\@sections));
         if (@sections > 0) {  
             if ($role eq 'cc') {  
                 $sections_sel = '<td align="right">'.  
                                 &mt('all sections').'<input type="hidden" '.   
                                 'name="sec_cc" value="all" /></td>';  
             } else {   
                 $sections_sel='<td align="right">'.  
                               &sections_selection(\@sections,'sec_'.$role).  
                               '</td>';  
             }  
         }  
         $r->print(&Apache::loncommon::start_data_table_row().  
   '<td><input type="checkbox" '.  
                   'name="autorole" value="'.$role.'" /></td><td>'.$plrole.  
                   '</td>'.$sections_sel.  
   &Apache::loncommon::end_data_table_row());  
     }      }
       my @customs;
     foreach my $role (sort(keys(%customroles))) {      foreach my $role (sort(keys(%customroles))) {
         my $sections_sel;          my ($roletitle) = ($role =~ m|^cr/[^/]+/[^/]+/(.+)$|);
         if (@sections > 0) {          push (@customs,$role);
             $sections_sel =           $r->print(&print_autorole_item($role,$roletitle,\@sections));
  '<td>'.&sections_selection(\@sections,'sec_'.$role).'</td>';      }
         }      if ($action eq 'modify') {
         $r->print(&Apache::loncommon::start_data_table_row().          foreach my $role (@{$$stored{'autorole'}}) {
   '<td><input type="checkbox" '.              if ((!grep(/^\Q$role\E$/,@customs)) && 
                   'value="'.$role.'" /></td><td>'.&mt('Custom role: ').                  (!grep(/^\Q$role\E$/,@roles))) {
                   '<i>'.$role.'</i></td>'.$sections_sel.                  my $roletitle;
   &Apache::loncommon::end_data_table_row());                  if ($role =~ /^cr/) {
                       ($roletitle) = ($role =~ m|_([^_]+)$|);
                   } else {
                       $roletitle = &Apache::lonnet::plaintext($role,$crstype);
                   }
                   $r->print(&print_autorole_item($role,$roletitle,\@sections));
               }
           }
     }      }
     $r->print(&Apache::loncommon::end_data_table());      $r->print(&Apache::loncommon::end_data_table());
     return;      return;
 }  }
   
   sub print_autorole_item {
       my ($role,$roletitle,$sections) = @_;
       my $sections_sel;
       if (@{$sections} > 0) {
           if ($role eq 'cc') {
               $sections_sel = '<td align="right">'.
                               &mt('all sections').'<input type="hidden" '.
                               'name="sec_cc" value="all" /></td>';
           } else {
               $sections_sel='<td align="right">'.
                             &sections_selection($sections,'sec_'.$role).
                             '</td>';
           }
       }
       my $output = &Apache::loncommon::start_data_table_row().
                    '<td><input type="checkbox" '.
                    'name="autorole" value="'.$role.'" />'.
                    '</td><td>'.$roletitle.'</td>'.$sections_sel.
                    &Apache::loncommon::end_data_table_row();
       return $output;
   } 
   
 sub standard_roles {  sub standard_roles {
     my @roles = ('cc','in','ta','ep','st');      my @roles = ('cc','in','ta','ep','st');
     return @roles;      return @roles;
 }  }
   
 sub my_custom_roles {  
     my %returnhash=();  
     my %rolehash=&Apache::lonnet::dump('roles');  
     foreach (keys %rolehash) {  
         if ($_=~/^rolesdef\_(\w+)$/) {  
             $returnhash{$1}=$1;  
         }  
     }  
     return %returnhash;  
 }  
   
 sub modify_menu {  sub modify_menu {
     my ($r,$groupname,$page,$gpterm) = @_;      my ($r,$groupname,$page,$gpterm) = @_;
     my @menu =      my @menu =
Line 3294  sub add_group_folder { Line 3673  sub add_group_folder {
     if ($cdom eq '' || $cnum eq '') {      if ($cdom eq '' || $cnum eq '') {
         return &mt('Error: invalid course domain or number - group folder creation failed');            return &mt('Error: invalid course domain or number - group folder creation failed');  
     }      }
     my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage);      my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage,$warning);
     my $navmap = Apache::lonnavmaps::navmap->new();  
     my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';      my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
     $allgrpsmap = $crspath.'group_allfolders.sequence';      $allgrpsmap = $crspath.'group_allfolders.sequence';
     my $topmap = $navmap->getResourceByUrl($allgrpsmap);  
     undef($navmap);  
     if ($action eq 'create') {      if ($action eq 'create') {
     # check if group_allfolders.sequence exists.          if (&get_folder_lock($cdom,$cnum,'group_allfolders',$now) eq 'ok') {
         if (!$topmap) {              # check if group_allfolders.sequence exists.
             my $grpstitle = &mt('[_1] [_2]s',$crstype,$ucgpterm);              my $mapcontents = &Apache::lonnet::getfile($allgrpsmap);
             my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};              if ($mapcontents eq '-1') { #file does not exist;
             $topmap_url =~ s|/+|/|g;                  my $grpstitle = &mt('[_1] [_2]s',$crstype,$ucgpterm);
             if ($topmap_url =~ m|^/uploaded|) {                  my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};
                 $outcome = &map_updater($cdom,$cnum,'group_allfolders.sequence',                  $topmap_url =~ s|/+|/|g;
                                         'toplevelgroup',$grpstitle,$topmap_url);                  if ($topmap_url =~ m|^/uploaded|) {
                       $outcome = &map_updater($cdom,$cnum,'group_allfolders.sequence',
                                               'toplevelgroup',$grpstitle,$topmap_url);
                   } else {
                       $outcome = &mt('Non-standard course - folder for all groups not added.');
                   }
                 if ($outcome ne 'ok') {                  if ($outcome ne 'ok') {
                       my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
                       if ($delresult ne 'ok') {
                           $warning = $delresult;
                       }
                     return $outcome;                      return $outcome;
                 }                  }
             } else {  
                 $outcome = &mt('Non-standard course - folder for all groups not added.');  
                 return $outcome;  
             }              }
               my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
               if ($delresult ne 'ok') {
                   $warning = $delresult ;
               }
           } else {
               $outcome = &mt('Could not obtain exclusive lock to check status of the folder for all groups. No group folder added.');
               return $outcome;
         }          }
         my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description;          my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description;
         $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg';          $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg';
         my $grptitle = &mt('Group homepage').' - '.$description;          my $grptitle = &mt('Group homepage').' - '.$description;
         my ($seqid,$discussions,$disctitle);          my ($discussions,$disctitle);
         my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.sequence',          my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.sequence',
                                    'grpseq',$grpfolder,$allgrpsmap,$grppage,                                     'grpseq',$grpfolder,$allgrpsmap,$grppage,
                                    $grptitle);                                     $grptitle);
         if ($outcome ne 'ok') {          if ($outcome ne 'ok') {
             return $outcome;              return $outcome.$warning;
         }          }
         my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,          my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,
                                        $tools,$gpterm,$ucgpterm,$now);                                         $tools,$gpterm,$ucgpterm,$now);
         # Link to folder for bulletin boards          # Link to folder for bulletin boards
         $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';          $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
         if (grep/^discussion$/,@{$tools}) {          if (grep/^discussion$/,@{$tools}) {
             $seqid = $now + 1;  
             $disctitle = &mt('Discussion Boards');              $disctitle = &mt('Discussion Boards');
             my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname.              my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname.
                                        '.sequence','bbseq',$disctitle,$grpmap);                                         '.sequence','bbseq',$disctitle,$grpmap);
             if ($outcome ne 'ok') {              if ($outcome ne 'ok') {
                 return $outcome;                  return $outcome.$warning;
             }              }
             $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';              $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
         }          }
Line 3345  sub add_group_folder { Line 3733  sub add_group_folder {
         #modify group folder if status of discussions tools is changed          #modify group folder if status of discussions tools is changed
     }      }
     my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);      my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
     $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     # modify parameters      # modify parameters
     my $parm_result;      my $parm_result;
     if ($action eq 'create') {      if ($action eq 'create') {
         if ($allgrpsmap) {   
             $parm_result .= &parm_setter($navmap,$cdom,$allgrpsmap,$groupname);  
         }  
         if ($grpmap) {          if ($grpmap) {
             $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname);              $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname);
         }          }
Line 3362  sub add_group_folder { Line 3747  sub add_group_folder {
             $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname);              $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname);
         }          }
     }      }
       undef($navmap);
     if ($parm_result) {      if ($parm_result) {
         return $parm_result;          return $warning.$parm_result;
       } else {
           return 'ok';
       }
   }
   
   sub get_folder_lock {
       my ($cdom,$cnum,$folder_name,$now) = @_;  
       # get lock for folder being edited.
       my $lockhash = {
                     $folder_name."\0".'locked_folder' => $now.':'.$env{'user.name'}.
                                                        ':'.$env{'user.domain'},
                      };
       my $tries = 0;
       my $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
   
       while (($gotlock ne 'ok') && $tries <3) {
           $tries ++;
           sleep(1);
           $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
       }
       return $gotlock;
   }
   
   sub release_folder_lock {
       my ($cdom,$cnum,$folder_name) = @_;  
       #  remove lock
       my @del_lock = ($folder_name."\0".'locked_folder');
       my $dellockoutcome=&Apache::lonnet::del('coursegroups',\@del_lock,$cdom,$cnum);
       if ($dellockoutcome ne 'ok') {
           return ('<br />'.&mt('Warning: failed to release lock for folder: [_1].',$folder_name).'<br />'); 
     } else {      } else {
         return 'ok';          return 'ok';
     }      }
Line 3380  sub map_updater { Line 3796  sub map_updater {
     if ($newmapurl !~ m|^/uploaded|) {      if ($newmapurl !~ m|^/uploaded|) {
         $outcome = &mt('Error uploading new folder.')." ($newfile): $newmapurl".'<br />';          $outcome = &mt('Error uploading new folder.')." ($newfile): $newmapurl".'<br />';
         return $outcome;          return $outcome;
     }       }
     my ($errtext,$fatal)=&Apache::lonratedt::mapread($parentmap);      my ($errtext,$fatal)=&LONCAPA::map::mapread($parentmap);
     if ($fatal) {      if ($fatal) {
         $outcome = &mt('Error reading contents of parent folder')." ($parentmap): $errtext".'<br />';          $outcome = &mt('Error reading contents of parent folder')." ($parentmap): $errtext".'<br />';
         return $outcome;          return $outcome;
     } else {      } else {
         my $newidx=&Apache::lonratedt::getresidx($newmapurl);          my $newidx=&LONCAPA::map::getresidx($newmapurl);
         $Apache::lonratedt::resources[$newidx] = $itemtitle.':'.$newmapurl.          $LONCAPA::map::resources[$newidx] = $itemtitle.':'.$newmapurl.
                                                  ':false:normal:res';                                                   ':false:normal:res';
         $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx;          $LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
         my ($outtext,$errtext) = &Apache::lonratedt::storemap($parentmap,1);          my ($outtext,$errtext) = &LONCAPA::map::storemap($parentmap,1);
         if ($errtext) {          if ($errtext) {
             $outcome = &mt('Error storing updated parent folder')." ($parentmap):  $errtext".'<br />';              $outcome = &mt('Error saving updated parent folder')." ($parentmap):  $errtext".'<br />';
             return $outcome;              return $outcome;
         }          }
     }      }
Line 3426  sub parm_setter { Line 3842  sub parm_setter {
                                         },                                          },
                         );                          );
     my $res = $navmap->getResourceByUrl($url);      my $res = $navmap->getResourceByUrl($url);
     my $symb = $res->symb();      if ($res) {
     foreach my $level (keys(%hide_settings)) {          my $symb = $res->symb();
         my $parmresult =  &Apache::lonparmset::storeparm_by_symb($symb,          foreach my $level (keys(%hide_settings)) {
               my $parmresult =  
                          &Apache::lonparmset::storeparm_by_symb($symb,
                                                  '0_hiddenresource',                                                   '0_hiddenresource',
                                                  $hide_settings{$level}{'num'},                                                   $hide_settings{$level}{'num'},
                                                  $hide_settings{$level}{'set'},                                                   $hide_settings{$level}{'set'},
                                                  'string_yesno',undef,$cdom,                                                   'string_yesno',undef,$cdom,
                                                  undef,undef,                                                   undef,undef,
                                                  $hide_settings{$level}{'extra'});                                                   $hide_settings{$level}{'extra'});
         if ($parmresult) {              if ($parmresult) {
             $allresults .= $level.': '.$parmresult;                  $allresults .= $level.': '.$parmresult;
               }
         }          }
       } else {
           $allresults = &mt('Parameters not set for [_1] because the resource was not recognized as part of the course',$url).'<br />';
     }      }
     return $allresults;      return $allresults;
 }  }
Line 3501  sub validate_groupname { Line 3922  sub validate_groupname {
     my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_;      my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_;
     my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);      my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
     my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);      my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
       my %deleted_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
                                                            'deleted_groups');
       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 (      my %lt = &Apache::lonlocal::texthash (
                       igna => "Invalid $gpterm name",                        igna => "Invalid $gpterm name",
                       tgne => "The $gpterm name entered ",                        tgne => "The $gpterm name entered ",
Line 3528  sub validate_groupname { Line 3954  sub validate_groupname {
  return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.   return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.
     '<br />'.$lt{'grna'};      '<br />'.$lt{'grna'};
     }      }
     if ($action eq 'create'       if ($action eq 'create') { 
  && exists($curr_groups{$groupname})) {   if (exists($curr_groups{$groupname})) {
       return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm).
  return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm).             $lt{'inth'}.'.<br />'.$lt{'grna'};
     $lt{'inth'}.'<br />'.$lt{'grna'};          } elsif (exists($deleted_groups{$groupname})) {
               return $exitmsg.$lt{'cnnb'}.&mt('a [_1] which previously existed',$gpterm).
                      $lt{'inth'}.'.<br />'.$lt{'grna'};
           }
     } elsif ($action eq 'modify') {      } elsif ($action eq 'modify') {
         unless(exists($curr_groups{$groupname})) {          unless(exists($curr_groups{$groupname})) {
             $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}.              $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}.

Removed from v.1.54  
changed lines
  Added in v.1.70


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.