Annotation of loncom/interface/lonmsg.pm, revision 1.146

1.1       www         1: # The LearningOnline Network with CAPA
1.26      albertel    2: # Routines for messaging
                      3: #
1.146   ! www         4: # $Id: lonmsg.pm,v 1.145 2005/06/06 02:29:46 albertel Exp $
1.26      albertel    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/
1.1       www        27: #
1.75      www        28: 
                     29: 
1.1       www        30: package Apache::lonmsg;
                     31: 
1.58      bowersj2   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: 
1.101     raeburn    77: =item * B<Blocking>: LON-CAPA can block display of e-mails that are 
                     78: sent to a student during an online exam. A course coordinator or
                     79: instructor can set an open and close date/time for scheduled online
                     80: exams in a course. If a user uses the LON-CAPA internal messaging 
                     81: system to display e-mails during the scheduled blocking event,  
                     82: display of all e-mail sent during the blocking period will be 
                     83: suppressed, and a message of explanation, including details of the 
                     84: currently active blocking periods will be displayed instead. A user 
                     85: who has a course coordinator or instructor role in a course will be
                     86: unaffected by any blocking periods for the course, unless the user
                     87: also has a student role in the course, AND has selected the student role.
                     88: 
1.58      bowersj2   89: =back
                     90: 
                     91: Users can ask LON-CAPA to forward messages to conventional e-mail
                     92: addresses on their B<PREF> screen, but generally, LON-CAPA messages
1.132     www        93: are much more useful than traditional email can be made to be, even
1.58      bowersj2   94: with HTML support.
                     95: 
                     96: Right now, this document will cover just how to send a message, since
                     97: it is likely you will not need to programmatically read messages,
                     98: since lonmsg already implements that functionality.
                     99: 
                    100: =head1 FUNCTIONS
                    101: 
                    102: =over 4
                    103: 
                    104: =cut
                    105: 
1.1       www       106: use strict;
1.140     albertel  107: use Apache::lonnet;
1.2       www       108: use vars qw($msgcount);
1.47      albertel  109: use HTML::TokeParser();
1.5       www       110: use Apache::Constants qw(:common);
1.47      albertel  111: use Apache::loncommon();
                    112: use Apache::lontexconvert();
                    113: use HTML::Entities();
1.53      www       114: use Mail::Send;
1.67      www       115: use Apache::lonlocal;
1.95      www       116: use Apache::loncommunicate;
1.1       www       117: 
1.65      www       118: # Querystring component with sorting type
                    119: my $sqs;
1.108     www       120: my $startdis;
                    121: my $interdis;
1.65      www       122: 
1.1       www       123: # ===================================================================== Package
                    124: 
1.3       www       125: sub packagemsg {
1.108     www       126:     my ($subject,$message,$citation,$baseurl,$attachmenturl,
                    127: 	$recuser,$recdomain)=@_;
1.96      albertel  128:     $message =&HTML::Entities::encode($message,'<>&"');
                    129:     $citation=&HTML::Entities::encode($citation,'<>&"');
                    130:     $subject =&HTML::Entities::encode($subject,'<>&"');
1.49      albertel  131:     #remove machine specification
                    132:     $baseurl =~ s|^http://[^/]+/|/|;
1.96      albertel  133:     $baseurl =&HTML::Entities::encode($baseurl,'<>&"');
1.51      www       134:     #remove machine specification
                    135:     $attachmenturl =~ s|^http://[^/]+/|/|;
1.96      albertel  136:     $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
1.51      www       137: 
1.2       www       138:     my $now=time;
                    139:     $msgcount++;
1.6       www       140:     my $partsubj=$subject;
                    141:     $partsubj=&Apache::lonnet::escape($partsubj);
                    142:     my $msgid=&Apache::lonnet::escape(
1.140     albertel  143:            $now.':'.$partsubj.':'.$env{'user.name'}.':'.
1.141     raeburn   144:            $env{'user.domain'}.':'.$msgcount.':'.
                    145:            $env{'request.course.id'}.':'.$$);
1.140     albertel  146:     my $result='<sendername>'.$env{'user.name'}.'</sendername>'.
                    147:            '<senderdomain>'.$env{'user.domain'}.'</senderdomain>'.
1.1       www       148:            '<subject>'.$subject.'</subject>'.
1.67      www       149: 	   '<time>'.&Apache::lonlocal::locallocaltime($now).'</time>'.
1.1       www       150: 	   '<servername>'.$ENV{'SERVER_NAME'}.'</servername>'.
                    151:            '<host>'.$ENV{'HTTP_HOST'}.'</host>'.
                    152: 	   '<client>'.$ENV{'REMOTE_ADDR'}.'</client>'.
1.140     albertel  153: 	   '<browsertype>'.$env{'browser.type'}.'</browsertype>'.
                    154: 	   '<browseros>'.$env{'browser.os'}.'</browseros>'.
                    155: 	   '<browserversion>'.$env{'browser.version'}.'</browserversion>'.
                    156:            '<browsermathml>'.$env{'browser.mathml'}.'</browsermathml>'.
1.1       www       157: 	   '<browserraw>'.$ENV{'HTTP_USER_AGENT'}.'</browserraw>'.
1.140     albertel  158: 	   '<courseid>'.$env{'request.course.id'}.'</courseid>'.
                    159: 	   '<coursesec>'.$env{'request.course.sec'}.'</coursesec>'.
                    160: 	   '<role>'.$env{'request.role'}.'</role>'.
                    161: 	   '<resource>'.$env{'request.filename'}.'</resource>'.
1.2       www       162:            '<msgid>'.$msgid.'</msgid>'.
1.108     www       163: 	   '<recuser>'.$recuser.'</recuser>'.
                    164: 	   '<recdomain>'.$recdomain.'</recdomain>'.
1.49      albertel  165: 	   '<message>'.$message.'</message>';
                    166:     if (defined($citation)) {
                    167: 	$result.='<citation>'.$citation.'</citation>';
                    168:     }
                    169:     if (defined($baseurl)) {
                    170: 	$result.= '<baseurl>'.$baseurl.'</baseurl>';
                    171:     }
1.51      www       172:     if (defined($attachmenturl)) {
1.52      www       173: 	$result.= '<attachmenturl>'.$attachmenturl.'</attachmenturl>';
1.51      www       174:     }
1.49      albertel  175:     return $msgid,$result;
1.1       www       176: }
                    177: 
1.2       www       178: # ================================================== Unpack message into a hash
                    179: 
1.3       www       180: sub unpackagemsg {
1.52      www       181:     my ($message,$notoken)=@_;
1.2       www       182:     my %content=();
                    183:     my $parser=HTML::TokeParser->new(\$message);
                    184:     my $token;
                    185:     while ($token=$parser->get_token) {
                    186:        if ($token->[0] eq 'S') {
                    187: 	   my $entry=$token->[1];
                    188:            my $value=$parser->get_text('/'.$entry);
                    189:            $content{$entry}=$value;
                    190:        }
                    191:     }
1.52      www       192:     if ($content{'attachmenturl'}) {
1.100     albertel  193:        my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
1.52      www       194:        if ($notoken) {
1.100     albertel  195: 	   $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'</tt>';
1.52      www       196:        } else {
1.99      albertel  197: 	   &Apache::lonnet::allowuploaded('/adm/msg',
                    198: 					  $content{'attachmenturl'});
                    199: 	   $content{'message'}.='<p>'.&mt('Attachment').
                    200: 	       ': <a href="'.$content{'attachmenturl'}.'"><tt>'.
1.100     albertel  201: 	       $fname.'</tt></a>';
1.52      www       202:        }
                    203:     }
1.2       www       204:     return %content;
                    205: }
                    206: 
1.6       www       207: # ======================================================= Get info out of msgid
                    208: 
                    209: sub unpackmsgid {
1.106     www       210:     my ($msgid,$folder)=@_;
                    211:     $msgid=&Apache::lonnet::unescape($msgid);
                    212:     my $suffix=&foldersuffix($folder);
1.141     raeburn   213:     my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid)=split(/\:/,
1.7       www       214:                           &Apache::lonnet::unescape($msgid));
1.106     www       215:     my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
1.6       www       216:     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
                    217:     unless ($status{$msgid}) { $status{$msgid}='new'; }
1.141     raeburn   218:     return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid);
                    219: }
