Annotation of loncom/interface/lonwhatsnew.pm, revision 1.43
1.2 albertel 1: #
1.43 ! albertel 2: # $Id: lonwhatsnew.pm,v 1.42 2005/12/22 03:39:39 raeburn Exp $
1.2 albertel 3: #
4: # Copyright Michigan State University Board of Trustees
5: #
6: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
7: #
8: # LON-CAPA is free software; you can redistribute it and/or modify
9: # it under the terms of the GNU General Public License as published by
10: # the Free Software Foundation; either version 2 of the License, or
11: # (at your option) any later version.
12: #
13: # LON-CAPA is distributed in the hope that it will be useful,
14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: # GNU General Public License for more details.
17: #
18: # You should have received a copy of the GNU General Public License
19: # along with LON-CAPA; if not, write to the Free Software
20: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21: #
22: # /home/httpd/html/adm/gpl.txt
23: #
24: # http://www.lon-capa.org/
25: #
26:
27:
1.1 raeburn 28: package Apache::lonwhatsnew;
29:
30: use strict;
31: use lib qw(/home/httpd/lib/perl);
32: use Apache::lonnet;
1.3 albertel 33: use Apache::loncommon();
34: use Apache::lonhtmlcommon();
1.1 raeburn 35: use Apache::lonlocal;
1.3 albertel 36: use Apache::loncoursedata();
37: use Apache::lonnavmaps();
1.18 raeburn 38: use Apache::lonuserstate;
1.1 raeburn 39: use Apache::Constants qw(:common :http);
40: use Time::Local;
1.24 albertel 41: use GDBM_File;
1.1 raeburn 42:
43: #----------------------------
44: # handler
45: #
46: #----------------------------
47:
48: sub handler {
49: my $r = shift;
1.7 raeburn 50: if ($r->header_only) {
51: &Apache::loncommon::content_type($r,'text/html');
52: $r->send_http_header;
53: return OK;
54: }
1.39 raeburn 55: &Apache::loncommon::get_unprocessed_cgi(
56: $ENV{'QUERY_STRING'},['command','refpage']);
1.1 raeburn 57:
1.36 raeburn 58: my $command = $env{'form.command'};
1.39 raeburn 59: my $refpage = $env{'form.refpage'};
1.1 raeburn 60:
1.7 raeburn 61: &Apache::loncommon::content_type($r,'text/html');
62: $r->send_http_header;
1.43 ! albertel 63:
! 64: if ( ! $env{'request.course.fn'}
! 65: ||
! 66: (!( &Apache::lonnet::allowed('whn',$env{'request.course.id'})
! 67: || &Apache::lonnet::allowed('whn',$env{'request.course.id'}
! 68: .'/'.$env{'request.course.sec'})))) {
! 69: # Not in a course, or no whn priv in course
1.42 raeburn 70: $env{'user.error.msg'}="/adm/whatsnew::whn:0:0:Cannot display what's new page";
1.1 raeburn 71: return HTTP_NOT_ACCEPTABLE;
72: }
73:
1.36 raeburn 74: my %checkallowed = (
75: coursediscussion => &Apache::lonnet::allowed('pch',$env{'request.course.id'}),
76: handgrading => &Apache::lonnet::allowed('mgr',$env{'request.course.id'}),
77: abovethreshold => &Apache::lonnet::allowed('vgr',$env{'request.course.id'}),
78: haserrors => &Apache::lonnet::allowed('opa',$env{'request.course.id'}),
79: versionchanges => &Apache::lonnet::allowed('opa',$env{'request.course.id'}),
80: coursenormalmail => 1,
81: coursecritmail => 1,
82: );
83:
84: $r->print(&display_header($command,\%checkallowed));
85:
1.7 raeburn 86: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.36 raeburn 87: &Apache::lonhtmlcommon::add_breadcrumb
88: ({href=>'/adm/whatsnew',
89: text=>"Display Action Items"});
1.33 raeburn 90: if (($command eq 'chgthreshold') && (&Apache::lonnet::allowed('vgr',$env{'request.course.id'}))) {
1.7 raeburn 91: &Apache::lonhtmlcommon::add_breadcrumb
1.39 raeburn 92: ({href=>'/adm/whatsnew?command=chgthreshold&refpage='.$refpage,
1.13 raeburn 93: text=>"Change thresholds"});
1.7 raeburn 94: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.40 raeburn 95: (undef,"What's New?",'Course_Action_Items_Thresholds'));
1.36 raeburn 96: } elsif (($command eq 'chginterval') && (&Apache::lonnet::allowed('vgr',$env{'request.course.id'}))) {
97: &Apache::lonhtmlcommon::add_breadcrumb
1.39 raeburn 98: ({href=>'/adm/whatsnew?command=chginterval&refpage='.$refpage,
1.36 raeburn 99: text=>"Change interval"});
100: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.40 raeburn 101: (undef,"What's New?",'Course_Action_Items_Intervals'));
1.39 raeburn 102: } elsif (($command eq 'chgdisc') && (&Apache::lonnet::allowed('pch',$env{'request.course.id'}))) {
103: &Apache::lonhtmlcommon::add_breadcrumb
104: ({href=>'/adm/whatsnew?command=chgdisc&refpage='.$refpage,
105: text=>"Change discussion display"});
106: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.40 raeburn 107: (undef,"What's New?",'Course_Action_Items_Intervals'));
1.39 raeburn 108: } elsif ($command eq 'courseinit') {
109: &Apache::lonhtmlcommon::add_breadcrumb
110: ({href=>'/adm/whatsnew?command=courseinit&refpage='.$refpage,
111: text=>"Course initialization preference"});
112: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.40 raeburn 113: (undef,"What's New?",'Course_Action_Items_Initialization'));
1.7 raeburn 114: } else {
115: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.40 raeburn 116: (undef,"What's New?",'Course_Action_Items_Display'));
1.7 raeburn 117: }
1.39 raeburn 118: &display_main_box($r,$command,$refpage,\%checkallowed);
1.14 albertel 119: return OK;
1.1 raeburn 120: }
121:
122: #------------------------------
123: # display_main_box
124: #
125: # Display all the elements within the main box
126: #------------------------------
127:
128: sub display_main_box {
1.39 raeburn 129: my ($r,$command,$refpage,$checkallowed) = @_;
1.1 raeburn 130: my $domain=&Apache::loncommon::determinedomain();
1.40 raeburn 131: my $function = &Apache::loncommon::get_users_function();
132: my $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);
1.7 raeburn 133: $r->print('<table width="100%" border="0" cellpadding="5" cellspacing="0"><tr><td width="100%">');
1.13 raeburn 134:
1.39 raeburn 135: my %threshold_titles = &Apache::lonlocal::texthash (
1.13 raeburn 136: av_attempts => 'Average number of attempts',
137: degdiff => 'Degree of difficulty',
138: numstudents => 'Total number of students with submissions',
139: );
1.36 raeburn 140:
1.39 raeburn 141: my %interval_titles = &Apache::lonlocal::texthash (
1.36 raeburn 142: -1 => 'since start of course',
143: 2592000 => 'since last month',
144: 604800 => 'since last week',
145: 86400 => 'since yesterday',
146: );
147:
1.39 raeburn 148: my %initpage = &Apache::lonlocal::texthash (
149: firstres => 'first resource in the course',
150: whatsnew => "what's new? page",
151: userpref => 'your general user preferences',
152: coursespecific => 'specific setting for this course',
153: );
1.15 raeburn 154: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
155: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
156:
1.36 raeburn 157: if (($command eq 'chgthreshold') &&
158: (&Apache::lonnet::allowed('vgr',$env{'request.course.id'}))) {
1.39 raeburn 159: &display_threshold_config($r,$refpage,$tabbg,\%threshold_titles,
1.36 raeburn 160: $cdom,$crs);
161: } elsif (($command eq 'chginterval') &&
162: (&Apache::lonnet::allowed('opa',$env{'request.course.id'}))) {
1.39 raeburn 163: &display_interval_config($r,$refpage,\%interval_titles);
164: } elsif (($command eq 'chgdisc') &&
165: (&Apache::lonnet::allowed('pch',$env{'request.course.id'}))) {
166: &display_discussion_config($r,$refpage);
167: } elsif ($command eq 'courseinit') {
168: &courseinit_config($r,$refpage,\%initpage);
1.1 raeburn 169: } else {
1.40 raeburn 170: &display_actions_box($r,$tabbg,$command,$refpage,\%threshold_titles,
1.39 raeburn 171: \%interval_titles,\%initpage,$cdom,$crs,$checkallowed);
1.1 raeburn 172: }
173: $r->print(<<END_OF_BLOCK);
174: </td>
175: </tr>
176: </table><br />
177: </body>
178: </html>
179: END_OF_BLOCK
180: }
181:
182: #-------------------------------
183: # display_header
184: #
185: # Display the header information and set
186: # up the HTML
187: #-------------------------------
188:
1.39 raeburn 189: sub display_header {
1.36 raeburn 190: my ($command,$checkallowed) = @_;
1.3 albertel 191: my $html=&Apache::lonxml::xmlbegin();
1.1 raeburn 192: my $bodytag=&Apache::loncommon::bodytag('Course Action Items');
1.36 raeburn 193: my $scripttag;
194: unless ($command eq 'chgthreshold' || $command eq 'chginterval') {
195: $scripttag = <<"END";
196: <script type="text/javascript">
197: function change_display(caller,change) {
198: caller.value = change;
199: document.visible.submit();
200: }
201:
202: function changeAll(change) {
203: END
204: foreach my $item (keys(%{$checkallowed})) {
1.39 raeburn 205: if ($$checkallowed{$item}) {
206: $scripttag.='document.visible.display_'.$item.'.value=change'.
207: "\n";
208: }
1.36 raeburn 209: }
210: $scripttag.='document.visible.submit();
211: }
212: </script>
213: ';
214: }
1.1 raeburn 215: return(<<ENDHEAD);
1.3 albertel 216: $html
1.1 raeburn 217: <head>
218: <title>Course Action Items</title>
1.36 raeburn 219: $scripttag
1.1 raeburn 220: </head>
221: $bodytag
222: ENDHEAD
223: }
224:
225: #-------------------------------
226: # display_actions_box
227: #
228: # Display the action items
229: #
230: #-------------------------------
231:
1.39 raeburn 232: sub display_actions_box {
1.40 raeburn 233: my ($r,$tabbg,$command,$refpage,$threshold_titles,$interval_titles,
234: $initpage,$cdom,$crs,$checkallowed) = @_;
1.1 raeburn 235: my $rowColor1 = "#ffffff";
236: my $rowColor2 = "#eeeeee";
237:
1.36 raeburn 238: my $udom = $env{'user.domain'};
239: my $uname = $env{'user.name'};
240: my $cid = $env{'request.course.id'};
241:
242: my %lt = &Apache::lonlocal::texthash(
243: 'yacc' => 'You are accessing an invalid course.',
244: 'gtfr' => 'Go to first resource',
1.39 raeburn 245: 'pgse' => 'Page set to be displayed after you have selected a role in this course?',
1.36 raeburn 246: 'hial' => 'Hide all',
247: 'shal' => 'Show all',
248: );
249:
1.1 raeburn 250: my %unread = ();
251: my %ungraded = ();
252: my %bombed = ();
1.11 raeburn 253: my %triggered = ();
1.33 raeburn 254: my %changed = ();
1.1 raeburn 255: my @newmsgs = ();
256: my @critmsgs = ();
257: my @newdiscussions = ();
258: my @tograde = ();
259: my @bombs = ();
1.11 raeburn 260: my @warnings = ();
1.33 raeburn 261: my $msgcount = 0;
262: my $critmsgcount = 0;
263:
1.16 raeburn 264: my %res_title = ();
1.33 raeburn 265: my %show = ();
266: my $needitems = 0;
267: my $boxcount = 0;
1.1 raeburn 268:
1.39 raeburn 269: my $result;
270: if ($command eq 'newcourseinit') {
271: $result = &store_courseinit_setting($uname,$udom,$cid,$initpage);
272: }
273:
1.13 raeburn 274: my %threshold = (
1.22 www 275: av_attempts => 2,
276: degdiff => 0.5,
277: numstudents => 2,
1.13 raeburn 278: );
1.39 raeburn 279: my %pagedesc = &Apache::lonlocal::texthash (
280: firstres => 'First resource',
1.40 raeburn 281: whatsnew => "What's New? page",
1.39 raeburn 282: userpref => 'user preference',
283: coursespecific => 'course only',
284: default => 'default',
285: );
286:
287: my ($initcontrol,$initdisp) = &curr_courseinit();
288: my $currinit = $pagedesc{$initdisp}.' ('.$pagedesc{$initcontrol}.')';
1.13 raeburn 289:
1.36 raeburn 290: unless ($cid) {
291: $r->print('<br /><b><center>'.$lt{'yacc'}.'</center></b><br /><br />');
1.1 raeburn 292: return;
293: }
1.33 raeburn 294:
1.39 raeburn 295: if ($refpage eq 'start') {
296: if (tie(my %bighash,'GDBM_File',$env{'request.course.fn'}.'.db',
1.36 raeburn 297: &GDBM_READER(),0640)) {
1.39 raeburn 298: my $furl=$bighash{'first_url'};
299: untie(%bighash);
300: $r->print('<font size="+1"><a href="'.$furl.'">'.$lt{'gtfr'}.
301: '</a></font><br />');
302: }
1.36 raeburn 303: }
1.39 raeburn 304: $r->print($lt{'pgse'}.' '.&mt('Currently: [_1]','<i>'.$currinit.'</i>').
305: '<nobr> '.&mt('[_1] for just [_2]','<b>Change</b>',
306: '<a href="/adm/whatsnew?command=courseinit&refpage='.$refpage.
307: '">this course</a>').' '.&mt('or for all [_1].',
308: '<a href="/adm/preferences?action=changecourseinit&refpage='.
309: $refpage.'">your courses</a>').'</nobr><br /><hr />');
1.36 raeburn 310:
311: if ($command eq 'reset') {
312: $result = &process_reset($cdom,$crs);
313: } elsif ($command eq 'update') {
1.39 raeburn 314: $result = &process_update($uname,$udom,$threshold_titles);
1.36 raeburn 315: } elsif ($command eq 'newinterval') {
316: $result = &store_interval_setting($uname,$udom,$cid,$interval_titles);
1.39 raeburn 317: } elsif ($command eq 'newdiscconf') {
318: $result = &store_discussion_setting($uname,$udom,$cid);
1.36 raeburn 319: }
320:
321: my $store_result=&store_display_settings($uname,$udom,$cid,$checkallowed);
322:
323: unless ($store_result eq 'ok') {
324: &Apache::lonnet::logthis('Error storing whatsnew settings: '.
325: $store_result.' for '.'user '.$uname.':'.$udom.' in course '.$cid);
326: $result .= &mt('Unable to store visibility settings due to [_1]',
327: $store_result);
328: }
329:
330: if ($result) {
331: $r->print($result.'<hr width="100%" />');
332: }
333: $r->rflush();
334:
1.33 raeburn 335:
1.36 raeburn 336: my %display_settings = &get_display_settings($uname,$udom,$cid);
337: my $timediff = $display_settings{$cid.':interval'};
338: unless (defined($timediff)) { $timediff = 604800; }
1.35 raeburn 339: my $now = time;
1.36 raeburn 340: my $interval = $$interval_titles{$timediff};
1.35 raeburn 341: if ($timediff == -1) {
342: $timediff = time;
343: }
344: my $starttime = $now - $timediff;
1.39 raeburn 345: my $countunread = $display_settings{$cid.':countunread'};
346: unless (defined($countunread)) {
347: $countunread = 'on';
348: }
1.33 raeburn 349:
350: my %headings = &Apache::lonlocal::texthash(
351: coursediscussion => 'Unread course discussion posts',
352: handgrading => 'Problems requiring handgrading',
353: haserrors => 'Problems with errors',
354: versionchanges => 'Resources in course with version changes '.$interval,
1.37 raeburn 355: coursenormalmail => 'New course messages',
1.33 raeburn 356: coursecritmail => 'New critical messages in course',
357: );
358:
1.36 raeburn 359: if ($$checkallowed{'abovethreshold'}) {
1.39 raeburn 360: &get_curr_thresholds(\%threshold,$uname,$udom,$cid,$cdom,$crs);
1.33 raeburn 361: }
362:
363: $headings{'abovethreshold'} = &mt('Problems with av. attempts').' ≥ '.$threshold{'av_attempts'}.' '.&mt('or deg. difficulty').' ≥ '.$threshold{'degdiff'}.'<br /> '.&mt('and total number of students with submissions').' ≥ '.$threshold{'numstudents'};
364:
365: my @actionorder = ('handgrading','haserrors','abovethreshold','versionchanges','coursediscussion','coursenormalmail','coursecritmail');
366:
1.36 raeburn 367: foreach my $key (keys(%{$checkallowed})) {
1.33 raeburn 368: $show{$key} = 0;
1.36 raeburn 369: if ($$checkallowed{$key}) {
370: unless ($display_settings{$cid.':'.$key} eq 'hide') {
1.33 raeburn 371: $show{$key} = 1;
372: }
373: }
374: }
375:
376: foreach my $item (@actionorder) {
377: unless ($item eq 'coursenormalmail' || $item eq 'coursecritmail') {
378: if ($show{$item}) {
379: $needitems = 1;
380: last;
381: }
382: }
383: }
384:
385: if ($needitems) {
1.37 raeburn 386: &getitems(\%unread,\%ungraded,\%bombed,\%triggered,\%changed,\@newdiscussions,\@tograde,\@bombs,\@warnings,$rowColor1,$rowColor2,\%threshold,$cdom,$crs,\%res_title,\%show,$starttime,$countunread);
1.1 raeburn 387: }
1.33 raeburn 388: if ($show{'coursenormalmail'}) {
389: &getnormalmail(\@newmsgs);
1.7 raeburn 390: }
1.33 raeburn 391: if ($show{'coursecritmail'}) {
392: &getcritmail(\@critmsgs);
1.11 raeburn 393: }
394:
1.36 raeburn 395: $r->print(qq|<a href="javascript:changeAll('hide');">$lt{'hial'}</a>
396: <a href="javascript:changeAll('show');">$lt{'shal'}</a>
397: <form method="post" name="visible" action="/adm/whatsnew">\n|);
398: foreach my $item (keys(%{$checkallowed})) {
399: if ($$checkallowed{$item}) {
400: $r->print('<input type="hidden" name="display_'.$item.'" />'."\n");
401: }
402: }
1.1 raeburn 403:
1.39 raeburn 404: $r->print('<input type="hidden" name="refpage" value="'.$refpage.'"></form><br /><table border="0" width="100%" cellpadding="2" cellspacing="4"><tr><td align="left" valign="top" width="45%">');
1.1 raeburn 405:
1.33 raeburn 406: my $displayed = 0;
1.40 raeburn 407: my $totalboxes = 0;
408: foreach my $key (keys(%{$checkallowed})) {
409: if ($$checkallowed{$key}) {
410: $totalboxes ++;
411: }
412: }
1.33 raeburn 413: my $halfway = int($totalboxes/2) + $totalboxes%2;
414: foreach my $actionitem (@actionorder) {
1.36 raeburn 415: if ($$checkallowed{$actionitem}) {
1.33 raeburn 416: if ($displayed == $halfway) {
1.40 raeburn 417: $r->print('</td><td width="6%"> </td><td align="left" valign="top" width="47%">');
1.1 raeburn 418: }
1.39 raeburn 419: &display_launcher($r,$actionitem,$refpage,$checkallowed,$tabbg,$rowColor1,$rowColor2,\%show,\%headings,\%res_title,\@tograde,\%ungraded,\@bombs,\%bombed,\%changed,\@warnings,\%triggered,\@newdiscussions,\%unread,$msgcount,\@newmsgs,$critmsgcount,\@critmsgs,$interval,$countunread);
1.33 raeburn 420: $displayed ++;
1.1 raeburn 421: }
422: }
423: $r->print('
424: </table>
425: </td>
426: </tr>
1.33 raeburn 427: </table>
428: </td>
429: </tr>
430: </table>');
1.1 raeburn 431: }
432:
1.11 raeburn 433: #-------------------------------
1.36 raeburn 434: # display_threshold_config
1.11 raeburn 435: #
1.13 raeburn 436: # Display the threshold setting screen
1.11 raeburn 437: #
438: #-------------------------------
439:
1.36 raeburn 440: sub display_threshold_config {
1.39 raeburn 441: my ($r,$refpage,$tabbg,$threshold_titles,$cdom,$crs) = @_;
442: my $uname = $env{'user.name'};
443: my $udom = $env{'user.dom'};
444: my $cid = $env{'request.course.id'};
1.13 raeburn 445: my %threshold = ();
446: my $rowColor1 = "#ffffff";
447: my $rowColor2 = "#eeeeee";
448: my $rowColor;
449:
450: my @thresholditems = ("av_attempts","degdiff","numstudents");
1.39 raeburn 451: foreach my $item (@thresholditems) {
452: $threshold{$item} = '';
453: }
454: my %threshold_titles = &Apache::lonlocal::texthash(
1.13 raeburn 455: av_attempts => 'Average number of attempts',
456: degdiff => 'Degree of difficulty',
457: numstudents => 'Total number of students with submissions',
458: );
1.39 raeburn 459: &get_curr_thresholds(\%threshold,$uname,$udom,$cid,$cdom,$crs);
1.13 raeburn 460:
1.36 raeburn 461: $r->print('<br /><form name="thresholdform" method="post" action="/adm/whatsnew">
462: <table border="0" cellpadding="2" cellspacing="4">
463: <tr>
464: <td align="left" valign="top" width="45%">
1.13 raeburn 465: <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000">
466: <tr>
467: <td>
468: <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000">
469: <tr>
470: <td bgcolor="#ffffff">
471: <table cellspacing="0" cellpadding="4" border="0">
472: <tr bgcolor="'.$tabbg.'">
473: <th>Threshold Name</th>
474: <th>Current value</th>
475: <th>Change?</th>
476: </tr>');
477: my $rowNum =0;
478: foreach my $type (@thresholditems) {
1.39 raeburn 479: my $parameter = $env{'request.course.id'}.':threshold_'.$type;
1.13 raeburn 480: # onchange is javascript to automatically check the 'Set' button.
481: my $onchange = 'onFocus="javascript:window.document.forms'.
482: "['thresholdform'].elements['".$parameter."_setparmval']".
483: '.checked=true;"';
484: if ($rowNum %2 == 1) {
485: $rowColor = $rowColor1;
486: } else {
487: $rowColor = $rowColor2;
488: }
489: $r->print('
490: <tr bgcolor="'.$rowColor.'">
491: <td>'.$threshold_titles{$type}.'</td>
492: <td>'.&Apache::lonhtmlcommon::textbox($parameter.'_value',
493: $threshold{$type},
494: 10,$onchange).'</td>
495: <td>'
496: .&Apache::lonhtmlcommon::checkbox($parameter.'_setparmval').
497: '</td>
498: </tr>');
499: $rowNum ++;
500: }
501: $r->print('</table></td></tr></table></td></tr></table>
502: <br /><input type="submit" name="threshold" value="Make changes" />
1.36 raeburn 503: <input type="hidden" name="command" value="update" />
1.39 raeburn 504: <input type="hidden" name="refpage" value="'.$refpage.'" />
1.13 raeburn 505: </form>');
1.11 raeburn 506: }
507:
1.36 raeburn 508: #-------------------------------
509: # display_interval_config
510: #
511: # Display the interval setting screen
512: #
513: #-------------------------------
514:
515: sub display_interval_config {
1.39 raeburn 516: my ($r,$refpage,$interval_titles) = @_;
517: my $current = &get_current($env{'user.name'},$env{'user.domain'},
518: $env{'request.course.id'},'interval');
1.36 raeburn 519: $r->print('<br />'.&mt('Choose the time window to use for display of version changes for resources in the course.'));
520: unless ($current eq '') {
1.39 raeburn 521: $r->print(' '.&mt('Current value is [_1]','<b>'.
522: $$interval_titles{$current}.'</b>.'));
1.36 raeburn 523: }
524: $r->print('<br /><br />
525: <form method="post" name="intervalswitch" action="/adm/whatsnew">
526: <input type="hidden" name="command" value="newinterval" />
1.39 raeburn 527: <input type="hidden" name="refpage" value="'.$refpage.'" />
1.36 raeburn 528: <select name="interval">
529: ');
530: foreach my $key (reverse sort ({$a cmp $b} (keys(%{$interval_titles})))) {
531: $r->print('<option value="'.$key.'">Version changes '.$$interval_titles{$key}.
532: '</option>'."\n");
533: }
534: $r->print('</select>
535: <input type="submit" name="display" value="'.
536: &mt('Change interval').'" /></form>');
537: return;
538: }
539:
1.39 raeburn 540: #----------------------------------------------
541: # display_discussion_config
542: #
543: # Display the discussion display setting screen
544: #
545: #----------------------------------------------
546:
547: sub display_discussion_config {
548: my ($r,$refpage) = @_;
549: my $current = &get_current($env{'user.name'},$env{'user.domain'},
550: $env{'request.course.id'},'countunread');
551: if ($current eq '') {
552: $current = 'on';
553: }
554: my %status = (
555: on => 'checked="checked"',
556: off => 'checked="checked"',
557: );
558: $status{$current} = '';
559: $r->print('<br />'.&mt('Choose whether or not to display a count of the number of new posts for each resource or bulletin board which has unread posts.').'<br />'.&mt('This can increase the time taken to gather data for the [_1] page by a few seconds.',"<i>What's New?</i>").' '.&mt('Currently set to [_1] .'),"<b>$current</b>.");
560: $r->print('<br /><br />
561: <form method="post" name="discussionswitch" action="/adm/whatsnew">'.
562: &mt('Display of unread post counts?').'
563: <input type="hidden" name="command" value="newdiscconf" />
564: <input type="hidden" name="refpage" value="'.$refpage.'" />
565: <input type ="radio" '.$status{'on'}.' name="countunread" value="on">on
566:
567: <input type ="radio" '.$status{'off'}.' name="countunread" value="off">off
568: ');
569: $r->print('<br/><br />
570: <input type="submit" name="display" value="'.
571: &mt('Make changes').'" /></form>');
572: return;
573: }
574:
575: #---------------------------------------------------
576: # courseinit_config
577: #
578: # Set page displayed when course loads after
579: # selecting a role in the course from the roles page.
580: #
581: #---------------------------------------------------
582:
583: sub courseinit_config {
584: my ($r,$refpage,$initpage) = @_;
585: my ($control,$current) = &curr_courseinit();
586: my @chgstate = ('userpref','coursespecific');
587: my @chgentry = ('firstres','whatsnew');
588: my %lt = &Apache::lonlocal::texthash(
589: 'chwp' => 'Choose which page will be displayed when you enter this course after selecting a role.',
590: 'cuva' => 'Current value is determined by',
591: 'anis' => 'and is set to display',
592: 'padc' => 'Page display controlled by',
593: 'chce' => 'Choose course entry',
594: 'moce' => 'Modify course entry',
595: );
596: $r->print(<<"END");
597: <br />$lt{'chwp'}
598: <br />$lt{'cuva'}: <b>
599: $$initpage{$control}</b> $lt{'anis'} <b>
600: $$initpage{$current}</b>.<br /><br />
601: <form method="post" name="courseinitswitch" action="/adm/whatsnew">
602: <input type="hidden" name="command" value="newcourseinit" />
603: <input type="hidden" name="refpage" value="$refpage" />
604: $lt{'padc'}
605: END
606: foreach my $choice (@chgstate) {
607: $r->print('<nobr><input type="radio" name="courseinit_control" value="'.
608: $choice.'"/>'.$$initpage{$choice}.' </nobr>');
609: }
610: $r->print('<br /><br />'.&mt('If').' '.$$initpage{'coursespecific'}.
611: '<br />'.$lt{'chce'}." \n");
612: foreach my $choice (@chgentry) {
613: $r->print('<nobr><input type="radio" name="courseinit_page" value="'.
614: $choice.'"/>'.$$initpage{$choice}.' </nobr>');
615: }
616: $r->print('<br /><br /><input type="submit" name="display" value="'.
617: $lt{'moce'}.'" /></form>');
618: return;
619: }
620:
621: sub curr_courseinit {
622: my $current = &get_current($env{'user.name'},$env{'user.domain'},
623: $env{'request.course.id'},'courseinit');
624: my $control;
1.40 raeburn 625: if ($current) {
626: $control = 'coursespecific';
627: } else {
1.39 raeburn 628: $control = 'userpref';
1.40 raeburn 629: my %userenv = &Apache::lonnet::get('environment',
630: ['course_init_display']);
631: if (exists($userenv{'course_init_display'})) {
632: $current = $userenv{'course_init_display'};
633: }
634: unless ($current) {
1.39 raeburn 635: $current = 'whatsnew';
636: }
637: }
638: return ($control,$current);
639: }
640:
1.33 raeburn 641: sub display_launcher {
1.39 raeburn 642: my ($r,$action,$refpage,$checkallowed,$tabbg,$rowColor1,$rowColor2,$show,
1.33 raeburn 643: $headings,$res_title,$tograde,$ungraded,$bombs,$bombed,$changed,
644: $warnings,$triggered,$newdiscussions,$unread,$msgcount,$newmsgs,
1.37 raeburn 645: $critmsgcount,$critmsgs,$interval,$countunread) = @_;
1.33 raeburn 646:
647: if ($$checkallowed{$action}) {
1.39 raeburn 648: &start_box($r,$tabbg,$show,$headings,$action,$refpage);
1.33 raeburn 649: if ($$show{$action}) {
650: if ($action eq 'handgrading') { # UNGRADED ITEMS
651: &display_handgrade($r,$tograde,$rowColor1,$rowColor2,
652: $ungraded);
653: } elsif ($action eq 'haserrors') { # BOMBS
654: &display_haserrors($r,$bombs,$rowColor1,$rowColor2,$bombed,
655: $res_title);
656: } elsif ($action eq 'versionchanges') { # VERSION CHANGES
657: &display_versionchanges($r,$changed,$res_title,$rowColor1,
658: $rowColor2,$interval);
659:
660: } elsif ($action eq 'abovethreshold') { # DEGDIFF/AV. TRIES TRIGGERS
1.39 raeburn 661: &display_abovethreshold($r,$refpage,$warnings,$triggered,
662: $res_title,$rowColor1,$rowColor2);
1.33 raeburn 663: } elsif ($action eq 'coursediscussion') { # UNREAD COURSE DISCUSSION
664: &display_coursediscussion($r,$newdiscussions,$unread,
1.37 raeburn 665: $countunread,$res_title,$rowColor1,$rowColor2);
1.33 raeburn 666: } elsif ($action eq 'coursenormalmail') { # NORMAL MESSAGES
667: &display_coursenormalmail($r,$msgcount,$newmsgs,$rowColor1,
668: $rowColor2);
669: } elsif ($action eq 'coursecritmail') { # CRITICAL MESSAGES
670: &display_coursecritmail($r,$critmsgcount,$critmsgs,$rowColor1,
671: $rowColor2);
672: }
673: }
674: &end_box($r);
675: }
676: return;
677: }
678:
1.1 raeburn 679: sub getitems {
1.33 raeburn 680: my ($unread,$ungraded,$bombed,$triggered,$changed,$newdiscussions,
681: $tograde,$bombs,$warnings,$rowColor1,$rowColor2,$threshold,$cdom,$crs,
1.37 raeburn 682: $res_title,$show,$starttime,$countunread) = @_;
1.1 raeburn 683: my $navmap = Apache::lonnavmaps::navmap->new();
1.26 albertel 684: # force retrieve Resource to seed the part id cache we'll need it later
1.37 raeburn 685: my @allres=$navmap->retrieveResources(undef,
686: sub {if ($_[0]->is_problem) { $_[0]->parts();} return 1;});
1.33 raeburn 687: my %lastreadtime;
688: my %resourcetracker;
1.37 raeburn 689: my $discussiontime;
1.33 raeburn 690:
691: # Resource version changes
692: if ($$show{'versionchanges'}) {
693: &checkversions($cdom,$crs,$navmap,$changed,$starttime);
694: }
695:
1.37 raeburn 696: if ($$show{'coursediscussion'}) {
1.33 raeburn 697: my %lastread = &Apache::lonnet::dump('nohist_'.
698: $env{'request.course.id'}.'_discuss',
699: $env{'user.domain'},$env{'user.name'},'lastread');
700: foreach my $key (keys(%lastread)) {
701: my $newkey = $key;
702: $newkey =~ s/_lastread$//;
703: $lastreadtime{$newkey} = $lastread{$key};
704: }
705: }
706:
707: if ($$show{'abovethreshold'}) {
708: %resourcetracker = &Apache::lonnet::dump('nohist_resourcetracker',
709: $cdom,$crs);
710: }
1.1 raeburn 711:
1.11 raeburn 712: my $warningnum = 0;
1.1 raeburn 713: foreach my $resource (@allres) {
714: my $result = '';
715: my $applies = 0;
716: my $symb = $resource->symb();
1.33 raeburn 717: %{$$bombed{$symb}} = ();
1.1 raeburn 718: %{$$ungraded{$symb}} = ();
1.11 raeburn 719: %{$$triggered{$symb}} = ();
720: $$triggered{$symb}{numparts} = 0;
1.1 raeburn 721: my $title = $resource->compTitle();
1.16 raeburn 722: $$res_title{$symb} = $title;
1.8 albertel 723: my $ressymb = $resource->wrap_symb();
1.33 raeburn 724:
1.37 raeburn 725: # Check if there are unread discussion postings
1.33 raeburn 726: if ($$show{'coursediscussion'}) {
727: &check_discussions($cdom,$crs,$resource,$symb,$ressymb,$title,
1.37 raeburn 728: $newdiscussions,$unread);
1.33 raeburn 729: }
1.1 raeburn 730:
731: # Check for ungraded problems
732: if ($resource->is_problem()) {
1.33 raeburn 733: if ($$show{'handgrading'}) {
734: &check_handgraded($resource,$symb,$title,$cdom,$crs,$ungraded,
735: $tograde);
736: }
1.1 raeburn 737: }
738:
739: # Check for bombs
1.33 raeburn 740: if ($$show{'haserrors'}) {
741: &check_bombed($resource,$symb,$title,$bombs,$bombed);
742: }
743:
744: # Maxtries and degree of difficulty for problem parts, unless handgradeable
745: if ($$show{'abovethreshold'}) {
746: &check_thresholds($resource,$symb,\%resourcetracker,$triggered,
747: $threshold,$warnings,$warningnum,$rowColor1,$rowColor2);
748: }
749:
750: }
1.37 raeburn 751: my $hasdiscussion = @{$newdiscussions};
752: if ($$show{'coursediscussion'} && $hasdiscussion) { # Get time of last post;
753: $discussiontime = $navmap->{DISCUSSION_TIME};
754: foreach my $ressymb (@{$newdiscussions}) {
755: $$unread{$ressymb}{'lastpost'} = $$discussiontime{$ressymb};
756: }
1.39 raeburn 757: if ($countunread eq 'on') { #Get count of unread postings for each resource
1.37 raeburn 758: my $discussiondata = $navmap->get_discussion_data();
759: foreach my $ressymb (@{$newdiscussions}) {
760: &get_discussions($cdom,$crs,$discussiondata,$ressymb,
761: $unread,\%lastreadtime);
762: }
763: }
764: }
1.33 raeburn 765: }
766:
767: sub check_discussions {
1.37 raeburn 768: my ($cdom,$crs,$resource,$symb,$ressymb,$title,$newdiscussions,
769: $unread) = @_;
1.33 raeburn 770: if ($resource->hasDiscussion()) {
771: %{$$unread{$ressymb}} = ();
772: $$unread{$ressymb}{'title'} = $title;
773: $$unread{$ressymb}{'symb'} = $symb;
1.37 raeburn 774: push(@{$newdiscussions}, $ressymb);
775: }
776: }
777:
778: sub get_discussions {
779: my ($cdom,$crs,$discussiondata,$ressymb,$unread,$lastreadtime) = @_;
780: my $prevread = 0;
781: my $unreadcount = 0;
782: if (defined($$lastreadtime{$ressymb})) {
783: $prevread = $$lastreadtime{$ressymb};
784: }
785: my $version = $$discussiondata{'version:'.$ressymb};
786: if ($version) {
787: my $hiddenflag = 0;
788: my $deletedflag = 0;
789: my ($hidden,$deleted);
790: for (my $id=$version; $id>0; $id--) {
791: my $vkeys=$$discussiondata{$id.':keys:'.$ressymb};
792: my @keys=split(/:/,$vkeys);
793: if (grep/^hidden$/,@keys) {
794: unless ($hiddenflag) {
795: $hidden = $$discussiondata{$id.':'.$ressymb.':hidden'};
796: $hiddenflag = 1;
797: }
1.38 raeburn 798: } elsif (grep/^deleted$/,@keys) {
1.37 raeburn 799: unless ($deletedflag) {
800: $deleted = $$discussiondata{$id.':'.$ressymb.':deleted'};
801: $deletedflag = 1;
802: }
1.39 raeburn 803: } else {
1.38 raeburn 804: unless (($hidden =~/\.$id\./) || ($deleted =~/\.$id\./)) {
805: if ($prevread <$$discussiondata{$id.':'.$ressymb.':timestamp'}) {
1.33 raeburn 806: $unreadcount ++;
1.37 raeburn 807: $$unread{$ressymb}{$unreadcount} = $id.': '.
808: $$discussiondata{$id.':'.$ressymb.':subject'};
1.33 raeburn 809: }
810: }
811: }
1.1 raeburn 812: }
1.37 raeburn 813: $$unread{$ressymb}{'unreadcount'} = $unreadcount;
1.33 raeburn 814: }
815: }
816:
1.37 raeburn 817:
1.33 raeburn 818: sub check_handgraded {
819: my ($resource,$symb,$title,$cdom,$cnum,$ungraded,$tograde) = @_;
820: if ($resource->is_problem()) {
821: my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
822: my $partlist=$resource->parts();
823: my $handgradeable;
824: foreach my $part (@$partlist) {
1.31 raeburn 825: if ($resource->handgrade($part) eq 'yes') {
1.33 raeburn 826: $handgradeable=1; last;
1.31 raeburn 827: }
1.33 raeburn 828: }
829: if ($handgradeable) {
1.35 raeburn 830: my @ungraded = &Apache::bridgetask::get_queue_symb_status(
1.33 raeburn 831: 'gradingqueue',$symb,$cdom,$cnum);
832: if (@ungraded > 0) {
833: $$ungraded{$symb}{count} = scalar(@ungraded);
834: $$ungraded{$symb}{title} = $title;
835: push(@{$tograde}, $symb);
1.11 raeburn 836: }
837: }
1.33 raeburn 838: }
839: }
840:
841: sub check_bombed {
842: my ($resource,$symb,$title,$bombs,$bombed) = @_;
843: if ($resource->getErrors()) {
844: my $errors = $resource->getErrors();
845: $errors =~ s/^,//;
846: my @bombs = split(/,/, $errors);
847: my $errorcount = scalar(@bombs);
848: my $errorlink = '<a href="/adm/email?display='.
849: &Apache::lonnet::escape($bombs[0]).'">'.
850: $title.'</a>';
851: $$bombed{$symb}{errorcount} = $errorcount;
852: $$bombed{$symb}{errorlink} = $errorlink;
853: push(@{$bombs}, $symb);
854: }
855: }
856:
857: sub check_thresholds {
858: my ($resource,$symb,$resourcetracker,$triggered,$threshold,$warnings,
859: $warningnum,$rowColor1,$rowColor2) = @_;
860: # Compile maxtries and degree of difficulty for problem parts, unless handgradeable
861: my @parts = @{$resource->parts()};
862: my %stats;
863: my %lastreset = ();
864: my $warning = 0;
865: my $rowColor;
866: foreach my $part (@parts) {
867: if ($resource->handgrade($part) eq 'yes') {
868: next;
869: }
870: %{$stats{$part}} = ();
871: my ($attempts,$users,$corrects,$degdiff,$av_attempts);
872: if (exists($$resourcetracker{$symb."\0".$part."\0attempts"})) {
873: $attempts = $$resourcetracker{$symb."\0".$part."\0attempts"};
874: }
875: if (exists($$resourcetracker{$symb."\0".$part."\0users"})) {
876: $users = $$resourcetracker{$symb."\0".$part."\0users"};
877: }
878: if (exists($$resourcetracker{$symb."\0".$part."\0correct"})) {
879: $corrects = $$resourcetracker{$symb."\0".$part."\0correct"};
880: }
881: if ($attempts > 0) {
882: $degdiff = 1 - ($corrects/$attempts);
883: $degdiff = sprintf("%.2f",$degdiff);
884: }
885: if ($users > 0) {
886: $av_attempts = $attempts/$users;
887: $av_attempts = sprintf("%.2f",$av_attempts);
888: }
889: if ((($degdiff ne '' && $degdiff >= $$threshold{'degdiff'}) || ($av_attempts ne '' && $av_attempts >= $$threshold{'av_attempts'})) && ($users >= $$threshold{'numstudents'})) {
890: $stats{$part}{degdiff} = $degdiff;
891: $stats{$part}{attempts} = $av_attempts;
892: $stats{$part}{users} = $users;
893: $lastreset{$part} = $$resourcetracker{$symb."\0".$part."\0resettime"};
894: if ($lastreset{$part}) {
895: $lastreset{$part} = &Apache::lonnavmaps::timeToHumanString($lastreset{$part});
1.11 raeburn 896: }
1.33 raeburn 897: $warning = 1;
898: }
899: }
900: if ($warning) {
1.35 raeburn 901: if ($warningnum %2 == 1) {
1.33 raeburn 902: $rowColor = $rowColor1;
903: } else {
904: $rowColor = $rowColor2;
905: }
906: $$triggered{$symb}{title} = $resource->title;
907: foreach my $part (@parts) {
908: if (exists($stats{$part}{users})) {
909: my $resetname = 'reset_'.&Apache::lonnet::escape($symb."\0".$part);
910: my $resettitle = 'title_'.&Apache::lonnet::escape($symb."\0".$part);
911: if ($$triggered{$symb}{numparts}) {
912: $$triggered{$symb}{text} .= '<tr bgcolor="'.$rowColor.'">'."\n";
913: }
914: if (@parts > 1) {
915: $$triggered{$symb}{text} .= '
916: <td align="right"><small>part - '.$part.'<small></td>';
917: } else {
1.11 raeburn 918: $$triggered{$symb}{text} .= '
1.33 raeburn 919: <td align="right"><small>single part</small></td>';
1.11 raeburn 920: }
1.33 raeburn 921: $$triggered{$symb}{text} .= '
922: <td align="right"><small>'.$stats{$part}{users}.'</small></td>
923: <td align="right"><small>'.$stats{$part}{attempts}.'</small></td>
924: <td align="right"><small>'.$stats{$part}{degdiff}.'</small></td>
925: <td align="right"><small>'.$lastreset{$part}.'</small></td>
926: <td align="right"><small><input type="checkbox" name="'.$resetname.'" /><input type="hidden" name="'.$resettitle.'" value="'.&Apache::lonnet::escape($$triggered{$symb}{title}).'" /></td>
927: </tr>';
928: $$triggered{$symb}{numparts} ++;
1.11 raeburn 929: }
930: }
1.33 raeburn 931: push(@{$warnings},$symb);
1.35 raeburn 932: $warningnum ++;
1.1 raeburn 933: }
934: }
935:
1.33 raeburn 936:
1.13 raeburn 937: sub get_curr_thresholds {
1.39 raeburn 938: my ($threshold,$uname,$udom,$cid,$cdom,$crs) = @_;
939: my %thresholdsettings = &Apache::lonnet::dump('nohist_whatsnew',$udom,
940: $uname,$cid.':threshold');
941: my $thresholdcount = 0;
942: my ($tmp) = %thresholdsettings;
1.40 raeburn 943: unless ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.39 raeburn 944: foreach my $item (keys %{$threshold}) {
945: if (exists($thresholdsettings{$cid.':threshold_'.$item})) {
946: $$threshold{$item} =
947: $thresholdsettings{$cid.':threshold_'.$item};
948: $thresholdcount ++;
949: }
950: }
1.13 raeburn 951: }
1.39 raeburn 952: if ($thresholdcount == 3) {
953: return;
1.13 raeburn 954: }
1.39 raeburn 955: my %coursesettings = &Apache::lonnet::dump('environment',
956: $cdom,$crs,'internal.threshold');
957: my ($temp) = %coursesettings;
1.40 raeburn 958: unless ($temp =~ /^(con_lost|error|no_such_host)/i) {
1.39 raeburn 959: foreach my $item (keys %{$threshold}) {
960: unless (exists($thresholdsettings{$cid.':threshold_'.$item})) {
961: if (exists($coursesettings{'internal.threshold_'.$item})) {
962: $$threshold{$item} =
963: $coursesettings{'internal.threshold_'.$item};
964: }
965: }
966: }
1.13 raeburn 967: }
1.39 raeburn 968: return;
1.13 raeburn 969: }
970:
1.39 raeburn 971: sub get_current {
972: my ($uname,$udom,$cid,$caller) = @_;
973: my $currvalue;
974: my %settings = &Apache::lonnet::dump('nohist_whatsnew',$udom,$uname,$cid.
975: ':'.$caller);
1.36 raeburn 976: my ($tmp) = %settings;
1.40 raeburn 977: unless ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.39 raeburn 978: $currvalue = $settings{$cid.':'.$caller};
1.36 raeburn 979: }
1.39 raeburn 980: return $currvalue;
1.36 raeburn 981: }
982:
1.13 raeburn 983: sub process_reset {
984: my ($dom,$crs) = @_;
1.39 raeburn 985: my $result = '<b>'.&mt('Counters reset for following problems (and parts):').
986: '</b><br />';
1.13 raeburn 987: my @agg_types = ('attempts','users','correct');
1.39 raeburn 988: my %agg_titles = &Apache::lonlocal::texthash (
1.13 raeburn 989: attempts => 'Number of submissions',
990: users => 'Students with submissions',
991: correct => 'Number of correct submissions',
992: );
993: my @resets = ();
994: my %titles = ();
1.17 albertel 995: foreach my $key (keys(%env)) {
1.13 raeburn 996: next if ($key !~ /^form\.reset_(.+)$/);
997: my $title = &Apache::lonnet::unescape($env{'form.title_'.$1});
998: my $reset_item = &Apache::lonnet::unescape($1);
999: my %curr_aggregates = &Apache::lonnet::dump('nohist_resourcetracker',$dom,$crs,$reset_item);
1000: my %aggregates = ();
1.17 albertel 1001: my ($symb,$part) = split(/\0/,$reset_item);
1.13 raeburn 1002: foreach my $type (@agg_types) {
1003: $aggregates{$reset_item."\0".$type} = 0;
1004: }
1.17 albertel 1005: $aggregates{$reset_item."\0".'resettime'} = time;
1.13 raeburn 1006: my $putresult = &Apache::lonnet::put('nohist_resourcetracker',\%aggregates,
1007: $dom,$crs);
1008: if ($putresult eq 'ok') {
1009: $result .= $title.' -part '.$part.': ';
1010: my %new_aggregates = &Apache::lonnet::dump('nohist_resourcetracker',$dom,$crs,$reset_item);
1011: foreach my $type (@agg_types) {
1012: $result .= $agg_titles{$type}.' = '.$new_aggregates{$reset_item."\0".$type}.'; ';
1013: }
1014: $result =~ s/; $//;
1015: $result .= '<br />';
1016: } else {
1.14 albertel 1017: $result = $title.' -part '.$part.': '.&mt('Unable to reset counters to zero due to [_1]',$putresult).'.<br />'."\n";
1.13 raeburn 1018: }
1019: }
1020: return $result;
1021: }
1022:
1023: sub process_update {
1.39 raeburn 1024: my ($uname,$udom,$threshold_titles) = @_;
1.15 raeburn 1025: my $setoutput = '<b>Changes to threshold(s) for problem tracking:</b><br />';
1.13 raeburn 1026: foreach (keys %env) {
1027: next if ($_!~/^form\.(.+)\_setparmval$/);
1028: my $name = $1;
1029: my $value = $env{'form.'.$name.'_value'};
1030: if ($name && defined($value)) {
1.39 raeburn 1031: my $put_result = &Apache::lonnet::put('nohist_whatsnew',
1032: {$name=>$value},$udom,$uname);
1.13 raeburn 1033:
1.39 raeburn 1034: my ($shortname) = ($name =~ /^\Q$env{'request.course.id'}\E:threshold_(.+)$/);
1.13 raeburn 1035: if ($put_result eq 'ok') {
1.14 albertel 1036: $setoutput.=&mt('Set threshold for [_1] to [_2]',
1037: '<b>'.$$threshold_titles{$shortname}.'</b>',
1038: '<b>'.$value.'</b>').'<br />';
1039: } else {
1040: $setoutput.=&mt('Unable to set threshold for [_1] to [_2] due to [_3].',
1041: '<b>'.$name.'</b>','<b>'.$value.'</b>',
1042: '<tt>'.$put_result.'</tt>').'<br />';
1.13 raeburn 1043: }
1044: }
1045: }
1046: return $setoutput;
1047: }
1048:
1.33 raeburn 1049: sub getnormalmail {
1050: my ($newmsgs) = @_;
1.1 raeburn 1051: # Check for unread mail in course
1052: my $msgcount = 0;
1.3 albertel 1053:
1.10 raeburn 1054: my @messages = sort(&Apache::lonnet::getkeys('nohist_email'));
1.3 albertel 1055: foreach my $message (@messages) {
1056: my $msgid=&Apache::lonnet::escape($message);
1.10 raeburn 1057: my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
1.1 raeburn 1058: &Apache::lonmsg::unpackmsgid($msgid);
1.10 raeburn 1059: if (($fromcid) && ($fromcid eq $env{'request.course.id'})) {
1.1 raeburn 1060: if (defined($sendtime) && $sendtime!~/error/) {
1061: my $numsendtime = $sendtime;
1062: $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
1063: if ($status eq 'new') {
1.10 raeburn 1064: $msgcount ++;
1065: if ($shortsubj eq '') {
1066: $shortsubj = &mt('No subject');
1067: }
1068: $shortsubj = &Apache::lonnet::unescape($shortsubj);
1.1 raeburn 1069: push(@{$newmsgs}, {
1070: msgid => $msgid,
1071: sendtime => $sendtime,
1.10 raeburn 1072: shortsub => $shortsubj,
1.1 raeburn 1073: from => $fromname,
1074: fromdom => $fromdom
1075: });
1076: }
1077: }
1078: }
1079: }
1.33 raeburn 1080: return $msgcount;
1081: }
1.1 raeburn 1082:
1.33 raeburn 1083: sub getcritmail {
1084: my ($critmsgs) = @_;
1.1 raeburn 1085: # Check for critical messages in course
1086: my %what=&Apache::lonnet::dump('critical');
1087: my $result = '';
1088: my $critmsgcount = 0;
1.3 albertel 1089: foreach my $msgid (sort(keys(%what))) {
1.10 raeburn 1090: my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
1091: &Apache::lonmsg::unpackmsgid($msgid);
1092: if (($fromcid) && ($fromcid eq $env{'request.course.id'})) {
1.1 raeburn 1093: if (defined($sendtime) && $sendtime!~/error/) {
1094: my $numsendtime = $sendtime;
1095: $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
1096: $critmsgcount ++;
1.10 raeburn 1097: if ($shortsubj eq '') {
1098: $shortsubj = &mt('No subject');
1099: }
1100: $shortsubj = &Apache::lonnet::unescape($shortsubj);
1.1 raeburn 1101: push(@{$critmsgs}, {
1102: msgid => $msgid,
1103: sendtime => $sendtime,
1.10 raeburn 1104: shortsub => $shortsubj,
1.1 raeburn 1105: from => $fromname,
1106: fromdom => $fromdom
1107: });
1108: }
1109: }
1110: }
1.33 raeburn 1111: return $critmsgcount;
1112: }
1113:
1114:
1115: sub checkversions {
1116: my ($cdom,$crs,$navmap,$changed,$starttime) = @_;
1117: my %changes=&Apache::lonnet::dump('versionupdate',$cdom,$crs);
1118: my ($tmp) = keys(%changes);
1.40 raeburn 1119: unless ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.33 raeburn 1120: if (keys(%changes) > 0) {
1121: foreach my $key (sort(keys(%changes))) {
1122: if ($changes{$key} > $starttime) {
1123: my $version;
1124: my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
1125: my $currentversion=&Apache::lonnet::getversion($key);
1126: my $revdate =
1127: &Apache::lonnet::metadata($root.'.'.$extension,
1128: 'lastrevisiondate');
1129: $revdate = &Apache::lonlocal::locallocaltime($revdate);
1130: my $linkurl=&Apache::lonnet::clutter($key);
1131: my $usedversion=$navmap->usedVersion('version_'.$linkurl);
1132: my @resources = $navmap->getResourceByUrl($linkurl,1);
1133: if (($usedversion) && ($usedversion ne 'mostrecent')) {
1134: $version = $usedversion;
1135: } else {
1136: $version = $currentversion;
1137: }
1138: foreach my $res (@resources) {
1.35 raeburn 1139: if (ref($res) eq 'Apache::lonnavmaps::resource') {
1140: my $symb = $res->symb();
1141: %{$$changed{$symb}} = (
1.33 raeburn 1142: current => $currentversion,
1143: version => $version,
1144: revdate => $revdate,
1.35 raeburn 1145: );
1146: }
1.33 raeburn 1147: }
1148: }
1149: }
1150: }
1151: }
1152: return;
1153: }
1154:
1155: sub display_handgrade {
1156: my ($r,$tograde,$rowColor1,$rowColor2,$ungraded) = @_;
1157: my $rowColor;
1158: my %lt = &Apache::lonlocal::texthash(
1159: 'prna' => 'Problem Name',
1160: 'nmun' => 'Number ungraded',
1161: 'nopr' => 'No problems require handgrading',
1162: );
1163: if (@{$tograde} > 0) {
1164: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.$lt{'prna'}.'</small></b></td><td align="right"><b><small>'.$lt{'nmun'}.'</small></b></td></tr>');
1165: my $rowNum = 0;
1166: foreach my $res (@{$tograde}) {
1167: if ($rowNum %2 == 1) {
1168: $rowColor = $rowColor1;
1169: } else {
1170: $rowColor = $rowColor2;
1171: }
1172: my ($map,$id,$url)=&Apache::lonnet::decode_symb($res);
1173: my $linkurl=&Apache::lonnet::clutter($url);
1174: $linkurl .= '?symb='.&Apache::lonnet::escape($res);
1175:
1176: $r->print('<tr bgcolor="'.$rowColor.'"><td><a href="'.$linkurl.'"><small>'.$$ungraded{$res}{title}.'</small></a></td><td align="right"><small>'.$$ungraded{$res}{count}.'</small></td></tr>');
1177: $rowNum ++;
1178: }
1179: } else {
1180: $r->print('<tr><td bgcolor="#ffffff"><br><center><i><b><small> '.$lt{'nopr'}.' </small><br><br></b></i></td></tr>');
1181: }
1182: }
1183:
1184: sub display_haserrors {
1185: my ($r,$bombs,$rowColor1,$rowColor2,$bombed,$res_title) = @_;
1186: my $bombnum = 0;
1187: my $rowColor;
1188: my %lt = &Apache::lonlocal::texthash(
1189: reso => 'Resource',
1190: nmer => 'Number of errors',
1191: noer => 'No problems with errors',
1192: );
1193: if (@{$bombs} > 0) {
1194: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.$lt{'reso'}.'</small></b></td><td align="right"><b><small>'.$lt{'nmer'}.'</small></b></td></tr>');
1195: @{$bombs} = sort { &cmp_title($a,$b,$res_title) } @{$bombs};
1196: foreach my $bomb (@{$bombs}) {
1197: if ($bombnum %2 == 1) {
1198: $rowColor = $rowColor1;
1199: } else {
1200: $rowColor = $rowColor2;
1201: }
1202: $r->print('<tr bgcolor="'.$rowColor.'"><td><small>'.$$bombed{$bomb}{errorlink}.'</small></td><td align="right"><small>'.$$bombed{$bomb}{errorcount}.'</small></td></tr>');
1203: $bombnum ++;
1204: }
1205: } else {
1206: $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>'.$lt{'noer'}.'</small></i></b></center><br /></td></tr>');
1207: }
1208: return;
1209: }
1210:
1211: sub display_abovethreshold {
1.39 raeburn 1212: my ($r,$refpage,$warnings,$triggered,$res_title,$rowColor1,$rowColor2) = @_;
1.33 raeburn 1213: my %lt = &Apache::lonlocal::texthash(
1214: reso => 'Resource',
1215: part => 'Part',
1216: nust => 'Num. students',
1217: avat => 'Av. Attempts',
1218: dedi => 'Deg. Diff',
1219: lare => 'Last Reset',
1220: reco => 'Reset Count?',
1221: rese => 'Reset counters to 0',
1222: nopr => 'No problems satisfy threshold criteria',
1223: );
1224: my $rowColor;
1225: my $warningnum = 0;
1226: if (@{$warnings} > 0) {
1227: @{$warnings} = sort { &cmp_title($a,$b,$res_title) } @{$warnings};
1.36 raeburn 1228: $r->print('<form name="reset_tracking" method="post" action="/adm/whatsnew">'.
1.39 raeburn 1229: ' <input type="hidden" name="command" value="reset" />'."\n".
1230: ' <input type="hidden" name="refpage" value="'.$refpage.'" />'.
1231: "\n");
1.33 raeburn 1232: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.$lt{'reso'}.'</small></b></td><td align="right"><b><small>'.$lt{'part'}.'</small></b></td><td align="right"><b><small>'.$lt{'nust'}.'</small></b></td><td align="right"><b><small>'.$lt{'avat'}.'</small></b></td><td align="right"><b><small>'.$lt{'dedi'}.'</small></b></td><td align="right"><b><small>'.$lt{'lare'}.'</small></b></td><td align="right"><b><small>'.$lt{'reco'}.'</small></b></td></tr>');
1233: foreach my $res (@{$warnings}) {
1234: if ($warningnum %2 == 1) {
1235: $rowColor = $rowColor1;
1236: } else {
1237: $rowColor = $rowColor2;
1238: }
1239: my ($map,$id,$url)=&Apache::lonnet::decode_symb($res);
1240: my $linkurl=&Apache::lonnet::clutter($url);
1241: my $rowspan;
1242: if ($$triggered{$res}{numparts} > 1) {
1243: $rowspan = 'rowspan="'.$$triggered{$res}{numparts}.'"';
1244: }
1245: $linkurl .= '?symb='.&Apache::lonnet::escape($res);
1246: $r->print('<tr bgcolor="'.$rowColor.'"><td '.$rowspan.'><a href="'.$linkurl.'"><small>'.$$triggered{$res}{title}.'</small></a></td>'.$$triggered{$res}{text});
1247: $warningnum ++;
1248: }
1.35 raeburn 1249: $r->print('<tr bgcolor="#cccccc"><td colspan="7" align="right"><br /><b><small><input type="submit" name="counters" value="'.$lt{'rese'}.'" /></form>');
1.33 raeburn 1250: } else {
1251: $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>'.$lt{'nopr'}.'</small></i></b></center><br /></td></tr>');
1252: }
1253: }
1254:
1255: sub display_versionchanges {
1256: my ($r,$changed,$res_title,$rowColor1,$rowColor2,$interval) = @_;
1257: my %lt = &Apache::lonlocal::texthash(
1258: 'reso' => 'Resource',
1259: 'revd' => 'Last revised',
1260: 'newv' => 'New version',
1261: 'veru' => 'Version used',
1262: 'noup' => 'No updated versions',
1263: );
1264: my $rowColor;
1265: if (keys(%{$changed}) > 0) {
1266: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.$lt{'reso'}.'</small></b></td><td><b><small>'.$lt{'revd'}.'</small></b></td><td><b><small>'.$lt{'newv'}.'</small></b></td><td><b><small>'.$lt{'veru'}.'</small></b></td></tr>');
1267:
1268:
1269: my @changes = sort { &cmp_title($a,$b,$res_title) } keys(%{$changed});
1270: my $changenum = 0;
1271: foreach my $item (@changes) {
1272: if ($changenum %2 == 1) {
1273: $rowColor = $rowColor1;
1274: } else {
1275: $rowColor = $rowColor2;
1276: }
1277: my ($map,$id,$url)=&Apache::lonnet::decode_symb($item);
1278: my $linkurl=&Apache::lonnet::clutter($url);
1279: $linkurl .= '?symb='.&Apache::lonnet::escape($item);
1280:
1281: $r->print('<tr bgcolor="'.$rowColor.'"><td><small><a href="'.$linkurl.'">'.$$res_title{$item}.'</a></small></td><td><small>'.$$changed{$item}{'revdate'}.'</small></td><td><small>'.$$changed{$item}{'current'}.'</small></td><td><small>'.$$changed{$item}{'version'}.'</small></td></tr>');
1282: $changenum ++;
1283: }
1284: } else {
1285: $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>'.$lt{'noup'}.' '.$interval.'</small></i></b></center><br /></td></tr>');
1286: }
1287: return;
1288: }
1289:
1290: sub display_coursediscussion {
1.37 raeburn 1291: my ($r,$newdiscussions,$unread,$countunread,$res_title,$rowColor1,
1292: $rowColor2) = @_;
1.33 raeburn 1293: my %lt = &Apache::lonlocal::texthash(
1294: 'loca' => 'Location',
1295: 'type' => 'Type',
1296: 'numn' => 'Number of new posts',
1297: 'noun' => 'No unread posts in course discussions',
1.37 raeburn 1298: 'tmlp' => 'Time of last post',
1.33 raeburn 1299: );
1300: my $rowColor;
1301: if (@{$newdiscussions} > 0) {
1302: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.$lt{'loca'}.
1303: '</small></b></td><td><b><small>'.$lt{'type'}.
1.37 raeburn 1304: '</small></b>');
1.39 raeburn 1305: if ($countunread eq 'on') {
1.37 raeburn 1306: $r->print('<td><b><small>'.$lt{'tmlp'}.'</small></b></td>'.
1307: '<td align="right"><b><small>'.$lt{'numn'}.
1308: '</small></b></td>');
1309: } else {
1310: $r->print('<td align="right"><b><small>'.$lt{'tmlp'}.
1311: '</small></b></td>');
1312: }
1313: $r->print("</tr>\n");
1.33 raeburn 1314: @{$newdiscussions} = sort { &cmp_title($a,$b,$res_title) }
1315: @{$newdiscussions};
1316: my $rowNum = 0;
1317: foreach my $ressymb (@{$newdiscussions}) {
1318: my $forum_title = $$unread{$ressymb}{'title'};
1319: my $type = 'Resource';
1320: my $feedurl=&Apache::lonfeedback::get_feedurl($ressymb);
1321: if ($feedurl =~ /bulletinboard/) {
1322: $type = 'Bulletin Board';
1323: }
1.37 raeburn 1324: if ($rowNum %2 == 1) {
1325: $rowColor = $rowColor1;
1326: } else {
1327: $rowColor = $rowColor2;
1328: }
1329: my $lastpost = &Apache::lonnavmaps::timeToHumanString(
1330: $$unread{$ressymb}{'lastpost'});
1331: $r->print('<tr bgcolor="'.$rowColor.'"><td><small><a href="'.$feedurl.'?symb='.$$unread{$ressymb}{symb}.'">'.$forum_title.'</a> </td><td><small>'.$type.' </small></td>');
1.39 raeburn 1332: if ($countunread eq 'on') {
1.37 raeburn 1333: my $unreadnum = $$unread{$ressymb}{'unreadcount'};
1334: $r->print('<td><small>'.$lastpost.'<small></td><td align="right">'.
1335: '<small>',$unreadnum.' </small></td>');
1336: } else {
1337: $r->print('<td align="right"><small>'.$lastpost.'</small></td>');
1.33 raeburn 1338: }
1.37 raeburn 1339: $r->print("</tr>\n");
1340: $rowNum ++;
1.33 raeburn 1341: }
1342: } else {
1343: $r->print('<tr><td bgcolor="#ffffff"><br><center> <i><b><small>'.
1344: $lt{'noun'}.'</small></b></i><br><br></td></tr>');
1345: }
1346: }
1347:
1348: sub display_coursenormalmail {
1349: my ($r,$msgcount,$newmsgs,$rowColor1,$rowColor2) = @_;
1350: my $rowColor;
1351: if ($msgcount > 0) {
1352: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.&mt('Number').'</small></b></td><td><b><small>'.&mt('Subject').'</small></b></td><td><b><small>'.&mt('Sender').'</small></b></td><td><b><small>'.&mt('Date/Time').'</small></b></td></tr>');
1353: my $rowNum = 0;
1354: my $mailcount = 1;
1355: foreach my $msg (@{$newmsgs}) {
1356: if ($rowNum %2 == 1) {
1357: $rowColor = $rowColor1;
1358: } else {
1359: $rowColor = $rowColor2;
1360: }
1361: $r->print('<tr bgcolor="'.$rowColor.'"><td valign="top"><small>'.$mailcount.'. </small></td><td valign="top"><small><a href="/adm/communicate">'.$msg->{'shortsub'}.'</a> </small></td><td valign="top"><small> '.$msg->{'from'}.'@'.$msg->{'fromdom'}.' </small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');
1362: $rowNum ++;
1363: $mailcount ++;
1364: }
1365: } else {
1366: $r->print('<tr><td bgcolor="#ffffff" width="100%"><center><br /><b><i><small>'.&mt('No new course messages').'</small></i></b><br /><br /></center></td></tr>');
1367: }
1368: }
1369:
1370: sub display_coursecritmail {
1371: my ($r,$critmsgcount,$critmsgs,$rowColor1,$rowColor2) = @_;
1372: my $rowColor;
1373: if ($critmsgcount > 0) {
1374: $r->print('<tr bgcolor="#cccccc"><td><b><small>'.&mt('Number').'</small></b></td><td><b><small>'.&mt('Subject').'</small></b></td><td><b><small>'.&mt('Sender').'</small></b></td><td><b><small>'.&mt('Date/Time').'</small></b></td></tr>');
1375: my $rowNum = 0;
1376: my $mailcount = 1;
1377: foreach my $msg (@{$critmsgs}) {
1378: if ($rowNum %2 == 1) {
1379: $rowColor = $rowColor1;
1380: } else {
1381: $rowColor = $rowColor2;
1382: }
1383: $r->print('<tr bgcolor="'.$rowColor.'"><td valign="top"><small>'.$mailcount.'. <small></td><td valign="top"><small><a href="/adm/email?folder=critical">'.$msg->{'shortsub'}.'</a> </small></td><td valign="top"><small> '.$msg->{'from'}.'@'.$msg->{'fromdom'}.' </small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');
1384: $rowNum ++;
1385: $mailcount ++;
1386: }
1387: } else {
1388: $r->print('<tr><td bgcolor="#ffffff" width="100%"><center><br /><b><i><small>'.&mt('No unread critical messages in course').'</small></i></b><br /><br /></center></td></tr>');
1389: }
1.1 raeburn 1390: }
1391:
1392: sub cmp_title {
1.16 raeburn 1393: my ($a,$b,$res_title) = @_;
1394: my ($atitle,$btitle) = (lc($$res_title{$a}),lc($$res_title{$b}));
1.1 raeburn 1395: $atitle=~s/^\s*//;
1396: $btitle=~s/^\s*//;
1397: return $atitle cmp $btitle;
1398: }
1399:
1.33 raeburn 1400: sub get_display_settings {
1.36 raeburn 1401: my ($uname,$udom,$cid) = @_;
1.33 raeburn 1402: my %settings = &Apache::lonnet::dump('nohist_whatsnew',$udom,$uname,$cid);
1403: my ($tmp) = keys(%settings);
1.40 raeburn 1404: if ($tmp=~ /^(con_lost|error|no_such_host)/i) {
1.33 raeburn 1405: %settings = ();
1.41 raeburn 1406: unless ($tmp =~ /^error: 2 /) {
1407: &Apache::lonnet::logthis('Error retrieving whatsnew settings: '.
1408: $tmp.' for '.$uname.':'.$udom.' for course: '.$cid);
1.33 raeburn 1409: }
1410: }
1411: return %settings;
1412: }
1413:
1.36 raeburn 1414: sub store_display_settings {
1415: my ($uname,$udom,$cid,$checkallowed) = @_;
1416: my %whatsnew_settings;
1417: my $result;
1418: foreach my $key (keys(%{$checkallowed})) {
1419: if (exists($env{'form.display_'.$key})) {
1420: unless ($env{'form.display_'.$key} eq '') {
1421: $whatsnew_settings{$cid.':'.$key} = $env{'form.display_'.$key};
1422: }
1423: }
1424: }
1425: if (keys(%whatsnew_settings)) {
1426: $result = &Apache::lonnet::put('nohist_whatsnew',\%whatsnew_settings,
1427: $udom,$uname);
1428: } else {
1429: $result = 'ok';
1430: }
1431: return $result;
1432: }
1433:
1434: sub store_interval_setting {
1435: my ($uname,$udom,$cid,$interval_titles) = @_;
1436: my %interval_settings = ();
1437: my $result;
1438: if (defined($env{'form.interval'})) {
1439: $interval_settings{$cid.':interval'} = $env{'form.interval'};
1440: my $outcome = &Apache::lonnet::put('nohist_whatsnew',
1441: \%interval_settings,$udom,$uname);
1442: if ($outcome eq 'ok') {
1443: $result = &mt('Interval set to version changes [_1]',
1444: '<b>'.$$interval_titles{$env{'form.interval'}}.'</b><br />');
1445:
1446: } else {
1447: &Apache::lonnet::logthis('Error storing whatsnew interval setting'.
1448: ' '.$outcome.' for '.$uname.':'.$udom.' in course '.$cid);
1449: $result = &mt('Unable to set interval to [_1] due to [_2].',
1450: '<b>'.$$interval_titles{$env{'form.interval'}}.'</b>',
1451: '<tt>'.$outcome.'</tt>.<br />');
1452: }
1453: }
1454: return $result;
1455: }
1456:
1.39 raeburn 1457: sub store_discussion_setting {
1458: my ($uname,$udom,$cid) = @_;
1459: my %discussion_settings;
1460: my $result;
1461: if (defined($env{'form.countunread'})) {
1462: $discussion_settings{$cid.':countunread'} = $env{'form.countunread'};
1463: my $outcome = &Apache::lonnet::put('nohist_whatsnew',
1464: \%discussion_settings,$udom,$uname);
1465: if ($outcome eq 'ok') {
1466: $result = &mt('Count unread posts in discussions display set to [_1]',
1467: '<b>'.$env{'form.countunread'}.'</b><br />');
1468:
1469: } else {
1470: &Apache::lonnet::logthis('Error storing whatsnew countunread setting'.
1471: ' '.$outcome.' for '.$uname.':'.$udom.' in course '.$cid);
1472: $result = &mt('Unable to set "number unread posts display" to [_1]'.
1473: ' due to [_2].',
1474: '<b>'.$env{'form.countunread'}.'</b>',
1475: '<tt>'.$outcome.'</tt>.<br />');
1476: }
1477: }
1478: return $result;
1479: }
1480:
1481: sub store_courseinit_setting {
1482: my ($uname,$udom,$cid,$initpage) = @_;
1483: my %courseinit_settings;
1484: my $page_control;
1485: my $result;
1486: if (defined($env{'form.courseinit_control'})) {
1487: if ($env{'form.courseinit_control'} eq 'userpref') {
1488: $courseinit_settings{$cid.':courseinit'} = '';
1489: $page_control = 'global preferences';
1490: } else {
1491: if (defined($env{'form.courseinit_page'})) {
1492: $courseinit_settings{$cid.':courseinit'} =
1493: $env{'form.courseinit_page'};
1494: $page_control = 'course specific setting';
1495: }
1496: }
1497: if ($page_control) {
1498: my $outcome = &Apache::lonnet::put('nohist_whatsnew',
1499: \%courseinit_settings,$udom,$uname);
1500: if ($outcome eq 'ok') {
1501: if ($page_control eq 'global preferences') {
1502: $result = &mt('Page displayed after role selection in course now set by [_1]',"<b>user's global preferences</b>.");
1503: } else {
1504: $result = &mt('Page displayed after role selection in this course set to [_1]','<b>'.$$initpage{$env{'form.courseinit_page'}}.'</b>.');
1505: }
1506: } else {
1507: &Apache::lonnet::logthis('Error storing whatsnew courseinit '.
1508: 'setting: '.$outcome.' for '.$uname.
1509: ':'.$udom.' in course '.$cid);
1510: if ($page_control eq 'global preferences') {
1511: $result = &mt('Unable to set control of page display to [_1]'.
1512: ' due to [_2].',
1513: '<b>'.$page_control.'</b>',
1514: '<tt>'.$outcome.'</tt>.<br />');
1515: } else {
1516: $result = &mt('Unable to set page display, after role selection, for this course to [_1] due to [_2].',
1517: '<b>'.$$initpage{$env{'form.courseinit_page'}}.'</b>',
1518: '<tt>'.$outcome.'</tt>.<br />');
1519: }
1520: }
1521: }
1522: }
1523: return $result;
1524: }
1525:
1.33 raeburn 1526: sub start_box {
1.39 raeburn 1527: my ($r,$tabbg,$show,$heading,$caller,$refpage) = @_;
1.33 raeburn 1528: my %lt = &Apache::lonlocal::texthash(
1529: chth => 'Change thresholds?',
1530: chin => 'Change interval?',
1.39 raeburn 1531: chop => 'Change options?',
1.33 raeburn 1532: );
1533: my $showhide;
1534: if ($$show{$caller}) {
1.36 raeburn 1535: $showhide = '<b><a href="javascript:change_display(document.visible.'.
1536: 'display_'.$caller.",'hide'".');">Hide</a></b>';
1.33 raeburn 1537:
1538: } else {
1.36 raeburn 1539: $showhide = '<b><a href="javascript:change_display(document.visible.'.
1540: 'display_'.$caller.",'show'".');">Show</a></b>';
1.33 raeburn 1541: }
1542:
1543: $r->print('
1544: <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">
1545: <tr>
1546: <td>
1547: <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">
1548: <tr>
1549: <td bgcolor="'.$tabbg.'">
1550: <table width="100%" border="0" cellspacing="0" cellpadding="0">
1551: <tr>
1552: <td><b>'.$$heading{$caller}.'</b></td>
1553: <td valign="top" align="right">'.$showhide.'</td>
1554: </tr>
1555: </table>
1556: </td>
1557: </tr>');
1558: if (($caller eq 'abovethreshold') && ($$show{$caller})) {
1.40 raeburn 1559: if ($$show{$caller}) {
1560: $r->print('
1.33 raeburn 1561: <tr>
1.39 raeburn 1562: <td bgcolor="'.$tabbg.'" align="right"><a href="/adm/whatsnew?command=chgthreshold&refpage='.$refpage.'"><b><small>'.$lt{'chth'}.'</small></b></a></td>
1.33 raeburn 1563: </tr>');
1.40 raeburn 1564: }
1.33 raeburn 1565: } elsif (($caller eq 'versionchanges') && ($$show{$caller})) {
1.40 raeburn 1566: if ($$show{$caller}) {
1567: $r->print('
1.33 raeburn 1568: <tr>
1.39 raeburn 1569: <td bgcolor="'.$tabbg.'" align="right"><a href="/adm/whatsnew?command=chginterval&refpage='.$refpage.'"><b><small>'.$lt{'chin'}.'</small></b></a></td>
1570: </tr>');
1.40 raeburn 1571: }
1.39 raeburn 1572: } elsif ($caller eq 'coursediscussion') {
1.40 raeburn 1573: if ($$show{$caller}) {
1574: $r->print('
1.39 raeburn 1575: <tr>
1576: <td bgcolor="'.$tabbg.'" align="right"><a href="/adm/whatsnew?command=chgdisc&refpage='.$refpage.'"><b><small>'.$lt{'chop'}.'</small></b></a></td>
1.33 raeburn 1577: </tr>');
1.40 raeburn 1578: }
1.33 raeburn 1579: }
1580: $r->print('
1581: <tr>
1582: <td bgcolor="#ffffff">
1583: <table cellpadding="2" cellspacing="0" border="0" width="100%">
1584: ');
1585: return;
1586: }
1587:
1588: sub end_box {
1589: my ($r) = shift;
1590: $r->print('
1591: </table>
1592: </td>
1593: </tr>
1594: </table>
1595: </td>
1596: </tr>
1597: </table><br />');
1598: return;
1599: }
1600:
1.7 raeburn 1601: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>