# The LearningOnline Network with CAPA # Routines for configuring blocking to collaborative functions, and specific # resources during an exam # # $Id: lonblockingmenu.pm,v 1.2 2011/12/28 22:09:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # ############################################################### ############################################################## =pod =head1 NAME lonblockingmenu - Handler to set/modify exam blocks in a course. =head1 SYNOPSIS lonblockingmenu provides an interface for setting exam blocks in a course. =head1 DESCRIPTION This module is used to configure blocking of access to collaborative tools and/or resources during an exam. =head1 INTERNAL SUBROUTINES =over =item &blockstore() =item &get_dates_from_form() =item &get_blockdates() =item &get_block_choices() =item &display_blocker_status() =item &display_addblocker_table() =item &blocktype_text() =back =cut package Apache::lonblockingmenu; use strict; use Apache::lonnet; use Apache::Constants qw(:common :http); use Apache::loncommon(); use Apache::lonhtmlcommon(); use HTML::Entities(); use Apache::lonlocal; use lib '/home/httpd/lib/perl/'; use LONCAPA qw(:DEFAULT :match); sub handler { my $r=shift; # ----------------------------------------------------------- Set document type &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; # Needs to be in a course if (! ($env{'request.course.fn'})) { # Not in a course $env{'user.error.msg'}= "/adm/setblock:dcm:0:0:Cannot set blocking of communications in a course"; return HTTP_NOT_ACCEPTABLE; } # ----------------------------------------------------------- Permissions check unless ((!&Apache::lonnet::allowed('dcm',$env{'request.course.id'})) || (!&Apache::lonnet::allowed('dcm',$env{'request.course.id'}. '/'.$env{'request.course.sec'}))) { return HTTP_NOT_ACCEPTABLE; } # -----------------------------Get action and calling context from query string &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['action','caller']); # ----------------------------------------------------------------- Breadcrumbs &Apache::lonhtmlcommon::clear_breadcrumbs(); if ($env{'form.caller'} eq 'email') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/communicate', text=>'Communication/Messages', faq=>12,bug=>'Communication Tools',}); } else { &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/parmset', text=>'Content and Problem Settings'}); } &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/setblock', text=>'Blocking communication/resource access'}); $r->print(&Apache::loncommon::start_page('Blocking communication/resource access'). &Apache::lonhtmlcommon::breadcrumbs('Blocking communication/resource access')); # ----------------------------------------------------------- Permissions check my $usertype; my $crstype = &Apache::loncommon::course_type(); if ($crstype eq 'Community') { $usertype = 'members'; } else { $usertype = 'students'; } my $lctype = lc($crstype); my %lt=&Apache::lonlocal::texthash( 'cbds' => 'Communication blocking during scheduled exams', '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.", 'mecb' => 'Modify existing communication blocking periods', 'ncbc' => 'No communication blocks currently saved', 'stor' => 'Save', ); my %ltext = &Apache::lonlocal::texthash( 'dura' => 'Duration', 'setb' => 'Set by', 'even' => 'Event', 'blck' => 'Blocked?', 'actn' => 'Action', 'star' => 'Start', 'endd' => 'End' ); $r->print('

'.$lt{'cbds'}.'

'); if ($env{'form.action'} eq 'store') { &blockstore($r); } $r->print($lt{'desc'}.'

'); $r->print('

'.$lt{'mecb'}.'

'); my %records = (); my $blockcount = 0; my $parmcount = 0; &get_blockdates(\%records,\$blockcount); if ($blockcount > 0) { $parmcount = &display_blocker_status($r,\%records,\%ltext); } else { $r->print($lt{'ncbc'}.'