1.6       www       220: 
1.53      www       221: 
                    222: sub sendemail {
                    223:     my ($to,$subject,$body)=@_;
                    224:     $body=
1.67      www       225:     "*** ".&mt('This is an automatic message generated by the LON-CAPA system.')."\n".
                    226:     "*** ".&mt('Please do not reply to this address.')."\n\n".$body;
1.53      www       227:     my $msg = new Mail::Send;
                    228:     $msg->to($to);
                    229:     $msg->subject('[LON-CAPA] '.$subject);
1.97      matthew   230:     if (my $fh = $msg->open()) {
1.68      www       231: 	print $fh $body;
                    232: 	$fh->close;
                    233:     }
1.53      www       234: }
                    235: 
                    236: # ==================================================== Send notification emails
                    237: 
                    238: sub sendnotification {
1.131     www       239:     my ($to,$touname,$toudom,$subj,$crit,$text)=@_;
1.140     albertel  240:     my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'};
1.131     www       241:     unless ($sender=~/\w/) { 
1.140     albertel  242: 	$sender=$env{'user.name'}.'@'.$env{'user.domain'};
1.131     www       243:     }
1.53      www       244:     my $critical=($crit?' critical':'');
1.131     www       245:     $text=~s/\&lt\;/\</gs;
                    246:     $text=~s/\&gt\;/\>/gs;
                    247:     $text=~s/\<\/*[^\>]+\>//gs;
1.53      www       248:     my $url='http://'.
                    249:       $Apache::lonnet::hostname{&Apache::lonnet::homeserver($touname,$toudom)}.
1.54      www       250:       '/adm/email?username='.$touname.'&domain='.$toudom;
1.53      www       251:     my $body=(<<ENDMSG);
                    252: You received a$critical message from $sender in LON-CAPA. The subject is
                    253: 
                    254:  $subj
                    255: 
1.131     www       256: === Excerpt ============================================================
                    257: $text
                    258: ========================================================================
                    259: 
1.53      www       260: Use
                    261: 
                    262:  $url
                    263: 
1.131     www       264: to access the full message.
1.53      www       265: ENDMSG
                    266:     &sendemail($to,'New'.$critical.' message from '.$sender,$body);
                    267: }
1.40      www       268: # ============================================================= Check for email
                    269: 
                    270: sub newmail {
1.140     albertel  271:     if ((time-$env{'user.mailcheck.time'})>300) {
1.40      www       272:         my %what=&Apache::lonnet::get('email_status',['recnewemail']);
                    273:         &Apache::lonnet::appenv('user.mailcheck.time'=>time);
                    274:         if ($what{'recnewemail'}>0) { return 1; }
                    275:     }
                    276:     return 0;
                    277: }
                    278: 
1.1       www       279: # =============================== Automated message to the author of a resource
                    280: 
1.58      bowersj2  281: =pod
                    282: 
                    283: =item * B<author_res_msg($filename, $message)>: Sends message $message to the owner
                    284:     of the resource with the URI $filename.
                    285: 
                    286: =cut
                    287: 
1.1       www       288: sub author_res_msg {
                    289:     my ($filename,$message)=@_;
1.2       www       290:     unless ($message) { return 'empty'; }
1.1       www       291:     $filename=&Apache::lonnet::declutter($filename);
1.72      www       292:     my ($domain,$author,@dummy)=split(/\//,$filename);
1.1       www       293:     my $homeserver=&Apache::lonnet::homeserver($author,$domain);
                    294:     if ($homeserver ne 'no_host') {
                    295:        my $id=unpack("%32C*",$message);
1.2       www       296:        my $msgid;
1.72      www       297:        ($msgid,$message)=&packagemsg($filename,$message);
1.3       www       298:        return &Apache::lonnet::reply('put:'.$domain.':'.$author.
1.72      www       299:          ':nohist_res_msgs:'.
                    300:           &Apache::lonnet::escape($filename.'_'.$id).'='.
                    301:           &Apache::lonnet::escape($message),$homeserver);
1.1       www       302:     }
1.2       www       303:     return 'no_host';
1.73      www       304: }
                    305: 
                    306: # =========================================== Retrieve author resource messages
                    307: 
                    308: sub retrieve_author_res_msg {
1.75      www       309:     my $url=shift;
1.73      www       310:     $url=&Apache::lonnet::declutter($url);
1.80      www       311:     my ($domain,$author)=($url=~/^(\w+)\/(\w+)\//);
1.76      www       312:     my %errormsgs=&Apache::lonnet::dump('nohist_res_msgs',$domain,$author);
1.73      www       313:     my $msgs='';
                    314:     foreach (keys %errormsgs) {
1.80      www       315: 	if ($_=~/^\Q$url\E\_\d+$/) {
1.73      www       316: 	    my %content=&unpackagemsg($errormsgs{$_});
1.74      www       317: 	    $msgs.='<p><img src="/adm/lonMisc/bomb.gif" /><b>'.
                    318: 		$content{'time'}.'</b>: '.$content{'message'}.
                    319: 		'<br /></p>';
1.73      www       320: 	}
                    321:     } 
                    322:     return $msgs;     
                    323: }
                    324: 
                    325: 
                    326: # =============================== Delete all author messages related to one URL
                    327: 
                    328: sub del_url_author_res_msg {
1.75      www       329:     my $url=shift;
1.73      www       330:     $url=&Apache::lonnet::declutter($url);
1.77      www       331:     my ($domain,$author)=($url=~/^(\w+)\/(\w+)\//);
                    332:     my @delmsgs=();
                    333:     foreach (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
                    334: 	if ($_=~/^\Q$url\E\_\d+$/) {
                    335: 	    push (@delmsgs,$_);
                    336: 	}
                    337:     }
                    338:     return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
1.73      www       339: }
                    340: 
                    341: # ================= Return hash with URLs for which there is a resource message
                    342: 
                    343: sub all_url_author_res_msg {
                    344:     my ($author,$domain)=@_;
1.75      www       345:     my %returnhash=();
1.76      www       346:     foreach (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
1.75      www       347: 	$_=~/^(.+)\_\d+/;
                    348: 	$returnhash{$1}=1;
                    349:     }
                    350:     return %returnhash;
1.1       www       351: }
                    352: 
                    353: # ================================================== Critical message to a user
                    354: 
1.38      www       355: sub user_crit_msg_raw {
1.132     www       356:     my ($user,$domain,$subject,$message,$sendback,$toperm)=@_;
1.2       www       357: # Check if allowed missing
                    358:     my $status='';
                    359:     my $msgid='undefined';
                    360:     unless (($message)&&($user)&&($domain)) { $status='empty'; };
1.131     www       361:     my $text=$message;
1.2       www       362:     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
                    363:     if ($homeserver ne 'no_host') {
1.3       www       364:        ($msgid,$message)=&packagemsg($subject,$message);
1.24      www       365:        if ($sendback) { $message.='<sendback>true</sendback>'; }
1.4       www       366:        $status=&Apache::lonnet::critical(
                    367:            'put:'.$domain.':'.$user.':critical:'.
                    368:            &Apache::lonnet::escape($msgid).'='.
                    369:            &Apache::lonnet::escape($message),$homeserver);
1.140     albertel  370:        if ($env{'request.course.id'}) {
1.45      www       371:           &user_normal_msg_raw(
1.140     albertel  372:             $env{'course.'.$env{'request.course.id'}.'.num'},
                    373:             $env{'course.'.$env{'request.course.id'}.'.domain'},
1.45      www       374:             'Critical ['.$user.':'.$domain.']',
                    375: 	    $message);
                    376:        }
1.2       www       377:     } else {
                    378:        $status='no_host';
                    379:     }
1.53      www       380: # Notifications
1.132     www       381:     my %userenv = &Apache::lonnet::get('environment',['critnotification',
                    382:                                                       'permanentemail'],
1.53      www       383:                                        $domain,$user);
                    384:     if ($userenv{'critnotification'}) {
1.131     www       385:       &sendnotification($userenv{'critnotification'},$user,$domain,$subject,1,
                    386: 			$text);
1.53      www       387:     }
1.132     www       388:     if ($toperm && $userenv{'permanentemail'}) {
                    389:       &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,1,
                    390: 			$text);
                    391:     }
1.53      www       392: # Log this
1.2       www       393:     &Apache::lonnet::logthis(
1.4       www       394:       'Sending critical email '.$msgid.
1.2       www       395:       ', log status: '.
1.140     albertel  396:       &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                    397:                          $env{'user.home'},
1.2       www       398:       'Sending critical '.$msgid.' to '.$user.' at '.$domain.' with status: '
1.4       www       399:       .$status));
1.2       www       400:     return $status;
                    401: }
                    402: 
1.38      www       403: # New routine that respects "forward" and calls old routine
                    404: 
1.58      bowersj2  405: =pod
                    406: 
                    407: =item * B<user_crit_msg($user, $domain, $subject, $message, $sendback)>: Sends
                    408:     a critical message $message to the $user at $domain. If $sendback is true,
                    409:     a reciept will be sent to the current user when $user recieves the message.
                    410: 
                    411: =cut
                    412: 
1.38      www       413: sub user_crit_msg {
1.133     www       414:     my ($user,$domain,$subject,$message,$sendback,$toperm)=@_;
1.38      www       415:     my $status='';
                    416:     my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                    417:                                        $domain,$user);
                    418:     my $msgforward=$userenv{'msgforward'};
                    419:     if ($msgforward) {
                    420:        foreach (split(/\,/,$msgforward)) {
                    421: 	 my ($forwuser,$forwdomain)=split(/\:/,$_);
                    422:          $status.=
                    423: 	   &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,
1.133     www       424:                 $sendback,$toperm).' ';
1.38      www       425:        }
                    426:     } else { 
1.133     www       427: 	$status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback,$toperm);
1.38      www       428:     }
                    429:     return $status;
                    430: }
                    431: 
1.2       www       432: # =================================================== Critical message received
                    433: 
                    434: sub user_crit_received {
1.12      www       435:     my $msgid=shift;
                    436:     my %message=&Apache::lonnet::get('critical',[$msgid]);
1.52      www       437:     my %contents=&unpackagemsg($message{$msgid},1);
1.24      www       438:     my $status='rec: '.($contents{'sendback'}?
1.5       www       439:      &user_normal_msg($contents{'sendername'},$contents{'senderdomain'},
1.140     albertel  440:                      &mt('Receipt').': '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.', '.$contents{'subject'},
                    441:                      &mt('User').' '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.
1.42      www       442:                      ' acknowledged receipt of message'."\n".'   "'.
1.67      www       443:                      $contents{'subject'}.'"'."\n".&mt('dated').' '.
1.42      www       444:                      $contents{'time'}.".\n"
                    445:                      ):'no msg req');
1.5       www       446:     $status.=' trans: '.
1.12      www       447:      &Apache::lonnet::put(
                    448:      'nohist_email',{$contents{'msgid'} => $message{$msgid}});
1.5       www       449:     $status.=' del: '.
1.9       albertel  450:      &Apache::lonnet::del('critical',[$contents{'msgid'}]);
1.140     albertel  451:     &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                    452:                          $env{'user.home'},'Received critical message '.
1.5       www       453:                          $contents{'msgid'}.
                    454:                          ', '.$status);
1.12      www       455:     return $status;
1.2       www       456: }
                    457: 
                    458: # ======================================================== Normal communication
                    459: 
1.38      www       460: sub user_normal_msg_raw {
1.132     www       461:     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
                    462: 	$toperm)=@_;
1.2       www       463: # Check if allowed missing
                    464:     my $status='';
                    465:     my $msgid='undefined';
1.131     www       466:     my $text=$message;
1.2       www       467:     unless (($message)&&($user)&&($domain)) { $status='empty'; };
                    468:     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
                    469:     if ($homeserver ne 'no_host') {
1.51      www       470:        ($msgid,$message)=&packagemsg($subject,$message,$citation,$baseurl,
1.108     www       471:                                      $attachmenturl,$user,$domain);
                    472: # Store in user folder
1.4       www       473:        $status=&Apache::lonnet::critical(
                    474:            'put:'.$domain.':'.$user.':nohist_email:'.
                    475:            &Apache::lonnet::escape($msgid).'='.
                    476:            &Apache::lonnet::escape($message),$homeserver);
1.108     www       477: # Save new message received time
1.40      www       478:        &Apache::lonnet::put
                    479:                          ('email_status',{'recnewemail'=>time},$domain,$user);
1.108     www       480: # Into sent-mail folder
                    481:        $status.=' '.&Apache::lonnet::critical(
1.140     albertel  482:            'put:'.$env{'user.domain'}.':'.$env{'user.name'}.
1.108     www       483: 					      ':nohist_email_sent:'.
                    484:            &Apache::lonnet::escape($msgid).'='.
1.140     albertel  485:            &Apache::lonnet::escape($message),$env{'user.home'});
1.2       www       486:     } else {
                    487:        $status='no_host';
1.53      www       488:     }
                    489: # Notifications
1.132     www       490:     my %userenv = &Apache::lonnet::get('environment',['notification',
                    491:                                                       'permanentemail'],
1.53      www       492:                                        $domain,$user);
                    493:     if ($userenv{'notification'}) {
1.131     www       494: 	&sendnotification($userenv{'notification'},$user,$domain,$subject,0,
                    495: 			  $text);
1.2       www       496:     }
1.132     www       497:     if ($toperm && $userenv{'permanentemail'}) {
                    498:       &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,0,
                    499: 			$text);
                    500:     }
1.140     albertel  501:     &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                    502:                          $env{'user.home'},
1.2       www       503:       'Sending '.$msgid.' to '.$user.' at '.$domain.' with status: '.$status);
                    504:     return $status;
                    505: }
1.38      www       506: 
                    507: # New routine that respects "forward" and calls old routine
                    508: 
1.58      bowersj2  509: =pod
                    510: 
                    511: =item * B<user_normal_msg($user, $domain, $subject, $message,
                    512:     $citation, $baseurl, $attachmenturl)>: Sends a message to the
                    513:     $user at $domain, with subject $subject and message $message.
                    514: 
                    515: =cut
                    516: 
1.38      www       517: sub user_normal_msg {
1.132     www       518:     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
                    519: 	$toperm)=@_;
1.38      www       520:     my $status='';
                    521:     my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                    522:                                        $domain,$user);
                    523:     my $msgforward=$userenv{'msgforward'};
                    524:     if ($msgforward) {
                    525:        foreach (split(/\,/,$msgforward)) {
                    526: 	 my ($forwuser,$forwdomain)=split(/\:/,$_);
                    527:          $status.=
                    528: 	  &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
1.132     www       529: 			       $citation,$baseurl,$attachmenturl,$toperm).' ';
1.38      www       530:        }
                    531:     } else { 
1.49      albertel  532: 	$status=&user_normal_msg_raw($user,$domain,$subject,$message,
1.132     www       533: 				     $citation,$baseurl,$attachmenturl,$toperm);
1.38      www       534:     }
                    535:     return $status;
                    536: }
                    537: 
1.2       www       538: 
1.106     www       539: # ============================================================ List all folders
                    540: 
                    541: sub folderlist {
                    542:     my $folder=shift;
                    543:     my @allfolders=&Apache::lonnet::getkeys('email_folders');
                    544:     if ($allfolders[0]=~/^error:/) { @allfolders=(); }
                    545:     return '<form method="post" action="/adm/email">'.
1.108     www       546: 	&mt('Folder').': '.
1.106     www       547: 	&Apache::loncommon::select_form($folder,'folder',
                    548: 			     ('' => &mt('INBOX'),'trash' => &mt('TRASH'),
1.114     www       549: 			      'new' => &mt('New Messages Only'),
1.113     www       550:                               'critical' => &mt('Critical'),
1.106     www       551: 			      'sent' => &mt('Sent Messages'),
                    552: 			      map { $_ => $_ } @allfolders)).
1.125     www       553: 			      ' '.&mt('Show').
                    554: 			      '<select name="interdis">'.
                    555: 			      join("\n",map { '<option value="'.$_.'"'.
                    556: 	 ($_==$interdis?' selected="selected"':'').'>'.$_.'</option>' }
                    557: 				   (10,20,50,100,200)).'</select>'.	
1.108     www       558:    '<input type="submit" value="'.&mt('View Folder').'" /><br />'.
1.140     albertel  559:     '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" />'.
1.118     www       560: 			      ($folder=~/^(new|critical)/?'</form>':'');
                    561: }
                    562: 
                    563: sub scrollbuttons {
                    564:     my ($start,$maxdis,$first,$finish,$total)=@_;
1.124     www       565:     unless ($total>0) { return ''; }
1.118     www       566:     $start++; $maxdis++;$first++;$finish++;
1.124     www       567:     return 
1.108     www       568:    '<input type="submit" name="firstview" value="'.&mt('First').'" />'.
                    569:    '<input type="submit" name="prevview" value="'.&mt('Previous').'" />'.
1.118     www       570:    '<input type="text" size="5" name="startdis" value="'.$start.'" onChange="this.form.submit()" /> of '.$maxdis.
1.108     www       571:    '<input type="submit" name="nextview" value="'.&mt('Next').'" />'.
1.118     www       572:    '<input type="submit" name="lastview" value="'.&mt('Last').'" /><br />'.
                    573:    &mt('Messages [_1] through [_2] of [_3]',$first,$finish,$total).'</form>';
1.106     www       574: }
1.108     www       575: 
1.106     www       576: # =============================================================== Folder suffix
                    577: 
                    578: sub foldersuffix {
                    579:     my $folder=shift;
                    580:     unless ($folder) { return ''; }
                    581:     return '_'.&Apache::lonnet::escape($folder);
                    582: }
                    583: 
1.7       www       584: # =============================================================== Status Change
                    585: 
                    586: sub statuschange {
1.106     www       587:     my ($msgid,$newstatus,$folder)=@_;
                    588:     my $suffix=&foldersuffix($folder);
                    589:     my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
1.7       www       590:     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
                    591:     unless ($status{$msgid}) { $status{$msgid}='new'; }
                    592:     unless (($status{$msgid} eq 'replied') || 
                    593:             ($status{$msgid} eq 'forwarded')) {
1.106     www       594: 	&Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
1.7       www       595:     }
1.14      www       596:     if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {
1.106     www       597: 	&Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
1.14      www       598:     }
1.7       www       599: }
1.14      www       600: 
1.106     www       601: # ============================================================= Make new folder
                    602: 
                    603: sub makefolder {
                    604:     my ($newfolder)=@_;
1.113     www       605:     if (($newfolder eq 'sent')
                    606:      || ($newfolder eq 'critical')
1.114     www       607:      || ($newfolder eq 'trash')
                    608:      || ($newfolder eq 'new')) { return; }
1.106     www       609:     &Apache::lonnet::put('email_folders',{$newfolder => time});
                    610: }
                    611: 
                    612: # ======================================================== Move between folders
                    613: 
                    614: sub movemsg {
                    615:     my ($msgid,$srcfolder,$trgfolder)=@_;
1.142     www       616:     if ($srcfolder eq 'new') { $srcfolder=''; }
1.106     www       617:     my $srcsuffix=&foldersuffix($srcfolder);
                    618:     my $trgsuffix=&foldersuffix($trgfolder);
1.107     www       619: 
                    620: # Copy message
                    621:     my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]);
                    622:     &Apache::lonnet::put('nohist_email'.$trgsuffix,{$msgid => $message{$msgid}});
                    623: 
                    624: # Copy status
1.128     www       625:     unless ($trgfolder eq 'trash') {
                    626: 	my %status=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);
                    627: 	&Apache::lonnet::put('email_status'.$trgsuffix,{$msgid => $status{$msgid}});
1.107     www       628:     }
                    629: # Delete orginals
1.106     www       630:     &Apache::lonnet::del('nohist_email'.$srcsuffix,[$msgid]);
1.127     www       631:     &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
1.106     www       632: }
                    633: 
1.17      www       634: # ======================================================= Display a course list
                    635: 
                    636: sub discourse {
                    637:     my $r=shift;
1.109     matthew   638:     my $classlist = &Apache::loncoursedata::get_classlist();
1.17      www       639:     my $now=time;
1.138     albertel  640:     my %lt=&Apache::lonlocal::texthash('cfa' => 'Check All',
                    641:             'cfs' => 'Check Section/Group',
                    642:             'cfn' => 'Uncheck All');
1.17      www       643:     $r->print(<<ENDDISHEADER);
1.92      www       644: <input type="hidden" name="sendmode" value="group" />
1.17      www       645: <script>
                    646:     function checkall() {
                    647: 	for (i=0; i<document.forms.compemail.elements.length; i++) {
                    648:             if 
                    649:           (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) {
                    650: 	      document.forms.compemail.elements[i].checked=true;
                    651:             }
                    652:         }
                    653:     }
                    654: 
1.19      www       655:     function checksec() {
                    656: 	for (i=0; i<document.forms.compemail.elements.length; i++) {
                    657:             if 
                    658:           (document.forms.compemail.elements[i].name.indexOf
                    659:            ('send_to_&&&'+document.forms.compemail.chksec.value)==0) {
                    660: 	      document.forms.compemail.elements[i].checked=true;
                    661:             }
                    662:         }
                    663:     }
                    664: 
1.17      www       665:     function uncheckall() {
                    666: 	for (i=0; i<document.forms.compemail.elements.length; i++) {
                    667:             if 
                    668:           (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) {
                    669: 	      document.forms.compemail.elements[i].checked=false;
                    670:             }
                    671:         }
                    672:     }
                    673: </script>
1.92      www       674: <input type="button" onClick="checkall()" value="$lt{'cfa'}" />&nbsp;
                    675: <input type="button" onClick="checksec()" value="$lt{'cfs'}" />
1.136     albertel  676: <input type="text" size="5" name="chksec" />&nbsp;
1.92      www       677: <input type="button" onClick="uncheckall()" value="$lt{'cfn'}" />
1.17      www       678: <p>
                    679: ENDDISHEADER
1.109     matthew   680:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles();
                    681:     $r->print('<table>');
1.61      www       682:     foreach my $role (sort keys %coursepersonnel) {
1.109     matthew   683:         foreach (split(/\,/,$coursepersonnel{$role})) {
                    684:             my ($puname,$pudom)=split(/\:/,$_);
                    685:             $r->print('<tr><td><label>'.
                    686:                       '<input type="checkbox" name="send_to_&&&&&&_'.
                    687:                       $puname.':'.$pudom.'" /> '.
                    688:                       &Apache::loncommon::plainname($puname,$pudom).
                    689:                       '</label></td>'.
                    690:                       '<td>('.$_.'),</td><td><i>'.$role.'</i></td></tr>');
                    691:         }
1.61      www       692:     }
1.110     matthew   693:     $r->print('</table><table>');
1.134     albertel  694:     my $sort = sub {
                    695: 	my $aname=lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]);
                    696: 	if (!$aname) { $aname=$a; }
                    697: 	my $bname=lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]);
                    698: 	if (!$bname) { $bname=$b; }
                    699: 	return $aname cmp $bname;
                    700:     };
                    701:     foreach my $student (sort $sort (keys(%{$classlist}))) {
                    702: 	my $info=$classlist->{$student};
1.109     matthew   703:         my ($sname,$sdom,$status,$fullname,$section) =
                    704:             (@{$info}[&Apache::loncoursedata::CL_SNAME(),
                    705:                       &Apache::loncoursedata::CL_SDOM(),
                    706:                       &Apache::loncoursedata::CL_STATUS(),
                    707:                       &Apache::loncoursedata::CL_FULLNAME(),
                    708:                       &Apache::loncoursedata::CL_SECTION()]);
1.110     matthew   709:         next if ($status ne 'Active');
1.143     albertel  710: 	next if ($env{'request.course.sec'} &&
                    711: 		 $section ne $env{'request.course.sec'});
1.129     matthew   712:         my $key = 'send_to_&&&'.$section.'&&&_'.$student;
1.109     matthew   713:         if (! defined($fullname) || $fullname eq '') { $fullname = $sname; }
                    714:         $r->print('<tr><td><label>'.
1.136     albertel  715:                   qq{<input type="checkbox" name="$key" />}.('&nbsp;'x2).
                    716:                   $fullname.'</label></td><td>'.$sname.'@'.$sdom.'</td><td>'.$section.
1.109     matthew   717:                   '</td></tr>');
1.28      harris41  718:     }
1.110     matthew   719:     $r->print('</table>');
1.17      www       720: }
                    721: 
1.13      www       722: # ==================================================== Display Critical Message
1.5       www       723: 
1.12      www       724: sub discrit {
                    725:     my $r=shift;
1.67      www       726:     my $header = '<h1><font color=red>'.&mt('Critical Messages').'</font></h1>'.
1.136     albertel  727:         '<form action="/adm/email" method="POST">'.
                    728:         '<input type="hidden" name="confirm" value="true" />';
1.30      matthew   729:     my %what=&Apache::lonnet::dump('critical');
                    730:     my $result = '';
                    731:     foreach (sort keys %what) {
                    732:         my %content=&unpackagemsg($what{$_});
                    733:         next if ($content{'senderdomain'} eq '');
1.106     www       734:         $result.='<hr />'.&mt('From').': <b>'.
1.37      www       735: &Apache::loncommon::aboutmewrapper(
                    736:  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
                    737: $content{'sendername'}.'@'.
                    738:             $content{'senderdomain'}.') '.$content{'time'}.
1.106     www       739:             '<br />'.&mt('Subject').': '.$content{'subject'}.
1.130     albertel  740:             '<br /><pre>'.
1.36      www       741:               &Apache::lontexconvert::msgtexconverted($content{'message'}).
1.130     albertel  742:             '</pre><small>'.
1.84      www       743: &mt('You have to confirm that you received this message. After confirmation, this message will be moved to your regular inbox').
                    744:             '</small><br />'.
1.136     albertel  745:             '<input type="submit" name="rec_'.$_.'" value="'.&mt('Confirm Receipt').'" />'.
                    746:             '<input type="submit" name="reprec_'.$_.'" '.
                    747:                   'value="'.&mt('Confirm Receipt and Reply').'" />';
1.30      matthew   748:     }
                    749:     # Check to see if there were any messages.
                    750:     if ($result eq '') {
1.67      www       751:         $result = "<h2>".&mt('You have no critical messages.')."</h2>".
1.106     www       752: 	    '<a href="/adm/roles">'.&mt('Select a course').'</a><br />'.
                    753:             '<a href="/adm/email">'.&mt('Communicate').'</a>';
1.30      matthew   754:     } else {
                    755:         $r->print($header);
                    756:     }
                    757:     $r->print($result);
1.108     www       758:     $r->print('<input type="hidden" name="displayedcrit" value="true" /></form>');
1.12      www       759: }
                    760: 
1.65      www       761: sub sortedmessages {
1.106     www       762:     my ($blocked,$startblock,$endblock,$numblocked,$folder) = @_;
                    763:     my $suffix=&foldersuffix($folder);
                    764:     my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
1.65      www       765:     #unpack the varibles and repack into temp for sorting
                    766:     my @temp;
                    767:     foreach (@messages) {
                    768: 	my $msgid=&Apache::lonnet::escape($_);
1.141     raeburn   769: 	my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)=
1.108     www       770: 	    &Apache::lonmsg::unpackmsgid($msgid,$folder);
1.65      www       771: 	my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
                    772: 		     $msgid);
1.101     raeburn   773:         # Check whether message was sent during blocking period.
                    774:         if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {
                    775:             my $escid = &Apache::lonnet::unescape($msgid);
                    776:             $$blocked{$escid} = 'ON';
                    777:             $$numblocked ++;
                    778:         } else { 
                    779:             push @temp ,\@temp1;
                    780:         }
1.65      www       781:     }
                    782:     #default sort
                    783:     @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
1.140     albertel  784:     if ($env{'form.sortedby'} eq "date"){
1.65      www       785:         @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
                    786:     }
1.140     albertel  787:     if ($env{'form.sortedby'} eq "revdate"){
1.65      www       788:     	@temp = sort  {$b->[0] <=> $a->[0]} @temp; 
                    789:     }
1.140     albertel  790:     if ($env{'form.sortedby'} eq "user"){
1.65      www       791: 	@temp = sort  {lc($a->[2]) cmp lc($b->[2])} @temp;
                    792:     }
1.140     albertel  793:     if ($env{'form.sortedby'} eq "revuser"){
1.65      www       794: 	@temp = sort  {lc($b->[2]) cmp lc($a->[2])} @temp;
                    795:     }
1.140     albertel  796:     if ($env{'form.sortedby'} eq "domain"){
1.65      www       797:         @temp = sort  {$a->[3] cmp $b->[3]} @temp;
                    798:     }
1.140     albertel  799:     if ($env{'form.sortedby'} eq "revdomain"){
1.65      www       800:         @temp = sort  {$b->[3] cmp $a->[3]} @temp;
                    801:     }
1.140     albertel  802:     if ($env{'form.sortedby'} eq "subject"){
1.65      www       803:         @temp = sort  {lc($a->[1]) cmp lc($b->[1])} @temp;
                    804:     }
1.140     albertel  805:     if ($env{'form.sortedby'} eq "revsubject"){
1.65      www       806:         @temp = sort  {lc($b->[1]) cmp lc($a->[1])} @temp;
                    807:     }
1.140     albertel  808:     if ($env{'form.sortedby'} eq "status"){
1.65      www       809:         @temp = sort  {$a->[4] cmp $b->[4]} @temp;
                    810:     }
1.140     albertel  811:     if ($env{'form.sortedby'} eq "revstatus"){
1.65      www       812:         @temp = sort  {$b->[4] cmp $a->[4]} @temp;
                    813:     }
                    814:     return @temp;
                    815: }
                    816: 
1.112     www       817: # ======================================================== Display new messages
                    818: 
                    819: 
                    820: sub disnew {
                    821:     my $r=shift;
                    822:     my %lt=&Apache::lonlocal::texthash(
                    823: 				       'nm' => 'New Messages',
                    824: 				       'su' => 'Subject',
                    825: 				       'da' => 'Date',
                    826: 				       'us' => 'Username',
                    827: 				       'op' => 'Open',
                    828: 				       'do' => 'Domain'
                    829: 				       );
                    830:     my @msgids = sort split(/\&/,&Apache::lonnet::reply
1.140     albertel  831:                             ('keys:'.$env{'user.domain'}.':'.
                    832:                              $env{'user.name'}.':nohist_email',
                    833:                              $env{'user.home'}));
1.112     www       834:     my @newmsgs;
                    835:     my %setters = ();
                    836:     my $startblock = 0;
                    837:     my $endblock = 0;
                    838:     my %blocked = ();
                    839:     my $numblocked = 0;
                    840:     # Check for blocking of display because of scheduled online exams.
                    841:     &blockcheck(\%setters,\$startblock,\$endblock);
                    842:     foreach (@msgids) {
1.141     raeburn   843:         my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
1.112     www       844: 	    &Apache::lonmsg::unpackmsgid($_);
                    845:         if (defined($sendtime) && $sendtime!~/error/) {
                    846:             my $numsendtime = $sendtime;
                    847:             $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
                    848:             if ($status eq 'new') {
                    849:                 if ($numsendtime >= $startblock && ($numsendtime <= $endblock && $endblock > 0) ) {
                    850:                     $blocked{$_} = 'ON';
                    851:                     $numblocked ++;
                    852:                 } else {
                    853:                     push @newmsgs, { 
                    854:                         msgid    => $_,
                    855:                         sendtime => $sendtime,
                    856:                         shortsub => &Apache::lonnet::unescape($shortsubj),
                    857:                         from     => $fromname,
                    858:                         fromdom  => $fromdom 
                    859:                         }
                    860:                 }
                    861:             }
                    862:         }
                    863:     }
                    864:     if ($#newmsgs >= 0) {
                    865:         $r->print(<<TABLEHEAD);
                    866: <h2>$lt{'nm'}</h2>
                    867: <table border=2><tr><th>&nbsp</th>
                    868: <th>$lt{'da'}</th><th>$lt{'us'}</th><th>$lt{'do'}</th><th>$lt{'su'}</th></tr>
                    869: TABLEHEAD
                    870:         foreach my $msg (@newmsgs) {
                    871:             $r->print(<<"ENDLINK");
                    872: <tr bgcolor="#FFBB77">
1.131     www       873: <td><a href="/adm/email?dismode=new&display=$msg->{'msgid'}">$lt{'op'}</a></td>
1.112     www       874: ENDLINK
                    875:             foreach ('sendtime','from','fromdom','shortsub') {
                    876:                 $r->print("<td>$msg->{$_}</td>");
                    877:             }
                    878:             $r->print("</td></tr>");
                    879:         }
1.139     albertel  880:         $r->print('</table>'.&Apache::loncommon::endbodytag().'</html>');
1.112     www       881:     } elsif ($numblocked == 0) {
                    882:         $r->print("<h3>".&mt('You have no unread messages')."</h3>");
                    883:     }
                    884:     if ($numblocked > 0) {
                    885:         my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
                    886:         my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
                    887:         if ($numblocked == 1) {
                    888:             $r->print("<h3>".&mt('You have').' '.$numblocked.' '.&mt('blocked unread message').".</h3>");
                    889:             $r->print(&mt('This message is not viewable because').' ');
                    890:         } else {
                    891:             $r->print("<h3>".&mt('You have').' '.$numblocked.' '.&mt('blocked unread messages').".</h3>");
                    892:             $r->print(&mt('These').' '.$numblocked.' '.&mt('messages are not viewable because '));
                    893:         }
                    894:         $r->print(
                    895: &mt('display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams').'.');
                    896:         &build_block_table($r,$startblock,$endblock,\%setters);
                    897:     }
                    898: }
                    899: 
                    900: 
1.15      www       901: # ======================================================== Display all messages
                    902: 
1.14      www       903: sub disall {
1.106     www       904:     my ($r,$folder)=@_;
1.113     www       905:     $r->print(&folderlist($folder));
1.114     www       906:     if ($folder eq 'new') {
                    907: 	&disnew($r);
                    908:     } elsif ($folder eq 'critical') {
                    909: 	&discrit($r);
                    910:     } else {
                    911: 	&disfolder($r,$folder);
1.113     www       912:     }
1.114     www       913: }
                    914: 
                    915: # ============================================================ Display a folder
                    916: 
                    917: sub disfolder {
                    918:     my ($r,$folder)=@_;
1.101     raeburn   919:     my %blocked = ();
                    920:     my %setters = ();
                    921:     my $startblock;
                    922:     my $endblock;
                    923:     my $numblocked = 0;
                    924:     &blockcheck(\%setters,\$startblock,\$endblock);
                    925:     $r->print(<<ENDDISHEADER);
1.29      www       926: <script>
                    927:     function checkall() {
                    928: 	for (i=0; i<document.forms.disall.elements.length; i++) {
                    929:             if 
                    930:           (document.forms.disall.elements[i].name.indexOf('delmark_')==0) {
                    931: 	      document.forms.disall.elements[i].checked=true;
                    932:             }
                    933:         }
                    934:     }
                    935: 
                    936:     function uncheckall() {
                    937: 	for (i=0; i<document.forms.disall.elements.length; i++) {
                    938:             if 
                    939:           (document.forms.disall.elements[i].name.indexOf('delmark_')==0) {
                    940: 	      document.forms.disall.elements[i].checked=false;
                    941:             }
                    942:         }
                    943:     }
                    944: </script>
                    945: ENDDISHEADER
1.108     www       946:     my $fsqs='&folder='.$folder;
                    947:     my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
                    948:     my $totalnumber=$#temp+1;
1.124     www       949:     unless ($totalnumber>0) {
                    950: 	$r->print('<h2>'.&mt('Empty Folder').'</h2>');
                    951: 	return;
                    952:     }
1.125     www       953:     unless ($interdis) {
                    954: 	$interdis=20;
                    955:     }
1.118     www       956:     my $number=int($totalnumber/$interdis);
                    957:     if (($startdis<0) || ($startdis>$number)) { $startdis=$number; }
1.108     www       958:     my $firstdis=$interdis*$startdis;
                    959:     if ($firstdis>$#temp) { $firstdis=$#temp-$interdis+1; }
                    960:     my $lastdis=$firstdis+$interdis-1;
                    961:     if ($lastdis>$#temp) { $lastdis=$#temp; }
1.118     www       962:     $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber));
1.113     www       963:     $r->print('<form method="post" name="disall" action="/adm/email">'.
1.106     www       964: 	      '<table border=2><tr><th colspan="3">&nbsp</th><th>');
1.140     albertel  965:     if ($env{'form.sortedby'} eq "revdate") {
1.108     www       966: 	$r->print('<a href = "?sortedby=date'.$fsqs.'">'.&mt('Date').'</a></th>');
1.62      www       967:     } else {
1.108     www       968: 	$r->print('<a href = "?sortedby=revdate'.$fsqs.'">'.&mt('Date').'</a></th>');
1.62      www       969:     }
                    970:     $r->print('<th>');
1.140     albertel  971:     if ($env{'form.sortedby'} eq "revuser") {
1.108     www       972: 	$r->print('<a href = "?sortedby=user'.$fsqs.'">'.&mt('Username').'</a>');
1.62      www       973:     } else {
1.108     www       974: 	$r->print('<a href = "?sortedby=revuser'.$fsqs.'">'.&mt('Username').'</a>');
1.62      www       975:     }
                    976:     $r->print('</th><th>');
1.140     albertel  977:     if ($env{'form.sortedby'} eq "revdomain") {
1.108     www       978: 	$r->print('<a href = "?sortedby=domain'.$fsqs.'">'.&mt('Domain').'</a>');
1.62      www       979:     } else {
1.108     www       980: 	$r->print('<a href = "?sortedby=revdomain'.$fsqs.'">'.&mt('Domain').'</a>');
1.62      www       981:     }
                    982:     $r->print('</th><th>');
1.140     albertel  983:     if ($env{'form.sortedby'} eq "revsubject") {
1.108     www       984: 	$r->print('<a href = "?sortedby=subject'.$fsqs.'">'.&mt('Subject').'</a>');
1.62      www       985:     } else {
1.108     www       986:     	$r->print('<a href = "?sortedby=revsubject'.$fsqs.'">'.&mt('Subject').'</a>');
1.62      www       987:     }
                    988:     $r->print('</th><th>');
1.140     albertel  989:     if ($env{'form.sortedby'} eq "revstatus") {
1.135     albertel  990: 	$r->print('<a href = "?sortedby=status'.$fsqs.'">'.&mt('Status').'</a></th>');
1.62      www       991:     } else {
1.135     albertel  992:      	$r->print('<a href = "?sortedby=revstatus'.$fsqs.'">'.&mt('Status').'</a></th>');
1.62      www       993:     }
1.126     www       994:     $r->print("</tr>\n");
1.108     www       995:     for (my $n=$firstdis;$n<=$lastdis;$n++) {
                    996: 	my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @{$temp[$n]};
1.63      albertel  997: 	if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) {
1.39      albertel  998: 	    if ($status eq 'new') {
                    999: 		$r->print('<tr bgcolor="#FFBB77">');
                   1000: 	    } elsif ($status eq 'read') {
                   1001: 		$r->print('<tr bgcolor="#BBBB77">');
                   1002: 	    } elsif ($status eq 'replied') {
1.62      www      1003: 		$r->print('<tr bgcolor="#AAAA88">'); 
1.39      albertel 1004: 	    } else {
                   1005: 		$r->print('<tr bgcolor="#99BBBB">');
                   1006: 	    }
1.136     albertel 1007: 	    $r->print('<td><input type="checkbox" name="delmark_'.$origID.'" /></td><td><a href="/adm/email?display='.$origID.$sqs. 
1.106     www      1008: 		      '">'.&mt('Open').'</a></td><td>'.
                   1009: 		      ($folder ne 'trash'?'<a href="/adm/email?markdel='.$origID.$sqs.
1.135     albertel 1010: 		      '">'.&mt('Delete'):'&nbsp').'</a></td>'.
1.66      www      1011: 		      '<td>'.&Apache::lonlocal::locallocaltime($sendtime).'</td><td>'.
1.39      albertel 1012: 		      $fromname.'</td><td>'.$fromdomain.'</td><td>'.
1.14      www      1013: 		      &Apache::lonnet::unescape($shortsubj).'</td><td>'.
1.126     www      1014:                       $status."</td></tr>\n");
1.106     www      1015: 	} elsif ($status eq 'deleted') {
                   1016: # purge
1.108     www      1017: 	    &movemsg(&Apache::lonnet::unescape($origID),$folder,'trash');
1.63      albertel 1018: 	}
                   1019:     }   
1.126     www      1020:     $r->print("</table>\n<p>".
1.106     www      1021:   '<a href="javascript:checkall()">'.&mt('Check All').'</a>&nbsp;'.
                   1022:   '<a href="javascript:uncheckall()">'.&mt('Uncheck All').'</a></p>'.
1.140     albertel 1023:   '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" />');
1.106     www      1024:     if ($folder ne 'trash') {
                   1025: 	$r->print(
                   1026: 	      '<p><input type="submit" name="markeddel" value="'.&mt('Delete Checked').'" /></p>');
                   1027:     }
1.118     www      1028:     $r->print('<p><input type="submit" name="markedmove" value="'.&mt('Move Checked to Folder').'" />');
1.106     www      1029:     my @allfolders=&Apache::lonnet::getkeys('email_folders');
                   1030:     if ($allfolders[0]=~/^error:/) { @allfolders=(); }
                   1031:     $r->print(
                   1032: 	&Apache::loncommon::select_form('','movetofolder',
                   1033: 			     ( map { $_ => $_ } @allfolders))
                   1034: 	      );
1.126     www      1035:     my $postedstartdis=$startdis+1;
1.140     albertel 1036:     $r->print('<input type="hidden" name="folder" value="'.$folder.'" /><input type="hidden" name="startdis" value="'.$postedstartdis.'" /><input type="hidden" name="interdis" value="'.$env{'form.interdis'}.'" /></form>');
1.101     raeburn  1037:     if ($numblocked > 0) {
                   1038:         my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
                   1039:         my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
                   1040:         $r->print('<br /><br />'.
                   1041:                   $numblocked.' '.&mt('message(s) is/are not viewable because display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams.'));
                   1042:         &build_block_table($r,$startblock,$endblock,\%setters);
                   1043:     }
1.14      www      1044: }
                   1045: 
1.15      www      1046: # ============================================================== Compose output
                   1047: 
                   1048: sub compout {
1.142     www      1049:     my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_;
1.121     www      1050:     my $suffix=&foldersuffix($folder);
1.92      www      1051: 
                   1052:     if ($broadcast eq 'individual') {
                   1053: 	&printheader($r,'/adm/email?compose=individual',
                   1054: 	     'Send a Message');
                   1055:     } elsif ($broadcast) {
                   1056: 	&printheader($r,'/adm/email?compose=group',
                   1057: 	     'Broadcast Message');
                   1058:     } elsif ($forwarding) {
                   1059: 	&Apache::lonhtmlcommon::add_breadcrumb
                   1060:         ({href=>"/adm/email?display=".&Apache::lonnet::escape($forwarding),
                   1061:           text=>"Display Message"});
                   1062: 	&printheader($r,'/adm/email?forward='.&Apache::lonnet::escape($forwarding),
                   1063: 	     'Forwarding a Message');
                   1064:     } elsif ($replying) {
                   1065: 	&Apache::lonhtmlcommon::add_breadcrumb
                   1066:         ({href=>"/adm/email?display=".&Apache::lonnet::escape($replying),
                   1067:           text=>"Display Message"});
                   1068: 	&printheader($r,'/adm/email?replyto='.&Apache::lonnet::escape($replying),
                   1069: 	     'Replying to a Message');
1.94      www      1070:     } elsif ($replycrit) {
                   1071: 	$r->print('<h3>'.&mt('Replying to a Critical Message').'</h3>');
                   1072: 	$replying=$replycrit;
1.92      www      1073:     } else {
                   1074: 	&printheader($r,'/adm/email?compose=upload',
                   1075: 	     'Distribute from Uploaded File');
                   1076:     }
                   1077: 
1.89      www      1078:     my $dispcrit='';
1.15      www      1079:     my $dissub='';
                   1080:     my $dismsg='';
1.115     www      1081:     my $disbase='';
1.67      www      1082:     my $func=&mt('Send New');
1.69      www      1083:     my %lt=&Apache::lonlocal::texthash('us' => 'Username',
                   1084: 				       'do' => 'Domain',
                   1085: 				       'ad' => 'Additional Recipients',
                   1086: 				       'sb' => 'Subject',
                   1087: 				       'ca' => 'Cancel',
                   1088: 				       'ma' => 'Mail');
                   1089: 
1.140     albertel 1090:     if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
1.35      bowersj2 1091: 	 my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
1.15      www      1092:          $dispcrit=
1.136     albertel 1093:  '<p><label><input type="checkbox" name="critmsg" /> '.&mt('Send as critical message').'</label> ' . $crithelp . 
                   1094:  '</p><p>'.
                   1095:  '<label><input type="checkbox" name="sendbck" /> '.&mt('Send as critical message').'  ' .
                   1096:  &mt('and return receipt') . '</label>' . $crithelp . 
                   1097:  '</p><p><label><input type="checkbox" name="permanent" /> '.
                   1098: &mt('Send copy to permanent email address (if known)').'</label></p>';
1.92      www      1099:      }
                   1100:     my %message;
                   1101:     my %content;
1.140     albertel 1102:     my $defdom=$env{'user.domain'};
1.15      www      1103:     if ($forwarding) {
1.121     www      1104: 	%message=&Apache::lonnet::get('nohist_email'.$suffix,[$forwarding]);
1.108     www      1105: 	%content=&unpackagemsg($message{$forwarding},$folder);
1.92      www      1106: 	$dispcrit.='<input type="hidden" name="forwid" value="'.
                   1107: 	    $forwarding.'" />';
                   1108: 	$func=&mt('Forward');
                   1109: 	
                   1110: 	$dissub=&mt('Forwarding').': '.$content{'subject'};
                   1111: 	$dismsg=&mt('Forwarded message from').' '.
                   1112: 	    $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'};
1.115     www      1113: 	if ($content{'baseurl'}) {
                   1114: 	    $disbase='<input type="hidden" name="baseurl" value="'.&Apache::lonnet::escape($content{'baseurl'}).'" />';
                   1115: 	}
1.92      www      1116:     }
                   1117:     if ($replying) {
1.121     www      1118: 	%message=&Apache::lonnet::get('nohist_email'.$suffix,[$replying]);
1.108     www      1119: 	%content=&unpackagemsg($message{$replying},$folder);
1.105     albertel 1120: 	$dispcrit.='<input type="hidden" name="replyid" value="'.
                   1121: 	    $replying.'" />';
1.108     www      1122: 	$func=&mt('Send Reply to');
1.92      www      1123: 	
                   1124: 	$dissub=&mt('Reply').': '.$content{'subject'};       
                   1125: 	$dismsg='> '.$content{'message'};
                   1126: 	$dismsg=~s/\r/\n/g;
                   1127: 	$dismsg=~s/\f/\n/g;
                   1128: 	$dismsg=~s/\n+/\n\> /g;
1.115     www      1129: 	if ($content{'baseurl'}) {
                   1130: 	    $disbase='<input type="hidden" name="baseurl" value="'.&Apache::lonnet::escape($content{'baseurl'}).'" />';
1.140     albertel 1131: 	    if ($env{'user.adv'}) {
1.136     albertel 1132: 		$disbase.='<label><input type="checkbox" name="storebasecomment" />'.&mt('Store message for re-use').
                   1133: 		    '</label> <a href="/adm/email?showcommentbaseurl='.
1.120     www      1134: 		    &Apache::lonnet::escape($content{'baseurl'}).'" target="comments">'.
                   1135: 		    &mt('Show re-usable messages').'</a><br />';
1.115     www      1136: 	    }
                   1137: 	}
1.15      www      1138:     }
1.111     www      1139:     my $citation=&displayresource(%content);
1.140     albertel 1140:     if ($env{'form.recdom'}) { $defdom=$env{'form.recdom'}; }
1.22      www      1141:       $r->print(
1.31      matthew  1142:                 '<form action="/adm/email"  name="compemail" method="post"'.
                   1143:                 ' enctype="multipart/form-data">'."\n".
1.92      www      1144:                 '<input type="hidden" name="sendmail" value="on" />'."\n".
1.31      matthew  1145:                 '<table>');
1.22      www      1146:     unless (($broadcast eq 'group') || ($broadcast eq 'upload')) {
1.92      www      1147: 	if ($replying) {
                   1148: 	    $r->print('<tr><td colspan="2">'.&mt('Replying to').' '.
                   1149: 		      &Apache::loncommon::aboutmewrapper(
                   1150: 							 &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('.
                   1151: 		      $content{'sendername'}.'@'.
                   1152: 		      $content{'senderdomain'}.')'.
                   1153: 		      '<input type="hidden" name="recuname" value="'.$content{'sendername'}.'" />'.
                   1154: 		      '<input type="hidden" name="recdomain" value="'.$content{'senderdomain'}.'" />'.
                   1155: 		      '</td></tr>');
                   1156: 	} else {
                   1157: 	    my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');
                   1158: 	    my $selectlink=&Apache::loncommon::selectstudent_link
1.46      www      1159: 	    ('compemail','recuname','recdomain');
1.92      www      1160: 	    $r->print(<<"ENDREC");
1.140     albertel 1161: <tr><td>$lt{'us'}:</td><td><input type="text" size="12" name="recuname" value="$env{'form.recname'}" /></td><td rowspan="2">$selectlink</td></tr>
1.69      www      1162: <tr><td>$lt{'do'}:</td>
1.31      matthew  1163: <td>$domform</td></tr>
1.17      www      1164: ENDREC
1.92      www      1165:         }
1.17      www      1166:     }
1.55      bowersj2 1167:     my $latexHelp = Apache::loncommon::helpLatexCheatsheet();
1.31      matthew  1168:     if ($broadcast ne 'upload') {
1.22      www      1169:        $r->print(<<"ENDCOMP");
1.69      www      1170: <tr><td>$lt{'ad'}<br /><tt>username\@domain,username\@domain, ...
1.20      www      1171: </tt></td><td>
1.91      www      1172: <input type="text" size="50" name="additionalrec" /></td></tr>
                   1173: <tr><td>$lt{'sb'}:</td><td><input type="text" size="50" name="subject" value="$dissub" />
1.15      www      1174: </td></tr></table>
1.55      bowersj2 1175: $latexHelp
1.144     albertel 1176: <textarea name="message" id="message" cols="80" rows="15" wrap="hard">$dismsg
1.69      www      1177: </textarea></p><br />
1.15      www      1178: $dispcrit
1.115     www      1179: $disbase
1.142     www      1180: <input type="hidden" name="folder" value="$folder" />
                   1181: <input type="hidden" name="dismode" value="$dismode" />
1.69      www      1182: <input type="submit" name="send" value="$func $lt{'ma'}" />
1.111     www      1183: <input type="submit" name="cancel" value="$lt{'ca'}" /><hr />
                   1184: $citation
1.15      www      1185: ENDCOMP
1.31      matthew  1186:     } else { # $broadcast is 'upload'
1.22      www      1187: 	$r->print(<<ENDUPLOAD);
1.91      www      1188: <input type="hidden" name="sendmode" value="upload" />
1.86      www      1189: <input type="hidden" name="send" value="on" />
1.22      www      1190: <h3>Generate messages from a file</h3>
1.31      matthew  1191: <p>
1.91      www      1192: Subject: <input type="text" size="50" name="subject" />
1.31      matthew  1193: </p>
                   1194: <p>General message text<br />
1.144     albertel 1195: <textarea name="message" id="message" cols="60" rows="10" wrap="hard">$dismsg
1.31      matthew  1196: </textarea></p>
                   1197: <p>
                   1198: The file format for the uploaded portion of the message is:
1.22      www      1199: <pre>
                   1200: username1\@domain1: text
                   1201: username2\@domain2: text
1.31      matthew  1202: username3\@domain1: text
1.22      www      1203: </pre>
1.31      matthew  1204: </p>
                   1205: <p>
1.22      www      1206: The messages will be assembled from all lines with the respective 
1.31      matthew  1207: <tt>username\@domain</tt>, and appended to the general message text.</p>
                   1208: <p>
1.91      www      1209: <input type="file" name="upfile" size="40" /></p><p>
1.22      www      1210: $dispcrit
1.92      www      1211: <input type="submit" value="Upload and Send" /></p>
1.22      www      1212: ENDUPLOAD
                   1213:     }
1.17      www      1214:     if ($broadcast eq 'group') {
                   1215:        &discourse;
                   1216:     }
1.144     albertel 1217:     $r->print('</form>'.
                   1218: 	      &Apache::lonhtmlcommon::htmlareaselectactive('message'));
1.15      www      1219: }
                   1220: 
1.45      www      1221: # ---------------------------------------------------- Display all face to face
                   1222: 
1.104     matthew  1223: sub retrieve_instructor_comments {
                   1224:     my ($user,$domain)=@_;
1.140     albertel 1225:     my $target=$env{'form.grade_target'};
                   1226:     if (! $env{'request.course.id'}) { return; }
                   1227:     if (! &Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
1.104     matthew  1228: 	return;
                   1229:     }
                   1230:     my %records=&Apache::lonnet::dump('nohist_email',
1.140     albertel 1231: 			 $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1232: 			 $env{'course.'.$env{'request.course.id'}.'.num'},
1.104     matthew  1233:                          '%255b'.$user.'%253a'.$domain.'%255d');
                   1234:     my $result='';
                   1235:     foreach (sort(keys(%records))) {
                   1236:         my %content=&unpackagemsg($records{$_});
                   1237:         next if ($content{'senderdomain'} eq '');
                   1238:         next if ($content{'subject'} !~ /^Record/);
1.145     albertel 1239: 	# &Apache::lonfeedback::newline_to_br(\$content{'message'});
                   1240: 	$result.='Recorded by '.
1.104     matthew  1241:             $content{'sendername'}.'@'.$content{'senderdomain'}."\n";
                   1242:         $result.=
                   1243:             &Apache::lontexconvert::msgtexconverted($content{'message'})."\n";
                   1244:      }
                   1245:     return $result;
                   1246: }
                   1247: 
1.45      www      1248: sub disfacetoface {
                   1249:     my ($r,$user,$domain)=@_;
1.140     albertel 1250:     my $target=$env{'form.grade_target'};
                   1251:     unless ($env{'request.course.id'}) { return; }
                   1252:     unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
1.45      www      1253: 	return;
                   1254:     }
                   1255:     my %records=&Apache::lonnet::dump('nohist_email',
1.140     albertel 1256: 			 $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1257: 			 $env{'course.'.$env{'request.course.id'}.'.num'},
1.45      www      1258:                          '%255b'.$user.'%253a'.$domain.'%255d');
                   1259:     my $result='';
                   1260:     foreach (sort keys %records) {
                   1261:         my %content=&unpackagemsg($records{$_});
                   1262:         next if ($content{'senderdomain'} eq '');
1.145     albertel 1263: 	&Apache::lonfeedback::newline_to_br(\$content{'message'});
1.45      www      1264:         if ($content{'subject'}=~/^Record/) {
1.69      www      1265: 	    $result.='<h3>'.&mt('Record').'</h3>';
1.102     raeburn  1266:         } elsif ($content{'subject'}=~/^Broadcast/) {
                   1267:             $result .='<h3>'.&mt('Broadcast Message').'</h3>';
1.45      www      1268:         } else {
1.102     raeburn  1269:             $result.='<h3>'.&mt('Critical Message').'</h3>';
1.45      www      1270:             %content=&unpackagemsg($content{'message'});
                   1271:             $content{'message'}=
1.92      www      1272:                 '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'.
1.45      www      1273: 		$content{'message'};
                   1274:         }
1.69      www      1275:         $result.=&mt('By').': <b>'.
1.45      www      1276: &Apache::loncommon::aboutmewrapper(
                   1277:  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
                   1278: $content{'sendername'}.'@'.
                   1279:             $content{'senderdomain'}.') '.$content{'time'}.
1.130     albertel 1280:             '<br /><pre>'.
1.45      www      1281:               &Apache::lontexconvert::msgtexconverted($content{'message'}).
1.130     albertel 1282: 	      '</pre>';
1.45      www      1283:      }
                   1284:     # Check to see if there were any messages.
                   1285:     if ($result eq '') {
1.98      sakharuk 1286: 	if ($target ne 'tex') { 
1.102     raeburn  1287: 	    $r->print("<p><b>".&mt("No notes, face-to-face discussion records, critical messages, or broadcast messages in this course.")."</b></p>");
1.98      sakharuk 1288: 	} else {
1.102     raeburn  1289: 	    $r->print('\textbf{'.&mt("No notes, face-to-face discussion records, critical messages or broadcast messages in this course.").'}\\\\');
1.98      sakharuk 1290: 	}
1.45      www      1291:     } else {
                   1292:        $r->print($result);
                   1293:     }
                   1294: }
                   1295: 
1.44      www      1296: # ---------------------------------------------------------------- Face to face
                   1297: 
                   1298: sub facetoface {
                   1299:     my ($r,$stage)=@_;
1.140     albertel 1300:     unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
1.44      www      1301: 	return;
                   1302:     }
1.89      www      1303:     &printheader($r,
                   1304: 		 '/adm/email?recordftf=query',
1.102     raeburn  1305: 		 "User Notes, Face-to-Face, Critical Messages, Broadcast Messages");
1.46      www      1306: # from query string
1.88      www      1307: 
1.140     albertel 1308:     if ($env{'form.recname'}) { $env{'form.recuname'}=$env{'form.recname'}; }
                   1309:     if ($env{'form.recdom'}) { $env{'form.recdomain'}=$env{'form.recdom'}; }
1.46      www      1310: 
1.140     albertel 1311:     my $defdom=$env{'user.domain'};
1.46      www      1312: # already filled in
1.140     albertel 1313:     if ($env{'form.recdomain'}) { $defdom=$env{'form.recdomain'}; }
1.46      www      1314: # generate output
1.44      www      1315:     my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');
1.46      www      1316:     my $stdbrws = &Apache::loncommon::selectstudent_link
                   1317: 	('stdselect','recuname','recdomain');
1.88      www      1318:     my %lt=&Apache::lonlocal::texthash('user' => 'Username',
                   1319: 				       'dom' => 'Domain',
1.102     raeburn  1320: 				       'head' => 'User Notes, Records of Face-To-Face Discussions, Critical Messages, and Broadcast Messages in Course',
1.88      www      1321: 				       'subm' => 'Retrieve discussion and message records',
                   1322: 				       'newr' => 'New Record (record is visible to course faculty and staff)',
                   1323: 				       'post' => 'Post this Record');
1.44      www      1324:     $r->print(<<"ENDTREC");
1.88      www      1325: <h3>$lt{'head'}</h3>
1.46      www      1326: <form method="post" action="/adm/email" name="stdselect">
1.44      www      1327: <input type="hidden" name="recordftf" value="retrieve" />
                   1328: <table>
1.140     albertel 1329: <tr><td>$lt{'user'}:</td><td><input type="text" size="12" name="recuname" value="$env{'form.recuname'}" /></td>
1.44      www      1330: <td rowspan="2">
1.46      www      1331: $stdbrws
1.88      www      1332: <input type="submit" value="$lt{'subm'}" /></td>
1.44      www      1333: </tr>
1.88      www      1334: <tr><td>$lt{'dom'}:</td>
1.44      www      1335: <td>$domform</td></tr>
                   1336: </table>
                   1337: </form>
                   1338: ENDTREC
                   1339:     if (($stage ne 'query') &&
1.140     albertel 1340:         ($env{'form.recdomain'}) && ($env{'form.recuname'})) {
                   1341:         chomp($env{'form.newrecord'});
                   1342:         if ($env{'form.newrecord'}) {
1.45      www      1343:            &user_normal_msg_raw(
1.140     albertel 1344:             $env{'course.'.$env{'request.course.id'}.'.num'},
                   1345:             $env{'course.'.$env{'request.course.id'}.'.domain'},
1.88      www      1346:             &mt('Record').
1.140     albertel 1347: 	     ' ['.$env{'form.recuname'}.':'.$env{'form.recdomain'}.']',
                   1348: 	    $env{'form.newrecord'});
1.44      www      1349:         }
1.140     albertel 1350:         $r->print('<h3>'.&Apache::loncommon::plainname($env{'form.recuname'},
                   1351: 				     $env{'form.recdomain'}).'</h3>');
                   1352:         &disfacetoface($r,$env{'form.recuname'},$env{'form.recdomain'});
1.44      www      1353: 	$r->print(<<ENDRHEAD);
                   1354: <form method="post" action="/adm/email">
1.140     albertel 1355: <input name="recdomain" value="$env{'form.recdomain'}" type="hidden" />
                   1356: <input name="recuname" value="$env{'form.recuname'}" type="hidden" />
1.44      www      1357: ENDRHEAD
                   1358:         $r->print(<<ENDBFORM);
1.88      www      1359: <hr />$lt{'newr'}<br />
1.44      www      1360: <textarea name="newrecord" cols="80" rows="10" wrap="hard"></textarea>
1.45      www      1361: <br />
                   1362: <input type="hidden" name="recordftf" value="post" />
1.88      www      1363: <input type="submit" value="$lt{'post'}" />
1.44      www      1364: </form>
                   1365: ENDBFORM
                   1366:     }
                   1367: }
1.91      www      1368: 
1.101     raeburn  1369: # ----------------------------------------------------------- Blocking during exams
                   1370: 
                   1371: sub examblock {
                   1372:     my ($r,$action) = @_;
1.140     albertel 1373:     unless ($env{'request.course.id'}) { return;}
                   1374:     unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) { $r->print('Not allowed'); }
1.101     raeburn  1375:     my %lt=&Apache::lonlocal::texthash(
                   1376:             'comb' => 'Communication Blocking',
                   1377:             'cbds' => 'Communication blocking during scheduled exams',
                   1378:             'desc' => 'You can use communication blocking to prevent students enrolled in this course from displaying LON-CAPA messages sent by other students during an online exam. As blocking of communication could potentially interrupt legitimate communication between students who are also both enrolled in a different LON-CAPA course, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.',
                   1379:              'mecb' => 'Modify existing communication blocking periods',
                   1380:              'ncbc' => 'No communication blocks currently stored'
                   1381:     );
                   1382: 
                   1383:     my %ltext = &Apache::lonlocal::texthash(
                   1384:             'dura' => 'Duration',
                   1385:             'setb' => 'Set by',
                   1386:             'even' => 'Event',
                   1387:             'actn' => 'Action',
                   1388:             'star' => 'Start',
                   1389:             'endd' => 'End'
                   1390:     );
                   1391: 
                   1392:     &printheader($r,'/adm/email?block=display',$lt{'comb'});
                   1393:     $r->print('<h3>'.$lt{'cbds'}.'</h3>');
                   1394: 
                   1395:     if ($action eq 'store') {
                   1396:         &blockstore($r);
                   1397:     }
                   1398: 
                   1399:     $r->print($lt{'desc'}.'<br /><br />
                   1400:                <form name="blockform" method="post" action="/adm/email?block=store">
                   1401:              ');
                   1402: 
                   1403:     $r->print('<h4>'.$lt{'mecb'}.'</h4>');
                   1404:     my %records = ();
                   1405:     my $blockcount = 0;
                   1406:     my $parmcount = 0;
                   1407:     &get_blockdates(\%records,\$blockcount);
                   1408:     if ($blockcount > 0) {
                   1409:         $parmcount = &display_blocker_status($r,\%records,\%ltext);
                   1410:     } else {
                   1411:         $r->print($lt{'ncbc'}.'<br /><br />');
                   1412:     }
                   1413:     &display_addblocker_table($r,$parmcount,\%ltext);
1.139     albertel 1414:     my $endbody=&Apache::loncommon::endbodytag();
1.101     raeburn  1415:     $r->print(<<"END");
                   1416: <br />
                   1417: <input type="hidden" name="blocktotal" value="$blockcount" />
                   1418: <input type ="submit" value="Save Changes" />
                   1419: </form>
1.139     albertel 1420: $endbody
1.101     raeburn  1421: </html>
                   1422: END
                   1423:     return;
                   1424: }
                   1425: 
                   1426: sub blockstore {
                   1427:     my $r = shift;
                   1428:     my %lt=&Apache::lonlocal::texthash(
                   1429:             'tfcm' => 'The following changes were made',
                   1430:             'cbps' => 'communication blocking period(s)',
                   1431:             'werm' => 'was/were removed',
                   1432:             'wemo' => 'was/were modified',
                   1433:             'wead' => 'was/were added',
                   1434:             'ncwm' => 'No changes were made.' 
                   1435:     );
                   1436:     my %adds = ();
                   1437:     my %removals = ();
                   1438:     my %cancels = ();
                   1439:     my $modtotal = 0;
                   1440:     my $canceltotal = 0;
                   1441:     my $addtotal = 0;
                   1442:     my %blocking = ();
                   1443:     $r->print('<h3>'.$lt{'head'}.'</h3>');
1.140     albertel 1444:     foreach (keys %env) {
1.101     raeburn  1445:         if ($_ =~ m/^form\.modify_(\w+)$/) {
                   1446:             $adds{$1} = $1;
                   1447:             $removals{$1} = $1;
                   1448:             $modtotal ++;
                   1449:         } elsif ($_ =~ m/^form\.cancel_(\d+)$/) {
                   1450:             $cancels{$1} = $1;
                   1451:             unless ( defined($removals{$1}) ) {
                   1452:                 $removals{$1} = $1;
                   1453:                 $canceltotal ++;
                   1454:             }
                   1455:         } elsif ($_ =~ m/^form\.add_(\d+)$/) {
                   1456:             $adds{$1} = $1;
                   1457:             $addtotal ++;
                   1458:         }
                   1459:     }
                   1460: 
                   1461:     foreach (keys %removals) {
1.140     albertel 1462:         my $hashkey = $env{'form.key_'.$_};
1.101     raeburn  1463:         &Apache::lonnet::del('comm_block',["$hashkey"],
1.140     albertel 1464:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1465:                          $env{'course.'.$env{'request.course.id'}.'.num'}
1.101     raeburn  1466:                          );
                   1467:     }
                   1468:     foreach (keys %adds) {
                   1469:         unless ( defined($cancels{$_}) ) {
                   1470:             my ($newstart,$newend) = &get_dates_from_form($_);
                   1471:             my $newkey = $newstart.'____'.$newend;
1.140     albertel 1472:             $blocking{$newkey} = $env{'user.name'}.'@'.$env{'user.domain'}.':'.$env{'form.title_'.$_};
1.101     raeburn  1473:         }
                   1474:     }
                   1475:     if ($addtotal + $modtotal > 0) {
                   1476:         &Apache::lonnet::put('comm_block',\%blocking,
1.140     albertel 1477:                      $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1478:                      $env{'course.'.$env{'request.course.id'}.'.num'}
1.101     raeburn  1479:                      );
                   1480:     }
                   1481:     my $chgestotal = $canceltotal + $modtotal + $addtotal;
                   1482:     if ($chgestotal > 0) {
                   1483:         $r->print($lt{'tfcm'}.'<ul>');
                   1484:         if ($canceltotal > 0) {
                   1485:             $r->print('<li>'.$canceltotal.' '.$lt{'cbps'},' '.$lt{'werm'}.'</li>');
                   1486:         }
                   1487:         if ($modtotal > 0) {
                   1488:             $r->print('<li>'.$modtotal.' '.$lt{'cbps'},' '.$lt{'wemo'}.'</li>');
                   1489:         }
                   1490:         if ($addtotal > 0) {
                   1491:             $r->print('<li>'.$addtotal.' '.$lt{'cbps'},' '.$lt{'wead'}.'</li>');
                   1492:         }
                   1493:         $r->print('</ul>');
                   1494:     } else {
                   1495:         $r->print($lt{'ncwm'});
                   1496:     }
                   1497:     $r->print('<br />');
                   1498:     return;
                   1499: }
                   1500: 
                   1501: sub get_dates_from_form {
                   1502:     my $item = shift;
                   1503:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item);
                   1504:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item);
                   1505:     return ($startdate,$enddate);
                   1506: }
                   1507: 
                   1508: sub get_blockdates {
                   1509:     my ($records,$blockcount) = @_;
                   1510:     $$blockcount = 0;
                   1511:     %{$records} = &Apache::lonnet::dump('comm_block',
1.140     albertel 1512:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1513:                          $env{'course.'.$env{'request.course.id'}.'.num'}
1.101     raeburn  1514:                          );
                   1515:     $$blockcount = keys %{$records};
                   1516:                                                                                                              
                   1517:     foreach (keys %{$records}) {
                   1518:         if ($_ eq 'error: 2 tie(GDBM) Failed while attempting dump') {
                   1519:             $$blockcount = 0;
                   1520:             last;
                   1521:         }
                   1522:     }
                   1523: }
                   1524: 
                   1525: sub display_blocker_status {
                   1526:     my ($r,$records,$ltext) = @_;
                   1527:     my $parmcount = 0;
                   1528:     my @bgcols = ("#eeeeee","#dddddd");
                   1529:     my $function = &Apache::loncommon::get_users_function();
                   1530:     my $color = &Apache::loncommon::designparm($function.'.tabbg',
1.140     albertel 1531:                                                     $env{'user.domain'});
1.101     raeburn  1532:     my %lt = &Apache::lonlocal::texthash(
                   1533:         'modi' => 'Modify',
                   1534:         'canc' => 'Cancel',
                   1535:     );
                   1536:     $r->print(<<"END");
                   1537: <table border="0" cellpadding="0" cellspacing="0">
                   1538:  <tr>
                   1539:   <td width="100%" bgcolor="#000000">
                   1540:    <table width="100%" border="0" cellpadding="1" cellspacing="0">
                   1541:     <tr>
                   1542:      <td width="100%" bgcolor="#000000">
                   1543:       <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
                   1544:        <tr bgcolor="$color">
                   1545:         <td><b>$$ltext{'dura'}</b></td>
                   1546:         <td><b>$$ltext{'setb'}</b></td>
                   1547:         <td><b>$$ltext{'even'}</b></td>
                   1548:         <td><b>$$ltext{'actn'}?</b></td>
                   1549:        </tr>
                   1550: END
                   1551:     foreach (sort keys %{$records}) {
                   1552:         my $iter = $parmcount%2;
                   1553:         my $onchange = 'onFocus="javascript:window.document.forms['.
                   1554:                        "'blockform'].elements['modify_".$parmcount."'].".
                   1555:                        'checked=true;"';
                   1556:         my ($start,$end) = split/____/,$_;
                   1557:         my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
                   1558:         my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
                   1559:         my ($setter,$title) = split/:/,$$records{$_};
                   1560:         my ($setuname,$setudom) = split/@/,$setter;
                   1561:         my $settername = &Apache::loncommon::plainname($setuname,$setudom);
                   1562:         $r->print(<<"END");
                   1563:        <tr bgcolor="$bgcols[$iter]">
                   1564:         <td>$$ltext{'star'}:&nbsp;$startform<br/>$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
                   1565:         <td>$settername</td>
1.136     albertel 1566:         <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$_" /></td>
                   1567:         <td><label>$lt{'modi'}?&nbsp;<input type="checkbox" name="modify_$parmcount" /></label><br /><label>$lt{'canc'}?&nbsp;&nbsp;<input type="checkbox" name="cancel_$parmcount" /></label>
1.101     raeburn  1568:        </tr>
                   1569: END
                   1570:         $parmcount ++;
                   1571:     }
                   1572:     $r->print(<<"END");
                   1573:       </table>
                   1574:      </td>
                   1575:     </tr>
                   1576:    </table>
                   1577:   </td>
                   1578:  </tr>
                   1579: </table>
                   1580: <br />
                   1581: <br />
                   1582: END
                   1583:     return $parmcount;
                   1584: }
                   1585: 
                   1586: sub display_addblocker_table {
                   1587:     my ($r,$parmcount,$ltext) = @_;
                   1588:     my $start = time;
                   1589:     my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration.
                   1590:     my $onchange = 'onFocus="javascript:window.document.forms['.
                   1591:                    "'blockform'].elements['add_".$parmcount."'].".
                   1592:                    'checked=true;"';
                   1593:     my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
                   1594:     my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
                   1595:     my $function = &Apache::loncommon::get_users_function();
                   1596:     my $color = &Apache::loncommon::designparm($function.'.tabbg',
1.140     albertel 1597:                                                     $env{'user.domain'});
1.101     raeburn  1598:     my %lt = &Apache::lonlocal::texthash(
                   1599:         'addb' => 'Add block',
                   1600:         'exam' => 'e.g., Exam 1',
                   1601:         'addn' => 'Add new communication blocking periods'
                   1602:     );
                   1603:     $r->print(<<"END");
                   1604: <h4>$lt{'addn'}</h4> 
                   1605: <table border="0" cellpadding="0" cellspacing="0">
                   1606:  <tr>
                   1607:   <td width="100%" bgcolor="#000000">
                   1608:    <table width="100%" border="0" cellpadding="1" cellspacing="0">
                   1609:     <tr>
                   1610:      <td width="100%" bgcolor="#000000">
                   1611:       <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
                   1612:        <tr bgcolor="#CCCCFF">
                   1613:         <td><b>$$ltext{'dura'}</b></td>
                   1614:         <td><b>$$ltext{'even'} $lt{'exam'}</b></td>
                   1615:         <td><b>$$ltext{'actn'}?</b></td>
                   1616:        </tr>
                   1617:        <tr bgcolor="#eeeeee">
                   1618:         <td>$$ltext{'star'}:&nbsp;$startform<br />$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
1.136     albertel 1619:         <td><input type="text" name="title_$parmcount" size="15" value="" /></td>
                   1620:         <td><label>$lt{'addb'}?&nbsp;<input type="checkbox" name="add_$parmcount" value="1" /></label></td>
1.101     raeburn  1621:        </tr>
                   1622:       </table>
                   1623:      </td>
                   1624:     </tr>
                   1625:    </table>
                   1626:   </td>
                   1627:  </tr>
                   1628: </table>
                   1629: END
                   1630:     return;
                   1631: }
                   1632: 
                   1633: sub blockcheck {
                   1634:     my ($setters,$startblock,$endblock) = @_;
                   1635:     # Retrieve active student roles and active course coordinator/instructor roles
                   1636:     my @livecses = ();
                   1637:     my @staffcses = ();
                   1638:     $$startblock = 0;
                   1639:     $$endblock = 0;
1.140     albertel 1640:     foreach (keys %env) {
1.101     raeburn  1641:         if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) {
                   1642:             my $role = $1;
                   1643:             my $cse = $2;
                   1644:             $cse =~ s|/|_|;
1.140     albertel 1645:             if ($env{$_} =~ m/^(\d*)\.(\d*)$/) {
1.101     raeburn  1646:                 unless (($2 > 0 && $2 < time) || ($1 > time)) {
                   1647:                     if ($role eq 'st') {
                   1648:                         push @livecses, $cse;
                   1649:                     } else {
                   1650:                         unless (grep/^$cse$/,@staffcses) {
                   1651:                             push @staffcses, $cse;
                   1652:                         }
                   1653:                     }
                   1654:                 }
                   1655:             }
                   1656:         } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) { 
1.140     albertel 1657:             my $rolepriv = $env{'user.role..rolesdef_'.$3};
1.101     raeburn  1658:         }
                   1659:     }
                   1660:     # Retrieve blocking times and identity of blocker for active courses for students.
                   1661:     if (@livecses > 0) {
                   1662:         foreach my $cse (@livecses) {
                   1663:             my ($cdom,$crs) = split/_/,$cse;
1.140     albertel 1664:             if ( (grep/^$cse$/,@staffcses) && ($env{'request.role'} !~ m-^st\./$cdom/$crs$-) ) {
1.101     raeburn  1665:                 next;
                   1666:             } else {
                   1667:                 %{$$setters{$cse}} = ();
                   1668:                 @{$$setters{$cse}{'staff'}} = ();
                   1669:                 @{$$setters{$cse}{'times'}} = ();
                   1670:                 my %records = &Apache::lonnet::dump('comm_block',$cdom,$crs);
                   1671:                 foreach (keys %records) {
                   1672:                     if ($_ =~ m/^(\d+)____(\d+)$/) {
                   1673:                         if ($1 <= time && $2 >= time) {
                   1674:                             my ($staff,$title) = split/:/,$records{$_};
                   1675:                             push @{$$setters{$cse}{'staff'}}, $staff;
                   1676:                             push @{$$setters{$cse}{'times'}}, $_;
                   1677:                             if ( ($$startblock == 0) || ($$startblock > $1) ) {
                   1678:                                 $$startblock = $1;
                   1679:                             }
                   1680:                             if ( ($$endblock == 0) || ($$endblock < $2) ) {
                   1681:                                 $$endblock = $2;
                   1682:                             }
                   1683:                         }
                   1684:                     }
                   1685:                 }
                   1686:             }
                   1687:         }
                   1688:     }
                   1689: }
                   1690: 
                   1691: sub build_block_table {
                   1692:     my ($r,$startblock,$endblock,$setters) = @_;
                   1693:     my $function = &Apache::loncommon::get_users_function();
                   1694:     my $color = &Apache::loncommon::designparm($function.'.tabbg',
1.140     albertel 1695:                                                     $env{'user.domain'});
1.101     raeburn  1696:     my %lt = &Apache::lonlocal::texthash(
                   1697:         'cacb' => 'Currently active communication blocks',
                   1698:         'cour' => 'Course',
                   1699:         'dura' => 'Duration',
                   1700:         'blse' => 'Block set by'
                   1701:     ); 
                   1702:     $r->print(<<"END");
                   1703: <br /<br />$lt{'cacb'}:<br /><br />
                   1704: <table border="0" cellpadding="0" cellspacing="0">
                   1705:  <tr>
                   1706:   <td width="100%" bgcolor="#000000">
                   1707:    <table width="100%" border="0" cellpadding="1" cellspacing="0">
                   1708:     <tr>
                   1709:      <td width="100%" bgcolor="#000000">
                   1710:       <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
                   1711:        <tr bgcolor="$color">
                   1712:         <td><b>$lt{'cour'}</b></td>
                   1713:         <td><b>$lt{'dura'}</b></td>
                   1714:         <td><b>$lt{'blse'}</b></td>
                   1715:        </tr>
                   1716: END
                   1717:     foreach (keys %{$setters}) {
                   1718:         my %courseinfo=&Apache::lonnet::coursedescription($_);
                   1719:         for (my $i=0; $i<@{$$setters{$_}{staff}}; $i++) {
                   1720:             my ($uname,$udom) = split/\@/,$$setters{$_}{staff}[$i];
                   1721:             my $fullname = &Apache::loncommon::plainname($uname,$udom);
                   1722:             my ($openblock,$closeblock) = split/____/,$$setters{$_}{times}[$i];
                   1723:             $openblock = &Apache::lonlocal::locallocaltime($openblock);
                   1724:             $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
                   1725:             $r->print('<tr><td>'.$courseinfo{'description'}.'</td>'.
                   1726:                       '<td>'.$openblock.' to '.$closeblock.'</td>'.
                   1727:                       '<td>'.$fullname.' ('.$uname.'@'.$udom.
                   1728:                       ')</td></tr>');
                   1729:         }
                   1730:     }
                   1731:     $r->print('</table></td></tr></table></td></tr></table>');
                   1732: }
                   1733: 
1.90      www      1734: # ----------------------------------------------------------- Display a message
                   1735: 
                   1736: sub displaymessage {
1.106     www      1737:     my ($r,$msgid,$folder)=@_;
                   1738:     my $suffix=&foldersuffix($folder);
1.101     raeburn  1739:     my %blocked = ();
                   1740:     my %setters = ();
                   1741:     my $startblock = 0;
                   1742:     my $endblock = 0;
                   1743:     my $numblocked = 0;
                   1744: # info to generate "next" and "previous" buttons and check if message is blocked
                   1745:     &blockcheck(\%setters,\$startblock,\$endblock);
1.107     www      1746:     my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
1.101     raeburn  1747:     if ( $blocked{$msgid} eq 'ON' ) {
                   1748:         &printheader($r,'/adm/email',&mt('Display a Message'));
                   1749:         $r->print(&mt('You attempted to display a message that is currently blocked because you are enrolled in one or more courses for which there is an ongoing online exam.'));
                   1750:         &build_block_table($r,$startblock,$endblock,\%setters);
                   1751:         return;
                   1752:     }
1.107     www      1753:     &statuschange($msgid,'read',$folder);
1.106     www      1754:     my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
1.90      www      1755:     my %content=&unpackagemsg($message{$msgid});
1.107     www      1756: 
1.90      www      1757:     my $counter=0;
                   1758:     $r->print('<pre>');
                   1759:     my $escmsgid=&Apache::lonnet::escape($msgid);
                   1760:     foreach (@messages) {
                   1761: 	if ($_->[5] eq $escmsgid){
                   1762: 	    last;
                   1763: 	}
                   1764: 	$counter++;
                   1765:     }
                   1766:     $r->print('</pre>');
                   1767:     my $number_of_messages = scalar(@messages); #subtract 1 for last index
                   1768: # start output
1.92      www      1769:     &printheader($r,'/adm/email?display='.&Apache::lonnet::escape($msgid),'Display a Message','',$content{'baseurl'});
1.90      www      1770:     my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'});
                   1771: # Functions
                   1772:     $r->print('<table border="2" width="100%"><tr bgcolor="#FFFFAA"><td>'.&mt('Functions').':</td>'.
                   1773: 	      '<td><a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).$sqs.
                   1774: 	      '"><b>'.&mt('Reply').'</b></a></td>'.
                   1775: 	      '<td><a href="/adm/email?forward='.&Apache::lonnet::escape($msgid).$sqs.
                   1776: 	      '"><b>'.&mt('Forward').'</b></a></td>'.
                   1777: 	      '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs.
                   1778: 	      '"><b>'.&mt('Mark Unread').'</b></a></td>'.
                   1779: 	      '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs.
                   1780: 	      '"><b>Delete</b></a></td>'.
1.125     www      1781: 	      '<td><a href="/adm/email?'.$sqs.
1.140     albertel 1782: 	      ($env{'form.dismode'} eq 'new'?'&folder=new':'').
1.125     www      1783: 	      '"><b>'.&mt('Back to Folder Display').'</b></a></td>');
1.90      www      1784:     if ($counter > 0){
                   1785: 	$r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.
                   1786: 		  '"><b>'.&mt('Previous').'</b></a></td>');
                   1787:     }
                   1788:     if ($counter < $number_of_messages - 1){
                   1789: 	$r->print('<td><a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.
                   1790: 		  '"><b>'.&mt('Next').'</b></a></td>');
                   1791:     }
                   1792:     $r->print('</tr></table>');
1.146   ! www      1793:     if ($env{'user.adv'}) {
        !          1794: 	$r->print('<table border="2" width="100%"><tr bgcolor="#FFAAAA"><td>'.&mt('Currently available actions (will open extra window)').':</td>');
        !          1795: 	      
        !          1796: 	if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
        !          1797: 		$r->print('<td><b>'.&Apache::loncommon::track_student_link(&mt('View recent activity'),$content{'sendername'},$content{'senderdomain'},'check').'</b></td>');
        !          1798: 	    }
        !          1799: 	if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {
        !          1800: 	    my $symb=&Apache::lonnet::symbread($content{'baseurl'});
        !          1801: 	    $r->print('<td><b>'.&Apache::loncommon::parm_direct_link(&mt('Set/Change parameters'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
        !          1802: 	}
        !          1803: 	if (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) {
        !          1804: 	    my $symb=&Apache::lonnet::symbread($content{'baseurl'});
        !          1805: 	    $r->print('<td><b>'.&Apache::loncommon::grds_direct_link(&mt('Set/Change grades'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
        !          1806: 	}
        !          1807: 	$r->print('</tr></table>');
        !          1808:     }
1.90      www      1809:     $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}.
1.108     www      1810: 	      ($folder ne 'sent'?'<br /><b>'.&mt('From').':</b> '.
1.90      www      1811: 	      &Apache::loncommon::aboutmewrapper(
                   1812: 						 &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
                   1813: 						 $content{'sendername'},$content{'senderdomain'}).' ('.
                   1814: 	      $content{'sendername'}.' at '.
1.108     www      1815: 	      $content{'senderdomain'}.') ':'<br /><b>'.&mt('To').':</b> '.
                   1816: 	      &Apache::loncommon::aboutmewrapper(
                   1817: 						 &Apache::loncommon::plainname($content{'recuser'},$content{'recdomain'}),
                   1818: 						 $content{'recuser'},$content{'recdomain'}).' ('.
                   1819: 	      $content{'recuser'}.' at '.
                   1820: 	      $content{'recdomain'}.') ').
1.90      www      1821: 	      ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}.
                   1822: 	       ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').
                   1823: 	      '<br /><b>'.&mt('Time').':</b> '.$content{'time'}.
1.115     www      1824: 	      ($content{'baseurl'}?'<br /><b>'.&mt('Refers to').':</b> <a href="'.$content{'baseurl'}.'">'.
                   1825: 	       $content{'baseurl'}.' ('.&Apache::lonnet::gettitle($content{'baseurl'}).')</a>':'').
1.90      www      1826: 	      '<p><pre>'.
                   1827: 	      &Apache::lontexconvert::msgtexconverted($content{'message'},1).
1.111     www      1828: 	      '</pre><hr />'.&displayresource(%content).'</p>');
1.90      www      1829:     return;   
                   1830: }
1.44      www      1831: 
1.111     www      1832: # =========================================================== Show the citation
                   1833: 
                   1834: sub displayresource {
                   1835:     my %content=@_;
                   1836: #
                   1837: # If the recipient is in the same course that the message was sent from and
                   1838: # has sufficient privileges, show "all details," else show citation
                   1839: #
1.140     albertel 1840:     if (($env{'request.course.id'} eq $content{'courseid'})
1.111     www      1841:      && (&Apache::lonnet::allowed('vgr',$content{'courseid'}))) {
                   1842: 	my $symb=&Apache::lonnet::symbread($content{'baseurl'});
                   1843: # Could not get a symb, give up
                   1844: 	unless ($symb) { return $content{'citation'}; }
                   1845: # Have a symb, can render
                   1846: 	return '<h2>'.&mt('Current attempts of student (if applicable)').'</h2>'.
                   1847: 	    &Apache::loncommon::get_previous_attempt($symb,
                   1848: 						     $content{'sendername'},
                   1849: 						     $content{'senderdomain'},
                   1850: 						     $content{'courseid'}).
                   1851: 	    '<hr /><h2>'.&mt('Current screen output (if applicable)').'</h2>'.
                   1852: 	    &Apache::loncommon::get_student_view($symb,
                   1853: 						 $content{'sendername'},
                   1854: 						 $content{'senderdomain'},
                   1855: 						 $content{'courseid'}).
                   1856: 	    '<h2>'.&mt('Correct Answer(s) (if applicable)').'</h2>'.
                   1857: 	    &Apache::loncommon::get_student_answers($symb,
                   1858: 						    $content{'sendername'},
                   1859: 						    $content{'senderdomain'},
                   1860: 						    $content{'courseid'});
                   1861:     } else {
                   1862: 	return $content{'citation'};
                   1863:     }
                   1864: }
                   1865: 
1.88      www      1866: # ================================================================== The Header
                   1867: 
                   1868: sub header {
1.90      www      1869:     my ($r,$title,$baseurl)=@_;
1.137     albertel 1870:     $r->print(&Apache::lonxml::xmlbegin().
                   1871: 	      '<head>'.&Apache::lonxml::fontsettings().
1.144     albertel 1872: 	      '<title>Communication and Messages</title>'.
                   1873: 	      &Apache::lonhtmlcommon::htmlareaheaders());
1.88      www      1874:     if ($baseurl) {
                   1875: 	$r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$baseurl\" />");
                   1876:     }
                   1877:     $r->print(&Apache::loncommon::studentbrowser_javascript().'</head>'.
                   1878: 	      &Apache::loncommon::bodytag('Communication and Messages'));
                   1879:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.90      www      1880:                   (undef,($title?$title:'Communication and Messages')));
1.88      www      1881: 
                   1882: }
                   1883: 
1.90      www      1884: # ---------------------------------------------------------------- Print header
                   1885: 
                   1886: sub printheader {
                   1887:     my ($r,$url,$desc,$title,$baseurl)=@_;
                   1888:     &Apache::lonhtmlcommon::add_breadcrumb
                   1889: 	({href=>$url,
                   1890: 	  text=>$desc});
                   1891:     &header($r,$title,$baseurl);
                   1892: }
                   1893: 
1.120     www      1894: # ------------------------------------------------------------ Store the comment
                   1895: 
                   1896: sub storecomment {
                   1897:     my ($r)=@_;
1.140     albertel 1898:     my $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'});
1.120     www      1899:     my $cleanmsgtxt='';
                   1900:     foreach (split(/[\n\r]/,$msgtxt)) {
                   1901: 	unless ($_=~/^\s*(\>|\&gt\;)/) {
                   1902: 	    $cleanmsgtxt.=$_."\n";
                   1903: 	}
                   1904:     }
1.140     albertel 1905:     my $key=&Apache::lonnet::escape($env{'form.baseurl'}).'___'.time;
1.120     www      1906:     &Apache::lonnet::put('nohist_stored_comments',{ $key => $cleanmsgtxt });
                   1907: }
                   1908: 
                   1909: sub storedcommentlisting {
                   1910:     my ($r)=@_;
                   1911:     my %msgs=&Apache::lonnet::dump('nohist_stored_comments',undef,undef,
1.140     albertel 1912:        '^'.&Apache::lonnet::escape(&Apache::lonnet::escape($env{'form.showcommentbaseurl'})));
1.137     albertel 1913:     $r->print(&Apache::lonxml::xmlbegin().'<head>'.
                   1914: 	      &Apache::lonxml::fontsettings().'</head><body>');
1.120     www      1915:     if ((keys %msgs)[0]=~/^error\:/) {
                   1916: 	$r->print(&mt('No stored comments yet.'));
                   1917:     } else {
                   1918: 	my $found=0;
                   1919: 	foreach (sort keys %msgs) {
                   1920: 	    $r->print("\n".$msgs{$_}."<hr />");
                   1921: 	    $found=1;
                   1922: 	}
                   1923: 	unless ($found) {
                   1924: 	    $r->print(&mt('No stored comments yet for this resource.'));
                   1925: 	}
                   1926:     }
                   1927: }
                   1928: 
1.115     www      1929: # ---------------------------------------------------------------- Send an email
                   1930: 
                   1931: sub sendoffmail {
1.120     www      1932:     my ($r,$folder)=@_;
                   1933:     my $suffix=&foldersuffix($folder);
1.115     www      1934:     my $sendstatus='';
1.140     albertel 1935:     if ($env{'form.send'}) {
1.115     www      1936: 	&printheader($r,'','Messages being sent.');
                   1937: 	$r->rflush();
                   1938: 	my %content=();
                   1939: 	undef %content;
1.140     albertel 1940: 	if ($env{'form.forwid'}) {
                   1941: 	    my $msgid=$env{'form.forwid'};
1.120     www      1942: 	    my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
1.115     www      1943: 	    %content=&unpackagemsg($message{$msgid},1);
1.120     www      1944: 	    &statuschange($msgid,'forwarded',$folder);
1.140     albertel 1945: 	    $env{'form.message'}.="\n\n-- Forwarded message --\n\n".
1.115     www      1946: 		$content{'message'};
                   1947: 	}
1.140     albertel 1948: 	if ($env{'form.replyid'}) {
                   1949: 	    my $msgid=$env{'form.replyid'};
1.120     www      1950: 	    my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
1.115     www      1951: 	    %content=&unpackagemsg($message{$msgid},1);
1.120     www      1952: 	    &statuschange($msgid,'replied',$folder);
1.115     www      1953: 	}
                   1954: 	my %toaddr=();
                   1955: 	undef %toaddr;
1.140     albertel 1956: 	if ($env{'form.sendmode'} eq 'group') {
                   1957: 	    foreach (keys %env) {
1.115     www      1958: 		if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) {
                   1959: 		    $toaddr{$1}='';
                   1960: 		}
                   1961: 	    }
1.140     albertel 1962: 	} elsif ($env{'form.sendmode'} eq 'upload') {
                   1963: 	    foreach (split(/[\n\r\f]+/,$env{'form.upfile'})) {
1.115     www      1964: 		my ($rec,$txt)=split(/\s*\:\s*/,$_);
                   1965: 		if ($txt) {
                   1966: 		    $rec=~s/\@/\:/;
                   1967: 		    $toaddr{$rec}.=$txt."\n";
                   1968: 		}
                   1969: 	    }
                   1970: 	} else {
1.140     albertel 1971: 	    $toaddr{$env{'form.recuname'}.':'.$env{'form.recdomain'}}='';
1.115     www      1972: 	}
1.140     albertel 1973: 	if ($env{'form.additionalrec'}) {
                   1974: 	    foreach (split(/\,/,$env{'form.additionalrec'})) {
1.115     www      1975: 		my ($auname,$audom)=split(/\@/,$_);
                   1976: 		$toaddr{$auname.':'.$audom}='';
                   1977: 	    }
                   1978: 	}
                   1979: 	
                   1980: 	foreach (keys %toaddr) {
                   1981: 	    my ($recuname,$recdomain)=split(/\:/,$_);
1.122     raeburn  1982:             my $msgtxt;
1.140     albertel 1983:             if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
                   1984:                 (&Apache::lonnet::allowed('srm',$env{'request.course.id'}))) {
                   1985:                 $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'},1);
1.122     raeburn  1986:             } else {  
1.140     albertel 1987: 	        $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'});
1.122     raeburn  1988:             }
1.115     www      1989: 	    if ($toaddr{$_}) { $msgtxt.='<hr />'.$toaddr{$_}; }
                   1990: 	    my $thismsg;    
1.140     albertel 1991: 	    if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) && 
                   1992: 		(&Apache::lonnet::allowed('srm',$env{'request.course.id'}))) {
1.115     www      1993: 		$r->print(&mt('Sending critical message').' '.$recuname.'@'.$recdomain.': ');
                   1994: 		$thismsg=&user_crit_msg($recuname,$recdomain,
1.140     albertel 1995: 					&Apache::lonfeedback::clear_out_html($env{'form.subject'}),
1.115     www      1996: 					$msgtxt,
1.140     albertel 1997: 					$env{'form.sendbck'},$env{'form.permanent'});
1.115     www      1998: 	    } else {
                   1999: 		$r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': ');
                   2000: 		$thismsg=&user_normal_msg($recuname,$recdomain,
1.140     albertel 2001: 					  &Apache::lonfeedback::clear_out_html($env{'form.subject'}),
1.115     www      2002: 					  $msgtxt,
1.140     albertel 2003: 					  $content{'citation'},undef,undef,$env{'form.permanent'});
                   2004: 		if (($env{'request.course.id'}) && ($env{'form.sendmode'} eq 'group')) {
1.115     www      2005: 		    &user_normal_msg_raw(
1.140     albertel 2006: 					 $env{'course.'.$env{'request.course.id'}.'.num'},
                   2007: 					 $env{'course.'.$env{'request.course.id'}.'.domain'},
1.115     www      2008: 					 'Broadcast ['.$recuname.':'.$recdomain.']',
                   2009: 					 $msgtxt);
                   2010: 		}
                   2011: 	    }
                   2012: 	    $r->print($thismsg.'<br />');
                   2013: 	    $sendstatus.=' '.$thismsg;
                   2014: 	}
                   2015:     } else {
                   2016: 	&printheader($r,'','No messages sent.'); 
                   2017:     }
                   2018:     if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) {
                   2019: 	$r->print('<br /><font color="green">'.&mt('Completed.').'</font>');
1.140     albertel 2020: 	if ($env{'form.displayedcrit'}) {
1.115     www      2021: 	    &discrit($r);
                   2022: 	} else {
                   2023: 	    &Apache::loncommunicate::menu($r);
                   2024: 	}
                   2025:     } else {
                   2026: 	$r->print(
                   2027: 		  '<h2><font color="red">'.&mt('Could not deliver message').'</font></h2>'.
                   2028: 		  &mt('Please use the browser "Back" button and correct the recipient addresses')
                   2029: 		  );
                   2030:     }
                   2031: }
1.90      www      2032: 
1.13      www      2033: # ===================================================================== Handler
                   2034: 
1.5       www      2035: sub handler {
                   2036:     my $r=shift;
                   2037: 
                   2038: # ----------------------------------------------------------- Set document type
1.87      www      2039:     
                   2040:     &Apache::loncommon::content_type($r,'text/html');
                   2041:     $r->send_http_header;
                   2042:     
                   2043:     return OK if $r->header_only;
                   2044:     
1.6       www      2045: # --------------------------- Get query string for limited number of parameters
1.32      matthew  2046:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   2047:         ['display','replyto','forward','markread','markdel','markunread',
1.44      www      2048:          'sendreply','compose','sendmail','critical','recname','recdom',
1.120     www      2049:          'recordftf','sortedby','block','folder','startdis','interdis',
1.131     www      2050: 	 'showcommentbaseurl','dismode']);
1.140     albertel 2051:     $sqs='&sortedby='.$env{'form.sortedby'};
1.108     www      2052: 
1.40      www      2053: # ------------------------------------------------------ They checked for email
1.140     albertel 2054:     unless ($env{'form.block'}) {
1.101     raeburn  2055:         &Apache::lonnet::put('email_status',{'recnewemail'=>0});
                   2056:     }
1.88      www      2057: 
                   2058: # ----------------------------------------------------------------- Breadcrumbs
                   2059: 
                   2060:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2061:     &Apache::lonhtmlcommon::add_breadcrumb
                   2062:         ({href=>"/adm/communicate",
                   2063:           text=>"Communication/Messages",
                   2064:           faq=>12,bug=>'Communication Tools',});
                   2065: 
1.106     www      2066: # ------------------------------------------------------------------ Get Folder
                   2067: 
1.140     albertel 2068:     my $folder=$env{'form.folder'};
1.106     www      2069:     unless ($folder) { 
                   2070: 	$folder=''; 
                   2071:     } else {
1.125     www      2072: 	$sqs.='&folder='.&Apache::lonnet::escape($folder);
1.106     www      2073:     }
1.142     www      2074: # ------------------------------------------------------------ Get Display Mode
                   2075: 
                   2076:     my $dismode=$env{'form.dismode'};
                   2077:     unless ($dismode) { 
                   2078: 	$dismode=''; 
                   2079:     } else {
                   2080: 	$sqs.='&dismode='.&Apache::lonnet::escape($dismode);
                   2081:     }
1.106     www      2082: 
1.108     www      2083: # --------------------------------------------------------------------- Display
                   2084: 
1.140     albertel 2085:     $startdis=$env{'form.startdis'};
1.118     www      2086:     $startdis--;
1.108     www      2087:     unless ($startdis) { $startdis=0; }
1.125     www      2088: 
1.140     albertel 2089:     $interdis=$env{'form.interdis'};
1.108     www      2090:     unless ($interdis) { $interdis=20; }
1.125     www      2091:     $sqs.='&interdis='.$interdis;
                   2092: 
1.140     albertel 2093:     if ($env{'form.firstview'}) {
1.117     www      2094: 	$startdis=0;
                   2095:     }
1.140     albertel 2096:     if ($env{'form.lastview'}) {
1.117     www      2097: 	$startdis=-1;
                   2098:     }
1.140     albertel 2099:     if ($env{'form.prevview'}) {
1.117     www      2100: 	$startdis--;
                   2101:     }
1.140     albertel 2102:     if ($env{'form.nextview'}) {
1.117     www      2103: 	$startdis++;
                   2104:     }
1.125     www      2105:     my $postedstartdis=$startdis+1;
                   2106:     $sqs.='&startdis='.$postedstartdis;
1.108     www      2107: 
1.5       www      2108: # --------------------------------------------------------------- Render Output
1.88      www      2109: 
1.140     albertel 2110:     if ($env{'form.display'}) {
                   2111: 	&displaymessage($r,$env{'form.display'},$folder);
                   2112:     } elsif ($env{'form.replyto'}) {
1.142     www      2113: 	&compout($r,'',$env{'form.replyto'},undef,undef,$folder,$dismode);
1.140     albertel 2114:     } elsif ($env{'form.confirm'}) {
1.92      www      2115: 	&printheader($r,'','Confirmed Receipt');
1.140     albertel 2116: 	foreach (keys %env) {
1.87      www      2117: 	    if ($_=~/^form\.rec\_(.*)$/) {
1.92      www      2118: 		$r->print('<b>'.&mt('Confirming Receipt').':</b> '.
1.87      www      2119: 			  &user_crit_received($1).'<br>');
                   2120: 	    }
                   2121: 	    if ($_=~/^form\.reprec\_(.*)$/) {
                   2122: 		my $msgid=$1;
1.92      www      2123: 		$r->print('<b>'.&mt('Confirming Receipt').':</b> '.
1.87      www      2124: 			  &user_crit_received($msgid).'<br>');
1.94      www      2125: 		&compout($r,'','','',$msgid);
1.87      www      2126: 	    }
                   2127: 	}
                   2128: 	&discrit($r);
1.140     albertel 2129:     } elsif ($env{'form.critical'}) {
1.92      www      2130: 	&printheader($r,'','Displaying Critical Messages');
1.87      www      2131: 	&discrit($r);
1.140     albertel 2132:     } elsif ($env{'form.forward'}) {
                   2133: 	&compout($r,$env{'form.forward'},undef,undef,undef,$folder);
                   2134:     } elsif ($env{'form.markdel'}) {
1.92      www      2135: 	&printheader($r,'','Deleted Message');
1.140     albertel 2136: 	&statuschange($env{'form.markdel'},'deleted',$folder);
1.120     www      2137: 	&Apache::loncommunicate::menu($r);
1.142     www      2138: 	&disall($r,($folder?$folder:$dismode));
1.140     albertel 2139:     } elsif ($env{'form.markedmove'}) {
1.106     www      2140: 	my $total=0;
1.140     albertel 2141: 	foreach (keys %env) {
1.106     www      2142: 	    if ($_=~/^form\.delmark_(.*)$/) {
                   2143: 		&movemsg(&Apache::lonnet::unescape($1),$folder,
1.140     albertel 2144: 			 $env{'form.movetofolder'});
1.106     www      2145: 		$total++;
                   2146: 	    }
                   2147: 	}
                   2148: 	&printheader($r,'','Moved Messages');
                   2149: 	$r->print('Moved '.$total.' message(s)<p>');
1.120     www      2150: 	&Apache::loncommunicate::menu($r);
1.142     www      2151: 	&disall($r,($folder?$folder:$dismode));
1.140     albertel 2152:     } elsif ($env{'form.markeddel'}) {
1.87      www      2153: 	my $total=0;
1.140     albertel 2154: 	foreach (keys %env) {
1.87      www      2155: 	    if ($_=~/^form\.delmark_(.*)$/) {
1.108     www      2156: 		&statuschange(&Apache::lonnet::unescape($1),'deleted',$folder);
1.87      www      2157: 		$total++;
                   2158: 	    }
                   2159: 	}
1.92      www      2160: 	&printheader($r,'','Deleted Messages');
1.87      www      2161: 	$r->print('Deleted '.$total.' message(s)<p>');
1.120     www      2162: 	&Apache::loncommunicate::menu($r);
1.142     www      2163: 	&disall($r,($folder?$folder:$dismode));
1.140     albertel 2164:     } elsif ($env{'form.markunread'}) {
1.92      www      2165: 	&printheader($r,'','Marked Message as Unread');
1.140     albertel 2166: 	&statuschange($env{'form.markunread'},'new');
1.120     www      2167: 	&Apache::loncommunicate::menu($r);
1.142     www      2168: 	&disall($r,($folder?$folder:$dismode));
1.140     albertel 2169:     } elsif ($env{'form.compose'}) {
                   2170: 	&compout($r,'','',$env{'form.compose'});
                   2171:     } elsif ($env{'form.recordftf'}) {
                   2172: 	&facetoface($r,$env{'form.recordftf'});
                   2173:     } elsif ($env{'form.block'}) {
                   2174:         &examblock($r,$env{'form.block'});
                   2175:     } elsif ($env{'form.sendmail'}) {
1.120     www      2176: 	&sendoffmail($r,$folder);
1.140     albertel 2177: 	if ($env{'form.storebasecomment'}) {
1.120     www      2178: 	    &storecomment($r);
                   2179: 	}
1.142     www      2180: 	&disall($r,($folder?$folder:$dismode));
1.140     albertel 2181:     } elsif ($env{'form.newfolder'}) {
1.106     www      2182: 	&printheader($r,'','New Folder');
1.140     albertel 2183: 	&makefolder($env{'form.newfolder'});
1.120     www      2184: 	&Apache::loncommunicate::menu($r);
1.140     albertel 2185: 	&disall($r,$env{'form.newfolder'});
                   2186:     } elsif ($env{'form.showcommentbaseurl'}) {
1.120     www      2187: 	&storedcommentlisting($r);
1.87      www      2188:     } else {
1.92      www      2189: 	&printheader($r,'','Display All Messages');
1.142     www      2190: 	&Apache::loncommunicate::menu($r); 
                   2191: 	&disall($r,($folder?$folder:$dismode));
1.87      www      2192:     }
1.139     albertel 2193:     $r->print(&Apache::loncommon::endbodytag().'</html>');
1.87      www      2194:     return OK;
1.5       www      2195: }
1.2       www      2196: # ================================================= Main program, reset counter
                   2197: 
1.27      www      2198: BEGIN {
1.2       www      2199:     $msgcount=0;
1.1       www      2200: }
1.58      bowersj2 2201: 
                   2202: =pod
                   2203: 
                   2204: =back
                   2205: 
1.59      bowersj2 2206: =cut
                   2207: 
                   2208: 1; 
1.1       www      2209: 
                   2210: __END__
                   2211: 
                   2212: 
                   2213: 
                   2214: 
                   2215: 
                   2216: 
                   2217: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.