Annotation of loncom/interface/lonblockingmenu.pm, revision 1.2
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: #
1.2 ! raeburn 5: # $Id: lonblockingmenu.pm,v 1.1 2011/12/28 21:49:54 raeburn Exp $
1.1 raeburn 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:
1.2 ! raeburn 67: =cut
1.1 raeburn 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'}: $startform<br />$ltext->{'endd'}: $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'}: $startform<br />$ltext->{'endd'}: $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>