'); } &display_addblocker_table($r,$parmcount,\%ltext); my $end_page=&Apache::loncommon::end_page(); $r->print(<<"END");
$end_page END $r->print(&Apache::loncommon::end_page()); return OK; } sub blockstore { my $r = shift; my %lt=&Apache::lonlocal::texthash( 'tfcm' => 'The following changes were made', 'ncwm' => 'No changes were made.' ); my %adds = (); my %removals = (); my %cancels = (); my $modtotal = 0; my $canceltotal = 0; my $addtotal = 0; my %blocking = (); $r->print('

'.$lt{'head'}.'

'); foreach my $envkey (keys(%env)) { if ($envkey =~ m/^form\.modify_(\d+)$/) { $adds{$1} = $1; $removals{$1} = $1; $modtotal ++; } elsif ($envkey =~ m/^form\.cancel_(\d+)$/) { $cancels{$1} = $1; unless ( defined($removals{$1}) ) { $removals{$1} = $1; $canceltotal ++; } } elsif ($envkey =~ m/^form\.add_(\d+)$/) { $adds{$1} = $1; $addtotal ++; } } foreach my $key (keys(%removals)) { my $hashkey = $env{'form.key_'.$key}; &Apache::lonnet::del('comm_block',["$hashkey"], $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'} ); } foreach my $key (keys(%adds)) { unless ( defined($cancels{$key}) ) { my ($newstart,$newend) = &get_dates_from_form($key); my $newkey = $newstart.'____'.$newend; my $blocktypes = &get_block_choices($key); $blocking{$newkey} = { setter => $env{'user.name'}.':'.$env{'user.domain'}, event => &escape($env{'form.title_'.$key}), blocks => $blocktypes, }; } } if ($addtotal + $modtotal > 0) { &Apache::lonnet::put('comm_block',\%blocking, $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'} ); } my $chgestotal = $canceltotal + $modtotal + $addtotal; if ($chgestotal > 0) { $r->print($lt{'tfcm'}.''); } else { $r->print($lt{'ncwm'}); } $r->print('
'); return; } sub get_dates_from_form { my $item = shift; my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item); my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item); return ($startdate,$enddate); } sub get_blockdates { my ($records,$blockcount) = @_; $$blockcount = 0; %{$records} = &Apache::lonnet::dump('comm_block', $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'} ); $$blockcount = keys(%{$records}); if ((keys(%{$records}))[0] =~ /^error: 2 /) { $$blockcount = 0; } } sub get_block_choices { my $item = shift; my $blocklist; my ($typeorder,$types) = &blocktype_text(); foreach my $type (@{$typeorder}) { if ($env{'form.'.$type.'_'.$item}) { $blocklist->{$type} = 'on'; } else { $blocklist->{$type} = 'off'; } } return $blocklist; } sub display_blocker_status { my ($r,$records,$ltext) = @_; my $parmcount = 0; my %lt = &Apache::lonlocal::texthash( 'modi' => 'Modify', 'canc' => 'Cancel', ); my ($typeorder,$types) = &blocktype_text(); $r->print(&Apache::loncommon::start_data_table()); $r->print(<<"END"); $ltext->{'dura'} $ltext->{'setb'} $ltext->{'even'} $ltext->{'blck'} $ltext->{'actn'} END foreach my $record (sort(keys(%{$records}))) { my $onchange = 'onFocus="javascript:window.document.forms['. "'blockform'].elements['modify_".$parmcount."'].". 'checked=true;"'; my ($start,$end) = split(/____/,$record); my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); my ($setuname,$setudom,$title,$blocks) = &Apache::loncommon::parse_block_record($$records{$record}); $title = &HTML::Entities::encode($title,'"<>&'); my $settername = &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($setuname,$setudom), $setuname,$setudom); $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); $ltext->{'star'}: $startform
$ltext->{'endd'}:  $endform $settername END foreach my $block (@{$typeorder}) { my $blockstatus = ''; if ($blocks->{$block} eq 'on') { $blockstatus = 'checked="checked"'; } $r->print('
'); } $r->print(<<"END");
END $r->print(&Apache::loncommon::end_data_table_row()); $parmcount++; } $r->print(<<"END");

END return $parmcount; } sub display_addblocker_table { my ($r,$parmcount,$ltext) = @_; my $start = time; my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration. my $onchange = 'onFocus="javascript:window.document.forms['. "'blockform'].elements['add_".$parmcount."'].". 'checked=true;"'; my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); my %lt = &Apache::lonlocal::texthash( 'addb' => 'Add block', 'exam' => 'e.g., Exam 1', 'addn' => 'Add new communication blocking periods' ); my ($typeorder,$types) = &blocktype_text(); $r->print(<<"END");

$lt{'addn'}

END $r->print(&Apache::loncommon::start_data_table()); $r->print(<<"END"); $ltext->{'dura'} $ltext->{'even'} $lt{'exam'} $ltext->{'blck'} $ltext->{'actn'} END $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); $ltext->{'star'}: $startform
$ltext->{'endd'}:  $endform END foreach my $block (@{$typeorder}) { $r->print('
'); } $r->print(<<"END"); END $r->print(&Apache::loncommon::end_data_table_row()); $r->print(&Apache::loncommon::end_data_table()); return; } sub blocktype_text { my %types = &Apache::lonlocal::texthash( 'com' => 'Messaging', 'chat' => 'Chat Room', 'boards' => 'Discussion', 'port' => 'Portfolio', 'groups' => 'Groups', 'blogs' => 'Blogs', ); my $typeorder = ['com','chat','boards','port','groups','blogs']; return ($typeorder,\%types); } 1; __END__