Annotation of loncom/interface/lonblockingmenu.pm, revision 1.1

1.1     ! raeburn     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 14:28:47 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>