File:  [LON-CAPA] / loncom / interface / lonblockingmenu.pm
Revision 1.3: download - view: text, annotated - select for diffs
Wed Dec 28 22:41:02 2011 UTC (12 years, 6 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD, BZ4492-merge, BZ4492-feature_horizontal_radioresponse
- Permissions checking
  - logic was backwards
  - custom handler for 406 error
  - include role switcher check for dcm priv

    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.3 2011/12/28 22:41:02 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:         $env{'user.error.msg'}=
  105:      "/adm/setblock:dcm:0:0:Cannot set blocking of communications in a course";
  106:         return HTTP_NOT_ACCEPTABLE;
  107:     }
  108: 
  109: # -----------------------------Get action and calling context from query string
  110: 
  111:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['action','caller']);
  112: 
  113: # ----------------------------------------------------------------- Breadcrumbs
  114: 
  115:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  116:     if ($env{'form.caller'} eq 'email') {  
  117:         &Apache::lonhtmlcommon::add_breadcrumb
  118:             ({href=>'/adm/communicate',
  119:               text=>'Communication/Messages',
  120:               faq=>12,bug=>'Communication Tools',});
  121:     } else {
  122:         &Apache::lonhtmlcommon::add_breadcrumb
  123:             ({href=>'/adm/parmset',
  124:               text=>'Content and Problem Settings'});
  125:     }
  126:     &Apache::lonhtmlcommon::add_breadcrumb
  127:         ({href=>'/adm/setblock',
  128:           text=>'Blocking communication/resource access'});
  129: 
  130:     $r->print(&Apache::loncommon::start_page('Blocking communication/resource access').
  131:               &Apache::lonhtmlcommon::breadcrumbs('Blocking communication/resource access'));
  132: 
  133: # ----------------------------------------------------------- Permissions check
  134: 
  135:     my $usertype;
  136:     my $crstype = &Apache::loncommon::course_type();
  137:     if ($crstype eq 'Community') {
  138:         $usertype = 'members';
  139:     } else {
  140:         $usertype = 'students';
  141:     }
  142:     my $lctype = lc($crstype);
  143:     my %lt=&Apache::lonlocal::texthash(
  144:             'cbds' => 'Communication blocking during scheduled exams',
  145:             '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.",
  146:              'mecb' => 'Modify existing communication blocking periods',
  147:              'ncbc' => 'No communication blocks currently saved',
  148:              'stor' => 'Save',
  149:     );
  150: 
  151:     my %ltext = &Apache::lonlocal::texthash(
  152:             'dura' => 'Duration',
  153:             'setb' => 'Set by',
  154:             'even' => 'Event',
  155:             'blck' => 'Blocked?',
  156:             'actn' => 'Action',
  157:             'star' => 'Start',
  158:             'endd' => 'End'
  159:     );
  160: 
  161:     $r->print('<h3>'.$lt{'cbds'}.'</h3>');
  162: 
  163:     if ($env{'form.action'} eq 'store') {
  164:         &blockstore($r);
  165:     }
  166: 
  167:     $r->print($lt{'desc'}.'<br /><br />
  168:                <form name="blockform" method="post" action="/adm/setblock?action=store">
  169:              ');
  170: 
  171:     $r->print('<h4>'.$lt{'mecb'}.'</h4>');
  172:     my %records = ();
  173:     my $blockcount = 0;
  174:     my $parmcount = 0;
  175:     &get_blockdates(\%records,\$blockcount);
  176:     if ($blockcount > 0) {
  177:         $parmcount = &display_blocker_status($r,\%records,\%ltext);
  178:     } else {
  179:         $r->print($lt{'ncbc'}.'<br /><br />');
  180:     }
  181:     &display_addblocker_table($r,$parmcount,\%ltext);
  182:     my $end_page=&Apache::loncommon::end_page();
  183:     $r->print(<<"END");
  184: <br />
  185: <input type="hidden" name="blocktotal" value="$blockcount" />
  186: <input type ="submit" value="$lt{'stor'}" />
  187: </form>
  188: $end_page
  189: END
  190: 
  191:     $r->print(&Apache::loncommon::end_page());
  192:     return OK;
  193: }
  194: 
  195: sub blockstore {
  196:     my $r = shift;
  197:     my %lt=&Apache::lonlocal::texthash(
  198:             'tfcm' => 'The following changes were made',
  199:             'ncwm' => 'No changes were made.'
  200:     );
  201:     my %adds = ();
  202:     my %removals = ();
  203:     my %cancels = ();
  204:     my $modtotal = 0;
  205:     my $canceltotal = 0;
  206:     my $addtotal = 0;
  207:     my %blocking = ();
  208:     $r->print('<h3>'.$lt{'head'}.'</h3>');
  209:     foreach my $envkey (keys(%env)) {
  210:         if ($envkey =~ m/^form\.modify_(\d+)$/) {
  211:             $adds{$1} = $1;
  212:             $removals{$1} = $1;
  213:             $modtotal ++;
  214:         } elsif ($envkey =~ m/^form\.cancel_(\d+)$/) {
  215:             $cancels{$1} = $1;
  216:             unless ( defined($removals{$1}) ) {
  217:                 $removals{$1} = $1;
  218:                 $canceltotal ++;
  219:             }
  220:         } elsif ($envkey =~ m/^form\.add_(\d+)$/) {
  221:             $adds{$1} = $1;
  222:             $addtotal ++;
  223:         }
  224:     }
  225: 
  226:     foreach my $key (keys(%removals)) {
  227:         my $hashkey = $env{'form.key_'.$key};
  228:         &Apache::lonnet::del('comm_block',["$hashkey"],
  229:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
  230:                          $env{'course.'.$env{'request.course.id'}.'.num'}
  231:                          );
  232:     }
  233:     foreach my $key (keys(%adds)) {
  234:         unless ( defined($cancels{$key}) ) {
  235:             my ($newstart,$newend) = &get_dates_from_form($key);
  236:             my $newkey = $newstart.'____'.$newend;
  237:             my $blocktypes = &get_block_choices($key);
  238:             $blocking{$newkey} = {
  239:                           setter => $env{'user.name'}.':'.$env{'user.domain'},
  240:                           event  => &escape($env{'form.title_'.$key}),
  241:                           blocks => $blocktypes,
  242:                         };
  243:         }
  244:     }
  245:     if ($addtotal + $modtotal > 0) {
  246:         &Apache::lonnet::put('comm_block',\%blocking,
  247:                      $env{'course.'.$env{'request.course.id'}.'.domain'},
  248:                      $env{'course.'.$env{'request.course.id'}.'.num'}
  249:                      );
  250:     }
  251:     my $chgestotal = $canceltotal + $modtotal + $addtotal;
  252:     if ($chgestotal > 0) {
  253:         $r->print($lt{'tfcm'}.'<ul>');
  254:         if ($canceltotal > 0) {
  255:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] removed.',$canceltotal).'</li>');
  256:         }
  257:         if ($modtotal > 0) {
  258:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] modified.',$modtotal).'</li>');
  259:         }
  260:         if ($addtotal > 0) {
  261:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] added.',$addtotal).'</li>');
  262:         }
  263:         $r->print('</ul>');
  264:     } else {
  265:         $r->print($lt{'ncwm'});
  266:     }
  267:     $r->print('<br />');
  268:     return;
  269: }
  270: 
  271: sub get_dates_from_form {
  272:     my $item = shift;
  273:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item);
  274:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item);
  275:     return ($startdate,$enddate);
  276: }
  277: 
  278: sub get_blockdates {
  279:     my ($records,$blockcount) = @_;
  280:     $$blockcount = 0;
  281:     %{$records} = &Apache::lonnet::dump('comm_block',
  282:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
  283:                          $env{'course.'.$env{'request.course.id'}.'.num'}
  284:                          );
  285:     $$blockcount = keys(%{$records});
  286: 
  287:     if ((keys(%{$records}))[0] =~ /^error: 2 /) {
  288:         $$blockcount = 0;
  289:     }
  290: }
  291: 
  292: sub get_block_choices {
  293:     my $item = shift;
  294:     my $blocklist;
  295:     my ($typeorder,$types) = &blocktype_text();
  296:     foreach my $type (@{$typeorder}) {
  297:         if ($env{'form.'.$type.'_'.$item}) {
  298:             $blocklist->{$type} = 'on';
  299:         } else {
  300:             $blocklist->{$type} = 'off';
  301:         }
  302:     }
  303:     return $blocklist;
  304: }
  305: 
  306: sub display_blocker_status {
  307:     my ($r,$records,$ltext) = @_;
  308:     my $parmcount = 0;
  309:  
  310:     my %lt = &Apache::lonlocal::texthash(
  311:         'modi' => 'Modify',
  312:         'canc' => 'Cancel',
  313:     );
  314:     my ($typeorder,$types) = &blocktype_text();
  315:     $r->print(&Apache::loncommon::start_data_table());
  316:     $r->print(<<"END");
  317:   <tr>
  318:     <th>$ltext->{'dura'}</th>
  319:     <th>$ltext->{'setb'}</th>
  320:     <th>$ltext->{'even'}</th>
  321:     <th>$ltext->{'blck'}</th>
  322:     <th>$ltext->{'actn'}</th>
  323:   </tr>
  324: END
  325:     foreach my $record (sort(keys(%{$records}))) {
  326:         my $onchange = 'onFocus="javascript:window.document.forms['.
  327:                        "'blockform'].elements['modify_".$parmcount."'].".
  328:                        'checked=true;"';
  329:         my ($start,$end) = split(/____/,$record);
  330:         my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
  331:         my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
  332: 
  333:         my ($setuname,$setudom,$title,$blocks) =
  334:             &Apache::loncommon::parse_block_record($$records{$record});
  335:         $title = &HTML::Entities::encode($title,'"<>&');
  336:         my $settername =
  337:            &Apache::loncommon::aboutmewrapper(
  338:                            &Apache::loncommon::plainname($setuname,$setudom),
  339:                            $setuname,$setudom);
  340:         $r->print(&Apache::loncommon::start_data_table_row());
  341:         $r->print(<<"END");
  342:         <td>$ltext->{'star'}:&nbsp;$startform<br />$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
  343:         <td>$settername</td>
  344:         <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$record" /></td>
  345:         <td>
  346: END
  347:         foreach my $block (@{$typeorder}) {
  348:             my $blockstatus = '';
  349:             if ($blocks->{$block} eq 'on') {
  350:                 $blockstatus = 'checked="checked"';
  351:             }
  352:             $r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" '.$blockstatus.' value="1" />'.$types->{$block}.'</label></span><br />');
  353:         }
  354:         $r->print(<<"END");
  355:         </td> 
  356:         <td><span class="LC_nobreak"><label>
  357:         <input type="checkbox" name="modify_$parmcount" />$lt{'modi'}
  358:         </label></span><br /><span class="LC_nobreak">
  359:         <label>
  360:         <input type="checkbox" name="cancel_$parmcount" />$lt{'canc'}
  361:         </label></span>
  362: END
  363:         $r->print(&Apache::loncommon::end_data_table_row());
  364:         $parmcount++;
  365:     }
  366:     $r->print(<<"END");
  367: </table>
  368: <br />
  369: <br />
  370: END
  371:     return $parmcount;
  372: }
  373: 
  374: sub display_addblocker_table {
  375:     my ($r,$parmcount,$ltext) = @_;
  376:     my $start = time;
  377:     my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration.
  378:     my $onchange = 'onFocus="javascript:window.document.forms['.
  379:                    "'blockform'].elements['add_".$parmcount."'].".
  380:                    'checked=true;"';
  381:     my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
  382:     my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
  383:     my %lt = &Apache::lonlocal::texthash(
  384:         'addb' => 'Add block',
  385:         'exam' => 'e.g., Exam 1',
  386:         'addn' => 'Add new communication blocking periods'
  387:     );
  388:     my ($typeorder,$types) = &blocktype_text();
  389:     $r->print(<<"END");
  390: <h4>$lt{'addn'}</h4>
  391: END
  392:     $r->print(&Apache::loncommon::start_data_table());
  393:     $r->print(<<"END");
  394:    <tr>
  395:      <th>$ltext->{'dura'}</th>
  396:      <th>$ltext->{'even'} $lt{'exam'}</th>
  397:      <th>$ltext->{'blck'}</th>
  398:      <th>$ltext->{'actn'}</th>
  399:    </tr>
  400: END
  401:     $r->print(&Apache::loncommon::start_data_table_row());
  402:     $r->print(<<"END");
  403:      <td>$ltext->{'star'}:&nbsp;$startform<br />$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
  404:      <td><input type="text" name="title_$parmcount" size="15" value="" /></td>
  405:      <td>
  406: END
  407:     foreach my $block (@{$typeorder}) {
  408:         $r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" value="1" />'.$types->{$block}.'</label></span><br />');
  409:      }
  410:      $r->print(<<"END");
  411:      </td>
  412:      <td><span class="LC_nobreak"><label>
  413:      <input type="checkbox" name="add_$parmcount" value="1" />$lt{'addb'}
  414:      </label></span></td>
  415: END
  416:     $r->print(&Apache::loncommon::end_data_table_row());
  417:     $r->print(&Apache::loncommon::end_data_table());
  418:     return;
  419: }
  420: 
  421: sub blocktype_text {
  422:     my %types = &Apache::lonlocal::texthash(
  423:         'com' => 'Messaging',
  424:         'chat' => 'Chat Room',
  425:         'boards' => 'Discussion',
  426:         'port' => 'Portfolio',
  427:         'groups' => 'Groups',
  428:         'blogs' => 'Blogs',
  429:     );
  430:     my $typeorder = ['com','chat','boards','port','groups','blogs'];
  431:     return ($typeorder,\%types);
  432: }
  433: 
  434: 1;
  435: 
  436: __END__

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