![]() ![]() | ![]() |
&comprep was removed, need to call &compout
1: # The LearningOnline Network with CAPA 2: # Routines for messaging 3: # 4: # $Id: lonmsg.pm,v 1.93 2004/03/26 16:57:53 www Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: # 28: 29: 30: package Apache::lonmsg; 31: 32: =pod 33: 34: =head1 NAME 35: 36: Apache::lonmsg: supports internal messaging 37: 38: =head1 SYNOPSIS 39: 40: lonmsg provides routines for sending messages, receiving messages, and 41: a handler to allow users to read, send, and delete messages. 42: 43: =head1 OVERVIEW 44: 45: =head2 Messaging Overview 46: 47: X<messages>LON-CAPA provides an internal messaging system similar to 48: email, but customized for LON-CAPA's usage. LON-CAPA implements its 49: own messaging system, rather then building on top of email, because of 50: the features LON-CAPA messages can offer that conventional e-mail can 51: not: 52: 53: =over 4 54: 55: =item * B<Critical messages>: A message the recipient B<must> 56: acknowlegde receipt of before they are allowed to continue using the 57: system, preventing a user from claiming they never got a message 58: 59: =item * B<Receipts>: LON-CAPA can reliably send reciepts informing the 60: sender that it has been read; again, useful for preventing students 61: from claiming they did not see a message. (While conventional e-mail 62: has some reciept support, it's sporadic, e-mail client-specific, and 63: generally the receiver can opt to not send one, making it useless in 64: this case.) 65: 66: =item * B<Context>: LON-CAPA knows about the sender, such as where 67: they are in a course. When a student mails an instructor asking for 68: help on the problem, the instructor receives not just the student's 69: question, but all submissions the student has made up to that point, 70: the user's rendering of the problem, and the complete view the student 71: saw of the resource, including discussion up to that point. Finally, 72: the instructor is reading all of this inside of LON-CAPA, not their 73: email program, so they have full access to LON-CAPA's grading 74: interface, or other features they may wish to use in response to the 75: student's query. 76: 77: =back 78: 79: Users can ask LON-CAPA to forward messages to conventional e-mail 80: addresses on their B<PREF> screen, but generally, LON-CAPA messages 81: are much more useful then traditional email can be made to be, even 82: with HTML support. 83: 84: Right now, this document will cover just how to send a message, since 85: it is likely you will not need to programmatically read messages, 86: since lonmsg already implements that functionality. 87: 88: =head1 FUNCTIONS 89: 90: =over 4 91: 92: =cut 93: 94: use strict; 95: use Apache::lonnet(); 96: use vars qw($msgcount); 97: use HTML::TokeParser(); 98: use Apache::Constants qw(:common); 99: use Apache::loncommon(); 100: use Apache::lontexconvert(); 101: use HTML::Entities(); 102: use Mail::Send; 103: use Apache::lonlocal; 104: 105: # Querystring component with sorting type 106: my $sqs; 107: 108: # ===================================================================== Package 109: 110: sub packagemsg { 111: my ($subject,$message,$citation,$baseurl,$attachmenturl)=@_; 112: $message =&HTML::Entities::encode($message); 113: $citation=&HTML::Entities::encode($citation); 114: $subject =&HTML::Entities::encode($subject); 115: #remove machine specification 116: $baseurl =~ s|^http://[^/]+/|/|; 117: $baseurl =&HTML::Entities::encode($baseurl); 118: #remove machine specification 119: $attachmenturl =~ s|^http://[^/]+/|/|; 120: $attachmenturl =&HTML::Entities::encode($attachmenturl); 121: 122: my $now=time; 123: $msgcount++; 124: my $partsubj=$subject; 125: $partsubj=&Apache::lonnet::escape($partsubj); 126: my $msgid=&Apache::lonnet::escape( 127: $now.':'.$partsubj.':'.$ENV{'user.name'}.':'. 128: $ENV{'user.domain'}.':'.$msgcount.':'.$$); 129: my $result='<sendername>'.$ENV{'user.name'}.'</sendername>'. 130: '<senderdomain>'.$ENV{'user.domain'}.'</senderdomain>'. 131: '<subject>'.$subject.'</subject>'. 132: '<time>'.&Apache::lonlocal::locallocaltime($now).'</time>'. 133: '<servername>'.$ENV{'SERVER_NAME'}.'</servername>'. 134: '<host>'.$ENV{'HTTP_HOST'}.'</host>'. 135: '<client>'.$ENV{'REMOTE_ADDR'}.'</client>'. 136: '<browsertype>'.$ENV{'browser.type'}.'</browsertype>'. 137: '<browseros>'.$ENV{'browser.os'}.'</browseros>'. 138: '<browserversion>'.$ENV{'browser.version'}.'</browserversion>'. 139: '<browsermathml>'.$ENV{'browser.mathml'}.'</browsermathml>'. 140: '<browserraw>'.$ENV{'HTTP_USER_AGENT'}.'</browserraw>'. 141: '<courseid>'.$ENV{'request.course.id'}.'</courseid>'. 142: '<coursesec>'.$ENV{'request.course.sec'}.'</coursesec>'. 143: '<role>'.$ENV{'request.role'}.'</role>'. 144: '<resource>'.$ENV{'request.filename'}.'</resource>'. 145: '<msgid>'.$msgid.'</msgid>'. 146: '<message>'.$message.'</message>'; 147: if (defined($citation)) { 148: $result.='<citation>'.$citation.'</citation>'; 149: } 150: if (defined($baseurl)) { 151: $result.= '<baseurl>'.$baseurl.'</baseurl>'; 152: } 153: if (defined($attachmenturl)) { 154: $result.= '<attachmenturl>'.$attachmenturl.'</attachmenturl>'; 155: } 156: return $msgid,$result; 157: } 158: 159: # ================================================== Unpack message into a hash 160: 161: sub unpackagemsg { 162: my ($message,$notoken)=@_; 163: my %content=(); 164: my $parser=HTML::TokeParser->new(\$message); 165: my $token; 166: while ($token=$parser->get_token) { 167: if ($token->[0] eq 'S') { 168: my $entry=$token->[1]; 169: my $value=$parser->get_text('/'.$entry); 170: $content{$entry}=$value; 171: } 172: } 173: if ($content{'attachmenturl'}) { 174: my ($fname,$ft)=($content{'attachmenturl'}=~/\/(\w+)\.(\w+)$/); 175: if ($notoken) { 176: $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'.'.$ft.'</tt>'; 177: } else { 178: $content{'message'}.='<p>'.&mt('Attachment').': <a href="'. 179: &Apache::lonnet::tokenwrapper($content{'attachmenturl'}). 180: '"><tt>'.$fname.'.'.$ft.'</tt></a>'; 181: } 182: } 183: return %content; 184: } 185: 186: # ======================================================= Get info out of msgid 187: 188: sub unpackmsgid { 189: my $msgid=&Apache::lonnet::unescape(shift); 190: my ($sendtime,$shortsubj,$fromname,$fromdomain)=split(/\:/, 191: &Apache::lonnet::unescape($msgid)); 192: my %status=&Apache::lonnet::get('email_status',[$msgid]); 193: if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; } 194: unless ($status{$msgid}) { $status{$msgid}='new'; } 195: return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid}); 196: } 197: 198: 199: sub sendemail { 200: my ($to,$subject,$body)=@_; 201: $body= 202: "*** ".&mt('This is an automatic message generated by the LON-CAPA system.')."\n". 203: "*** ".&mt('Please do not reply to this address.')."\n\n".$body; 204: my $msg = new Mail::Send; 205: $msg->to($to); 206: $msg->subject('[LON-CAPA] '.$subject); 207: if (my $fh = $msg->open('smtp',Server => 'localhost')) { 208: print $fh $body; 209: $fh->close; 210: } 211: } 212: 213: # ==================================================== Send notification emails 214: 215: sub sendnotification { 216: my ($to,$touname,$toudom,$subj,$crit)=@_; 217: my $sender=$ENV{'environment.firstname'}.' '.$ENV{'environment.lastname'}; 218: my $critical=($crit?' critical':''); 219: my $url='http://'. 220: $Apache::lonnet::hostname{&Apache::lonnet::homeserver($touname,$toudom)}. 221: '/adm/email?username='.$touname.'&domain='.$toudom; 222: my $body=(<<ENDMSG); 223: You received a$critical message from $sender in LON-CAPA. The subject is 224: 225: $subj 226: 227: Use 228: 229: $url 230: 231: to access this message. 232: ENDMSG 233: &sendemail($to,'New'.$critical.' message from '.$sender,$body); 234: } 235: # ============================================================= Check for email 236: 237: sub newmail { 238: if ((time-$ENV{'user.mailcheck.time'})>300) { 239: my %what=&Apache::lonnet::get('email_status',['recnewemail']); 240: &Apache::lonnet::appenv('user.mailcheck.time'=>time); 241: if ($what{'recnewemail'}>0) { return 1; } 242: } 243: return 0; 244: } 245: 246: # =============================== Automated message to the author of a resource 247: 248: =pod 249: 250: =item * B<author_res_msg($filename, $message)>: Sends message $message to the owner 251: of the resource with the URI $filename. 252: 253: =cut 254: 255: sub author_res_msg { 256: my ($filename,$message)=@_; 257: unless ($message) { return 'empty'; } 258: $filename=&Apache::lonnet::declutter($filename); 259: my ($domain,$author,@dummy)=split(/\//,$filename); 260: my $homeserver=&Apache::lonnet::homeserver($author,$domain); 261: if ($homeserver ne 'no_host') { 262: my $id=unpack("%32C*",$message); 263: my $msgid; 264: ($msgid,$message)=&packagemsg($filename,$message); 265: return &Apache::lonnet::reply('put:'.$domain.':'.$author. 266: ':nohist_res_msgs:'. 267: &Apache::lonnet::escape($filename.'_'.$id).'='. 268: &Apache::lonnet::escape($message),$homeserver); 269: } 270: return 'no_host'; 271: } 272: 273: # =========================================== Retrieve author resource messages 274: 275: sub retrieve_author_res_msg { 276: my $url=shift; 277: $url=&Apache::lonnet::declutter($url); 278: my ($domain,$author)=($url=~/^(\w+)\/(\w+)\//); 279: my %errormsgs=&Apache::lonnet::dump('nohist_res_msgs',$domain,$author); 280: my $msgs=''; 281: foreach (keys %errormsgs) { 282: if ($_=~/^\Q$url\E\_\d+$/) { 283: my %content=&unpackagemsg($errormsgs{$_}); 284: $msgs.='<p><img src="/adm/lonMisc/bomb.gif" /><b>'. 285: $content{'time'}.'</b>: '.$content{'message'}. 286: '<br /></p>'; 287: } 288: } 289: return $msgs; 290: } 291: 292: 293: # =============================== Delete all author messages related to one URL 294: 295: sub del_url_author_res_msg { 296: my $url=shift; 297: $url=&Apache::lonnet::declutter($url); 298: my ($domain,$author)=($url=~/^(\w+)\/(\w+)\//); 299: my @delmsgs=(); 300: foreach (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) { 301: if ($_=~/^\Q$url\E\_\d+$/) { 302: push (@delmsgs,$_); 303: } 304: } 305: return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author); 306: } 307: 308: # ================= Return hash with URLs for which there is a resource message 309: 310: sub all_url_author_res_msg { 311: my ($author,$domain)=@_; 312: my %returnhash=(); 313: foreach (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) { 314: $_=~/^(.+)\_\d+/; 315: $returnhash{$1}=1; 316: } 317: return %returnhash; 318: } 319: 320: # ================================================== Critical message to a user 321: 322: sub user_crit_msg_raw { 323: my ($user,$domain,$subject,$message,$sendback)=@_; 324: # Check if allowed missing 325: my $status=''; 326: my $msgid='undefined'; 327: unless (($message)&&($user)&&($domain)) { $status='empty'; }; 328: my $homeserver=&Apache::lonnet::homeserver($user,$domain); 329: if ($homeserver ne 'no_host') { 330: ($msgid,$message)=&packagemsg($subject,$message); 331: if ($sendback) { $message.='<sendback>true</sendback>'; } 332: $status=&Apache::lonnet::critical( 333: 'put:'.$domain.':'.$user.':critical:'. 334: &Apache::lonnet::escape($msgid).'='. 335: &Apache::lonnet::escape($message),$homeserver); 336: if ($ENV{'request.course.id'}) { 337: &user_normal_msg_raw( 338: $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, 339: $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, 340: 'Critical ['.$user.':'.$domain.']', 341: $message); 342: } 343: } else { 344: $status='no_host'; 345: } 346: # Notifications 347: my %userenv = &Apache::lonnet::get('environment',['critnotification'], 348: $domain,$user); 349: if ($userenv{'critnotification'}) { 350: &sendnotification($userenv{'critnotification'},$user,$domain,$subject,1); 351: } 352: # Log this 353: &Apache::lonnet::logthis( 354: 'Sending critical email '.$msgid. 355: ', log status: '. 356: &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'}, 357: $ENV{'user.home'}, 358: 'Sending critical '.$msgid.' to '.$user.' at '.$domain.' with status: ' 359: .$status)); 360: return $status; 361: } 362: 363: # New routine that respects "forward" and calls old routine 364: 365: =pod 366: 367: =item * B<user_crit_msg($user, $domain, $subject, $message, $sendback)>: Sends 368: a critical message $message to the $user at $domain. If $sendback is true, 369: a reciept will be sent to the current user when $user recieves the message. 370: 371: =cut 372: 373: sub user_crit_msg { 374: my ($user,$domain,$subject,$message,$sendback)=@_; 375: my $status=''; 376: my %userenv = &Apache::lonnet::get('environment',['msgforward'], 377: $domain,$user); 378: my $msgforward=$userenv{'msgforward'}; 379: if ($msgforward) { 380: foreach (split(/\,/,$msgforward)) { 381: my ($forwuser,$forwdomain)=split(/\:/,$_); 382: $status.= 383: &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message, 384: $sendback).' '; 385: } 386: } else { 387: $status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback); 388: } 389: return $status; 390: } 391: 392: # =================================================== Critical message received 393: 394: sub user_crit_received { 395: my $msgid=shift; 396: my %message=&Apache::lonnet::get('critical',[$msgid]); 397: my %contents=&unpackagemsg($message{$msgid},1); 398: my $status='rec: '.($contents{'sendback'}? 399: &user_normal_msg($contents{'sendername'},$contents{'senderdomain'}, 400: &mt('Receipt').': '.$ENV{'user.name'}.' '.&mt('at').' '.$ENV{'user.domain'}.', '.$contents{'subject'}, 401: &mt('User').' '.$ENV{'user.name'}.' '.&mt('at').' '.$ENV{'user.domain'}. 402: ' acknowledged receipt of message'."\n".' "'. 403: $contents{'subject'}.'"'."\n".&mt('dated').' '. 404: $contents{'time'}.".\n" 405: ):'no msg req'); 406: $status.=' trans: '. 407: &Apache::lonnet::put( 408: 'nohist_email',{$contents{'msgid'} => $message{$msgid}}); 409: $status.=' del: '. 410: &Apache::lonnet::del('critical',[$contents{'msgid'}]); 411: &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'}, 412: $ENV{'user.home'},'Received critical message '. 413: $contents{'msgid'}. 414: ', '.$status); 415: return $status; 416: } 417: 418: # ======================================================== Normal communication 419: 420: sub user_normal_msg_raw { 421: my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl)=@_; 422: # Check if allowed missing 423: my $status=''; 424: my $msgid='undefined'; 425: unless (($message)&&($user)&&($domain)) { $status='empty'; }; 426: my $homeserver=&Apache::lonnet::homeserver($user,$domain); 427: if ($homeserver ne 'no_host') { 428: ($msgid,$message)=&packagemsg($subject,$message,$citation,$baseurl, 429: $attachmenturl); 430: $status=&Apache::lonnet::critical( 431: 'put:'.$domain.':'.$user.':nohist_email:'. 432: &Apache::lonnet::escape($msgid).'='. 433: &Apache::lonnet::escape($message),$homeserver); 434: &Apache::lonnet::put 435: ('email_status',{'recnewemail'=>time},$domain,$user); 436: } else { 437: $status='no_host'; 438: } 439: # Notifications 440: my %userenv = &Apache::lonnet::get('environment',['notification'], 441: $domain,$user); 442: if ($userenv{'notification'}) { 443: &sendnotification($userenv{'notification'},$user,$domain,$subject,0); 444: } 445: &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'}, 446: $ENV{'user.home'}, 447: 'Sending '.$msgid.' to '.$user.' at '.$domain.' with status: '.$status); 448: return $status; 449: } 450: 451: # New routine that respects "forward" and calls old routine 452: 453: =pod 454: 455: =item * B<user_normal_msg($user, $domain, $subject, $message, 456: $citation, $baseurl, $attachmenturl)>: Sends a message to the 457: $user at $domain, with subject $subject and message $message. 458: 459: =cut 460: 461: sub user_normal_msg { 462: my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl)=@_; 463: my $status=''; 464: my %userenv = &Apache::lonnet::get('environment',['msgforward'], 465: $domain,$user); 466: my $msgforward=$userenv{'msgforward'}; 467: if ($msgforward) { 468: foreach (split(/\,/,$msgforward)) { 469: my ($forwuser,$forwdomain)=split(/\:/,$_); 470: $status.= 471: &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message, 472: $citation,$baseurl,$attachmenturl).' '; 473: } 474: } else { 475: $status=&user_normal_msg_raw($user,$domain,$subject,$message, 476: $citation,$baseurl,$attachmenturl); 477: } 478: return $status; 479: } 480: 481: 482: # =============================================================== Status Change 483: 484: sub statuschange { 485: my ($msgid,$newstatus)=@_; 486: my %status=&Apache::lonnet::get('email_status',[$msgid]); 487: if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; } 488: unless ($status{$msgid}) { $status{$msgid}='new'; } 489: unless (($status{$msgid} eq 'replied') || 490: ($status{$msgid} eq 'forwarded')) { 491: &Apache::lonnet::put('email_status',{$msgid => $newstatus}); 492: } 493: if (($newstatus eq 'deleted') || ($newstatus eq 'new')) { 494: &Apache::lonnet::put('email_status',{$msgid => $newstatus}); 495: } 496: } 497: 498: # ======================================================= Display a course list 499: 500: sub discourse { 501: my $r=shift; 502: my %courselist=&Apache::lonnet::dump( 503: 'classlist', 504: $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, 505: $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); 506: my $now=time; 507: my %lt=&Apache::lonlocal::texthash('cfa' => 'Check for All', 508: 'cfs' => 'Check for Section/Group', 509: 'cfn' => 'Check for None'); 510: $r->print(<<ENDDISHEADER); 511: <input type="hidden" name="sendmode" value="group" /> 512: <script> 513: function checkall() { 514: for (i=0; i<document.forms.compemail.elements.length; i++) { 515: if 516: (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) { 517: document.forms.compemail.elements[i].checked=true; 518: } 519: } 520: } 521: 522: function checksec() { 523: for (i=0; i<document.forms.compemail.elements.length; i++) { 524: if 525: (document.forms.compemail.elements[i].name.indexOf 526: ('send_to_&&&'+document.forms.compemail.chksec.value)==0) { 527: document.forms.compemail.elements[i].checked=true; 528: } 529: } 530: } 531: 532: function uncheckall() { 533: for (i=0; i<document.forms.compemail.elements.length; i++) { 534: if 535: (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) { 536: document.forms.compemail.elements[i].checked=false; 537: } 538: } 539: } 540: </script> 541: <input type="button" onClick="checkall()" value="$lt{'cfa'}" /> 542: <input type="button" onClick="checksec()" value="$lt{'cfs'}" /> 543: <input type="text" size="5" name=chksec /> 544: <input type="button" onClick="uncheckall()" value="$lt{'cfn'}" /> 545: <p> 546: ENDDISHEADER 547: my %coursepersonnel= 548: &Apache::lonnet::get_course_adv_roles(); 549: foreach my $role (sort keys %coursepersonnel) { 550: foreach (split(/\,/,$coursepersonnel{$role})) { 551: my ($puname,$pudom)=split(/\:/,$_); 552: $r->print( 553: '<br /><input type="checkbox" name="send_to_&&&&&&_'. 554: $puname.':'.$pudom.'" /> '. 555: &Apache::loncommon::plainname($puname, 556: $pudom).' ('.$_.'), <i>'.$role.'</i>'); 557: } 558: } 559: 560: foreach (sort keys %courselist) { 561: my ($end,$start)=split(/\:/,$courselist{$_}); 562: my $active=1; 563: if (($end) && ($now>$end)) { $active=0; } 564: if ($active) { 565: my ($sname,$sdom)=split(/\:/,$_); 566: my %reply=&Apache::lonnet::get('environment', 567: ['firstname','middlename','lastname','generation'], 568: $sdom,$sname); 569: my $section=&Apache::lonnet::usection 570: ($sdom,$sname,$ENV{'request.course.id'}); 571: $r->print( 572: '<br><input type=checkbox name="send_to_&&&'.$section.'&&&_'.$_.'"> '. 573: $reply{'firstname'}.' '. 574: $reply{'middlename'}.' '. 575: $reply{'lastname'}.' '. 576: $reply{'generation'}. 577: ' ('.$_.') '.$section); 578: } 579: } 580: } 581: 582: # ==================================================== Display Critical Message 583: 584: sub discrit { 585: my $r=shift; 586: my $header = '<h1><font color=red>'.&mt('Critical Messages').'</font></h1>'. 587: '<form action=/adm/email method=post>'. 588: '<input type=hidden name=confirm value=true>'; 589: my %what=&Apache::lonnet::dump('critical'); 590: my $result = ''; 591: foreach (sort keys %what) { 592: my %content=&unpackagemsg($what{$_}); 593: next if ($content{'senderdomain'} eq ''); 594: $content{'message'}=~s/\n/\<br\>/g; 595: $result.='<hr>'.&mt('From').': <b>'. 596: &Apache::loncommon::aboutmewrapper( 597: &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('. 598: $content{'sendername'}.'@'. 599: $content{'senderdomain'}.') '.$content{'time'}. 600: '<br>'.&mt('Subject').': '.$content{'subject'}. 601: '<br><blockquote>'. 602: &Apache::lontexconvert::msgtexconverted($content{'message'}). 603: '</blockquote><small>'. 604: &mt('You have to confirm that you received this message. After confirmation, this message will be moved to your regular inbox'). 605: '</small><br />'. 606: '<input type=submit name="rec_'.$_.'" value="'.&mt('Confirm Receipt').'">'. 607: '<input type=submit name="reprec_'.$_.'" '. 608: 'value="'.&mt('Confirm Receipt and Reply').'">'; 609: } 610: # Check to see if there were any messages. 611: if ($result eq '') { 612: $result = "<h2>".&mt('You have no critical messages.')."</h2>". 613: '<a href="/adm/roles">'.&mt('Select a course').'</a>'; 614: } else { 615: $r->print($header); 616: } 617: $r->print($result); 618: $r->print('<input type=hidden name="displayedcrit" value="true"></form>'); 619: } 620: 621: sub sortedmessages { 622: my @messages = &Apache::lonnet::getkeys('nohist_email'); 623: #unpack the varibles and repack into temp for sorting 624: my @temp; 625: foreach (@messages) { 626: my $msgid=&Apache::lonnet::escape($_); 627: my ($sendtime,$shortsubj,$fromname,$fromdomain,$status)= 628: &Apache::lonmsg::unpackmsgid($msgid); 629: my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status, 630: $msgid); 631: push @temp ,\@temp1; 632: } 633: #default sort 634: @temp = sort {$a->[0] <=> $b->[0]} @temp; 635: if ($ENV{'form.sortedby'} eq "date"){ 636: @temp = sort {$a->[0] <=> $b->[0]} @temp; 637: } 638: if ($ENV{'form.sortedby'} eq "revdate"){ 639: @temp = sort {$b->[0] <=> $a->[0]} @temp; 640: } 641: if ($ENV{'form.sortedby'} eq "user"){ 642: @temp = sort {lc($a->[2]) cmp lc($b->[2])} @temp; 643: } 644: if ($ENV{'form.sortedby'} eq "revuser"){ 645: @temp = sort {lc($b->[2]) cmp lc($a->[2])} @temp; 646: } 647: if ($ENV{'form.sortedby'} eq "domain"){ 648: @temp = sort {$a->[3] cmp $b->[3]} @temp; 649: } 650: if ($ENV{'form.sortedby'} eq "revdomain"){ 651: @temp = sort {$b->[3] cmp $a->[3]} @temp; 652: } 653: if ($ENV{'form.sortedby'} eq "subject"){ 654: @temp = sort {lc($a->[1]) cmp lc($b->[1])} @temp; 655: } 656: if ($ENV{'form.sortedby'} eq "revsubject"){ 657: @temp = sort {lc($b->[1]) cmp lc($a->[1])} @temp; 658: } 659: if ($ENV{'form.sortedby'} eq "status"){ 660: @temp = sort {$a->[4] cmp $b->[4]} @temp; 661: } 662: if ($ENV{'form.sortedby'} eq "revstatus"){ 663: @temp = sort {$b->[4] cmp $a->[4]} @temp; 664: } 665: return @temp; 666: } 667: 668: # ======================================================== Display all messages 669: 670: sub disall { 671: my $r=shift; 672: $r->print(<<ENDDISHEADER); 673: <script> 674: function checkall() { 675: for (i=0; i<document.forms.disall.elements.length; i++) { 676: if 677: (document.forms.disall.elements[i].name.indexOf('delmark_')==0) { 678: document.forms.disall.elements[i].checked=true; 679: } 680: } 681: } 682: 683: function uncheckall() { 684: for (i=0; i<document.forms.disall.elements.length; i++) { 685: if 686: (document.forms.disall.elements[i].name.indexOf('delmark_')==0) { 687: document.forms.disall.elements[i].checked=false; 688: } 689: } 690: } 691: </script> 692: ENDDISHEADER 693: $r->print('<h1>'.&mt('Display All Messages').'</h1><form method=post name=disall '. 694: 'action="/adm/email">'. 695: '<table border=2><tr><th colspan=2> </th><th>'); 696: if ($ENV{'form.sortedby'} eq "revdate") { 697: $r->print('<a href = "?sortedby=date">'.&mt('Date').'</a></th>'); 698: } else { 699: $r->print('<a href = "?sortedby=revdate">'.&mt('Date').'</a></th>'); 700: } 701: $r->print('<th>'); 702: if ($ENV{'form.sortedby'} eq "revuser") { 703: $r->print('<a href = "?sortedby=user">'.&mt('Username').'</a>'); 704: } else { 705: $r->print('<a href = "?sortedby=revuser">'.&mt('Username').'</a>'); 706: } 707: $r->print('</th><th>'); 708: if ($ENV{'form.sortedby'} eq "revdomain") { 709: $r->print('<a href = "?sortedby=domain">'.&mt('Domain').'</a>'); 710: } else { 711: $r->print('<a href = "?sortedby=revdomain">'.&mt('Domain').'</a>'); 712: } 713: $r->print('</th><th>'); 714: if ($ENV{'form.sortedby'} eq "revsubject") { 715: $r->print('<a href = "?sortedby=subject">'.&mt('Subject').'</a>'); 716: } else { 717: $r->print('<a href = "?sortedby=revsubject">'.&mt('Subject').'</a>'); 718: } 719: $r->print('</th><th>'); 720: if ($ENV{'form.sortedby'} eq "revstatus") { 721: $r->print('<a href = "?sortedby=status">'.&mt('Status').'</th>'); 722: } else { 723: $r->print('<a href = "?sortedby=revstatus">'.&mt('Status').'</th>'); 724: } 725: $r->print('</tr>'); 726: my @temp=sortedmessages(); 727: foreach (@temp){ 728: my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @$_; 729: if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) { 730: if ($status eq 'new') { 731: $r->print('<tr bgcolor="#FFBB77">'); 732: } elsif ($status eq 'read') { 733: $r->print('<tr bgcolor="#BBBB77">'); 734: } elsif ($status eq 'replied') { 735: $r->print('<tr bgcolor="#AAAA88">'); 736: } else { 737: $r->print('<tr bgcolor="#99BBBB">'); 738: } 739: $r->print('<td><a href="/adm/email?display='.$origID.$sqs. 740: '">'.&mt('Open').'</a></td><td><a href="/adm/email?markdel='.$origID.$sqs. 741: '">'.&mt('Delete').'</a><input type=checkbox name="delmark_'.$origID.'" /></td>'. 742: '<td>'.&Apache::lonlocal::locallocaltime($sendtime).'</td><td>'. 743: $fromname.'</td><td>'.$fromdomain.'</td><td>'. 744: &Apache::lonnet::unescape($shortsubj).'</td><td>'. 745: $status.'</td></tr>'); 746: } 747: } 748: $r->print('</table><p>'. 749: '<a href="javascript:checkall()">'.&mt('Check All').'</a> '. 750: '<a href="javascript:uncheckall()">'.&mt('Uncheck All').'</a><p>'. 751: '<input type="hidden" name="sortedby" value="'.$ENV{'form.sortedby'}.'" />'. 752: '<input type="submit" name="markeddel" value="'.&mt('Delete Checked').'" />'. 753: '</form></body></html>'); 754: } 755: 756: # ============================================================== Compose output 757: 758: sub compout { 759: my ($r,$forwarding,$replying,$broadcast)=@_; 760: 761: if ($broadcast eq 'individual') { 762: &printheader($r,'/adm/email?compose=individual', 763: 'Send a Message'); 764: } elsif ($broadcast) { 765: &printheader($r,'/adm/email?compose=group', 766: 'Broadcast Message'); 767: } elsif ($forwarding) { 768: &Apache::lonhtmlcommon::add_breadcrumb 769: ({href=>"/adm/email?display=".&Apache::lonnet::escape($forwarding), 770: text=>"Display Message"}); 771: &printheader($r,'/adm/email?forward='.&Apache::lonnet::escape($forwarding), 772: 'Forwarding a Message'); 773: } elsif ($replying) { 774: &Apache::lonhtmlcommon::add_breadcrumb 775: ({href=>"/adm/email?display=".&Apache::lonnet::escape($replying), 776: text=>"Display Message"}); 777: &printheader($r,'/adm/email?replyto='.&Apache::lonnet::escape($replying), 778: 'Replying to a Message'); 779: } else { 780: &printheader($r,'/adm/email?compose=upload', 781: 'Distribute from Uploaded File'); 782: } 783: 784: my $dispcrit=''; 785: my $dissub=''; 786: my $dismsg=''; 787: my $func=&mt('Send New'); 788: my %lt=&Apache::lonlocal::texthash('us' => 'Username', 789: 'do' => 'Domain', 790: 'ad' => 'Additional Recipients', 791: 'sb' => 'Subject', 792: 'ca' => 'Cancel', 793: 'ma' => 'Mail'); 794: 795: if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) { 796: my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message"); 797: $dispcrit= 798: '<input type="checkbox" name="critmsg" /> '.&mt('Send as critical message').' ' . $crithelp . 799: '<br>'. 800: '<input type="checkbox" name="sendbck" /> '.&mt('Send as critical message').' ' . 801: &mt('and return receipt') . $crithelp . '<p>'; 802: } 803: my %message; 804: my %content; 805: my $defdom=$ENV{'user.domain'}; 806: if ($forwarding) { 807: %message=&Apache::lonnet::get('nohist_email',[$forwarding]); 808: %content=&unpackagemsg($message{$forwarding}); 809: $dispcrit.='<input type="hidden" name="forwid" value="'. 810: $forwarding.'" />'; 811: $func=&mt('Forward'); 812: 813: $dissub=&mt('Forwarding').': '.$content{'subject'}; 814: $dismsg=&mt('Forwarded message from').' '. 815: $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'}; 816: } 817: if ($replying) { 818: %message=&Apache::lonnet::get('nohist_email',[$replying]); 819: %content=&unpackagemsg($message{$replying}); 820: $dispcrit.='<input type="hidden" name="forwid" value="'. 821: $forwarding.'" />'; 822: $func=&mt('Replying to'); 823: 824: $dissub=&mt('Reply').': '.$content{'subject'}; 825: $dismsg='> '.$content{'message'}; 826: $dismsg=~s/\r/\n/g; 827: $dismsg=~s/\f/\n/g; 828: $dismsg=~s/\n+/\n\> /g; 829: } 830: if ($ENV{'form.recdom'}) { $defdom=$ENV{'form.recdom'}; } 831: $r->print( 832: '<form action="/adm/email" name="compemail" method="post"'. 833: ' enctype="multipart/form-data">'."\n". 834: '<input type="hidden" name="sendmail" value="on" />'."\n". 835: '<table>'); 836: unless (($broadcast eq 'group') || ($broadcast eq 'upload')) { 837: if ($replying) { 838: $r->print('<tr><td colspan="2">'.&mt('Replying to').' '. 839: &Apache::loncommon::aboutmewrapper( 840: &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('. 841: $content{'sendername'}.'@'. 842: $content{'senderdomain'}.')'. 843: '<input type="hidden" name="recuname" value="'.$content{'sendername'}.'" />'. 844: '<input type="hidden" name="recdomain" value="'.$content{'senderdomain'}.'" />'. 845: '</td></tr>'); 846: } else { 847: my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain'); 848: my $selectlink=&Apache::loncommon::selectstudent_link 849: ('compemail','recuname','recdomain'); 850: $r->print(<<"ENDREC"); 851: <tr><td>$lt{'us'}:</td><td><input type="text" size="12" name="recuname" value="$ENV{'form.recname'}"></td><td rowspan="2">$selectlink</td></tr> 852: <tr><td>$lt{'do'}:</td> 853: <td>$domform</td></tr> 854: ENDREC 855: } 856: } 857: my $latexHelp = Apache::loncommon::helpLatexCheatsheet(); 858: if ($broadcast ne 'upload') { 859: $r->print(<<"ENDCOMP"); 860: <tr><td>$lt{'ad'}<br /><tt>username\@domain,username\@domain, ... 861: </tt></td><td> 862: <input type="text" size="50" name="additionalrec" /></td></tr> 863: <tr><td>$lt{'sb'}:</td><td><input type="text" size="50" name="subject" value="$dissub" /> 864: </td></tr></table> 865: $latexHelp 866: <textarea name="message" cols="80" rows="15" wrap="hard">$dismsg 867: </textarea></p><br /> 868: $dispcrit 869: <input type="submit" name="send" value="$func $lt{'ma'}" /> 870: <input type="submit" name="cancel" value="$lt{'ca'}" /> 871: ENDCOMP 872: } else { # $broadcast is 'upload' 873: $r->print(<<ENDUPLOAD); 874: <input type="hidden" name="sendmode" value="upload" /> 875: <input type="hidden" name="send" value="on" /> 876: <h3>Generate messages from a file</h3> 877: <p> 878: Subject: <input type="text" size="50" name="subject" /> 879: </p> 880: <p>General message text<br /> 881: <textarea name="message" cols="60" rows="10" wrap="hard">$dismsg 882: </textarea></p> 883: <p> 884: The file format for the uploaded portion of the message is: 885: <pre> 886: username1\@domain1: text 887: username2\@domain2: text 888: username3\@domain1: text 889: </pre> 890: </p> 891: <p> 892: The messages will be assembled from all lines with the respective 893: <tt>username\@domain</tt>, and appended to the general message text.</p> 894: <p> 895: <input type="file" name="upfile" size="40" /></p><p> 896: $dispcrit 897: <input type="submit" value="Upload and Send" /></p> 898: ENDUPLOAD 899: } 900: if ($broadcast eq 'group') { 901: &discourse; 902: } 903: $r->print('</form>'); 904: } 905: 906: # ---------------------------------------------------- Display all face to face 907: 908: sub disfacetoface { 909: my ($r,$user,$domain)=@_; 910: unless ($ENV{'request.course.id'}) { return; } 911: unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) { 912: return; 913: } 914: my %records=&Apache::lonnet::dump('nohist_email', 915: $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, 916: $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, 917: '%255b'.$user.'%253a'.$domain.'%255d'); 918: my $result=''; 919: foreach (sort keys %records) { 920: my %content=&unpackagemsg($records{$_}); 921: next if ($content{'senderdomain'} eq ''); 922: $content{'message'}=~s/\n/\<br\>/g; 923: if ($content{'subject'}=~/^Record/) { 924: $result.='<h3>'.&mt('Record').'</h3>'; 925: } else { 926: $result.='<h3>'.&mt('Sent Message').'</h3>'; 927: %content=&unpackagemsg($content{'message'}); 928: $content{'message'}= 929: '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'. 930: $content{'message'}; 931: } 932: $result.=&mt('By').': <b>'. 933: &Apache::loncommon::aboutmewrapper( 934: &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('. 935: $content{'sendername'}.'@'. 936: $content{'senderdomain'}.') '.$content{'time'}. 937: '<br /><blockquote>'. 938: &Apache::lontexconvert::msgtexconverted($content{'message'}). 939: '</blockquote>'; 940: } 941: # Check to see if there were any messages. 942: if ($result eq '') { 943: $r->print("<p><b>".&mt("No notes, face-to-face discussion records, or critical messages in this course.")."</b></p>"); 944: } else { 945: $r->print($result); 946: } 947: } 948: 949: # ---------------------------------------------------------------- Face to face 950: 951: sub facetoface { 952: my ($r,$stage)=@_; 953: unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) { 954: return; 955: } 956: &printheader($r, 957: '/adm/email?recordftf=query', 958: "User Notes, Face-to-Face, Critical Messages"); 959: # from query string 960: 961: if ($ENV{'form.recname'}) { $ENV{'form.recuname'}=$ENV{'form.recname'}; } 962: if ($ENV{'form.recdom'}) { $ENV{'form.recdomain'}=$ENV{'form.recdom'}; } 963: 964: my $defdom=$ENV{'user.domain'}; 965: # already filled in 966: if ($ENV{'form.recdomain'}) { $defdom=$ENV{'form.recdomain'}; } 967: # generate output 968: my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain'); 969: my $stdbrws = &Apache::loncommon::selectstudent_link 970: ('stdselect','recuname','recdomain'); 971: my %lt=&Apache::lonlocal::texthash('user' => 'Username', 972: 'dom' => 'Domain', 973: 'head' => 'User Notes, Records of Face-To-Face Discussions, and Critical Messages in Course', 974: 'subm' => 'Retrieve discussion and message records', 975: 'newr' => 'New Record (record is visible to course faculty and staff)', 976: 'post' => 'Post this Record'); 977: $r->print(<<"ENDTREC"); 978: <h3>$lt{'head'}</h3> 979: <form method="post" action="/adm/email" name="stdselect"> 980: <input type="hidden" name="recordftf" value="retrieve" /> 981: <table> 982: <tr><td>$lt{'user'}:</td><td><input type="text" size="12" name="recuname" value="$ENV{'form.recuname'}" /></td> 983: <td rowspan="2"> 984: $stdbrws 985: <input type="submit" value="$lt{'subm'}" /></td> 986: </tr> 987: <tr><td>$lt{'dom'}:</td> 988: <td>$domform</td></tr> 989: </table> 990: </form> 991: ENDTREC 992: if (($stage ne 'query') && 993: ($ENV{'form.recdomain'}) && ($ENV{'form.recuname'})) { 994: chomp($ENV{'form.newrecord'}); 995: if ($ENV{'form.newrecord'}) { 996: &user_normal_msg_raw( 997: $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, 998: $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, 999: &mt('Record'). 1000: ' ['.$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}.']', 1001: $ENV{'form.newrecord'}); 1002: } 1003: $r->print('<h3>'.&Apache::loncommon::plainname($ENV{'form.recuname'}, 1004: $ENV{'form.recdomain'}).'</h3>'); 1005: &disfacetoface($r,$ENV{'form.recuname'},$ENV{'form.recdomain'}); 1006: $r->print(<<ENDRHEAD); 1007: <form method="post" action="/adm/email"> 1008: <input name="recdomain" value="$ENV{'form.recdomain'}" type="hidden" /> 1009: <input name="recuname" value="$ENV{'form.recuname'}" type="hidden" /> 1010: ENDRHEAD 1011: $r->print(<<ENDBFORM); 1012: <hr />$lt{'newr'}<br /> 1013: <textarea name="newrecord" cols="80" rows="10" wrap="hard"></textarea> 1014: <br /> 1015: <input type="hidden" name="recordftf" value="post" /> 1016: <input type="submit" value="$lt{'post'}" /> 1017: </form> 1018: ENDBFORM 1019: } 1020: } 1021: 1022: # ----------------------------------------------------------- Display a message 1023: 1024: sub displaymessage { 1025: my ($r,$msgid)=@_; 1026: &statuschange($msgid,'read'); 1027: my %message=&Apache::lonnet::get('nohist_email',[$msgid]); 1028: my %content=&unpackagemsg($message{$msgid}); 1029: # info to generate "next" and "previous" buttons 1030: my @messages=&sortedmessages(); 1031: my $counter=0; 1032: $r->print('<pre>'); 1033: my $escmsgid=&Apache::lonnet::escape($msgid); 1034: foreach (@messages) { 1035: if ($_->[5] eq $escmsgid){ 1036: last; 1037: } 1038: $counter++; 1039: } 1040: $r->print('</pre>'); 1041: my $number_of_messages = scalar(@messages); #subtract 1 for last index 1042: # start output 1043: &printheader($r,'/adm/email?display='.&Apache::lonnet::escape($msgid),'Display a Message','',$content{'baseurl'}); 1044: my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'}); 1045: # Functions 1046: $r->print('<table border="2" width="100%"><tr bgcolor="#FFFFAA"><td>'.&mt('Functions').':</td>'. 1047: '<td><a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).$sqs. 1048: '"><b>'.&mt('Reply').'</b></a></td>'. 1049: '<td><a href="/adm/email?forward='.&Apache::lonnet::escape($msgid).$sqs. 1050: '"><b>'.&mt('Forward').'</b></a></td>'. 1051: '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs. 1052: '"><b>'.&mt('Mark Unread').'</b></a></td>'. 1053: '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs. 1054: '"><b>Delete</b></a></td>'. 1055: '<td><a href="/adm/email?sortedby='.$ENV{'form.sortedby'}. 1056: '"><b>'.&mt('Display all Messages').'</b></a></td>'); 1057: if ($counter > 0){ 1058: $r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs. 1059: '"><b>'.&mt('Previous').'</b></a></td>'); 1060: } 1061: if ($counter < $number_of_messages - 1){ 1062: $r->print('<td><a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs. 1063: '"><b>'.&mt('Next').'</b></a></td>'); 1064: } 1065: $r->print('</tr></table>'); 1066: $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}. 1067: '<br /><b>'.&mt('From').':</b> '. 1068: &Apache::loncommon::aboutmewrapper( 1069: &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}), 1070: $content{'sendername'},$content{'senderdomain'}).' ('. 1071: $content{'sendername'}.' at '. 1072: $content{'senderdomain'}.') '. 1073: ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}. 1074: ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):''). 1075: '<br /><b>'.&mt('Time').':</b> '.$content{'time'}. 1076: '<p><pre>'. 1077: &Apache::lontexconvert::msgtexconverted($content{'message'},1). 1078: '</pre><hr />'.$content{'citation'}.'</p>'); 1079: return; 1080: } 1081: 1082: # ================================================================== The Header 1083: 1084: sub header { 1085: my ($r,$title,$baseurl)=@_; 1086: $r->print('<html><head><title>Communication and Messages</title>'); 1087: if ($baseurl) { 1088: $r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$baseurl\" />"); 1089: } 1090: $r->print(&Apache::loncommon::studentbrowser_javascript().'</head>'. 1091: &Apache::loncommon::bodytag('Communication and Messages')); 1092: $r->print(&Apache::lonhtmlcommon::breadcrumbs 1093: (undef,($title?$title:'Communication and Messages'))); 1094: 1095: } 1096: 1097: # ---------------------------------------------------------------- Print header 1098: 1099: sub printheader { 1100: my ($r,$url,$desc,$title,$baseurl)=@_; 1101: &Apache::lonhtmlcommon::add_breadcrumb 1102: ({href=>$url, 1103: text=>$desc}); 1104: &header($r,$title,$baseurl); 1105: } 1106: 1107: 1108: # ===================================================================== Handler 1109: 1110: sub handler { 1111: my $r=shift; 1112: 1113: # ----------------------------------------------------------- Set document type 1114: 1115: &Apache::loncommon::content_type($r,'text/html'); 1116: $r->send_http_header; 1117: 1118: return OK if $r->header_only; 1119: 1120: # --------------------------- Get query string for limited number of parameters 1121: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, 1122: ['display','replyto','forward','markread','markdel','markunread', 1123: 'sendreply','compose','sendmail','critical','recname','recdom', 1124: 'recordftf','sortedby']); 1125: $sqs='&sortedby='.$ENV{'form.sortedby'}; 1126: # ------------------------------------------------------ They checked for email 1127: &Apache::lonnet::put('email_status',{'recnewemail'=>0}); 1128: 1129: # ----------------------------------------------------------------- Breadcrumbs 1130: 1131: &Apache::lonhtmlcommon::clear_breadcrumbs(); 1132: &Apache::lonhtmlcommon::add_breadcrumb 1133: ({href=>"/adm/communicate", 1134: text=>"Communication/Messages", 1135: faq=>12,bug=>'Communication Tools',}); 1136: 1137: # --------------------------------------------------------------- Render Output 1138: 1139: if ($ENV{'form.display'}) { 1140: &displaymessage($r,$ENV{'form.display'}); 1141: } elsif ($ENV{'form.replyto'}) { 1142: &compout($r,'',$ENV{'form.replyto'}); 1143: } elsif ($ENV{'form.confirm'}) { 1144: &printheader($r,'','Confirmed Receipt'); 1145: foreach (keys %ENV) { 1146: if ($_=~/^form\.rec\_(.*)$/) { 1147: $r->print('<b>'.&mt('Confirming Receipt').':</b> '. 1148: &user_crit_received($1).'<br>'); 1149: } 1150: if ($_=~/^form\.reprec\_(.*)$/) { 1151: my $msgid=$1; 1152: $r->print('<b>'.&mt('Confirming Receipt').':</b> '. 1153: &user_crit_received($msgid).'<br>'); 1154: &compout($r,'',$msgid); 1155: } 1156: } 1157: &discrit($r); 1158: } elsif ($ENV{'form.critical'}) { 1159: &printheader($r,'','Displaying Critical Messages'); 1160: &discrit($r); 1161: } elsif ($ENV{'form.forward'}) { 1162: &compout($r,$ENV{'form.forward'}); 1163: } elsif ($ENV{'form.markdel'}) { 1164: &printheader($r,'','Deleted Message'); 1165: &statuschange($ENV{'form.markdel'},'deleted'); 1166: &disall($r); 1167: } elsif ($ENV{'form.markeddel'}) { 1168: my $total=0; 1169: foreach (keys %ENV) { 1170: if ($_=~/^form\.delmark_(.*)$/) { 1171: &statuschange(&Apache::lonnet::unescape($1),'deleted'); 1172: $total++; 1173: } 1174: } 1175: &printheader($r,'','Deleted Messages'); 1176: $r->print('Deleted '.$total.' message(s)<p>'); 1177: &disall($r); 1178: } elsif ($ENV{'form.markunread'}) { 1179: &printheader($r,'','Marked Message as Unread'); 1180: &statuschange($ENV{'form.markunread'},'new'); 1181: &disall($r); 1182: } elsif ($ENV{'form.compose'}) { 1183: &compout($r,'','',$ENV{'form.compose'}); 1184: } elsif ($ENV{'form.recordftf'}) { 1185: &facetoface($r,$ENV{'form.recordftf'}); 1186: } elsif ($ENV{'form.sendmail'}) { 1187: my $sendstatus=''; 1188: if ($ENV{'form.send'}) { 1189: &printheader($r,'','Messages being sent.'); 1190: $r->rflush(); 1191: my %content=(); 1192: undef %content; 1193: if ($ENV{'form.forwid'}) { 1194: my $msgid=$ENV{'form.forwid'}; 1195: my %message=&Apache::lonnet::get('nohist_email',[$msgid]); 1196: %content=&unpackagemsg($message{$msgid},1); 1197: &statuschange($msgid,'forwarded'); 1198: $ENV{'form.message'}.="\n\n-- Forwarded message --\n\n". 1199: $content{'message'}; 1200: } 1201: my %toaddr=(); 1202: undef %toaddr; 1203: if ($ENV{'form.sendmode'} eq 'group') { 1204: foreach (keys %ENV) { 1205: if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) { 1206: $toaddr{$1}=''; 1207: } 1208: } 1209: } elsif ($ENV{'form.sendmode'} eq 'upload') { 1210: foreach (split(/[\n\r\f]+/,$ENV{'form.upfile'})) { 1211: my ($rec,$txt)=split(/\s*\:\s*/,$_); 1212: if ($txt) { 1213: $rec=~s/\@/\:/; 1214: $toaddr{$rec}.=$txt."\n"; 1215: } 1216: } 1217: } else { 1218: $toaddr{$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}}=''; 1219: } 1220: if ($ENV{'form.additionalrec'}) { 1221: foreach (split(/\,/,$ENV{'form.additionalrec'})) { 1222: my ($auname,$audom)=split(/\@/,$_); 1223: $toaddr{$auname.':'.$audom}=''; 1224: } 1225: } 1226: 1227: foreach (keys %toaddr) { 1228: my ($recuname,$recdomain)=split(/\:/,$_); 1229: my $msgtxt=&Apache::lonfeedback::clear_out_html($ENV{'form.message'}); 1230: if ($toaddr{$_}) { $msgtxt.='<hr />'.$toaddr{$_}; } 1231: my $thismsg; 1232: if ((($ENV{'form.critmsg'}) || ($ENV{'form.sendbck'})) && 1233: (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) { 1234: $r->print(&mt('Sending critical message').' '.$recuname.'@'.$recdomain.': '); 1235: $thismsg=&user_crit_msg($recuname,$recdomain, 1236: &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}), 1237: $msgtxt, 1238: $ENV{'form.sendbck'}); 1239: } else { 1240: $r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': '); 1241: $thismsg=&user_normal_msg($recuname,$recdomain, 1242: &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}), 1243: $msgtxt, 1244: $content{'citation'}); 1245: } 1246: $r->print($thismsg.'<br />'); 1247: $sendstatus.=' '.$thismsg; 1248: } 1249: } 1250: if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) { 1251: $r->print('<br /><font color="green">'.&mt('Completed.').'</font>'); 1252: if ($ENV{'form.displayedcrit'}) { 1253: &discrit($r); 1254: } else { 1255: &disall($r); 1256: } 1257: } else { 1258: $r->print( 1259: '<h2><font color="red">'.&mt('Could not deliver message').'</font></h2>'. 1260: &mt('Please use the browser "Back" button and correct the recipient addresses') 1261: ); 1262: } 1263: } else { 1264: &printheader($r,'','Display All Messages'); 1265: &disall($r); 1266: } 1267: $r->print('</body></html>'); 1268: return OK; 1269: } 1270: # ================================================= Main program, reset counter 1271: 1272: BEGIN { 1273: $msgcount=0; 1274: } 1275: 1276: =pod 1277: 1278: =back 1279: 1280: =cut 1281: 1282: 1; 1283: 1284: __END__ 1285: 1286: 1287: 1288: 1289: 1290: 1291: