File:  [LON-CAPA] / loncom / interface / lonblockingmenu.pm
Revision 1.1: download - view: text, annotated - select for diffs
Wed Dec 28 21:49:54 2011 UTC (12 years, 6 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Move routines for configuration of blocking communication during an exam
  from lonmsgdisplay.pm to separate handler -- lonblockingmenu.pm
- Access to corresponding URL: /adm/setblock from both Messages menu (as before)
  and also from Content and Problem Settings menu.

    1: # The LearningOnline Network with CAPA
    2: # Routines for configuring blocking to collaborative functions, and specific
    3: # resources during an exam 
    4: #
    5: # $Id: lonblockingmenu.pm,v 1.1 2011/12/28 21:49:54 raeburn Exp $
    6: #
    7: # Copyright Michigan State University Board of Trustees
    8: #
    9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   10: #
   11: # LON-CAPA is free software; you can redistribute it and/or modify
   12: # it under the terms of the GNU General Public License as published by
   13: # the Free Software Foundation; either version 2 of the License, or
   14: # (at your option) any later version.
   15: #
   16: # LON-CAPA is distributed in the hope that it will be useful,
   17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19: # GNU General Public License for more details.
   20: #
   21: # You should have received a copy of the GNU General Public License
   22: # along with LON-CAPA; if not, write to the Free Software
   23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24: #
   25: # /home/httpd/html/adm/gpl.txt
   26: #
   27: # http://www.lon-capa.org/
   28: #
   29: ###############################################################
   30: ##############################################################
   31: 
   32: =pod
   33: 
   34: =head1 NAME
   35: 
   36: lonblockingmenu - Handler to set/modify exam blocks in a course.
   37: 
   38: =head1 SYNOPSIS
   39: 
   40: lonblockingmenu provides an interface for setting exam blocks in a course.  
   41: 
   42: =head1 DESCRIPTION
   43: 
   44: This module is used to configure blocking of access to collaborative tools
   45: and/or resources during an exam.
   46: 
   47: =head1 INTERNAL SUBROUTINES
   48: 
   49: =over
   50: 
   51: =item &blockstore()
   52: 
   53: =item &get_dates_from_form()
   54: 
   55: =item &get_blockdates()
   56: 
   57: =item &get_block_choices()
   58: 
   59: =item &display_blocker_status()
   60: 
   61: =item &display_addblocker_table()
   62: 
   63: =item &blocktype_text()
   64: 
   65: =back  
   66: 
   67: =cut;
   68: 
   69: package Apache::lonblockingmenu;
   70: 
   71: use strict;
   72: use Apache::lonnet;
   73: use Apache::Constants qw(:common :http);
   74: use Apache::loncommon();
   75: use Apache::lonhtmlcommon();
   76: use HTML::Entities();
   77: use Apache::lonlocal;
   78: use lib '/home/httpd/lib/perl/';
   79: use LONCAPA qw(:DEFAULT :match);
   80: 
   81: sub handler {
   82:     my $r=shift;
   83: 
   84: # ----------------------------------------------------------- Set document type
   85: 
   86:     &Apache::loncommon::content_type($r,'text/html');
   87:     $r->send_http_header;
   88: 
   89:     return OK if $r->header_only;
   90: 
   91:     #  Needs to be in a course
   92:     if (! ($env{'request.course.fn'})) {
   93:         # Not in a course
   94:         $env{'user.error.msg'}=
   95:      "/adm/setblock:dcm:0:0:Cannot set blocking of communications in a course";
   96:         return HTTP_NOT_ACCEPTABLE;
   97:     }
   98: 
   99: # ----------------------------------------------------------- Permissions check
  100: 
  101:     unless ((!&Apache::lonnet::allowed('dcm',$env{'request.course.id'})) ||
  102:             (!&Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
  103:                                       '/'.$env{'request.course.sec'}))) {
  104:         return HTTP_NOT_ACCEPTABLE;
  105:     }
  106: 
  107: # -----------------------------Get action and calling context from query string
  108: 
  109:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['action','caller']);
  110: 
  111: # ----------------------------------------------------------------- Breadcrumbs
  112: 
  113:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  114:     if ($env{'form.caller'} eq 'email') {  
  115:         &Apache::lonhtmlcommon::add_breadcrumb
  116:             ({href=>'/adm/communicate',
  117:               text=>'Communication/Messages',
  118:               faq=>12,bug=>'Communication Tools',});
  119:     } else {
  120:         &Apache::lonhtmlcommon::add_breadcrumb
  121:             ({href=>'/adm/parmset',
  122:               text=>'Content and Problem Settings'});
  123:     }
  124:     &Apache::lonhtmlcommon::add_breadcrumb
  125:         ({href=>'/adm/setblock',
  126:           text=>'Blocking communication/resource access'});
  127: 
  128:     $r->print(&Apache::loncommon::start_page('Blocking communication/resource access').
  129:               &Apache::lonhtmlcommon::breadcrumbs('Blocking communication/resource access'));
  130: 
  131: # ----------------------------------------------------------- Permissions check
  132: 
  133:     my $usertype;
  134:     my $crstype = &Apache::loncommon::course_type();
  135:     if ($crstype eq 'Community') {
  136:         $usertype = 'members';
  137:     } else {
  138:         $usertype = 'students';
  139:     }
  140:     my $lctype = lc($crstype);
  141:     my %lt=&Apache::lonlocal::texthash(
  142:             'cbds' => 'Communication blocking during scheduled exams',
  143:             'desc' => "You can use communication blocking to prevent $usertype enrolled in this $lctype from displaying LON-CAPA messages sent by other $usertype during an online exam. As blocking of communication could potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA course or community, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.",
  144:              'mecb' => 'Modify existing communication blocking periods',
  145:              'ncbc' => 'No communication blocks currently saved',
  146:              'stor' => 'Save',
  147:     );
  148: 
  149:     my %ltext = &Apache::lonlocal::texthash(
  150:             'dura' => 'Duration',
  151:             'setb' => 'Set by',
  152:             'even' => 'Event',
  153:             'blck' => 'Blocked?',
  154:             'actn' => 'Action',
  155:             'star' => 'Start',
  156:             'endd' => 'End'
  157:     );
  158: 
  159:     $r->print('<h3>'.$lt{'cbds'}.'</h3>');
  160: 
  161:     if ($env{'form.action'} eq 'store') {
  162:         &blockstore($r);
  163:     }
  164: 
  165:     $r->print($lt{'desc'}.'<br /><br />
  166:                <form name="blockform" method="post" action="/adm/setblock?action=store">
  167:              ');
  168: 
  169:     $r->print('<h4>'.$lt{'mecb'}.'</h4>');
  170:     my %records = ();
  171:     my $blockcount = 0;
  172:     my $parmcount = 0;
  173:     &get_blockdates(\%records,\$blockcount);
  174:     if ($blockcount > 0) {
  175:         $parmcount = &display_blocker_status($r,\%records,\%ltext);
  176:     } else {
  177:         $r->print($lt{'ncbc'}.'<br /><br />');
  178:     }
  179:     &display_addblocker_table($r,$parmcount,\%ltext);
  180:     my $end_page=&Apache::loncommon::end_page();
  181:     $r->print(<<"END");
  182: <br />
  183: <input type="hidden" name="blocktotal" value="$blockcount" />
  184: <input type ="submit" value="$lt{'stor'}" />
  185: </form>
  186: $end_page
  187: END
  188: 
  189:     $r->print(&Apache::loncommon::end_page());
  190:     return OK;
  191: }
  192: 
  193: sub blockstore {
  194:     my $r = shift;
  195:     my %lt=&Apache::lonlocal::texthash(
  196:             'tfcm' => 'The following changes were made',
  197:             'ncwm' => 'No changes were made.'
  198:     );
  199:     my %adds = ();
  200:     my %removals = ();
  201:     my %cancels = ();
  202:     my $modtotal = 0;
  203:     my $canceltotal = 0;
  204:     my $addtotal = 0;
  205:     my %blocking = ();
  206:     $r->print('<h3>'.$lt{'head'}.'</h3>');
  207:     foreach my $envkey (keys(%env)) {
  208:         if ($envkey =~ m/^form\.modify_(\d+)$/) {
  209:             $adds{$1} = $1;
  210:             $removals{$1} = $1;
  211:             $modtotal ++;
  212:         } elsif ($envkey =~ m/^form\.cancel_(\d+)$/) {
  213:             $cancels{$1} = $1;
  214:             unless ( defined($removals{$1}) ) {
  215:                 $removals{$1} = $1;
  216:                 $canceltotal ++;
  217:             }
  218:         } elsif ($envkey =~ m/^form\.add_(\d+)$/) {
  219:             $adds{$1} = $1;
  220:             $addtotal ++;
  221:         }
  222:     }
  223: 
  224:     foreach my $key (keys(%removals)) {
  225:         my $hashkey = $env{'form.key_'.$key};
  226:         &Apache::lonnet::del('comm_block',["$hashkey"],
  227:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
  228:                          $env{'course.'.$env{'request.course.id'}.'.num'}
  229:                          );
  230:     }
  231:     foreach my $key (keys(%adds)) {
  232:         unless ( defined($cancels{$key}) ) {
  233:             my ($newstart,$newend) = &get_dates_from_form($key);
  234:             my $newkey = $newstart.'____'.$newend;
  235:             my $blocktypes = &get_block_choices($key);
  236:             $blocking{$newkey} = {
  237:                           setter => $env{'user.name'}.':'.$env{'user.domain'},
  238:                           event  => &escape($env{'form.title_'.$key}),
  239:                           blocks => $blocktypes,
  240:                         };
  241:         }
  242:     }
  243:     if ($addtotal + $modtotal > 0) {
  244:         &Apache::lonnet::put('comm_block',\%blocking,
  245:                      $env{'course.'.$env{'request.course.id'}.'.domain'},
  246:                      $env{'course.'.$env{'request.course.id'}.'.num'}
  247:                      );
  248:     }
  249:     my $chgestotal = $canceltotal + $modtotal + $addtotal;
  250:     if ($chgestotal > 0) {
  251:         $r->print($lt{'tfcm'}.'<ul>');
  252:         if ($canceltotal > 0) {
  253:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] removed.',$canceltotal).'</li>');
  254:         }
  255:         if ($modtotal > 0) {
  256:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] modified.',$modtotal).'</li>');
  257:         }
  258:         if ($addtotal > 0) {
  259:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] added.',$addtotal).'</li>');
  260:         }
  261:         $r->print('</ul>');
  262:     } else {
  263:         $r->print($lt{'ncwm'});
  264:     }
  265:     $r->print('<br />');
  266:     return;
  267: }
  268: 
  269: sub get_dates_from_form {
  270:     my $item = shift;
  271:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item);
  272:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item);
  273:     return ($startdate,$enddate);
  274: }
  275: 
  276: sub get_blockdates {
  277:     my ($records,$blockcount) = @_;
  278:     $$blockcount = 0;
  279:     %{$records} = &Apache::lonnet::dump('comm_block',
  280:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
  281:                          $env{'course.'.$env{'request.course.id'}.'.num'}
  282:                          );
  283:     $$blockcount = keys(%{$records});
  284: 
  285:     if ((keys(%{$records}))[0] =~ /^error: 2 /) {
  286:         $$blockcount = 0;
  287:     }
  288: }
  289: 
  290: sub get_block_choices {
  291:     my $item = shift;
  292:     my $blocklist;
  293:     my ($typeorder,$types) = &blocktype_text();
  294:     foreach my $type (@{$typeorder}) {
  295:         if ($env{'form.'.$type.'_'.$item}) {
  296:             $blocklist->{$type} = 'on';
  297:         } else {
  298:             $blocklist->{$type} = 'off';
  299:         }
  300:     }
  301:     return $blocklist;
  302: }
  303: 
  304: sub display_blocker_status {
  305:     my ($r,$records,$ltext) = @_;
  306:     my $parmcount = 0;
  307:  
  308:     my %lt = &Apache::lonlocal::texthash(
  309:         'modi' => 'Modify',
  310:         'canc' => 'Cancel',
  311:     );
  312:     my ($typeorder,$types) = &blocktype_text();
  313:     $r->print(&Apache::loncommon::start_data_table());
  314:     $r->print(<<"END");
  315:   <tr>
  316:     <th>$ltext->{'dura'}</th>
  317:     <th>$ltext->{'setb'}</th>
  318:     <th>$ltext->{'even'}</th>
  319:     <th>$ltext->{'blck'}</th>
  320:     <th>$ltext->{'actn'}</th>
  321:   </tr>
  322: END
  323:     foreach my $record (sort(keys(%{$records}))) {
  324:         my $onchange = 'onFocus="javascript:window.document.forms['.
  325:                        "'blockform'].elements['modify_".$parmcount."'].".
  326:                        'checked=true;"';
  327:         my ($start,$end) = split(/____/,$record);
  328:         my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
  329:         my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
  330: 
  331:         my ($setuname,$setudom,$title,$blocks) =
  332:             &Apache::loncommon::parse_block_record($$records{$record});
  333:         $title = &HTML::Entities::encode($title,'"<>&');
  334:         my $settername =
  335:            &Apache::loncommon::aboutmewrapper(
  336:                            &Apache::loncommon::plainname($setuname,$setudom),
  337:                            $setuname,$setudom);
  338:         $r->print(&Apache::loncommon::start_data_table_row());
  339:         $r->print(<<"END");
  340:         <td>$ltext->{'star'}:&nbsp;$startform<br />$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
  341:         <td>$settername</td>
  342:         <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$record" /></td>
  343:         <td>
  344: END
  345:         foreach my $block (@{$typeorder}) {
  346:             my $blockstatus = '';
  347:             if ($blocks->{$block} eq 'on') {
  348:                 $blockstatus = 'checked="checked"';
  349:             }
  350:             $r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" '.$blockstatus.' value="1" />'.$types->{$block}.'</label></span><br />');
  351:         }
  352:         $r->print(<<"END");
  353:         </td> 
  354:         <td><span class="LC_nobreak"><label>
  355:         <input type="checkbox" name="modify_$parmcount" />$lt{'modi'}
  356:         </label></span><br /><span class="LC_nobreak">
  357:         <label>
  358:         <input type="checkbox" name="cancel_$parmcount" />$lt{'canc'}
  359:         </label></span>
  360: END
  361:         $r->print(&Apache::loncommon::end_data_table_row());
  362:         $parmcount++;
  363:     }
  364:     $r->print(<<"END");
  365: </table>
  366: <br />
  367: <br />
  368: END
  369:     return $parmcount;
  370: }
  371: 
  372: sub display_addblocker_table {
  373:     my ($r,$parmcount,$ltext) = @_;
  374:     my $start = time;
  375:     my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration.
  376:     my $onchange = 'onFocus="javascript:window.document.forms['.
  377:                    "'blockform'].elements['add_".$parmcount."'].".
  378:                    'checked=true;"';
  379:     my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
  380:     my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
  381:     my %lt = &Apache::lonlocal::texthash(
  382:         'addb' => 'Add block',
  383:         'exam' => 'e.g., Exam 1',
  384:         'addn' => 'Add new communication blocking periods'
  385:     );
  386:     my ($typeorder,$types) = &blocktype_text();
  387:     $r->print(<<"END");
  388: <h4>$lt{'addn'}</h4>
  389: END
  390:     $r->print(&Apache::loncommon::start_data_table());
  391:     $r->print(<<"END");
  392:    <tr>
  393:      <th>$ltext->{'dura'}</th>
  394:      <th>$ltext->{'even'} $lt{'exam'}</th>
  395:      <th>$ltext->{'blck'}</th>
  396:      <th>$ltext->{'actn'}</th>
  397:    </tr>
  398: END
  399:     $r->print(&Apache::loncommon::start_data_table_row());
  400:     $r->print(<<"END");
  401:      <td>$ltext->{'star'}:&nbsp;$startform<br />$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
  402:      <td><input type="text" name="title_$parmcount" size="15" value="" /></td>
  403:      <td>
  404: END
  405:     foreach my $block (@{$typeorder}) {
  406:         $r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" value="1" />'.$types->{$block}.'</label></span><br />');
  407:      }
  408:      $r->print(<<"END");
  409:      </td>
  410:      <td><span class="LC_nobreak"><label>
  411:      <input type="checkbox" name="add_$parmcount" value="1" />$lt{'addb'}
  412:      </label></span></td>
  413: END
  414:     $r->print(&Apache::loncommon::end_data_table_row());
  415:     $r->print(&Apache::loncommon::end_data_table());
  416:     return;
  417: }
  418: 
  419: sub blocktype_text {
  420:     my %types = &Apache::lonlocal::texthash(
  421:         'com' => 'Messaging',
  422:         'chat' => 'Chat Room',
  423:         'boards' => 'Discussion',
  424:         'port' => 'Portfolio',
  425:         'groups' => 'Groups',
  426:         'blogs' => 'Blogs',
  427:     );
  428:     my $typeorder = ['com','chat','boards','port','groups','blogs'];
  429:     return ($typeorder,\%types);
  430: }
  431: 
  432: 1;
  433: 
  434: __END__

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