File:  [LON-CAPA] / loncom / interface / loncoursegroups.pm
Revision 1.4: download - view: text, annotated - select for diffs
Tue Nov 22 00:01:41 2005 UTC (18 years, 5 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_1_X, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_0_99_1, HEAD
Modify lonnet::get_coursegroups() to return a hash for consistency with other lonnet routines, and move sanity checking functionality to loncommon::coursegroups. Additional routines in lonnet to find out about groups.  Some fix-ups to loncoursegroups.pm

    1: #
    2: # Copyright Michigan State University Board of Trustees
    3: #
    4: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    5: #
    6: # LON-CAPA is free software; you can redistribute it and/or modify
    7: # it under the terms of the GNU General Public License as published by
    8: # the Free Software Foundation; either version 2 of the License, or
    9: # (at your option) any later version.
   10: #
   11: # LON-CAPA is distributed in the hope that it will be useful,
   12: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14: # GNU General Public License for more details.
   15: #
   16: # You should have received a copy of the GNU General Public License
   17: # along with LON-CAPA; if not, write to the Free Software
   18: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19: #
   20: # /home/httpd/html/adm/gpl.txt
   21: #
   22: # http://www.lon-capa.org/
   23: #
   24: 
   25: package Apache::loncoursegroups;
   26: 
   27: use strict;
   28: use Apache::lonnet;
   29: use Apache::loncommon;
   30: use Apache::lonhtmlcommon;
   31: use Apache::lonlocal;
   32: use Apache::lonnavmaps;
   33: use Apache::Constants qw(:common :http);
   34: 
   35: sub handler {
   36:     my ($r) = @_;
   37: 
   38:     &Apache::loncommon::content_type($r,'text/html');
   39:     $r->send_http_header;
   40:                                                                                 
   41:     if ($r->header_only) {
   42:         return OK;
   43:     }
   44: 
   45:     #  Needs to be in a course
   46:     if (! ($env{'request.course.fn'})) {
   47:         # Not in a course
   48:         $env{'user.error.msg'}=
   49:      "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
   50:         return HTTP_NOT_ACCEPTABLE;
   51:     }
   52: 
   53:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   54:                                             ['action','refpage']);
   55:                                                                                       
   56:     my $function = &Apache::loncommon::get_users_function();
   57:     my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
   58:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
   59:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   60: 
   61:     my $view_permission =
   62:           &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
   63:     my $manage_permission =
   64:           &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
   65: 
   66:     &Apache::lonhtmlcommon::clear_breadcrumbs();
   67: 
   68:     my %functions = (
   69:                       email => 'E-mail',
   70:                       discussion => 'Discussion boards',
   71:                       chat => 'Chat',
   72:                       files => 'File repository',
   73:                       roster => 'Membership roster',
   74:                       homepage => 'Group home page',
   75:                     );
   76: 
   77:     my %idx = ();
   78:     $idx{id} = &Apache::loncoursedata::CL_ID();
   79:     $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
   80:     $idx{udom} = &Apache::loncoursedata::CL_SDOM();
   81:     $idx{uname} = &Apache::loncoursedata::CL_SNAME();
   82: 
   83:     my $action = $env{'form.action'};
   84:     if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
   85:         if ($view_permission || $manage_permission) {
   86:             &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
   87:                         \%functions,\%idx,$view_permission,$manage_permission);
   88:         } else {
   89:             $r->print('You do not have group administration '.
   90:                       'privileges in this course');
   91:         }
   92:     } else {
   93:         &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,
   94:                                           $view_permission,$manage_permission);
   95:     }
   96:     return OK;
   97: }
   98: 
   99: sub print_main_menu {
  100:     my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
  101:                                                           $manage_permission)
  102:                                                                           = @_;
  103:     $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'),
  104:                                                  undef,undef,undef,$function));
  105:     &Apache::lonhtmlcommon::add_breadcrumb
  106:         ({href=>"/adm/coursegroups",
  107:           text=>"Course Groups",});
  108:     $r->print(&Apache::lonhtmlcommon::breadcrumbs
  109:                 (undef,'Course Groups'));
  110:     &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
  111:                                           $view_permission,$manage_permission);
  112:     $r->print(&footer());
  113:     return;
  114: }
  115: 
  116: sub display_groups {
  117:     my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
  118:                                                           $manage_permission) = @_;
  119:     my %curr_groups = ();
  120:     my %grp_info = ();
  121:     my $rowColor1 = "#dddddd";
  122:     my $rowColor2 = "#eeeeee";
  123: 
  124:     $r->print('<br /><br />');
  125:     if ($view_permission) {
  126:         my %curr_groups;
  127:         if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
  128:             $r->print(&Apache::lonhtmlcommon::start_pick_box());
  129:             $r->print(<<"END");
  130:       <table border="0" cellpadding="4" cellspacing="1">
  131:        <tr bgcolor="$tabcol" align="center">
  132:         <td><b>Action</b></td>
  133:         <td><b><a href="javascript:changeSort('groupname')">Group Name</a></b></td>
  134:         <td><b><a href="javascript:changeSort('description')">Description</a></b></td>
  135:         <td><b><a href="javascript:changeSort('creator')">Creator</a></b>
  136:         </td>
  137:         <td><b><a href="javascript:changeSort('creation')">Created</a></b>
  138:         </td>
  139:         <td><b><a href="javascript:changeSort('modified')">Last Modified</a></b>
  140:         </td>
  141:         <td><b>Functionality</b>
  142:         </td>
  143:         <td><b><a href="javascript:changeSort('quota')">Quota (Mb)</a></b></td>
  144:         <td><b><a href="javascript:changeSort('totalmembers)">Members</a></b></td>
  145:         <td><b><a href="javascript:changeSort('totalfiles')">Files</a></b></td>
  146:         <td><b><a href="javascript:changeSort('boards')">Discussion boards</a></b></td>
  147:         <td><b><a href="javascript:changeSort('diskuse')">Disk use</a></b></td>
  148:        </tr>
  149: END
  150:             my %Sortby = ();
  151:             foreach my $group (sort(keys(%curr_groups))) {
  152:                 %{$grp_info{$group}} = 
  153:                                   &Apache::loncommon::get_group_settings(
  154:                                                          $curr_groups{$group});
  155:                 my $members_result = &group_members($cdom,$cnum,$group,\%grp_info);
  156:                 my $files_result = &group_files($group,\%grp_info); 
  157:                 if ($env{'form.sortby'} eq 'groupname') {
  158:                     push(@{$Sortby{$group}},$group);
  159:                 } elsif ($env{'form.sortby'} eq 'description') {
  160:                     push(@{$Sortby{$grp_info{$group}{'description'}}},
  161:                                                                      $group);
  162:                 } elsif ($env{'form.sortby'} eq 'creator') {
  163:                     push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);
  164:                 } elsif ($env{'form.sortby'} eq 'creation') {
  165:                     push(@{$Sortby{$grp_info{$group}{'creation'}}},$group);
  166:                 } elsif ($env{'form.sortby'} eq 'modified') {
  167:                     push(@{$Sortby{$grp_info{$group}{'modified'}}},$group);
  168:                 } elsif ($env{'form.sortby'} eq 'quota') {
  169:                     push(@{$Sortby{$grp_info{$group}{'quota'}}},$group);
  170:                 } elsif ($env{'form.sortby'} eq 'totalmembers') {
  171:                     push(@{$Sortby{$grp_info{$group}{'totalmembers'}}},
  172:                                                                        $group);
  173:                 } elsif ($env{'form.sortby'} eq 'totalfiles') {
  174:                     push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},
  175:                                                                        $group);
  176:                 } elsif ($env{'form.sortby'} eq 'boards') {
  177:                     push(@{$Sortby{$grp_info{$group}{'boards'}}},$group);
  178:                 } elsif ($env{'form.sortby'} eq 'diskuse') {
  179:                     push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group);
  180:                 } else {
  181:                     push(@{$Sortby{$group}},$group);
  182:                 }
  183:             }
  184:             my $rowNum = 0;
  185:             my $rowColor;
  186:             foreach my $key (sort(keys(%Sortby))) {
  187:                 foreach my $group (@{$Sortby{$key}}) {
  188:                     if ($rowNum %2 == 1) {
  189:                         $rowColor = $rowColor1;
  190:                     } else {
  191:                         $rowColor = $rowColor2;
  192:                     }
  193:                     my $description = 
  194:                    &Apache::lonnet::unescape($grp_info{$group}{'description'});
  195:                     my $creator = $grp_info{$group}{'creator'};
  196:                     my $creation = $grp_info{$group}{'creation'};
  197:                     my $modified = $grp_info{$group}{'modified'}; 
  198:                     my $quota = $grp_info{$group}{'quota'};
  199:                     my $totalmembers = $grp_info{$group}{'totalmembers'};
  200:                     my $totalfiles = $grp_info{$group}{'totalfiles'};
  201:                     my $boards = $grp_info{$group}{'boards'};
  202:                     my $diskuse = $grp_info{$group}{'diskuse'};
  203:                     my $functionality;
  204:                     foreach my $tool (sort keys(%{$functions})) {
  205:                         if (defined($grp_info{$group}{functions}{$tool})) {
  206:                             $functionality .= ' '.$tool;
  207:                         }
  208:                     }
  209:                     if (!$functionality) {
  210:                         $functionality = 'None available';
  211:                     }
  212:                     $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
  213:    <a href="/adm/'.$cdom.'/'.$cnum.'/'.$group.'/grppg?register=1"/>View</a>&nbsp;<a href="/adm/coursegroups?action=modify&group='.$group.'">Modify</a></td><td><small>'.$group.'</small></td><td><small>'.$description.'</small></td><td><small>'.$creator.'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($creation).'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($modified).'</small></td><td><small>'.$functionality.'</small></td><td><small>'.$quota.'</small></td><td><small>'.$totalmembers.'</small></td><td><small>'.$totalfiles.'</small></td><td><small>'.$boards.'</small></td><td><small>'.$diskuse.'</small></td></tr>');
  214:                     $rowNum ++;
  215:                 }
  216:             }
  217:             $r->print('</table>');
  218:             $r->print(&Apache::lonhtmlcommon::end_pick_box());
  219:         } else {
  220:             $r->print('No groups exist');
  221:         }
  222:     } else {
  223:         my @coursegroups = split(/:/,$env{'request.course.groups'});
  224:         if (@coursegroups > 0) {
  225:             my %curr_groups;
  226:             if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
  227:                 foreach my $group (@coursegroups) {
  228:                     my %group_info =  &Apache::loncommon::get_group_settings(
  229:                                                    $curr_groups{$group});
  230:                     my $description = &Apache::lonnet::unescape(
  231:                                                      $group_info{description});
  232:                     my ($uname,$udom) = split(/:/,$group_info{creator});
  233:                     $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
  234:                 }
  235:             }
  236:         } else {
  237:             $r->print('You are not currently a member of any active groups in this course');
  238:         }
  239:     }
  240:     return;
  241: }
  242: 
  243: sub group_administration {
  244:     my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,
  245:                                      $view_permission,$manage_permission) = @_;
  246:     my %sectioncount = ();
  247:     my @tools = ();
  248:     my @types = ();
  249:     my @roles = ();
  250:     my @sections = ();
  251:     my %users = ();
  252:     my %userdata = ();
  253:     my @members = ();
  254:     my %usertools = ();
  255: 
  256:     my $state = $env{'form.state'};
  257:     my ($groupname,$description,$startdate,$enddate);
  258: 
  259:     if ($action eq 'create') {
  260:         if ($state eq '') {
  261:             $state = 'pick_name';
  262:         } else {
  263:             ($startdate,$enddate) = &get_dates_from_form();
  264:             if (defined($env{'form.groupname'})) {
  265:                 $groupname = $env{'form.groupname'};
  266:             }
  267:             if (defined($env{'form.description'})) {
  268:                 $description = $env{'form.description'};
  269:             }
  270:             if (defined($env{'form.tool'})) {
  271:                 @tools=&Apache::loncommon::get_env_multiple('form.tool');
  272:             }
  273:             if (defined($env{'form.member'})) {
  274:                 @members = &Apache::loncommon::get_env_multiple('form.member');
  275:                 foreach my $user (@members) {
  276:                     %{$usertools{$user}} = ();
  277:                 }
  278:             }
  279:         }
  280:     }
  281: 
  282:     my %toolprivs = ();
  283:     %{$toolprivs{'email'}} = (
  284:                                  sgm => 'Send group mail',
  285:                                  sgb => 'Broadcast mail',
  286:                              );
  287:     %{$toolprivs{'discussion'}} =  (
  288:                                      cgb => 'Create boards',
  289:                                      pgd => 'Post',
  290:                                      pag => 'Anon. posts',
  291:                                      rgi => 'Get identities', 
  292:                                      vgb => 'View boards',
  293:                                    );
  294:     %{$toolprivs{'chat'}} =  (
  295:                                 pgc => 'Chat',
  296:                              );
  297:     %{$toolprivs{'files'}} =  (
  298:                                  rgf => 'Retrieve',
  299:                                  ugf => 'Upload',
  300:                                  dgf => 'Delete',
  301:                               );
  302:     %{$toolprivs{'roster'}} = (
  303:                                  vgm => 'View',
  304:                               );
  305:     %{$toolprivs{'homepage'}} = (
  306:                                 vgh => 'View page',
  307:                                 mgh => 'Modify page',
  308:                               );
  309:     my %fixedprivs = ();
  310:     %{$fixedprivs{'email'}} = ('sgm' => 1);
  311:     %{$fixedprivs{'discussion'}} = ('vgb' => 1);
  312:     %{$fixedprivs{'chat'}} = ('pgc' => 1);
  313:     %{$fixedprivs{'files'}} = ('rgf' => 1);
  314:     %{$fixedprivs{'roster'}} = ('vgm' => 1);
  315:     %{$fixedprivs{'homepage'}} = ('vgh' => 1);
  316: 
  317:     my %elements = ();
  318:     %{$elements{'create'}} = ();
  319:     %{$elements{'modify'}} = ();
  320:     %{$elements{'create'}{'pick_name'}} = (
  321:         startdate_month => 'selectbox',
  322:         startdate_hour => 'selectbox',
  323:         enddate_month => 'selectbox',
  324:         enddate_hour => 'selectbox',
  325:         types => 'selectbox',
  326:         roles => 'selectbox',
  327:         startdate_day => 'text',
  328:         startdate_year => 'text',
  329:         startdate_minute => 'text',
  330:         startdate_second => 'text',
  331:         enddate_day => 'text',
  332:         enddate_year => 'text',
  333:         enddate_minute => 'text',
  334:         enddate_second => 'text',
  335:         groupname => 'text',
  336:         description => 'text',
  337:         tool => 'checkbox',
  338:         granularity => 'radio',
  339:         no_end_date => 'checkbox',
  340:     );
  341:     %{$elements{'create'}{'pick_members'}} = (
  342:         member => 'checkbox',
  343:     );
  344:     if (($action eq 'create') && ($state eq 'pick_name')) {
  345:         my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,
  346:                            \%sectioncount);
  347:         if ($numsections > 0) {
  348:             $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
  349:         }
  350:     }
  351:                                                                                       
  352:     if (($action eq 'create') && (($state eq 'pick_members') ||
  353:                                   ($state eq 'pick_privs'))) {
  354:         if (defined($env{'form.types'})) {
  355:             @types=&Apache::loncommon::get_env_multiple('form.types');
  356:         }
  357:         if (defined($env{'form.roles'})) {
  358:             @roles=&Apache::loncommon::get_env_multiple('form.roles');
  359:         }
  360:         if (defined($env{'form.sectionpick'})) {
  361:             @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
  362:             if (grep/^_all$/,@sections) {
  363:                 @sections = sort {$a cmp $b} keys(%sectioncount);
  364:             }
  365:         }
  366:         &build_members_list($cdom,$cnum,\@types,\@roles,
  367:                         \@sections,\%users,\%userdata);
  368:         if ((keys(%users) > 0) && (@tools > 0)) {
  369:             foreach my $tool (@tools) {
  370:                 if ($env{'form.granularity'} eq 'Yes') {
  371:                     $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox';
  372:                 }
  373:             }
  374:             $elements{'create'}{'pick_members'}{'specificity'} = 'radio';
  375:         }
  376:     }
  377: 
  378:     if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') &&
  379:          ($env{'form.specificity'} eq 'No')))) {
  380:         foreach my $tool (@tools) {
  381:             my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);
  382:             foreach my $user (@values) {
  383:                 unless(exists($usertools{$user}{$tool})) {
  384:                     $usertools{$user}{$tool} = 1;
  385:                 }
  386:             }
  387:         }
  388:         if (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) {
  389:             foreach my $member (@members) {
  390:                 foreach my $tool (keys(%{$usertools{$member}})) {
  391:                     foreach my $priv (keys(%{$toolprivs{$tool}})) {
  392:                         unless (exists($fixedprivs{$tool}{$priv})) {
  393:                             $elements{'create'}{'pick_privs'}{'userpriv_'.$priv} =
  394:                                                                    'checkbox';
  395:                         }
  396:                     }
  397:                 }
  398:             }
  399:         }
  400:     }
  401:  
  402:     my $jscript;
  403:     if ($env{'form.action'} eq 'create') {
  404:         $jscript = &Apache::loncommon::check_uncheck_jscript();
  405:     }
  406:     $jscript .= qq|
  407: function nextPage(formname,nextstate) {
  408:     formname.state.value= nextstate;
  409:     formname.submit();
  410: }
  411: function backPage(formname,prevstate) {
  412:     formname.state.value = prevstate;
  413:     formname.submit();
  414: }
  415:                                                                                       
  416: |;
  417:                                                                                       
  418:     $jscript .= &Apache::lonhtmlcommon::set_form_elements(
  419:                            \%{$elements{$action}{$state}});
  420: 
  421: 
  422:     my $loaditems =  &onload_action($action,$state);
  423:     $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'),
  424:                                $jscript,$action,$state,$function,$loaditems));
  425: 
  426:     if ($env{'form.refpage'} eq 'enrl') {
  427:         &Apache::lonhtmlcommon::add_breadcrumb
  428:         ({href=>"/adm/dropadd",
  429:           text=>"Enrollment Manager",
  430:           faq=>9,bug=>'Instructor Interface',});
  431:     } else {
  432:         &Apache::lonhtmlcommon::add_breadcrumb
  433:        ({href=>"/adm/coursegroups",
  434:           text=>"Course Groups",
  435:           faq=>9,bug=>'Instructor Interface',});
  436:     }
  437: 
  438:     my %states = ();
  439:     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
  440:     @{$states{'modify'}} = ();
  441:                                                                                       
  442:     my %trail = ();
  443:     %{$trail{'create'}} = (
  444:                             pick_name => 'Group Settings',
  445:                             pick_members => 'Select Members',
  446:                             pick_privs => 'Choose Privileges',
  447:                             result => 'Creation Complete',
  448:                           );
  449:     %{$trail{'modify'}} = ();
  450:                                                                                       
  451:     if ((($action eq 'create') || ($action eq 'modify')) &&
  452:               ($manage_permission)) {
  453:         for (my $i=0; $i<@{$states{$action}}; $i++) {
  454:             if ($state eq $states{$action}[$i]) {
  455:                 &Apache::lonhtmlcommon::add_breadcrumb(
  456:                    {text=>"$trail{$action}{$state}"});
  457:                 $r->print(&Apache::lonhtmlcommon::breadcrumbs
  458:                      (undef,'Course Groups Manager'));
  459:                 &display_control($r,$cdom,$cnum,$tabcol,$action,$state,
  460:                          \%sectioncount,$groupname,$description,$functions,
  461:                          \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,
  462:                          \%users,\%userdata,$idx,\@members,\%usertools);
  463:                 last;
  464:             } else {
  465:                 if ($state eq 'result' && $i > 0) {
  466:                     &Apache::lonhtmlcommon::add_breadcrumb(
  467:     {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
  468:       text=>"$trail{$action}{$states{$action}[$i]}"});
  469:                 } else { 
  470:                     &Apache::lonhtmlcommon::add_breadcrumb(
  471:      {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
  472:       text=>"$trail{$action}{$states{$action}[$i]}"});
  473:                 }
  474:             }
  475:         }
  476:     } elsif (($action eq 'view') && ($view_permission)) {
  477:                         &Apache::lonhtmlcommon::add_breadcrumb(
  478:                    {text=>"View groups"});
  479:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
  480:                      (undef,'Course Groups Manager'));
  481:         &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
  482:                                         $view_permission,$manage_permission);
  483: 
  484:     }
  485:     $r->print(&footer());
  486:     return;
  487: }
  488: 
  489: sub display_control {
  490:     my ($r,$cdom,$cnum,$tabcol,$action,$state,$sectioncount,$groupname,
  491:         $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
  492:                       $enddate,$users,$userdata,$idx,$members,$usertools) = @_;
  493:     if ($action eq 'create') {
  494:         if ($state eq 'pick_name') {
  495:             &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions,
  496:                                                                 $sectioncount);
  497:         } elsif ($state eq 'pick_members') {
  498:             &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname,
  499:                                   $description,$startdate,$enddate,$tools,
  500:                                              $functions,$users,$userdata,$idx);
  501:         } elsif ($state eq 'pick_privs') {
  502:             &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate,
  503:                            $enddate,$tools,$functions,$toolprivs,$fixedprivs,
  504:                                            $userdata,$members,$usertools,$idx);
  505:         } elsif ($state eq 'result') {
  506:             &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname,
  507:                             $description,$userdata,$startdate,$enddate,$tools,
  508:                                $functions,$toolprivs,$members,$usertools,$idx);
  509:         }
  510:     }
  511: }
  512: 
  513: sub header {
  514:     my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_;
  515:     my $html=&Apache::lonxml::xmlbegin();
  516:     my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems);
  517:     my $output = <<"END";
  518: $html
  519: <head>
  520: <title>$title</title>
  521: <script type="text/javascript">
  522: $jscript
  523: </script>
  524: </head>
  525: $bodytag
  526: <form method="post" name="$state">
  527: 
  528: END
  529:     if ($action eq 'create' || $action eq 'modify') {
  530:         $output .= <<"END";
  531:  <input type="hidden" name="action" value="$action" />
  532:  <input type="hidden" name="state" value="" />
  533:  <input type="hidden" name="origin" value="$state" />
  534: END
  535:     }
  536:     return $output;
  537: }
  538: 
  539: sub onload_action {
  540:     my ($action,$state) = @_;
  541:     my $loaditems;
  542:     if ((defined($env{'form.origin'})) && ($action eq 'create') &&
  543:                 ($state eq 'pick_name' || $state eq 'pick_members' || 
  544:                  $state eq 'pick_privs')) {
  545:         unless ($env{'form.origin'} eq '') {
  546:             $loaditems = 
  547:              'onload="javascript:setFormElements(document.'.$state.')"';
  548:         }
  549:     }
  550:     return $loaditems;
  551: }
  552: 
  553: sub footer {
  554:        return(<<ENDFOOT);
  555:   </form>
  556:  </body>
  557: </html>
  558: ENDFOOT
  559: }
  560: 
  561: sub build_members_list {
  562:     my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_;
  563:     my %access = ();
  564:     foreach my $role (@{$roles}) {
  565:         %{$$users{$role}} = ();
  566:     }
  567:     foreach my $type (@{$types}) {
  568:         $access{$type} = $type;
  569:     }
  570:     &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles,
  571:                                           $sections,$users,$userdata);
  572:     return;
  573: }
  574: 
  575: sub group_files {
  576:     return;
  577: }
  578: 
  579: sub group_members {
  580:     my ($cdom,$cnum,$group,$group_info) = @_;
  581:     my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
  582:     my $now = time;
  583:     my ($tmp)=keys(%memberhash);
  584:     if ($tmp=~/^error:/) {
  585:         $$group_info{'totalmembers'} = 'Unknown - an error occurred';
  586:         return $tmp;
  587:     }
  588:     my $now = time;
  589:     my $totalmembers = 0;
  590:     my $active = 0;
  591:     my $previous = 0;
  592:     my $future = 0;
  593:     foreach my $member (keys %memberhash) {
  594:         $totalmembers ++;
  595:         my ($end,$start) = split(/:/,$memberhash{$member});
  596:         if (($end!=0) && ($end<$now)) {
  597:             $previous ++;
  598:         } elsif (($start!=0) && ($start>$now)) {
  599:             $future ++;
  600:         } else {
  601:             $active ++;
  602:         }
  603:     }
  604:     if ($totalmembers == 0) {
  605:         $$group_info{$group}{'totalmembers'} = 'None';
  606:     } else {
  607:         $$group_info{$group}{'totalmembers'} = $active.' - active<br />'.$previous.' -previous<br />'.$future.' -future';
  608:     }
  609:     return 'ok';
  610: }
  611: 
  612: 
  613: sub first_creation_form {
  614:     my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_;
  615:     my %lt = &Apache::lonlocal::texthash(
  616:         'gmem' => 'Group membership options',
  617:         'picr' => 'Pick the criteria to use to build a list of course users '.
  618:                   'from which you will select members of the new group',   
  619:         'gdat' => 'Group open and close dates',
  620:         'sten' => 'Set a start date/time and end date/time for the group',
  621:         'acty' => 'Access types',
  622:         'coro' => 'Course roles',
  623:         'cose' => 'Course sections',
  624:         'gfun' => 'Group functionality',
  625:     );
  626: 
  627:     my %status_types = (
  628:                    active => &mt('Currently has access'),
  629:                    previous => &mt('Previously had access'),
  630:                    future => &mt('Will have future access'),
  631:                    );
  632: 
  633:     my @roles = ('st','cc','in','ta','ep','cr');
  634: 
  635:     my $starttime = time;
  636:     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
  637:     my ($start_table,$end_table) = &date_setting_table
  638:                                     ($starttime,$endtime,$formname);
  639: 
  640:     my @sections = ();
  641:     my $section_sel = '';
  642:     my $numvisible = 4;
  643: 
  644:     @sections = sort {$a cmp $b} keys(%{$sectioncount});
  645:     if (@sections > 0) {
  646:         unshift(@sections,'_all'); # Put 'all' at the front of the list
  647:         if (@sections < 4) {
  648:             $numvisible = @sections;
  649:         }
  650:         foreach (@sections) {
  651:             if ($_ eq '_all') {
  652:                 $section_sel .= '  <option value="'.$_.'" />all sections'."\n";
  653:             } else {
  654:                 $section_sel .= '  <option value="'.$_.'" />'.$_."\n";
  655:             }
  656:         }
  657:     }
  658: 
  659:     $r->print(<<"END");
  660:  <br />
  661:  <table width="100%" cellpadding="0" cellspacing="0" border="0">
  662:    <tr bgcolor="$tabcol">
  663:      <td>&nbsp;</td>
  664:      <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step1.gif" 
  665:          valign="bottom">&nbsp;&nbsp;</nobr>
  666:      </td>
  667:      <td align="left"><nobr>
  668:        <font face="arial,helvetica,sans-serif"><b>Group name, description
  669:          and available functionality</b></font></nobr> 
  670:      </td>
  671:      <td width="100%">&nbsp;</td>
  672:    </tr>
  673:    <tr>
  674:     <td colspan="4">&nbsp;</td>
  675:    </tr>
  676:    <tr>
  677:     <td>&nbsp;</td>
  678:     <td colspan="3">
  679:      <table border="0" cellpadding="2" cellspacing="2">
  680:       <tr>
  681:        <td><b>Group Name:</b></td>
  682:        <td colspan="5"><input type="text" name="groupname" size="25" />
  683:        </td>
  684:       <tr>
  685:       <tr>
  686:        <td><b>Description:</b></td>
  687:        <td colspan="5"><input type="text" name="description" size="40" />
  688:        </td>
  689:       <tr>
  690:       <tr>
  691:        <td><b>Functionality:</b></td>
  692: END
  693:     my $numitems = keys(%{$functions});
  694:     my $halfnum = int($numitems/2);
  695:     my $remnum = $numitems%2;
  696:     if ($remnum) {
  697:         $halfnum ++;
  698:     }
  699:     my @allfunctions = sort (keys (%{$functions}));
  700:     for (my $i=0; $i<$halfnum; $i++) {
  701:         $r->print('<td><input type="checkbox" name="tool" value="'.
  702:                   $allfunctions[$i].'" />&nbsp;'.
  703:                    $$functions{$allfunctions[$i]}.'</td>
  704:                    <td>&nbsp;</td><td>&nbsp;</td>');
  705:     }
  706:     $r->print('<td><input type="button" value="check all" '.
  707:               'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.
  708:               '</td></tr><tr><td>&nbsp;</td>');
  709:     for (my $j=$halfnum; $j<@allfunctions; $j++) {
  710:         $r->print('<td><input type="checkbox" name="tool" value="'.
  711:                   $allfunctions[$j].'" />&nbsp;'.
  712:                   $$functions{$allfunctions[$j]}.'</td>
  713:                   <td>&nbsp;</td><td>&nbsp;</td>');
  714:     }
  715:     if ($remnum) {
  716:         $r->print('<td>&nbsp;</td>');
  717:     }
  718:     $r->print(<<"END"); 
  719:        <td>
  720:         <input type="button" value="uncheck all" 
  721:           onclick="javascript:uncheckAll(document.$formname.tool)" />
  722:        </td>
  723:       </tr>
  724:       <tr>
  725:        <td><b>Granularity:</b></td>
  726:        <td colspan="9">Do you want to assign different functionality to different group members?&nbsp;<input type="radio" name="granularity" value="Yes" />Yes&nbsp;<input type="radio" name="granularity" value="No" checked="checked" />No</td>
  727:       </tr> 
  728:      </table>
  729:     </td>
  730:    </tr>
  731:    <tr>
  732:     <td colspan="4">&nbsp;</td>
  733:    </tr>
  734:    <tr bgcolor="$tabcol">
  735:     <td>&nbsp;</td>
  736:     <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step2.gif" 
  737:         valign="bottom">&nbsp;&nbsp;</nobr>
  738:     </td>
  739:     <td align="left"><nobr>
  740:       <font face="arial,helvetica,sans-serif"><b>Start and end dates for group
  741:                                                   access</b></font></nobr>
  742:     </td>
  743:     <td width="100%">&nbsp;</td>
  744:    </tr>
  745:    <tr>
  746:     <td colspan="4">&nbsp;</td>
  747:    </tr>
  748:    <tr>
  749:     <td>&nbsp;</td>
  750:     <td colspan="3">$start_table</td>
  751:    <tr>
  752:    <tr>
  753:     <td colspan="4">&nbsp;</td>
  754:    </tr>
  755:    <tr>
  756:     <td>&nbsp;</td>
  757:     <td colspan="3">$end_table</td>
  758:    <tr>
  759:    <tr>
  760:     <td colspan="4">&nbsp;</td>
  761:    </tr>
  762:    <tr bgcolor="$tabcol">
  763:     <td>&nbsp;</td>
  764:     <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step3.gif" 
  765:         valign="bottom">&nbsp;&nbsp;</nobr>
  766:     </td>
  767:     <td align="left"><nobr>
  768:      <font face="arial,helvetica,sans-serif"><b>Pick parameters to generate 
  769:          membership list</b></nobr>
  770:      </font>
  771:     </td>
  772:     <td width="100%">&nbsp;</td>
  773:    </tr>
  774:    <tr>
  775:     <td colspan="4">&nbsp;</td>
  776:    </tr>
  777:    <tr>
  778:     <td>&nbsp;</td>
  779:     <td colspan="3">
  780:      <b>$lt{'gmem'}</b><br/> $lt{'picr'}
  781:      <br /><br />
  782:      <table border="0">
  783:       <tr>
  784:        <td><b>$lt{'acty'}</b></td>
  785:        <td>&nbsp;</td>
  786:        <td><b>$lt{'coro'}</b></td>
  787: END
  788:     if (@sections >0) {
  789:          $r->print('
  790:        <td>&nbsp;</td>
  791:        <td><b>'.$lt{'cose'}.'</b></td>
  792:        <td>&nbsp;</td>');
  793:     }
  794:     $r->print('</tr><tr>');
  795:     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
  796:     $r->print('<td>&nbsp;</td>');
  797:     $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
  798:     if (@sections > 0) {
  799:         $r->print('
  800:        <td>&nbsp;</td>
  801:        <td colspan="3" align="center" valign="top">
  802:         <select name="sectionpick" multiple="true" size="'.$numvisible.'">
  803:           '.$section_sel.'
  804:         </select>
  805:        </td>');
  806:     }
  807:     $r->print('
  808:       </tr>
  809:      </table>
  810:     </td>
  811:    </tr>
  812:    <tr>
  813:     <td colspan="4">&nbsp;</td>
  814:    </tr>
  815:    <tr>
  816:     <td>&nbsp;</td>
  817:     <td colspan="3" align="left">
  818:      <input type="button" value="Go to next step"  
  819:      onclick="javascript:nextPage(document.'.$formname.','."'pick_members'".')>
  820:     </td>
  821:    </tr>
  822: </table>
  823: ');
  824:     return;
  825: }
  826: 
  827: sub second_creation_form {
  828:     my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$startdate,
  829:                         $enddate,$tools,$functions,$users,$userdata,$idx) = @_;
  830:     my @regexps = ('user_','userpriv_');
  831:     $r->print(&Apache::lonhtmlcommon::echo_form_input(
  832:                 ['origin','action','state','member','specificity'],\@regexps));
  833:     my %sectioncount = ();
  834:     my $numsec = &Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);
  835:     my %curr_groups;
  836:     my $numgroups =  &Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
  837:     my $earlyout;
  838:     my $exitmsg = '<b>Invalid group name</b><br /><br />The group name entered "'.
  839:                   $groupname.'" ';
  840:     my $dupmsg = 'Group names and section names used in a course must be unique.'; 
  841:     if ($groupname =~ /\W/) {
  842:         $earlyout = $exitmsg.'is not a valid name.<br />Group names may only contain letters, numbers or underscores';
  843:     }
  844:     if ($numsec) {
  845:         if (exists($sectioncount{$groupname})) {
  846:             $earlyout = $exitmsg.'can not be used as it is the name of a '.
  847:                                  'section in this course.<br />'.$dupmsg;
  848:         }
  849:     }
  850:     if ($numgroups) {
  851:         if (exists($curr_groups{$groupname})) {
  852:             $earlyout = $exitmsg.'can not be used as it is the name of an 
  853:                                  existing group in this course.<br />'.$dupmsg;
  854:         }
  855:     }
  856:     if ($earlyout) {
  857:         $r->print('<table border="0" cellpadding="2" cellspacing="2">
  858:  <tr>
  859:   <td>&nbsp;</td>
  860:   <td>'.$earlyout.'</td>
  861:  </tr>
  862:  <tr>
  863:   <td colspan="2">&nbsp;</td>
  864:  </tr>
  865:  <tr>
  866:   <td>&nbsp;</td>
  867:   <td align="left">
  868:    <input type="button" name="previous" value = "Go to previous page"
  869:     onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
  870:   </td>
  871:  </tr>
  872: </table>
  873:         ');
  874:         return;
  875:     }
  876:     my $rowColor1 = "#dddddd";
  877:     my $rowColor2 = "#eeeeee";
  878:     my $showstart = &Apache::lonlocal::locallocaltime($startdate);
  879:     my $showend = &Apache::lonlocal::locallocaltime($enddate);
  880:     $r->print('<table border="0" cellpadding="0" cellspacing="20">
  881: <tr>
  882:  <td><font face="arial,helvetica,sans-serif"><b>New group selections</b></font>
  883: <br />When you create the new group, the following settings will apply:
  884:  </td>
  885: </tr>
  886: <tr>
  887:  <td>');
  888:     $r->print(&Apache::lonhtmlcommon::start_pick_box());
  889:     $r->print('
  890: <table cellspacing="1" cellpadding="4">
  891:  <tr bgcolor="'.$tabcol.'" align="center">
  892:   <td><b>Group Name</b></td>
  893:   <td><b>Description</b></td>
  894:   <td><b>Group Functionality</b></td>
  895:   <td><b>Default access dates</b></td>
  896:  </tr>
  897:  <tr bgcolor="'.$rowColor2.'">
  898:   <td valign="top"><small>'.$groupname.'</small></td>
  899:   <td valign="top"><small>'.$description.'</small></td>
  900:   <td>
  901: ');
  902:     my @available = ();
  903:     my @unavailable = ();
  904:     foreach my $item (sort(keys(%{$functions}))) {
  905:         if (grep/^$item$/,@{$tools}) {
  906:             push(@available,$item);
  907:         } else {
  908:             push(@unavailable,$item);
  909:         }
  910:     }
  911:     if (@available > 0) {
  912:         $r->print('<small><b>Available:</b></small>
  913:                     <table cellpadding="" cellspacing="1"><tr>');
  914:         my $rowcell = int(@available/2) + @available%2;
  915:         for (my $i=0; $i<@available; $i++) {
  916:             if (@available > 3) {
  917:                 if ($i==$rowcell) {
  918:                     $r->print('</tr><tr>');
  919:                 }
  920:             }
  921:             $r->print('<td><small>'.$$functions{$available[$i]}.
  922:                                           '</small></td><td>&nbsp;</td>');
  923:         }
  924:         if ((@available > 3) && (@available%2)) {
  925:             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
  926:         }
  927:         $r->print('</tr></table><br />');
  928:     }
  929:     if (@unavailable > 0) {
  930:         $r->print('<small><b>Unavailable:</b></small>
  931:                     <table cellpadding="0" cellspacing="1"  border="0"><tr>');
  932:         my $rowcell = int(@unavailable/2) + @unavailable%2;
  933:         for (my $j=0; $j<@unavailable; $j++) {
  934:             if (@unavailable > 3) {
  935:                 if ($j==$rowcell) {
  936:                     $r->print('</tr><tr>');
  937:                 }
  938:             }
  939:             $r->print('<td><small>'.$$functions{$unavailable[$j]}.
  940:                                               '</small></td><td>&nbsp;</td>');
  941:         }
  942:         if ((@unavailable > 3) && (@unavailable%2)) {
  943:             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
  944:         }
  945:         $r->print('</tr></table>');
  946:     }
  947:     $r->print(<<"END");
  948:   </td>
  949:   <td valign="top"><small><b>Start date:</b> $showstart<br />
  950:       <b>End date:</b> $showend</small>
  951:   </td>
  952:  </tr>
  953: </table>
  954: END
  955:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
  956:     my %members = ();
  957:     foreach my $role (keys(%{$users})) {
  958:         foreach my $user (keys(%{$$users{$role}})) {
  959:             unless (defined($members{$user})) {
  960:                 @{$members{$user}} = @{$$userdata{$user}};
  961:             }
  962:         }
  963:     }
  964:     $r->print('</td></tr></table><br />');
  965:     if (keys(%members) > 0) {
  966:         if ($env{'form.granularity'} eq 'Yes') {
  967:             $r->print('
  968: <script type="text/javascript">
  969: function checkAllTools(formname) {
  970: ');
  971:             foreach my $tool (@available) {
  972:                 $r->print('  checkAll(formname.user_'.$tool.');'."\n");
  973:             }
  974:             $r->print('
  975: }
  976: function uncheckAllTools(formname) {
  977: ');
  978:             foreach my $tool (@available) {
  979:                 $r->print('  uncheckAll(formname.user_'.$tool.');'."\n");
  980:             }
  981:             $r->print('
  982: }
  983: </script>
  984:             ');
  985:        }
  986:        $r->print(<<"END");
  987: <table width="100%" cellpadding="0" cellspacing="0" border="0">
  988:  <tr bgcolor="$tabcol">
  989:   <td>&nbsp;</td>
  990:   <td valign="top" align="left">
  991:    <nobr><img src="/res/adm/pages/bl_step4.gif" valign="middle">&nbsp;</nobr>
  992:   </td>
  993:   <td alin="left">
  994:    <nobr>
  995:    <font face="arial,helvetica,sans-serif">
  996:     <b>Select group members</b>
  997:    </font></nobr>
  998:   </td>
  999:   <td width="100%">&nbsp;</td>
 1000:  </tr>
 1001:  <tr>
 1002:   <td colspan="4">&nbsp;</td>
 1003:  </tr>
 1004:  <tr>
 1005:   <td>&nbsp;</td>
 1006:   <td colspan="2">
 1007:     <table>
 1008:      <tr>
 1009:       <td>
 1010:    <nobr>
 1011:     <fieldset><legend><b>Add members</b></legend>
 1012:      <input type="button" value="check all" 
 1013:        onclick="javascript:checkAll(document.$formname.member)" />
 1014:       &nbsp;&nbsp;
 1015:      <input type="button" value="uncheck all" 
 1016:       onclick="javascript:uncheckAll(document.$formname.member)" />
 1017:     </fieldset></nobr></td>
 1018: END
 1019:         if (@available > 0 && $env{'form.granularity'} eq 'Yes') {
 1020:             $r->print('<td><nobr><fieldset><legend><b> 
 1021:                                       Set functionality</b></legend>
 1022:      <input type="button" value="check all" 
 1023:        onclick="javascript:checkAllTools(document.'.$formname.')" />
 1024:        &nbsp;&nbsp;
 1025:      <input type="button" value="uncheck all" 
 1026:         onclick="javascript:uncheckAllTools(document.'.$formname.')" />
 1027:     </fieldset></nobr></td>');
 1028:         }
 1029:         $r->print('</tr></table>
 1030:   </td>
 1031:   <td width="100%">&nbsp;</td>
 1032:  </tr>
 1033:  <tr>
 1034:   <td colspan="4">&nbsp;</td>
 1035:  </tr>
 1036:  <tr>
 1037:   <td>&nbsp;</td>
 1038:   <td colspan="3">
 1039:         ');
 1040:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
 1041:         $r->print(<<"END");
 1042:    <table border="0" cellpadding="4" cellspacing="1">
 1043:     <tr bgcolor="$tabcol" align="center">
 1044:      <td><b>Add?</b></td>
 1045:      <td><b><a href="javascript:changeSort('fullname')">Name</a></b></td>
 1046:      <td><b><a href="javascript:changeSort('username')">Username</a></b>
 1047:      </td>
 1048:      <td><b><a href="javascript:changeSort('domain')">Domain</a></b></td>
 1049:      <td><b><a href="javascript:changeSort('id')">ID</a></b></td>
 1050: END
 1051:         if (@available > 0) {
 1052:             $r->print('<td><b>Functionality</b></td>');
 1053:         }
 1054:         $r->print('</tr>');
 1055:         my %Sortby = ();
 1056:         foreach my $user (sort(keys(%members))) {
 1057:             if ($env{'form.sortby'} eq 'fullname') {
 1058:                 push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
 1059:             } elsif ($env{'form.sortby'} eq 'username') {
 1060:                 push(@{$Sortby{$members{$user}[$$idx{uname}]}},$user);
 1061:             } elsif ($env{'form.sortby'} eq 'domain') {
 1062:                 push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);
 1063:             } elsif ($env{'form.sortby'} eq 'id') {
 1064:                 push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);
 1065:             } else {
 1066:                 push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
 1067:             }
 1068:         }
 1069:         my $rowNum = 0;
 1070:         my $rowColor;
 1071:         foreach my $key (sort(keys(%Sortby))) {
 1072:             foreach my $user (@{$Sortby{$key}}) {
 1073:                 if ($rowNum %2 == 1) {
 1074:                     $rowColor = $rowColor1;
 1075:                 } else {
 1076:                     $rowColor = $rowColor2;
 1077:                 }
 1078:                 my $id = $members{$user}[$$idx{id}];
 1079:                 my $fullname = $members{$user}[$$idx{fullname}];
 1080:                 my $udom = $members{$user}[$$idx{udom}];
 1081:                 my $uname = $members{$user}[$$idx{uname}];
 1082:                 $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
 1083:    <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.
 1084:     $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
 1085:     $udom.'</small></td><td><small>'.$id.'</small></td>');
 1086:                 if (@available > 0) {
 1087:                     $r->print('<td align="center"><small>'); 
 1088:                     foreach my $tool (@available) {
 1089:                         if ($env{'form.granularity'} eq 'Yes') {
 1090:                             $r->print('<input type="checkbox" name="user_'.
 1091:                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
 1092:                         } else {
 1093:                             $r->print('<input type="hidden" name="user_'.
 1094:                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
 1095:                         }
 1096:                     }
 1097:                     $r->print('</small></td>');
 1098:                 }
 1099:                 $r->print('</tr>'."\n");
 1100:                 $rowNum ++;
 1101:             }
 1102:         }
 1103:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
 1104:         $r->print('
 1105:   </td>
 1106:  </tr>
 1107:  <tr>
 1108:   <td colspan="4">&nbsp;</td>
 1109:  </tr>');
 1110:         if (@available > 0) {
 1111:             $r->print('
 1112:  <tr bgcolor="'.$tabcol.'">
 1113:   <td>&nbsp;</td>
 1114:   <td valign="middle" align="left">
 1115:    <nobr><img src="/res/adm/pages/bl_step5.gif" valign="middle">&nbsp;</nobr>
 1116:   </td>
 1117:   <td align="left"><nobr>
 1118:    <font face="arial,helvetica,sans-serif">
 1119:     <b>User privileges</b>
 1120:    </font></nobr>
 1121:   </td>
 1122:   <td width="100%">&nbsp;</td>
 1123:  </tr>
 1124:  <tr>
 1125:   <td>&nbsp;</td>
 1126:   <td colspan="3">
 1127:    <br />
 1128:    For each type of functionality you have chosen to include, there is a 
 1129: set of standard privileges which apply to all of those for whom the functionality is enabled.<br />There are also additional privileges which can be set for some, or all, members. Please choose one of the following:<br />
 1130: <br /><input type="radio" name="specificity" value="No" checked="checked" />&nbsp;All group members will receive the same privileges.<br/><input type="radio" name="specificity" value="Yes" />&nbsp;Some group members will receive different privileges from others.
 1131:   </td>
 1132:  </tr>
 1133:  <tr>
 1134:   <td colspan="4">&nbsp;</td>
 1135:  </tr>
 1136: ');
 1137:         }
 1138:         $r->print('    
 1139:  <tr>
 1140:   <td>&nbsp;</td>
 1141:   <td colspan="3">
 1142:    <input type="button" name="previous" value = "Go to previous page" 
 1143:     onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
 1144:    &nbsp;&nbsp;&nbsp;
 1145:    <input type="button" name="next" value="Go to next page" 
 1146:  onclick="javascript:nextPage(document.'.$formname.','."'pick_privs'".')" />
 1147:   </td>
 1148:  </tr>
 1149:         ');
 1150:     } else {
 1151:         $r->print('No members to add');
 1152:     }
 1153:     $r->print('
 1154:    </table>
 1155:   </td>
 1156:  </tr>
 1157: </table>');
 1158:     return;
 1159: }
 1160: 
 1161: sub third_creation_form {
 1162:     my ($r,$cdom,$cnum,$tabcol,$formname,$startdate,$enddate,$tools,$functions,
 1163:                $toolprivs,$fixedprivs,$userdata,$members,$usertools,$idx) = @_;
 1164:     my @regexps = ('userpriv_','allpriv_');
 1165:     $r->print(&Apache::lonhtmlcommon::echo_form_input(
 1166:                              ['origin','action','state'],\@regexps));
 1167:     my %possibles = ();
 1168:     my %showboxes = ();
 1169:     my $totalboxes = 0;
 1170:     my $rowColor1 = "#dddddd";
 1171:     my $rowColor2 = "#eeeeee";
 1172:     my $numtools = 1 + @{$tools};
 1173:     foreach my $tool (@{$tools}) {
 1174:         @{$showboxes{$tool}} = ();
 1175:         foreach my $user (@{$members}) {
 1176:             if (exists($$usertools{$user}{$tool})) {
 1177:                 foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
 1178:                     unless (exists($$fixedprivs{$tool}{$priv})) {
 1179:                         push(@{$possibles{$user}},$priv);
 1180:                         unless(grep(/^$priv$/,@{$showboxes{$tool}})) {
 1181:                             push(@{$showboxes{$tool}},$priv);
 1182:                             $totalboxes ++;
 1183:                         }
 1184:                     }
 1185:                 }
 1186:             }
 1187:         }
 1188:     }
 1189:     if ($totalboxes > 0) {
 1190:         $r->print('
 1191: <script type="text/javascript">
 1192: function checkAllTools(formname) {
 1193: ');
 1194:         foreach my $tool (sort(keys(%showboxes))) {
 1195:             foreach my $priv (@{$showboxes{$tool}}) {
 1196:                 $r->print('  checkAll(formname.userpriv_'.$priv.');'."\n");
 1197:             }
 1198:         }
 1199:         $r->print('
 1200: }
 1201: function uncheckAllTools(formname) {
 1202: ');
 1203:         foreach my $tool (sort(keys(%showboxes))) {
 1204:             foreach my $priv (@{$showboxes{$tool}}) {
 1205:                 $r->print('  uncheckAll(formname.userpriv_'.$priv.');'."\n");
 1206:             }
 1207:         }
 1208:         $r->print('
 1209: }
 1210: </script>
 1211:        ');
 1212:    }
 1213:    $r->print(<<"END");
 1214: <br />
 1215: <table width="100%" cellpadding="0" cellspacing="0" border="0">
 1216:  <tr bgcolor="$tabcol">
 1217:   <td>&nbsp;</td>
 1218:   <td valign="middle" align="left">
 1219:    <nobr><img src="/res/adm/pages/bl_step6.gif" valign="middle">&nbsp;</nobr>
 1220:   </td>
 1221:   <th align="left"><nobr>
 1222:     Group member privileges
 1223:    </nobr>
 1224:   </th>
 1225:   <td width="100%">&nbsp;</td>
 1226:  </tr>
 1227:  <tr>
 1228:   <td colspan="4">&nbsp;</td>
 1229:  </tr>
 1230:  <tr>
 1231:   <td>&nbsp;</td>
 1232:   <td colspan="3">
 1233: END
 1234:     if ($env{'form.specificity'} eq 'Yes') {
 1235:         $r->print('
 1236:    <table border="0" cellspacing="2" cellpadding="2" border="0">
 1237:     <tr>
 1238:      <td valign="top">
 1239: ');
 1240:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
 1241:         $r->print(<<"END");
 1242:    <tr bgcolor="$tabcol">
 1243:     <th><b>Fullname</th>
 1244:     <th><b>Username</th>
 1245:     <th>Domain</th>
 1246:     <th colspan="$numtools">Additional Privileges</th>
 1247:   </tr>
 1248: END
 1249:     }
 1250:     if ($env{'form.specificity'} eq 'Yes') {
 1251:         &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,
 1252:                              $usertools,$toolprivs,$fixedprivs,$userdata,$idx);
 1253:     }
 1254:     if ($env{'form.specificity'} eq 'Yes') {
 1255:         $r->print('</td>');
 1256:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
 1257:         $r->print('<td>&nbsp;</td>
 1258:                <td>&nbsp;</td><td valign="top">');
 1259:         my @toolboxes = sort(keys(%showboxes));
 1260:         foreach my $tool (@{$tools}) {
 1261:             if (@{$showboxes{$tool}} > 0) { 
 1262:                 $r->print('<table class="thinborder"><tr bgcolor="'.$tabcol.
 1263:                       '"><th>'.$tool.'</th></tr>');
 1264:                 foreach my $priv (@{$showboxes{$tool}}) {
 1265:                     $r->print(qq|
 1266:        <tr><td>
 1267:        <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
 1268:        <input type="button" value="check all"
 1269:          onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />
 1270:        &nbsp; 
 1271:        <input type="button" value="uncheck all"
 1272:         onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
 1273:       </nobr></fieldset></td></tr>|);
 1274:                 }
 1275:                 $r->print('</table><br /><br />');
 1276:             }
 1277:         }
 1278:         $r->print('</td></tr></table>');
 1279:     } else {
 1280:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
 1281:         $r->print('<tr><td bgcolor="'.$tabcol.'" valign="top"><table cellspacing="0" cellpadding="1"><tr><td valign="top"><b>Function</b></td></tr><tr><td valign="top"><b>Fixed privileges</b>'.
 1282:                   '</td></tr><tr><td valign="top"><b>Optional privileges</b></td></tr></table></td>');
 1283:         foreach my $tool (@{$tools}) {
 1284:             $r->print('<td align="center" valign="top"><table cellspacing="0" cellpadding="1"><tr bgcolor="#cccccc">'.
 1285:                        '<td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
 1286:             my $privcount = 0;
 1287:             my $fixed = '';
 1288:             my $dynamic = '';
 1289:             foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
 1290:                 if (exists($$fixedprivs{$tool}{$priv})) {
 1291:                     $fixed .= '<input type="hidden" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
 1292:                 } else {
 1293:                     $privcount ++;
 1294:                     if ($privcount == 3) {
 1295:                         $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'">';
 1296:                     }
 1297:                     $dynamic .= '<td><input type="checkbox" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'</td>';
 1298:                 }
 1299:             }
 1300:             if ($dynamic eq '') {
 1301:                 $dynamic = '<td>None</td>'; 
 1302:             }
 1303:             if ($privcount < 3) {
 1304:                 $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'"><td colspan="2">&nbsp;</td>';
 1305:             } elsif ($privcount%2) {
 1306:                 $dynamic = '<td>&nbsp;</td>';
 1307:             }
 1308:             $r->print('<tr bgcolor="'.$rowColor2.'"><td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td></tr><tr bgcolor="'.$rowColor1.'">'.$dynamic.'</tr></table></td>');
 1309:         }
 1310:         $r->print('</tr>');
 1311:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
 1312:     }
 1313:     $r->print('</td></tr>
 1314:  <tr>
 1315:   <td colspan="4">&nbsp;</td>
 1316:  </tr>
 1317:  <tr>
 1318:   <td>&nbsp;</td>
 1319:   <td colspan="3">
 1320:    <input type="button" name="previous" value = "Go to previous page"
 1321:     onclick="javascript:backPage(document.'.$formname.','."'pick_members'".')"/>
 1322:    &nbsp;&nbsp;
 1323:    <input type="button" name="next" value="Create group"
 1324:  onclick="javascript:nextPage(document.'.$formname.','."'result'".')" />
 1325:   </td>
 1326:  </tr>
 1327:     ');
 1328:     $r->print('
 1329: </table>');
 1330: 
 1331:     return;
 1332: }
 1333: 
 1334: sub completed_creation {
 1335:     my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$userdata,
 1336: $startdate,$enddate,$tools,$functions,$toolprivs,$members,$usertools,$idx) = @_;
 1337: 
 1338:     $r->print(&Apache::lonhtmlcommon::echo_form_input(
 1339:                                         ['origin','action','state']));
 1340:     my @added= ();
 1341:     my @failed = ();
 1342:     my $now = time;
 1343:     my %group_privs = ();
 1344:     my %tooltype = ();
 1345:     foreach my $tool (@{$tools}) {
 1346:         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
 1347:             $tooltype{$priv} = $tool;
 1348:             if ($env{'form.specificity'} eq 'Yes') {
 1349:                 my @users =
 1350:                   &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv);
 1351:                 foreach my $user (@users) {
 1352:                     $group_privs{$user} .= $priv.':';
 1353:                 }
 1354:             } else {
 1355:                 if (defined($env{'form.allpriv_'.$priv})) {
 1356:                     foreach my $user (@{$members}) {
 1357:                         if ($$usertools{$user}{$tool}) {
 1358:                             $group_privs{$user} .= $priv.':';
 1359:                         }
 1360:                     }
 1361:                 }
 1362:             }
 1363:         }
 1364:     }
 1365:     foreach my $user (keys(%group_privs)) {
 1366:         $group_privs{$user} =~ s/:$//;
 1367:     }
 1368:     my $esc_description = &Apache::lonnet::escape($description);
 1369:     my @attributes = ('description','functions','startdate','enddate','creation','modified','creator');
 1370:         
 1371:     my %groupinfo = (
 1372:                       description => $esc_description,
 1373:                       startdate => $startdate,
 1374:                       enddate => $enddate,
 1375:                       creation => $now,
 1376:                       modified => $now,
 1377:                       creator => $env{'user.name'}.':'.$env{'user.domain'}, 
 1378:                     );
 1379:     foreach my $func (keys(%{$functions})) {
 1380:         my $status;
 1381:         if (grep(/^$func$/,@{$tools})) {
 1382:             $status = 'on';
 1383:         } else {
 1384:             $status = 'off';
 1385:         } 
 1386:         $groupinfo{'functions'} .=  qq|<name id="$func">$status</name>|;
 1387:     }
 1388: 
 1389:     my %curr_groups = ();
 1390:     my %groupsettings = ();
 1391:     my %usersettings = ();
 1392:     if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum,$groupname)) {
 1393:         if (exists($curr_groups{$groupname})) {
 1394:             $r->print('Non-unique name - please choose another');
 1395:             return; 
 1396:         }
 1397:     }
 1398:     my $groupentry;
 1399:     foreach my $item (@attributes) {
 1400:         $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}</$item>|;
 1401:     }
 1402:     my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum,
 1403:                                                           \%groupsettings);
 1404:     if ($result eq 'ok') {
 1405:         my $put_result = &create_homepage($cdom,$cnum,$groupname,\%groupinfo,$tools);
 1406:         foreach my $user (sort(@{$members})) {
 1407:             $usersettings{$groupname.':'.$user} = $enddate.':'.$startdate.':'.$group_privs{$user};
 1408:             if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
 1409:                   $user,$enddate,$startdate,$group_privs{$user}) eq 'ok') {
 1410:                 push(@added,$user);
 1411:             } else {
 1412:                 push(@failed,$user);
 1413:             }
 1414:         }
 1415:         my $roster_result = &Apache::lonnet::modify_coursegroup_membership(
 1416:              $cdom,$cnum,\%usersettings);
 1417:         $r->print('
 1418: Group '.$groupname.' was created.<br />');
 1419:         if (@added > 0) {
 1420:             $r->print('Users were added with following privileges:<br />');
 1421:             foreach my $user (@added) {
 1422:                 my @privs = split(/:/,$group_privs{$user});
 1423:                 my $privlist= '';
 1424:                 my $curr_tool = '';
 1425:                 foreach my $priv (@privs) {
 1426:                     unless ($curr_tool eq $tooltype{$priv}) {
 1427:                         $curr_tool = $tooltype{$priv};
 1428:                         $privlist .= '<b>'.$curr_tool.'</b>: ';
 1429:                     }
 1430:                     $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
 1431:                 }
 1432:                 $privlist =~ s/, $//;
 1433:                 $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.': '.$privlist.'<br />');
 1434:             }
 1435:         }
 1436:         if (@failed > 0) {
 1437:             $r->print('Addition of the following users was unsuccessful:<br />');
 1438:             foreach my $user (@failed) {
 1439:                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
 1440:             }
 1441:         }
 1442:         if ($roster_result eq 'ok') {
 1443:             $r->print('<br />Group membership list updated.');
 1444:         } else {
 1445:             $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');
 1446:         } 
 1447:     } else {
 1448:         &Apache::lonnet::logthis('Failed to create group '.$groupname. 
 1449:                                  'in course: '.$cnum.' in domain: '.$cdom);
 1450: 
 1451:         $r->print('An error occurred when creating the new group. '.
 1452:                                                       'Please try again.');
 1453:     }
 1454:     return;
 1455: }
 1456: 
 1457: sub member_privs_entries {
 1458:     my ($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,$usertools,$toolprivs,
 1459:                                               $fixedprivs,$userdata,$idx) = @_;
 1460:     my $rowColor;
 1461:     my $rowNum = 0;
 1462:     foreach my $member (@{$members}) {
 1463:         my ($uname,$udom) = split(/:/,$member);
 1464:         if ($rowNum %2 == 1) {
 1465:             $rowColor = $rowColor1;
 1466:         } else {
 1467:             $rowColor = $rowColor2;
 1468:         }
 1469:         $r->print('<tr bgcolor="'.$rowColor.'">
 1470:                 <td>'.$$userdata{$member}[$$idx{fullname}].'</td>
 1471:                 <td>'.$uname.'</td>
 1472:                 <td>'.$udom.'</td>
 1473:                 <td valign="top"><table><tr><td><b>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');
 1474:         foreach my $tool (@{$tools}) {
 1475:             if (exists($$usertools{$member}{$tool})) {
 1476:                 $r->print('<td valign="top"><table><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
 1477:                 my $privcount = 0;
 1478:                 my $fixed = '';
 1479:                 my $dynamic = '';
 1480:                 foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
 1481:                     if (exists($$fixedprivs{$tool}{$priv})) {
 1482:                         $fixed .= '<input type="hidden" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
 1483:                     } else {
 1484:                         $privcount ++;
 1485:                         if ($privcount == 3) {
 1486:                             $dynamic .= '</tr><tr>';
 1487:                         }
 1488:                         $dynamic .= '<td><input type="checkbox" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'</td>';
 1489:                     }
 1490:                 }
 1491:                 $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
 1492:             } else {
 1493:                 $r->print('<td>&nbsp;</td>');
 1494:             }
 1495:         }
 1496:         $rowNum ++;
 1497:     }
 1498: }
 1499: 
 1500: 
 1501: sub get_dates_from_form {
 1502:     my $startdate;
 1503:     my $enddate;
 1504:     $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
 1505:     $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
 1506:     if ( exists ($env{'form.no_end_date'}) ) {
 1507:         $enddate = 0;
 1508:     }
 1509:     return ($startdate,$enddate);
 1510: }                                                                                     
 1511: sub date_setting_table {
 1512:     my ($starttime,$endtime,$formname) = @_;
 1513:     my $startform = &Apache::lonhtmlcommon::date_setter($formname,
 1514:                                                       'startdate',$starttime);
 1515:     my $endform = &Apache::lonhtmlcommon::date_setter($formname,
 1516:                                                       'enddate',$endtime);
 1517:     my $perpetual = '<nobr><input type="checkbox" name="no_end_date" />
 1518:                                                   no ending date</nobr>';
 1519:     my $start_table = '';
 1520:     $start_table .= "<table>\n";
 1521:     $start_table .= '<tr><td align="right">Default starting date for 
 1522:                                            member access</td>'.
 1523:         '<td>'.$startform.'</td>'.
 1524:         '<td>&nbsp;</td>'."</tr>\n";
 1525:     $start_table .= "</table>";
 1526:     my $end_table = '';
 1527:     $end_table .= "<table>\n";
 1528:     $end_table .= '<tr><td align="right">Default ending date for 
 1529:                                          member access</td>'.
 1530:         '<td>'.$endform.'</td>'.
 1531:         '<td>'.$perpetual.'</td>'."</tr>\n";
 1532:     $end_table .= "</table>\n";
 1533:     return ($start_table, $end_table);
 1534: }
 1535: 
 1536: sub create_homepage {
 1537:     my ($cdom,$cnum,$name,$groupinfo,$tools) = @_;
 1538:     my $functionality = join(',',@{$tools});
 1539:     my $content = &Apache::lonnet::unescape($$groupinfo{description});
 1540:     $content=~s/\s+$//s;
 1541:     $content=~s/^\s+//s;
 1542:     $content=~s/\<br\s*\/*\>$//s;
 1543:     $content=&Apache::lonfeedback::clear_out_html($content,1);
 1544: 
 1545:     my %pageinfo = (
 1546:                      'aaa_title' => 'Group: '.$name,
 1547:                      'abb_links' => $functionality,
 1548:                      'bbb_content' => $content,
 1549:                      'ccc_webreferences' => '',
 1550:                      'uploaded.lastmodified' => time,
 1551:                    );
 1552:    my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);
 1553:    return $putresult;
 1554: }
 1555: 
 1556: 
 1557: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>