Diff for /loncom/interface/lonmsg.pm between versions 1.87 and 1.128

version 1.87, 2004/03/01 01:19:51 version 1.128, 2005/01/01 18:36:13
Line 74  email program, so they have full access Line 74  email program, so they have full access
 interface, or other features they may wish to use in response to the  interface, or other features they may wish to use in response to the
 student's query.  student's query.
   
   =item * B<Blocking>: LON-CAPA can block display of e-mails that are 
   sent to a student during an online exam. A course coordinator or
   instructor can set an open and close date/time for scheduled online
   exams in a course. If a user uses the LON-CAPA internal messaging 
   system to display e-mails during the scheduled blocking event,  
   display of all e-mail sent during the blocking period will be 
   suppressed, and a message of explanation, including details of the 
   currently active blocking periods will be displayed instead. A user 
   who has a course coordinator or instructor role in a course will be
   unaffected by any blocking periods for the course, unless the user
   also has a student role in the course, AND has selected the student role.
   
 =back  =back
   
 Users can ask LON-CAPA to forward messages to conventional e-mail  Users can ask LON-CAPA to forward messages to conventional e-mail
Line 101  use Apache::lontexconvert(); Line 113  use Apache::lontexconvert();
 use HTML::Entities();  use HTML::Entities();
 use Mail::Send;  use Mail::Send;
 use Apache::lonlocal;  use Apache::lonlocal;
   use Apache::loncommunicate;
   
 # Querystring component with sorting type  # Querystring component with sorting type
 my $sqs;  my $sqs;
   my $startdis;
   my $interdis;
   
 # ===================================================================== Package  # ===================================================================== Package
   
 sub packagemsg {  sub packagemsg {
     my ($subject,$message,$citation,$baseurl,$attachmenturl)=@_;      my ($subject,$message,$citation,$baseurl,$attachmenturl,
     $message =&HTML::Entities::encode($message);   $recuser,$recdomain)=@_;
     $citation=&HTML::Entities::encode($citation);      $message =&HTML::Entities::encode($message,'<>&"');
     $subject =&HTML::Entities::encode($subject);      $citation=&HTML::Entities::encode($citation,'<>&"');
       $subject =&HTML::Entities::encode($subject,'<>&"');
     #remove machine specification      #remove machine specification
     $baseurl =~ s|^http://[^/]+/|/|;      $baseurl =~ s|^http://[^/]+/|/|;
     $baseurl =&HTML::Entities::encode($baseurl);      $baseurl =&HTML::Entities::encode($baseurl,'<>&"');
     #remove machine specification      #remove machine specification
     $attachmenturl =~ s|^http://[^/]+/|/|;      $attachmenturl =~ s|^http://[^/]+/|/|;
     $attachmenturl =&HTML::Entities::encode($attachmenturl);      $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
   
     my $now=time;      my $now=time;
     $msgcount++;      $msgcount++;
Line 143  sub packagemsg { Line 159  sub packagemsg {
    '<role>'.$ENV{'request.role'}.'</role>'.     '<role>'.$ENV{'request.role'}.'</role>'.
    '<resource>'.$ENV{'request.filename'}.'</resource>'.     '<resource>'.$ENV{'request.filename'}.'</resource>'.
            '<msgid>'.$msgid.'</msgid>'.             '<msgid>'.$msgid.'</msgid>'.
      '<recuser>'.$recuser.'</recuser>'.
      '<recdomain>'.$recdomain.'</recdomain>'.
    '<message>'.$message.'</message>';     '<message>'.$message.'</message>';
     if (defined($citation)) {      if (defined($citation)) {
  $result.='<citation>'.$citation.'</citation>';   $result.='<citation>'.$citation.'</citation>';
Line 171  sub unpackagemsg { Line 189  sub unpackagemsg {
        }         }
     }      }
     if ($content{'attachmenturl'}) {      if ($content{'attachmenturl'}) {
        my ($fname,$ft)=($content{'attachmenturl'}=~/\/(\w+)\.(\w+)$/);         my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
        if ($notoken) {         if ($notoken) {
    $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'.'.$ft.'</tt>';     $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'</tt>';
        } else {         } else {
    $content{'message'}.='<p>'.&mt('Attachment').': <a href="'.     &Apache::lonnet::allowuploaded('/adm/msg',
        &Apache::lonnet::tokenwrapper($content{'attachmenturl'}).    $content{'attachmenturl'});
        '"><tt>'.$fname.'.'.$ft.'</tt></a>';     $content{'message'}.='<p>'.&mt('Attachment').
          ': <a href="'.$content{'attachmenturl'}.'"><tt>'.
          $fname.'</tt></a>';
        }         }
     }      }
     return %content;      return %content;
Line 186  sub unpackagemsg { Line 206  sub unpackagemsg {
 # ======================================================= Get info out of msgid  # ======================================================= Get info out of msgid
   
 sub unpackmsgid {  sub unpackmsgid {
     my $msgid=&Apache::lonnet::unescape(shift);      my ($msgid,$folder)=@_;
       $msgid=&Apache::lonnet::unescape($msgid);
       my $suffix=&foldersuffix($folder);
     my ($sendtime,$shortsubj,$fromname,$fromdomain)=split(/\:/,      my ($sendtime,$shortsubj,$fromname,$fromdomain)=split(/\:/,
                           &Apache::lonnet::unescape($msgid));                            &Apache::lonnet::unescape($msgid));
     my %status=&Apache::lonnet::get('email_status',[$msgid]);      my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }      if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
     unless ($status{$msgid}) { $status{$msgid}='new'; }      unless ($status{$msgid}) { $status{$msgid}='new'; }
     return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid});      return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid});
Line 204  sub sendemail { Line 226  sub sendemail {
     my $msg = new Mail::Send;      my $msg = new Mail::Send;
     $msg->to($to);      $msg->to($to);
     $msg->subject('[LON-CAPA] '.$subject);      $msg->subject('[LON-CAPA] '.$subject);
     if (my $fh = $msg->open('smtp',Server => 'localhost')) {      my %oldENV=%ENV;
       undef(%ENV);
       if (my $fh = $msg->open()) {
  print $fh $body;   print $fh $body;
  $fh->close;   $fh->close;
     }      }
       %ENV=%oldENV;
       undef(%oldENV);
 }  }
   
 # ==================================================== Send notification emails  # ==================================================== Send notification emails
Line 426  sub user_normal_msg_raw { Line 452  sub user_normal_msg_raw {
     my $homeserver=&Apache::lonnet::homeserver($user,$domain);      my $homeserver=&Apache::lonnet::homeserver($user,$domain);
     if ($homeserver ne 'no_host') {      if ($homeserver ne 'no_host') {
        ($msgid,$message)=&packagemsg($subject,$message,$citation,$baseurl,         ($msgid,$message)=&packagemsg($subject,$message,$citation,$baseurl,
                                      $attachmenturl);                                       $attachmenturl,$user,$domain);
   # Store in user folder
        $status=&Apache::lonnet::critical(         $status=&Apache::lonnet::critical(
            'put:'.$domain.':'.$user.':nohist_email:'.             'put:'.$domain.':'.$user.':nohist_email:'.
            &Apache::lonnet::escape($msgid).'='.             &Apache::lonnet::escape($msgid).'='.
            &Apache::lonnet::escape($message),$homeserver);             &Apache::lonnet::escape($message),$homeserver);
   # Save new message received time
        &Apache::lonnet::put         &Apache::lonnet::put
                          ('email_status',{'recnewemail'=>time},$domain,$user);                           ('email_status',{'recnewemail'=>time},$domain,$user);
   # Into sent-mail folder
          $status.=' '.&Apache::lonnet::critical(
              'put:'.$ENV{'user.domain'}.':'.$ENV{'user.name'}.
         ':nohist_email_sent:'.
              &Apache::lonnet::escape($msgid).'='.
              &Apache::lonnet::escape($message),$ENV{'user.home'});
     } else {      } else {
        $status='no_host';         $status='no_host';
     }      }
Line 479  sub user_normal_msg { Line 513  sub user_normal_msg {
 }  }
   
   
   # ============================================================ List all folders
   
   sub folderlist {
       my $folder=shift;
       my @allfolders=&Apache::lonnet::getkeys('email_folders');
       if ($allfolders[0]=~/^error:/) { @allfolders=(); }
       return '<form method="post" action="/adm/email">'.
    &mt('Folder').': '.
    &Apache::loncommon::select_form($folder,'folder',
        ('' => &mt('INBOX'),'trash' => &mt('TRASH'),
         'new' => &mt('New Messages Only'),
                                 'critical' => &mt('Critical'),
         'sent' => &mt('Sent Messages'),
         map { $_ => $_ } @allfolders)).
         ' '.&mt('Show').
         '<select name="interdis">'.
         join("\n",map { '<option value="'.$_.'"'.
    ($_==$interdis?' selected="selected"':'').'>'.$_.'</option>' }
      (10,20,50,100,200)).'</select>'.
      '<input type="submit" value="'.&mt('View Folder').'" /><br />'.
       '<input type="hidden" name="sortedby" value="'.$ENV{'form.sortedby'}.'" />'.
         ($folder=~/^(new|critical)/?'</form>':'');
   }
   
   sub scrollbuttons {
       my ($start,$maxdis,$first,$finish,$total)=@_;
       unless ($total>0) { return ''; }
       $start++; $maxdis++;$first++;$finish++;
       return 
      '<input type="submit" name="firstview" value="'.&mt('First').'" />'.
      '<input type="submit" name="prevview" value="'.&mt('Previous').'" />'.
      '<input type="text" size="5" name="startdis" value="'.$start.'" onChange="this.form.submit()" /> of '.$maxdis.
      '<input type="submit" name="nextview" value="'.&mt('Next').'" />'.
      '<input type="submit" name="lastview" value="'.&mt('Last').'" /><br />'.
      &mt('Messages [_1] through [_2] of [_3]',$first,$finish,$total).'</form>';
   }
   
   # =============================================================== Folder suffix
   
   sub foldersuffix {
       my $folder=shift;
       unless ($folder) { return ''; }
       return '_'.&Apache::lonnet::escape($folder);
   }
   
 # =============================================================== Status Change  # =============================================================== Status Change
   
 sub statuschange {  sub statuschange {
     my ($msgid,$newstatus)=@_;      my ($msgid,$newstatus,$folder)=@_;
     my %status=&Apache::lonnet::get('email_status',[$msgid]);      my $suffix=&foldersuffix($folder);
       my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }      if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
     unless ($status{$msgid}) { $status{$msgid}='new'; }      unless ($status{$msgid}) { $status{$msgid}='new'; }
     unless (($status{$msgid} eq 'replied') ||       unless (($status{$msgid} eq 'replied') || 
             ($status{$msgid} eq 'forwarded')) {              ($status{$msgid} eq 'forwarded')) {
  &Apache::lonnet::put('email_status',{$msgid => $newstatus});   &Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
     }      }
     if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {      if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {
  &Apache::lonnet::put('email_status',{$msgid => $newstatus});   &Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
       }
   }
   
   # ============================================================= Make new folder
   
   sub makefolder {
       my ($newfolder)=@_;
       if (($newfolder eq 'sent')
        || ($newfolder eq 'critical')
        || ($newfolder eq 'trash')
        || ($newfolder eq 'new')) { return; }
       &Apache::lonnet::put('email_folders',{$newfolder => time});
   }
   
   # ======================================================== Move between folders
   
   sub movemsg {
       my ($msgid,$srcfolder,$trgfolder)=@_;
       my $srcsuffix=&foldersuffix($srcfolder);
       my $trgsuffix=&foldersuffix($trgfolder);
   
   # Copy message
       my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]);
       &Apache::lonnet::put('nohist_email'.$trgsuffix,{$msgid => $message{$msgid}});
   
   # Copy status
       unless ($trgfolder eq 'trash') {
    my %status=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);
    &Apache::lonnet::put('email_status'.$trgsuffix,{$msgid => $status{$msgid}});
     }      }
   # Delete orginals
       &Apache::lonnet::del('nohist_email'.$srcsuffix,[$msgid]);
       &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
 }  }
   
 # ======================================================= Display a course list  # ======================================================= Display a course list
   
 sub discourse {  sub discourse {
     my $r=shift;      my $r=shift;
     my %courselist=&Apache::lonnet::dump(      my $classlist = &Apache::loncoursedata::get_classlist();
                    'classlist',  
    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},  
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'});  
     my $now=time;      my $now=time;
     my %lt=&Apache::lonlocal::texthash('cfa' => 'Check for All',      my %lt=&Apache::lonlocal::texthash('cfa' => 'Check for All',
             'cfs' => 'Check for Section/Group',              'cfs' => 'Check for Section/Group',
             'cfn' => 'Check for None');              'cfn' => 'Check for None');
     $r->print(<<ENDDISHEADER);      $r->print(<<ENDDISHEADER);
 <input type=hidden name=sendmode value=group>  <input type="hidden" name="sendmode" value="group" />
 <script>  <script>
     function checkall() {      function checkall() {
  for (i=0; i<document.forms.compemail.elements.length; i++) {   for (i=0; i<document.forms.compemail.elements.length; i++) {
Line 538  sub discourse { Line 647  sub discourse {
         }          }
     }      }
 </script>  </script>
 <input type=button onClick="checkall()" value="$lt{'cfa'}">&nbsp;  <input type="button" onClick="checkall()" value="$lt{'cfa'}" />&nbsp;
 <input type=button onClick="checksec()" value="$lt{'cfs'}">  <input type="button" onClick="checksec()" value="$lt{'cfs'}" />
 <input type=text size=5 name=chksec>&nbsp;  <input type="text" size="5" name=chksec />&nbsp;
 <input type=button onClick="uncheckall()" value="$lt{'cfn'}">  <input type="button" onClick="uncheckall()" value="$lt{'cfn'}" />
 <p>  <p>
 ENDDISHEADER  ENDDISHEADER
     my %coursepersonnel=      my %coursepersonnel=&Apache::lonnet::get_course_adv_roles();
        &Apache::lonnet::get_course_adv_roles();      $r->print('<table>');
     foreach my $role (sort keys %coursepersonnel) {      foreach my $role (sort keys %coursepersonnel) {
        foreach (split(/\,/,$coursepersonnel{$role})) {          foreach (split(/\,/,$coursepersonnel{$role})) {
    my ($puname,$pudom)=split(/\:/,$_);              my ($puname,$pudom)=split(/\:/,$_);
    $r->print(              $r->print('<tr><td><label>'.
              '<br /><input type="checkbox" name="send_to_&&&&&&_'.                        '<input type="checkbox" name="send_to_&&&&&&_'.
              $puname.':'.$pudom.'" /> '.                        $puname.':'.$pudom.'" /> '.
      &Apache::loncommon::plainname($puname,                        &Apache::loncommon::plainname($puname,$pudom).
                           $pudom).' ('.$_.'), <i>'.$role.'</i>');                        '</label></td>'.
  }                        '<td>('.$_.'),</td><td><i>'.$role.'</i></td></tr>');
           }
     }      }
       $r->print('</table><table>');
     foreach (sort keys %courselist) {      while (my ($student,$info) = each(%$classlist)) {
         my ($end,$start)=split(/\:/,$courselist{$_});          my ($sname,$sdom,$status,$fullname,$section) =
         my $active=1;              (@{$info}[&Apache::loncoursedata::CL_SNAME(),
         if (($end) && ($now>$end)) { $active=0; }                        &Apache::loncoursedata::CL_SDOM(),
         if ($active) {                        &Apache::loncoursedata::CL_STATUS(),
            my ($sname,$sdom)=split(/\:/,$_);                        &Apache::loncoursedata::CL_FULLNAME(),
            my %reply=&Apache::lonnet::get('environment',                        &Apache::loncoursedata::CL_SECTION()]);
               ['firstname','middlename','lastname','generation'],          next if ($status ne 'Active');
               $sdom,$sname);          my $key = 'send_to_&&&'.$section.'&&&'.$student;
            my $section=&Apache::lonnet::usection          if (! defined($fullname) || $fullname eq '') { $fullname = $sname; }
        ($sdom,$sname,$ENV{'request.course.id'});          $r->print('<tr><td><label>'.
            $r->print(                    qq{<input type="checkbox" name="$key">}.('&nbsp;'x2).
         '<br><input type=checkbox name="send_to_&&&'.$section.'&&&_'.$_.'"> '.                    $fullname.'</td><td>'.$sname.'@'.$sdom.'</td><td>'.$section.
       $reply{'firstname'}.' '.                     '</td></tr>');
                       $reply{'middlename'}.' '.  
                       $reply{'lastname'}.' '.  
                       $reply{'generation'}.  
                       ' ('.$_.') '.$section);  
         }   
     }      }
       $r->print('</table>');
 }  }
   
 # ==================================================== Display Critical Message  # ==================================================== Display Critical Message
Line 591  sub discrit { Line 697  sub discrit {
     foreach (sort keys %what) {      foreach (sort keys %what) {
         my %content=&unpackagemsg($what{$_});          my %content=&unpackagemsg($what{$_});
         next if ($content{'senderdomain'} eq '');          next if ($content{'senderdomain'} eq '');
         $content{'message'}=~s/\n/\<br\>/g;          $result.='<hr />'.&mt('From').': <b>'.
         $result.='<hr>'.&mt('From').': <b>'.  
 &Apache::loncommon::aboutmewrapper(  &Apache::loncommon::aboutmewrapper(
  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.   &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
 $content{'sendername'}.'@'.  $content{'sendername'}.'@'.
             $content{'senderdomain'}.') '.$content{'time'}.              $content{'senderdomain'}.') '.$content{'time'}.
             '<br>'.&mt('Subject').': '.$content{'subject'}.              '<br />'.&mt('Subject').': '.$content{'subject'}.
             '<br><blockquote>'.              '<br /><blockquote>'.
               &Apache::lontexconvert::msgtexconverted($content{'message'}).                &Apache::lontexconvert::msgtexconverted($content{'message'}).
             '</blockquote><small>'.              '</blockquote><small>'.
 &mt('You have to confirm that you received this message. After confirmation, this message will be moved to your regular inbox').  &mt('You have to confirm that you received this message. After confirmation, this message will be moved to your regular inbox').
Line 610  $content{'sendername'}.'@'. Line 715  $content{'sendername'}.'@'.
     # Check to see if there were any messages.      # Check to see if there were any messages.
     if ($result eq '') {      if ($result eq '') {
         $result = "<h2>".&mt('You have no critical messages.')."</h2>".          $result = "<h2>".&mt('You have no critical messages.')."</h2>".
     '<a href="/adm/roles">'.&mt('Select a course').'</a>';      '<a href="/adm/roles">'.&mt('Select a course').'</a><br />'.
               '<a href="/adm/email">'.&mt('Communicate').'</a>';
     } else {      } else {
         $r->print($header);          $r->print($header);
     }      }
     $r->print($result);      $r->print($result);
     $r->print('<input type=hidden name="displayedcrit" value="true"></form>');      $r->print('<input type="hidden" name="displayedcrit" value="true" /></form>');
 }  
   
 # =============================================================== Compose reply  
   
 sub comprep {  
     my ($r,$msgid)=@_;  
       my %message=&Apache::lonnet::get('nohist_email',[$msgid]);  
       my %content=&unpackagemsg($message{$msgid},1);  
       my $quotemsg='> '.$content{'message'};  
       $quotemsg=~s/\r/\n/g;  
       $quotemsg=~s/\f/\n/g;  
       $quotemsg=~s/\n+/\n\> /g;  
       my $torepl=&Apache::loncommon::aboutmewrapper(  
  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('.  
 $content{'sendername'}.'@'.  
             $content{'senderdomain'}.')';  
       my $subject=&mt('Re').': '.$content{'subject'};  
       my $dispcrit='';  
       if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {  
  my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");  
          $dispcrit=  
  '<input type=checkbox name=critmsg> '.&mt('Send as critical message').' ' . $crithelp .   
  '<br>'.  
  '<input type=checkbox name=sendbck> '.&mt('Send as critical message').' ' .  
  &mt('and return receipt') . $crithelp . '<p>';  
       }  
     my %lt=&Apache::lonlocal::texthash(  
    'to' => 'To',  
    'sb' => 'Subject',  
    'sr' => 'Send Reply',  
    'ca' => 'Cancel'  
    );  
       $r->print(<<"ENDREPLY");  
 <form action="/adm/email" method="post">  
 <input type="hidden" name="sendreply" value="$msgid">  
 $lt{'to'}: $torepl<br />  
 $lt{'sb'}: <input type="text" size=50 name="subject" value="$subject"><p>  
 <textarea name="message" cols="84" rows="10" wrap="hard">  
 $quotemsg  
 </textarea></p><br />  
 $dispcrit  
 <input type="submit" name="send" value="$lt{'sr'}" />  
 <input type="submit" name="cancel" value="$lt{'ca'}"/ >  
 </form>  
 ENDREPLY  
 }  }
   
 sub sortedmessages {  sub sortedmessages {
     my @messages = &Apache::lonnet::getkeys('nohist_email');      my ($blocked,$startblock,$endblock,$numblocked,$folder) = @_;
       my $suffix=&foldersuffix($folder);
       my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
     #unpack the varibles and repack into temp for sorting      #unpack the varibles and repack into temp for sorting
     my @temp;      my @temp;
     foreach (@messages) {      foreach (@messages) {
  my $msgid=&Apache::lonnet::escape($_);   my $msgid=&Apache::lonnet::escape($_);
  my ($sendtime,$shortsubj,$fromname,$fromdomain,$status)=   my ($sendtime,$shortsubj,$fromname,$fromdomain,$status)=
     &Apache::lonmsg::unpackmsgid($msgid);      &Apache::lonmsg::unpackmsgid($msgid,$folder);
  my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,   my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
      $msgid);       $msgid);
  push @temp ,\@temp1;          # Check whether message was sent during blocking period.
           if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {
               my $escid = &Apache::lonnet::unescape($msgid);
               $$blocked{$escid} = 'ON';
               $$numblocked ++;
           } else { 
               push @temp ,\@temp1;
           }
     }      }
     #default sort      #default sort
     @temp = sort  {$a->[0] <=> $b->[0]} @temp;          @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
Line 710  sub sortedmessages { Line 780  sub sortedmessages {
     return @temp;      return @temp;
 }  }
   
   # ======================================================== Display new messages
   
   
   sub disnew {
       my $r=shift;
       my %lt=&Apache::lonlocal::texthash(
          'nm' => 'New Messages',
          'su' => 'Subject',
          'da' => 'Date',
          'us' => 'Username',
          'op' => 'Open',
          'do' => 'Domain'
          );
       my @msgids = sort split(/\&/,&Apache::lonnet::reply
                               ('keys:'.$ENV{'user.domain'}.':'.
                                $ENV{'user.name'}.':nohist_email',
                                $ENV{'user.home'}));
       my @newmsgs;
       my %setters = ();
       my $startblock = 0;
       my $endblock = 0;
       my %blocked = ();
       my $numblocked = 0;
       # Check for blocking of display because of scheduled online exams.
       &blockcheck(\%setters,\$startblock,\$endblock);
       foreach (@msgids) {
           my ($sendtime,$shortsubj,$fromname,$fromdom,$status)=
       &Apache::lonmsg::unpackmsgid($_);
           if (defined($sendtime) && $sendtime!~/error/) {
               my $numsendtime = $sendtime;
               $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
               if ($status eq 'new') {
                   if ($numsendtime >= $startblock && ($numsendtime <= $endblock && $endblock > 0) ) {
                       $blocked{$_} = 'ON';
                       $numblocked ++;
                   } else {
                       push @newmsgs, { 
                           msgid    => $_,
                           sendtime => $sendtime,
                           shortsub => &Apache::lonnet::unescape($shortsubj),
                           from     => $fromname,
                           fromdom  => $fromdom 
                           }
                   }
               }
           }
       }
       if ($#newmsgs >= 0) {
           $r->print(<<TABLEHEAD);
   <h2>$lt{'nm'}</h2>
   <table border=2><tr><th>&nbsp</th>
   <th>$lt{'da'}</th><th>$lt{'us'}</th><th>$lt{'do'}</th><th>$lt{'su'}</th></tr>
   TABLEHEAD
           foreach my $msg (@newmsgs) {
               $r->print(<<"ENDLINK");
   <tr bgcolor="#FFBB77">
   <td><a href="/adm/email?display=$msg->{'msgid'}">$lt{'op'}</a></td>
   ENDLINK
               foreach ('sendtime','from','fromdom','shortsub') {
                   $r->print("<td>$msg->{$_}</td>");
               }
               $r->print("</td></tr>");
           }
           $r->print('</table></body></html>');
       } elsif ($numblocked == 0) {
           $r->print("<h3>".&mt('You have no unread messages')."</h3>");
       }
       if ($numblocked > 0) {
           my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
           my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
           if ($numblocked == 1) {
               $r->print("<h3>".&mt('You have').' '.$numblocked.' '.&mt('blocked unread message').".</h3>");
               $r->print(&mt('This message is not viewable because').' ');
           } else {
               $r->print("<h3>".&mt('You have').' '.$numblocked.' '.&mt('blocked unread messages').".</h3>");
               $r->print(&mt('These').' '.$numblocked.' '.&mt('messages are not viewable because '));
           }
           $r->print(
   &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').'.');
           &build_block_table($r,$startblock,$endblock,\%setters);
       }
   }
   
   
 # ======================================================== Display all messages  # ======================================================== Display all messages
   
 sub disall {  sub disall {
     my $r=shift;      my ($r,$folder)=@_;
      $r->print(<<ENDDISHEADER);      $r->print(&folderlist($folder));
       if ($folder eq 'new') {
    &disnew($r);
       } elsif ($folder eq 'critical') {
    &discrit($r);
       } else {
    &disfolder($r,$folder);
       }
   }
   
   # ============================================================ Display a folder
   
   sub disfolder {
       my ($r,$folder)=@_;
       my %blocked = ();
       my %setters = ();
       my $startblock;
       my $endblock;
       my $numblocked = 0;
       &blockcheck(\%setters,\$startblock,\$endblock);
       $r->print(<<ENDDISHEADER);
 <script>  <script>
     function checkall() {      function checkall() {
  for (i=0; i<document.forms.disall.elements.length; i++) {   for (i=0; i<document.forms.disall.elements.length; i++) {
Line 735  sub disall { Line 909  sub disall {
     }      }
 </script>  </script>
 ENDDISHEADER  ENDDISHEADER
     $r->print('<h1>'.&mt('Display All Messages').'</h1><form method=post name=disall '.      my $fsqs='&folder='.$folder;
       'action="/adm/email">'.      my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
       '<table border=2><tr><th colspan=2>&nbsp</th><th>');      my $totalnumber=$#temp+1;
       unless ($totalnumber>0) {
    $r->print('<h2>'.&mt('Empty Folder').'</h2>');
    return;
       }
       unless ($interdis) {
    $interdis=20;
       }
       my $number=int($totalnumber/$interdis);
       if (($startdis<0) || ($startdis>$number)) { $startdis=$number; }
       my $firstdis=$interdis*$startdis;
       if ($firstdis>$#temp) { $firstdis=$#temp-$interdis+1; }
       my $lastdis=$firstdis+$interdis-1;
       if ($lastdis>$#temp) { $lastdis=$#temp; }
       $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber));
       $r->print('<form method="post" name="disall" action="/adm/email">'.
         '<table border=2><tr><th colspan="3">&nbsp</th><th>');
     if ($ENV{'form.sortedby'} eq "revdate") {      if ($ENV{'form.sortedby'} eq "revdate") {
  $r->print('<a href = "?sortedby=date">'.&mt('Date').'</a></th>');   $r->print('<a href = "?sortedby=date'.$fsqs.'">'.&mt('Date').'</a></th>');
     } else {      } else {
  $r->print('<a href = "?sortedby=revdate">'.&mt('Date').'</a></th>');   $r->print('<a href = "?sortedby=revdate'.$fsqs.'">'.&mt('Date').'</a></th>');
     }      }
     $r->print('<th>');      $r->print('<th>');
     if ($ENV{'form.sortedby'} eq "revuser") {      if ($ENV{'form.sortedby'} eq "revuser") {
  $r->print('<a href = "?sortedby=user">'.&mt('Username').'</a>');   $r->print('<a href = "?sortedby=user'.$fsqs.'">'.&mt('Username').'</a>');
     } else {      } else {
  $r->print('<a href = "?sortedby=revuser">'.&mt('Username').'</a>');   $r->print('<a href = "?sortedby=revuser'.$fsqs.'">'.&mt('Username').'</a>');
     }      }
     $r->print('</th><th>');      $r->print('</th><th>');
     if ($ENV{'form.sortedby'} eq "revdomain") {      if ($ENV{'form.sortedby'} eq "revdomain") {
  $r->print('<a href = "?sortedby=domain">'.&mt('Domain').'</a>');   $r->print('<a href = "?sortedby=domain'.$fsqs.'">'.&mt('Domain').'</a>');
     } else {      } else {
  $r->print('<a href = "?sortedby=revdomain">'.&mt('Domain').'</a>');   $r->print('<a href = "?sortedby=revdomain'.$fsqs.'">'.&mt('Domain').'</a>');
     }      }
     $r->print('</th><th>');      $r->print('</th><th>');
     if ($ENV{'form.sortedby'} eq "revsubject") {      if ($ENV{'form.sortedby'} eq "revsubject") {
  $r->print('<a href = "?sortedby=subject">'.&mt('Subject').'</a>');   $r->print('<a href = "?sortedby=subject'.$fsqs.'">'.&mt('Subject').'</a>');
     } else {      } else {
     $r->print('<a href = "?sortedby=revsubject">'.&mt('Subject').'</a>');      $r->print('<a href = "?sortedby=revsubject'.$fsqs.'">'.&mt('Subject').'</a>');
     }      }
     $r->print('</th><th>');      $r->print('</th><th>');
     if ($ENV{'form.sortedby'} eq "revstatus") {      if ($ENV{'form.sortedby'} eq "revstatus") {
  $r->print('<a href = "?sortedby=status">'.&mt('Status').'</th>');   $r->print('<a href = "?sortedby=status'.$fsqs.'">'.&mt('Status').'</th>');
     } else {      } else {
       $r->print('<a href = "?sortedby=revstatus">'.&mt('Status').'</th>');        $r->print('<a href = "?sortedby=revstatus'.$fsqs.'">'.&mt('Status').'</th>');
     }      }
     $r->print('</tr>');      $r->print("</tr>\n");
     my @temp=sortedmessages();      for (my $n=$firstdis;$n<=$lastdis;$n++) {
     foreach (@temp){   my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @{$temp[$n]};
  my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @$_;  
  if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) {   if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) {
     if ($status eq 'new') {      if ($status eq 'new') {
  $r->print('<tr bgcolor="#FFBB77">');   $r->print('<tr bgcolor="#FFBB77">');
Line 781  ENDDISHEADER Line 970  ENDDISHEADER
     } else {      } else {
  $r->print('<tr bgcolor="#99BBBB">');   $r->print('<tr bgcolor="#99BBBB">');
     }      }
     $r->print('<td><a href="/adm/email?display='.$origID.$sqs.       $r->print('<td></a><input type=checkbox name="delmark_'.$origID.'" /></td><td><a href="/adm/email?display='.$origID.$sqs. 
       '">'.&mt('Open').'</a></td><td><a href="/adm/email?markdel='.$origID.$sqs.        '">'.&mt('Open').'</a></td><td>'.
       '">'.&mt('Delete').'</a><input type=checkbox name="delmark_'.$origID.'"></td>'.        ($folder ne 'trash'?'<a href="/adm/email?markdel='.$origID.$sqs.
         '">'.&mt('Delete'):'&nbsp').'</td>'.
       '<td>'.&Apache::lonlocal::locallocaltime($sendtime).'</td><td>'.        '<td>'.&Apache::lonlocal::locallocaltime($sendtime).'</td><td>'.
       $fromname.'</td><td>'.$fromdomain.'</td><td>'.        $fromname.'</td><td>'.$fromdomain.'</td><td>'.
       &Apache::lonnet::unescape($shortsubj).'</td><td>'.        &Apache::lonnet::unescape($shortsubj).'</td><td>'.
                       $status.'</td></tr>');                        $status."</td></tr>\n");
    } elsif ($status eq 'deleted') {
   # purge
       &movemsg(&Apache::lonnet::unescape($origID),$folder,'trash');
  }   }
     }         }   
     $r->print('</table><p>'.      $r->print("</table>\n<p>".
               '<a href="javascript:checkall()">'.&mt('Check All').'</a>&nbsp;'.    '<a href="javascript:checkall()">'.&mt('Check All').'</a>&nbsp;'.
               '<a href="javascript:uncheckall()">'.&mt('Uncheck All').'</a><p>'.    '<a href="javascript:uncheckall()">'.&mt('Uncheck All').'</a></p>'.
       '<input type="hidden" name="sortedby" value="'.$ENV{'form.sortedby'}.'" />'.    '<input type="hidden" name="sortedby" value="'.$ENV{'form.sortedby'}.'" />');
               '<input type=submit name="markeddel" value="'.&mt('Delete Checked').'">'.      if ($folder ne 'trash') {
               '</form></body></html>');   $r->print(
         '<p><input type="submit" name="markeddel" value="'.&mt('Delete Checked').'" /></p>');
       }
       $r->print('<p><input type="submit" name="markedmove" value="'.&mt('Move Checked to Folder').'" />');
       my @allfolders=&Apache::lonnet::getkeys('email_folders');
       if ($allfolders[0]=~/^error:/) { @allfolders=(); }
       $r->print(
    &Apache::loncommon::select_form('','movetofolder',
        ( map { $_ => $_ } @allfolders))
         );
       my $postedstartdis=$startdis+1;
       $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>');
       if ($numblocked > 0) {
           my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
           my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
           $r->print('<br /><br />'.
                     $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.'));
           &build_block_table($r,$startblock,$endblock,\%setters);
       }
 }  }
   
 # ============================================================== Compose output  # ============================================================== Compose output
   
 sub compout {  sub compout {
     my ($r,$forwarding,$broadcast)=@_;      my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder)=@_;
       my $dispcrit='';      my $suffix=&foldersuffix($folder);
   
       if ($broadcast eq 'individual') {
    &printheader($r,'/adm/email?compose=individual',
        'Send a Message');
       } elsif ($broadcast) {
    &printheader($r,'/adm/email?compose=group',
        'Broadcast Message');
       } elsif ($forwarding) {
    &Apache::lonhtmlcommon::add_breadcrumb
           ({href=>"/adm/email?display=".&Apache::lonnet::escape($forwarding),
             text=>"Display Message"});
    &printheader($r,'/adm/email?forward='.&Apache::lonnet::escape($forwarding),
        'Forwarding a Message');
       } elsif ($replying) {
    &Apache::lonhtmlcommon::add_breadcrumb
           ({href=>"/adm/email?display=".&Apache::lonnet::escape($replying),
             text=>"Display Message"});
    &printheader($r,'/adm/email?replyto='.&Apache::lonnet::escape($replying),
        'Replying to a Message');
       } elsif ($replycrit) {
    $r->print('<h3>'.&mt('Replying to a Critical Message').'</h3>');
    $replying=$replycrit;
       } else {
    &printheader($r,'/adm/email?compose=upload',
        'Distribute from Uploaded File');
       }
   
       my $dispcrit='';
     my $dissub='';      my $dissub='';
     my $dismsg='';      my $dismsg='';
       my $disbase='';
     my $func=&mt('Send New');      my $func=&mt('Send New');
     my %lt=&Apache::lonlocal::texthash('us' => 'Username',      my %lt=&Apache::lonlocal::texthash('us' => 'Username',
        'do' => 'Domain',         'do' => 'Domain',
Line 816  sub compout { Line 1056  sub compout {
     if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
  my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");   my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
          $dispcrit=           $dispcrit=
  '<input type="checkbox" name="critmsg"> '.&mt('Send as critical message').' ' . $crithelp .    '<input type="checkbox" name="critmsg" /> '.&mt('Send as critical message').' ' . $crithelp . 
  '<br>'.   '<br>'.
  '<input type="checkbox" name="sendbck"> '.&mt('Send as critical message').'  ' .   '<input type="checkbox" name="sendbck" /> '.&mt('Send as critical message').'  ' .
  &mt('and return receipt') . $crithelp . '<p>';   &mt('and return receipt') . $crithelp . '<p>';
       }       }
       my %message;
       my %content;
       my $defdom=$ENV{'user.domain'};
     if ($forwarding) {      if ($forwarding) {
        $dispcrit.='<input type="hidden" name="forwid" value="'.   %message=&Apache::lonnet::get('nohist_email'.$suffix,[$forwarding]);
    $forwarding.'">';   %content=&unpackagemsg($message{$forwarding},$folder);
        $func=&mt('Forward');   $dispcrit.='<input type="hidden" name="forwid" value="'.
       my %message=&Apache::lonnet::get('nohist_email',[$forwarding]);      $forwarding.'" />';
       my %content=&unpackagemsg($message{$forwarding});   $func=&mt('Forward');
   
        $dissub=&mt('Forwarding').': '.$content{'subject'};   $dissub=&mt('Forwarding').': '.$content{'subject'};
        $dismsg=&mt('Forwarded message from').' '.   $dismsg=&mt('Forwarded message from').' '.
    $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'};      $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'};
    if ($content{'baseurl'}) {
       $disbase='<input type="hidden" name="baseurl" value="'.&Apache::lonnet::escape($content{'baseurl'}).'" />';
    }
     }      }
     my $defdom=$ENV{'user.domain'};      if ($replying) {
    %message=&Apache::lonnet::get('nohist_email'.$suffix,[$replying]);
    %content=&unpackagemsg($message{$replying},$folder);
    $dispcrit.='<input type="hidden" name="replyid" value="'.
       $replying.'" />';
    $func=&mt('Send Reply to');
   
    $dissub=&mt('Reply').': '.$content{'subject'};       
    $dismsg='> '.$content{'message'};
    $dismsg=~s/\r/\n/g;
    $dismsg=~s/\f/\n/g;
    $dismsg=~s/\n+/\n\> /g;
    if ($content{'baseurl'}) {
       $disbase='<input type="hidden" name="baseurl" value="'.&Apache::lonnet::escape($content{'baseurl'}).'" />';
       if ($ENV{'user.adv'}) {
    $disbase.='<input type="checkbox" name="storebasecomment" />'.&mt('Store message for re-use').
       ' <a href="/adm/email?showcommentbaseurl='.
       &Apache::lonnet::escape($content{'baseurl'}).'" target="comments">'.
       &mt('Show re-usable messages').'</a><br />';
       }
    }
       }
       my $citation=&displayresource(%content);
     if ($ENV{'form.recdom'}) { $defdom=$ENV{'form.recdom'}; }      if ($ENV{'form.recdom'}) { $defdom=$ENV{'form.recdom'}; }
       $r->print(        $r->print(
                 '<form action="/adm/email"  name="compemail" method="post"'.                  '<form action="/adm/email"  name="compemail" method="post"'.
                 ' enctype="multipart/form-data">'."\n".                  ' enctype="multipart/form-data">'."\n".
                 '<input type="hidden" name="sendmail" value="on">'."\n".                  '<input type="hidden" name="sendmail" value="on" />'."\n".
                 '<table>');                  '<table>');
     unless (($broadcast eq 'group') || ($broadcast eq 'upload')) {      unless (($broadcast eq 'group') || ($broadcast eq 'upload')) {
         my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');   if ($replying) {
         my $selectlink=&Apache::loncommon::selectstudent_link      $r->print('<tr><td colspan="2">'.&mt('Replying to').' '.
         &Apache::loncommon::aboutmewrapper(
    &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('.
         $content{'sendername'}.'@'.
         $content{'senderdomain'}.')'.
         '<input type="hidden" name="recuname" value="'.$content{'sendername'}.'" />'.
         '<input type="hidden" name="recdomain" value="'.$content{'senderdomain'}.'" />'.
         '</td></tr>');
    } else {
       my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');
       my $selectlink=&Apache::loncommon::selectstudent_link
     ('compemail','recuname','recdomain');      ('compemail','recuname','recdomain');
        $r->print(<<"ENDREC");      $r->print(<<"ENDREC");
 <table>  
 <tr><td>$lt{'us'}:</td><td><input type="text" size="12" name="recuname" value="$ENV{'form.recname'}"></td><td rowspan="2">$selectlink</td></tr>  <tr><td>$lt{'us'}:</td><td><input type="text" size="12" name="recuname" value="$ENV{'form.recname'}"></td><td rowspan="2">$selectlink</td></tr>
 <tr><td>$lt{'do'}:</td>  <tr><td>$lt{'do'}:</td>
 <td>$domform</td></tr>  <td>$domform</td></tr>
 ENDREC  ENDREC
           }
     }      }
     my $latexHelp = Apache::loncommon::helpLatexCheatsheet();      my $latexHelp = Apache::loncommon::helpLatexCheatsheet();
     if ($broadcast ne 'upload') {      if ($broadcast ne 'upload') {
        $r->print(<<"ENDCOMP");         $r->print(<<"ENDCOMP");
 <tr><td>$lt{'ad'}<br /><tt>username\@domain,username\@domain, ...  <tr><td>$lt{'ad'}<br /><tt>username\@domain,username\@domain, ...
 </tt></td><td>  </tt></td><td>
 <input type="text" size="50" name="additionalrec"></td></tr>  <input type="text" size="50" name="additionalrec" /></td></tr>
 <tr><td>$lt{'sb'}:</td><td><input type="text" size="50" name="subject" value="$dissub">  <tr><td>$lt{'sb'}:</td><td><input type="text" size="50" name="subject" value="$dissub" />
 </td></tr></table>  </td></tr></table>
 $latexHelp  $latexHelp
 <textarea name="message" cols="80" rows="10" wrap="hard">$dismsg  <textarea name="message" cols="80" rows="15" wrap="hard">$dismsg
 </textarea></p><br />  </textarea></p><br />
 $dispcrit  $dispcrit
   $disbase
 <input type="submit" name="send" value="$func $lt{'ma'}" />  <input type="submit" name="send" value="$func $lt{'ma'}" />
 <input type="submit" name="cancel" value="$lt{'ca'}" />  <input type="submit" name="cancel" value="$lt{'ca'}" /><hr />
   $citation
 ENDCOMP  ENDCOMP
     } else { # $broadcast is 'upload'      } else { # $broadcast is 'upload'
  $r->print(<<ENDUPLOAD);   $r->print(<<ENDUPLOAD);
 <input type=hidden name=sendmode value=upload>  <input type="hidden" name="sendmode" value="upload" />
 <input type="hidden" name="send" value="on" />  <input type="hidden" name="send" value="on" />
 <h3>Generate messages from a file</h3>  <h3>Generate messages from a file</h3>
 <p>  <p>
 Subject: <input type=text size=50 name=subject>  Subject: <input type="text" size="50" name="subject" />
 </p>  </p>
 <p>General message text<br />  <p>General message text<br />
 <textarea name=message cols=60 rows=10 wrap=hard>$dismsg  <textarea name="message" cols="60" rows="10" wrap="hard">$dismsg
 </textarea></p>  </textarea></p>
 <p>  <p>
 The file format for the uploaded portion of the message is:  The file format for the uploaded portion of the message is:
Line 888  username3\@domain1: text Line 1168  username3\@domain1: text
 The messages will be assembled from all lines with the respective   The messages will be assembled from all lines with the respective 
 <tt>username\@domain</tt>, and appended to the general message text.</p>  <tt>username\@domain</tt>, and appended to the general message text.</p>
 <p>  <p>
 <input type=file name=upfile size=20><p>  <input type="file" name="upfile" size="40" /></p><p>
 $dispcrit  $dispcrit
 <input type=submit value="Upload and send">  <input type="submit" value="Upload and Send" /></p>
 ENDUPLOAD  ENDUPLOAD
     }      }
     if ($broadcast eq 'group') {      if ($broadcast eq 'group') {
Line 901  ENDUPLOAD Line 1181  ENDUPLOAD
   
 # ---------------------------------------------------- Display all face to face  # ---------------------------------------------------- Display all face to face
   
   sub retrieve_instructor_comments {
       my ($user,$domain)=@_;
       my $target=$ENV{'form.grade_target'};
       if (! $ENV{'request.course.id'}) { return; }
       if (! &Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
    return;
       }
       my %records=&Apache::lonnet::dump('nohist_email',
    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'},
                            '%255b'.$user.'%253a'.$domain.'%255d');
       my $result='';
       foreach (sort(keys(%records))) {
           my %content=&unpackagemsg($records{$_});
           next if ($content{'senderdomain'} eq '');
           next if ($content{'subject'} !~ /^Record/);
           # $content{'message'}=~s/\n/\<br\>/g;
           $result.='Recorded by '.
               $content{'sendername'}.'@'.$content{'senderdomain'}."\n";
           $result.=
               &Apache::lontexconvert::msgtexconverted($content{'message'})."\n";
        }
       return $result;
   }
   
 sub disfacetoface {  sub disfacetoface {
     my ($r,$user,$domain)=@_;      my ($r,$user,$domain)=@_;
       my $target=$ENV{'form.grade_target'};
     unless ($ENV{'request.course.id'}) { return; }      unless ($ENV{'request.course.id'}) { return; }
     unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
  return;   return;
Line 918  sub disfacetoface { Line 1224  sub disfacetoface {
         $content{'message'}=~s/\n/\<br\>/g;          $content{'message'}=~s/\n/\<br\>/g;
         if ($content{'subject'}=~/^Record/) {          if ($content{'subject'}=~/^Record/) {
     $result.='<h3>'.&mt('Record').'</h3>';      $result.='<h3>'.&mt('Record').'</h3>';
           } elsif ($content{'subject'}=~/^Broadcast/) {
               $result .='<h3>'.&mt('Broadcast Message').'</h3>';
         } else {          } else {
             $result.='<h3>'.&mt('Sent Message').'</h3>';              $result.='<h3>'.&mt('Critical Message').'</h3>';
             %content=&unpackagemsg($content{'message'});              %content=&unpackagemsg($content{'message'});
             $content{'message'}=              $content{'message'}=
                 '<b>Subject: '.$content{'subject'}.'</b><br />'.                  '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'.
  $content{'message'};   $content{'message'};
         }          }
         $result.=&mt('By').': <b>'.          $result.=&mt('By').': <b>'.
Line 930  sub disfacetoface { Line 1238  sub disfacetoface {
  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.   &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
 $content{'sendername'}.'@'.  $content{'sendername'}.'@'.
             $content{'senderdomain'}.') '.$content{'time'}.              $content{'senderdomain'}.') '.$content{'time'}.
             '<br><blockquote>'.              '<br /><blockquote>'.
               &Apache::lontexconvert::msgtexconverted($content{'message'}).                &Apache::lontexconvert::msgtexconverted($content{'message'}).
       '</blockquote>';        '</blockquote>';
      }       }
     # Check to see if there were any messages.      # Check to see if there were any messages.
     if ($result eq '') {      if ($result eq '') {
         $r->print("<p><b>No notes, face-to-face discussion records, or critical messages in this course.</b></p>");   if ($target ne 'tex') { 
       $r->print("<p><b>".&mt("No notes, face-to-face discussion records, critical messages, or broadcast messages in this course.")."</b></p>");
    } else {
       $r->print('\textbf{'.&mt("No notes, face-to-face discussion records, critical messages or broadcast messages in this course.").'}\\\\');
    }
     } else {      } else {
        $r->print($result);         $r->print($result);
     }      }
Line 949  sub facetoface { Line 1261  sub facetoface {
     unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
  return;   return;
     }      }
       &printheader($r,
    '/adm/email?recordftf=query',
    "User Notes, Face-to-Face, Critical Messages, Broadcast Messages");
 # from query string  # from query string
   
     if ($ENV{'form.recname'}) { $ENV{'form.recuname'}=$ENV{'form.recname'}; }      if ($ENV{'form.recname'}) { $ENV{'form.recuname'}=$ENV{'form.recname'}; }
     if ($ENV{'form.recdom'}) { $ENV{'form.recdomain'}=$ENV{'form.recdom'}; }      if ($ENV{'form.recdom'}) { $ENV{'form.recdomain'}=$ENV{'form.recdom'}; }
   
Line 960  sub facetoface { Line 1276  sub facetoface {
     my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');      my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');
     my $stdbrws = &Apache::loncommon::selectstudent_link      my $stdbrws = &Apache::loncommon::selectstudent_link
  ('stdselect','recuname','recdomain');   ('stdselect','recuname','recdomain');
       my %lt=&Apache::lonlocal::texthash('user' => 'Username',
          'dom' => 'Domain',
          'head' => 'User Notes, Records of Face-To-Face Discussions, Critical Messages, and Broadcast Messages in Course',
          'subm' => 'Retrieve discussion and message records',
          'newr' => 'New Record (record is visible to course faculty and staff)',
          'post' => 'Post this Record');
     $r->print(<<"ENDTREC");      $r->print(<<"ENDTREC");
 <h3>User Notes, Records of Face-To-Face Discussions, and Critical Messages in Course</h3>  <h3>$lt{'head'}</h3>
 <form method="post" action="/adm/email" name="stdselect">  <form method="post" action="/adm/email" name="stdselect">
 <input type="hidden" name="recordftf" value="retrieve" />  <input type="hidden" name="recordftf" value="retrieve" />
 <table>  <table>
 <tr><td>Username:</td><td><input type=text size=12 name=recuname value="$ENV{'form.recuname'}"></td>  <tr><td>$lt{'user'}:</td><td><input type="text" size="12" name="recuname" value="$ENV{'form.recuname'}" /></td>
 <td rowspan="2">  <td rowspan="2">
 $stdbrws  $stdbrws
 <input type="submit" value="Retrieve discussion and message records"></td>  <input type="submit" value="$lt{'subm'}" /></td>
 </tr>  </tr>
 <tr><td>Domain:</td>  <tr><td>$lt{'dom'}:</td>
 <td>$domform</td></tr>  <td>$domform</td></tr>
 </table>  </table>
 </form>  </form>
Line 982  ENDTREC Line 1304  ENDTREC
            &user_normal_msg_raw(             &user_normal_msg_raw(
             $ENV{'course.'.$ENV{'request.course.id'}.'.num'},              $ENV{'course.'.$ENV{'request.course.id'}.'.num'},
             $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},              $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
             'Record ['.$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}.']',              &mt('Record').
        ' ['.$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}.']',
     $ENV{'form.newrecord'});      $ENV{'form.newrecord'});
         }          }
         $r->print('<h3>'.&Apache::loncommon::plainname($ENV{'form.recuname'},          $r->print('<h3>'.&Apache::loncommon::plainname($ENV{'form.recuname'},
Line 994  ENDTREC Line 1317  ENDTREC
 <input name="recuname" value="$ENV{'form.recuname'}" type="hidden" />  <input name="recuname" value="$ENV{'form.recuname'}" type="hidden" />
 ENDRHEAD  ENDRHEAD
         $r->print(<<ENDBFORM);          $r->print(<<ENDBFORM);
 <hr />New Record (record is visible to course faculty and staff)<br />  <hr />$lt{'newr'}<br />
 <textarea name="newrecord" cols="80" rows="10" wrap="hard"></textarea>  <textarea name="newrecord" cols="80" rows="10" wrap="hard"></textarea>
 <br />  <br />
 <input type="hidden" name="recordftf" value="post" />  <input type="hidden" name="recordftf" value="post" />
 <input type="submit" value="Post this record" />  <input type="submit" value="$lt{'post'}" />
 </form>  </form>
 ENDBFORM  ENDBFORM
     }      }
 }  }
   
   # ----------------------------------------------------------- Blocking during exams
   
   sub examblock {
       my ($r,$action) = @_;
       unless ($ENV{'request.course.id'}) { return;}
       unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) { $r->print('Not allowed'); }
       my %lt=&Apache::lonlocal::texthash(
               'comb' => 'Communication Blocking',
               'cbds' => 'Communication blocking during scheduled exams',
               '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.',
                'mecb' => 'Modify existing communication blocking periods',
                'ncbc' => 'No communication blocks currently stored'
       );
   
       my %ltext = &Apache::lonlocal::texthash(
               'dura' => 'Duration',
               'setb' => 'Set by',
               'even' => 'Event',
               'actn' => 'Action',
               'star' => 'Start',
               'endd' => 'End'
       );
   
       &printheader($r,'/adm/email?block=display',$lt{'comb'});
       $r->print('<h3>'.$lt{'cbds'}.'</h3>');
   
       if ($action eq 'store') {
           &blockstore($r);
       }
   
       $r->print($lt{'desc'}.'<br /><br />
                  <form name="blockform" method="post" action="/adm/email?block=store">
                ');
   
       $r->print('<h4>'.$lt{'mecb'}.'</h4>');
       my %records = ();
       my $blockcount = 0;
       my $parmcount = 0;
       &get_blockdates(\%records,\$blockcount);
       if ($blockcount > 0) {
           $parmcount = &display_blocker_status($r,\%records,\%ltext);
       } else {
           $r->print($lt{'ncbc'}.'<br /><br />');
       }
       &display_addblocker_table($r,$parmcount,\%ltext);
       $r->print(<<"END");
   <br />
   <input type="hidden" name="blocktotal" value="$blockcount" />
   <input type ="submit" value="Save Changes" />
   </form>
   </body>
   </html>
   END
       return;
   }
   
   sub blockstore {
       my $r = shift;
       my %lt=&Apache::lonlocal::texthash(
               'tfcm' => 'The following changes were made',
               'cbps' => 'communication blocking period(s)',
               'werm' => 'was/were removed',
               'wemo' => 'was/were modified',
               'wead' => 'was/were added',
               'ncwm' => 'No changes were made.' 
       );
       my %adds = ();
       my %removals = ();
       my %cancels = ();
       my $modtotal = 0;
       my $canceltotal = 0;
       my $addtotal = 0;
       my %blocking = ();
       $r->print('<h3>'.$lt{'head'}.'</h3>');
       foreach (keys %ENV) {
           if ($_ =~ m/^form\.modify_(\w+)$/) {
               $adds{$1} = $1;
               $removals{$1} = $1;
               $modtotal ++;
           } elsif ($_ =~ m/^form\.cancel_(\d+)$/) {
               $cancels{$1} = $1;
               unless ( defined($removals{$1}) ) {
                   $removals{$1} = $1;
                   $canceltotal ++;
               }
           } elsif ($_ =~ m/^form\.add_(\d+)$/) {
               $adds{$1} = $1;
               $addtotal ++;
           }
       }
   
       foreach (keys %removals) {
           my $hashkey = $ENV{'form.key_'.$_};
           &Apache::lonnet::del('comm_block',["$hashkey"],
                            $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                            $ENV{'course.'.$ENV{'request.course.id'}.'.num'}
                            );
       }
       foreach (keys %adds) {
           unless ( defined($cancels{$_}) ) {
               my ($newstart,$newend) = &get_dates_from_form($_);
               my $newkey = $newstart.'____'.$newend;
               $blocking{$newkey} = $ENV{'user.name'}.'@'.$ENV{'user.domain'}.':'.$ENV{'form.title_'.$_};
           }
       }
       if ($addtotal + $modtotal > 0) {
           &Apache::lonnet::put('comm_block',\%blocking,
                        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                        $ENV{'course.'.$ENV{'request.course.id'}.'.num'}
                        );
       }
       my $chgestotal = $canceltotal + $modtotal + $addtotal;
       if ($chgestotal > 0) {
           $r->print($lt{'tfcm'}.'<ul>');
           if ($canceltotal > 0) {
               $r->print('<li>'.$canceltotal.' '.$lt{'cbps'},' '.$lt{'werm'}.'</li>');
           }
           if ($modtotal > 0) {
               $r->print('<li>'.$modtotal.' '.$lt{'cbps'},' '.$lt{'wemo'}.'</li>');
           }
           if ($addtotal > 0) {
               $r->print('<li>'.$addtotal.' '.$lt{'cbps'},' '.$lt{'wead'}.'</li>');
           }
           $r->print('</ul>');
       } else {
           $r->print($lt{'ncwm'});
       }
       $r->print('<br />');
       return;
   }
   
   sub get_dates_from_form {
       my $item = shift;
       my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item);
       my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item);
       return ($startdate,$enddate);
   }
   
   sub get_blockdates {
       my ($records,$blockcount) = @_;
       $$blockcount = 0;
       %{$records} = &Apache::lonnet::dump('comm_block',
                            $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                            $ENV{'course.'.$ENV{'request.course.id'}.'.num'}
                            );
       $$blockcount = keys %{$records};
                                                                                                                
       foreach (keys %{$records}) {
           if ($_ eq 'error: 2 tie(GDBM) Failed while attempting dump') {
               $$blockcount = 0;
               last;
           }
       }
   }
   
   sub display_blocker_status {
       my ($r,$records,$ltext) = @_;
       my $parmcount = 0;
       my @bgcols = ("#eeeeee","#dddddd");
       my $function = &Apache::loncommon::get_users_function();
       my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $ENV{'user.domain'});
       my %lt = &Apache::lonlocal::texthash(
           'modi' => 'Modify',
           'canc' => 'Cancel',
       );
       $r->print(<<"END");
   <table border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td width="100%" bgcolor="#000000">
      <table width="100%" border="0" cellpadding="1" cellspacing="0">
       <tr>
        <td width="100%" bgcolor="#000000">
         <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
          <tr bgcolor="$color">
           <td><b>$$ltext{'dura'}</b></td>
           <td><b>$$ltext{'setb'}</b></td>
           <td><b>$$ltext{'even'}</b></td>
           <td><b>$$ltext{'actn'}?</b></td>
          </tr>
   END
       foreach (sort keys %{$records}) {
           my $iter = $parmcount%2;
           my $onchange = 'onFocus="javascript:window.document.forms['.
                          "'blockform'].elements['modify_".$parmcount."'].".
                          'checked=true;"';
           my ($start,$end) = split/____/,$_;
           my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
           my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
           my ($setter,$title) = split/:/,$$records{$_};
           my ($setuname,$setudom) = split/@/,$setter;
           my $settername = &Apache::loncommon::plainname($setuname,$setudom);
           $r->print(<<"END");
          <tr bgcolor="$bgcols[$iter]">
           <td>$$ltext{'star'}:&nbsp;$startform<br/>$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
           <td>$settername</td>
           <td><input type="text" name="title_$parmcount" size="15" value="$title"/><input type="hidden" name="key_$parmcount" value="$_"></td>
           <td>$lt{'modi'}?&nbsp;<input type="checkbox" name="modify_$parmcount"/><br />$lt{'canc'}?&nbsp;&nbsp;<input type="checkbox" name="cancel_$parmcount"/>
          </tr>
   END
           $parmcount ++;
       }
       $r->print(<<"END");
         </table>
        </td>
       </tr>
      </table>
     </td>
    </tr>
   </table>
   <br />
   <br />
   END
       return $parmcount;
   }
   
   sub display_addblocker_table {
       my ($r,$parmcount,$ltext) = @_;
       my $start = time;
       my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration.
       my $onchange = 'onFocus="javascript:window.document.forms['.
                      "'blockform'].elements['add_".$parmcount."'].".
                      'checked=true;"';
       my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
       my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
       my $function = &Apache::loncommon::get_users_function();
       my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $ENV{'user.domain'});
       my %lt = &Apache::lonlocal::texthash(
           'addb' => 'Add block',
           'exam' => 'e.g., Exam 1',
           'addn' => 'Add new communication blocking periods'
       );
       $r->print(<<"END");
   <h4>$lt{'addn'}</h4> 
   <table border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td width="100%" bgcolor="#000000">
      <table width="100%" border="0" cellpadding="1" cellspacing="0">
       <tr>
        <td width="100%" bgcolor="#000000">
         <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
          <tr bgcolor="#CCCCFF">
           <td><b>$$ltext{'dura'}</b></td>
           <td><b>$$ltext{'even'} $lt{'exam'}</b></td>
           <td><b>$$ltext{'actn'}?</b></td>
          </tr>
          <tr bgcolor="#eeeeee">
           <td>$$ltext{'star'}:&nbsp;$startform<br />$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
           <td><input type="text" name="title_$parmcount" size="15" value=""/></td>
           <td>$lt{'addb'}?&nbsp;<input type="checkbox" name="add_$parmcount" value="1"/></td>
          </tr>
         </table>
        </td>
       </tr>
      </table>
     </td>
    </tr>
   </table>
   END
       return;
   }
   
   sub blockcheck {
       my ($setters,$startblock,$endblock) = @_;
       # Retrieve active student roles and active course coordinator/instructor roles
       my @livecses = ();
       my @staffcses = ();
       $$startblock = 0;
       $$endblock = 0;
       foreach (keys %ENV) {
           if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) {
               my $role = $1;
               my $cse = $2;
               $cse =~ s|/|_|;
               if ($ENV{$_} =~ m/^(\d*)\.(\d*)$/) {
                   unless (($2 > 0 && $2 < time) || ($1 > time)) {
                       if ($role eq 'st') {
                           push @livecses, $cse;
                       } else {
                           unless (grep/^$cse$/,@staffcses) {
                               push @staffcses, $cse;
                           }
                       }
                   }
               }
           } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) { 
               my $rolepriv = $ENV{'user.role..rolesdef_'.$3};
           }
       }
       # Retrieve blocking times and identity of blocker for active courses for students.
       if (@livecses > 0) {
           foreach my $cse (@livecses) {
               my ($cdom,$crs) = split/_/,$cse;
               if ( (grep/^$cse$/,@staffcses) && ($ENV{'request.role'} !~ m-^st\./$cdom/$crs$-) ) {
                   next;
               } else {
                   %{$$setters{$cse}} = ();
                   @{$$setters{$cse}{'staff'}} = ();
                   @{$$setters{$cse}{'times'}} = ();
                   my %records = &Apache::lonnet::dump('comm_block',$cdom,$crs);
                   foreach (keys %records) {
                       if ($_ =~ m/^(\d+)____(\d+)$/) {
                           if ($1 <= time && $2 >= time) {
                               my ($staff,$title) = split/:/,$records{$_};
                               push @{$$setters{$cse}{'staff'}}, $staff;
                               push @{$$setters{$cse}{'times'}}, $_;
                               if ( ($$startblock == 0) || ($$startblock > $1) ) {
                                   $$startblock = $1;
                               }
                               if ( ($$endblock == 0) || ($$endblock < $2) ) {
                                   $$endblock = $2;
                               }
                           }
                       }
                   }
               }
           }
       }
   }
   
   sub build_block_table {
       my ($r,$startblock,$endblock,$setters) = @_;
       my $function = &Apache::loncommon::get_users_function();
       my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $ENV{'user.domain'});
       my %lt = &Apache::lonlocal::texthash(
           'cacb' => 'Currently active communication blocks',
           'cour' => 'Course',
           'dura' => 'Duration',
           'blse' => 'Block set by'
       ); 
       $r->print(<<"END");
   <br /<br />$lt{'cacb'}:<br /><br />
   <table border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td width="100%" bgcolor="#000000">
      <table width="100%" border="0" cellpadding="1" cellspacing="0">
       <tr>
        <td width="100%" bgcolor="#000000">
         <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
          <tr bgcolor="$color">
           <td><b>$lt{'cour'}</b></td>
           <td><b>$lt{'dura'}</b></td>
           <td><b>$lt{'blse'}</b></td>
          </tr>
   END
       foreach (keys %{$setters}) {
           my %courseinfo=&Apache::lonnet::coursedescription($_);
           for (my $i=0; $i<@{$$setters{$_}{staff}}; $i++) {
               my ($uname,$udom) = split/\@/,$$setters{$_}{staff}[$i];
               my $fullname = &Apache::loncommon::plainname($uname,$udom);
               my ($openblock,$closeblock) = split/____/,$$setters{$_}{times}[$i];
               $openblock = &Apache::lonlocal::locallocaltime($openblock);
               $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
               $r->print('<tr><td>'.$courseinfo{'description'}.'</td>'.
                         '<td>'.$openblock.' to '.$closeblock.'</td>'.
                         '<td>'.$fullname.' ('.$uname.'@'.$udom.
                         ')</td></tr>');
           }
       }
       $r->print('</table></td></tr></table></td></tr></table>');
   }
   
   # ----------------------------------------------------------- Display a message
   
   sub displaymessage {
       my ($r,$msgid,$folder)=@_;
       my $suffix=&foldersuffix($folder);
       my %blocked = ();
       my %setters = ();
       my $startblock = 0;
       my $endblock = 0;
       my $numblocked = 0;
   # info to generate "next" and "previous" buttons and check if message is blocked
       &blockcheck(\%setters,\$startblock,\$endblock);
       my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
       if ( $blocked{$msgid} eq 'ON' ) {
           &printheader($r,'/adm/email',&mt('Display a Message'));
           $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.'));
           &build_block_table($r,$startblock,$endblock,\%setters);
           return;
       }
       &statuschange($msgid,'read',$folder);
       my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
       my %content=&unpackagemsg($message{$msgid});
   
       my $counter=0;
       $r->print('<pre>');
       my $escmsgid=&Apache::lonnet::escape($msgid);
       foreach (@messages) {
    if ($_->[5] eq $escmsgid){
       last;
    }
    $counter++;
       }
       $r->print('</pre>');
       my $number_of_messages = scalar(@messages); #subtract 1 for last index
   # start output
       &printheader($r,'/adm/email?display='.&Apache::lonnet::escape($msgid),'Display a Message','',$content{'baseurl'});
       my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'});
   # Functions
       $r->print('<table border="2" width="100%"><tr bgcolor="#FFFFAA"><td>'.&mt('Functions').':</td>'.
         '<td><a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).$sqs.
         '"><b>'.&mt('Reply').'</b></a></td>'.
         '<td><a href="/adm/email?forward='.&Apache::lonnet::escape($msgid).$sqs.
         '"><b>'.&mt('Forward').'</b></a></td>'.
         '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs.
         '"><b>'.&mt('Mark Unread').'</b></a></td>'.
         '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs.
         '"><b>Delete</b></a></td>'.
         '<td><a href="/adm/email?'.$sqs.
         '"><b>'.&mt('Back to Folder Display').'</b></a></td>');
       if ($counter > 0){
    $r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.
     '"><b>'.&mt('Previous').'</b></a></td>');
       }
       if ($counter < $number_of_messages - 1){
    $r->print('<td><a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.
     '"><b>'.&mt('Next').'</b></a></td>');
       }
       $r->print('</tr></table>');
       $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}.
         ($folder ne 'sent'?'<br /><b>'.&mt('From').':</b> '.
         &Apache::loncommon::aboutmewrapper(
    &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
    $content{'sendername'},$content{'senderdomain'}).' ('.
         $content{'sendername'}.' at '.
         $content{'senderdomain'}.') ':'<br /><b>'.&mt('To').':</b> '.
         &Apache::loncommon::aboutmewrapper(
    &Apache::loncommon::plainname($content{'recuser'},$content{'recdomain'}),
    $content{'recuser'},$content{'recdomain'}).' ('.
         $content{'recuser'}.' at '.
         $content{'recdomain'}.') ').
         ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}.
          ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').
         '<br /><b>'.&mt('Time').':</b> '.$content{'time'}.
         ($content{'baseurl'}?'<br /><b>'.&mt('Refers to').':</b> <a href="'.$content{'baseurl'}.'">'.
          $content{'baseurl'}.' ('.&Apache::lonnet::gettitle($content{'baseurl'}).')</a>':'').
         '<p><pre>'.
         &Apache::lontexconvert::msgtexconverted($content{'message'},1).
         '</pre><hr />'.&displayresource(%content).'</p>');
       return;   
   }
   
   # =========================================================== Show the citation
   
   sub displayresource {
       my %content=@_;
   #
   # If the recipient is in the same course that the message was sent from and
   # has sufficient privileges, show "all details," else show citation
   #
       if (($ENV{'request.course.id'} eq $content{'courseid'})
        && (&Apache::lonnet::allowed('vgr',$content{'courseid'}))) {
    my $symb=&Apache::lonnet::symbread($content{'baseurl'});
   # Could not get a symb, give up
    unless ($symb) { return $content{'citation'}; }
   # Have a symb, can render
    return '<h2>'.&mt('Current attempts of student (if applicable)').'</h2>'.
       &Apache::loncommon::get_previous_attempt($symb,
        $content{'sendername'},
        $content{'senderdomain'},
        $content{'courseid'}).
       '<hr /><h2>'.&mt('Current screen output (if applicable)').'</h2>'.
       &Apache::loncommon::get_student_view($symb,
    $content{'sendername'},
    $content{'senderdomain'},
    $content{'courseid'}).
       '<h2>'.&mt('Correct Answer(s) (if applicable)').'</h2>'.
       &Apache::loncommon::get_student_answers($symb,
       $content{'sendername'},
       $content{'senderdomain'},
       $content{'courseid'});
       } else {
    return $content{'citation'};
       }
   }
   
   # ================================================================== The Header
   
   sub header {
       my ($r,$title,$baseurl)=@_;
       $r->print('<html><head><title>Communication and Messages</title>');
       if ($baseurl) {
    $r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$baseurl\" />");
       }
       $r->print(&Apache::loncommon::studentbrowser_javascript().'</head>'.
         &Apache::loncommon::bodytag('Communication and Messages'));
           $r->print(&Apache::lonhtmlcommon::breadcrumbs
                     (undef,($title?$title:'Communication and Messages')));
   
   }
   
   # ---------------------------------------------------------------- Print header
   
   sub printheader {
       my ($r,$url,$desc,$title,$baseurl)=@_;
       &Apache::lonhtmlcommon::add_breadcrumb
    ({href=>$url,
     text=>$desc});
       &header($r,$title,$baseurl);
   }
   
   # ------------------------------------------------------------ Store the comment
   
   sub storecomment {
       my ($r)=@_;
       my $msgtxt=&Apache::lonfeedback::clear_out_html($ENV{'form.message'});
       my $cleanmsgtxt='';
       foreach (split(/[\n\r]/,$msgtxt)) {
    unless ($_=~/^\s*(\>|\&gt\;)/) {
       $cleanmsgtxt.=$_."\n";
    }
       }
       my $key=&Apache::lonnet::escape($ENV{'form.baseurl'}).'___'.time;
       &Apache::lonnet::put('nohist_stored_comments',{ $key => $cleanmsgtxt });
   }
   
   sub storedcommentlisting {
       my ($r)=@_;
       my %msgs=&Apache::lonnet::dump('nohist_stored_comments',undef,undef,
          '^'.&Apache::lonnet::escape(&Apache::lonnet::escape($ENV{'form.showcommentbaseurl'})));
       $r->print('<html><body>');
       if ((keys %msgs)[0]=~/^error\:/) {
    $r->print(&mt('No stored comments yet.'));
       } else {
    my $found=0;
    foreach (sort keys %msgs) {
       $r->print("\n".$msgs{$_}."<hr />");
       $found=1;
    }
    unless ($found) {
       $r->print(&mt('No stored comments yet for this resource.'));
    }
       }
   }
   
   # ---------------------------------------------------------------- Send an email
   
   sub sendoffmail {
       my ($r,$folder)=@_;
       my $suffix=&foldersuffix($folder);
       my $sendstatus='';
       if ($ENV{'form.send'}) {
    &printheader($r,'','Messages being sent.');
    $r->rflush();
    my %content=();
    undef %content;
    if ($ENV{'form.forwid'}) {
       my $msgid=$ENV{'form.forwid'};
       my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
       %content=&unpackagemsg($message{$msgid},1);
       &statuschange($msgid,'forwarded',$folder);
       $ENV{'form.message'}.="\n\n-- Forwarded message --\n\n".
    $content{'message'};
    }
    if ($ENV{'form.replyid'}) {
       my $msgid=$ENV{'form.replyid'};
       my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
       %content=&unpackagemsg($message{$msgid},1);
       &statuschange($msgid,'replied',$folder);
    }
    my %toaddr=();
    undef %toaddr;
    if ($ENV{'form.sendmode'} eq 'group') {
       foreach (keys %ENV) {
    if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) {
       $toaddr{$1}='';
    }
       }
    } elsif ($ENV{'form.sendmode'} eq 'upload') {
       foreach (split(/[\n\r\f]+/,$ENV{'form.upfile'})) {
    my ($rec,$txt)=split(/\s*\:\s*/,$_);
    if ($txt) {
       $rec=~s/\@/\:/;
       $toaddr{$rec}.=$txt."\n";
    }
       }
    } else {
       $toaddr{$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}}='';
    }
    if ($ENV{'form.additionalrec'}) {
       foreach (split(/\,/,$ENV{'form.additionalrec'})) {
    my ($auname,$audom)=split(/\@/,$_);
    $toaddr{$auname.':'.$audom}='';
       }
    }
   
    foreach (keys %toaddr) {
       my ($recuname,$recdomain)=split(/\:/,$_);
               my $msgtxt;
               if ((($ENV{'form.critmsg'}) || ($ENV{'form.sendbck'})) &&
                   (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {
                   $msgtxt=&Apache::lonfeedback::clear_out_html($ENV{'form.message'},1);
               } else {  
           $msgtxt=&Apache::lonfeedback::clear_out_html($ENV{'form.message'});
               }
       if ($toaddr{$_}) { $msgtxt.='<hr />'.$toaddr{$_}; }
       my $thismsg;    
       if ((($ENV{'form.critmsg'}) || ($ENV{'form.sendbck'})) && 
    (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {
    $r->print(&mt('Sending critical message').' '.$recuname.'@'.$recdomain.': ');
    $thismsg=&user_crit_msg($recuname,$recdomain,
    &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),
    $msgtxt,
    $ENV{'form.sendbck'});
       } else {
    $r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': ');
    $thismsg=&user_normal_msg($recuname,$recdomain,
     &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),
     $msgtxt,
     $content{'citation'});
    if (($ENV{'request.course.id'}) && ($ENV{'form.sendmode'} eq 'group')) {
       &user_normal_msg_raw(
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'},
    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
    'Broadcast ['.$recuname.':'.$recdomain.']',
    $msgtxt);
    }
       }
       $r->print($thismsg.'<br />');
       $sendstatus.=' '.$thismsg;
    }
       } else {
    &printheader($r,'','No messages sent.'); 
       }
       if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) {
    $r->print('<br /><font color="green">'.&mt('Completed.').'</font>');
    if ($ENV{'form.displayedcrit'}) {
       &discrit($r);
    } else {
       &Apache::loncommunicate::menu($r);
    }
       } else {
    $r->print(
     '<h2><font color="red">'.&mt('Could not deliver message').'</font></h2>'.
     &mt('Please use the browser "Back" button and correct the recipient addresses')
     );
       }
   }
   
 # ===================================================================== Handler  # ===================================================================== Handler
   
 sub handler {  sub handler {
Line 1020  sub handler { Line 1985  sub handler {
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
         ['display','replyto','forward','markread','markdel','markunread',          ['display','replyto','forward','markread','markdel','markunread',
          'sendreply','compose','sendmail','critical','recname','recdom',           'sendreply','compose','sendmail','critical','recname','recdom',
          'recordftf','sortedby']);           'recordftf','sortedby','block','folder','startdis','interdis',
    'showcommentbaseurl']);
     $sqs='&sortedby='.$ENV{'form.sortedby'};      $sqs='&sortedby='.$ENV{'form.sortedby'};
   
 # ------------------------------------------------------ They checked for email  # ------------------------------------------------------ They checked for email
     &Apache::lonnet::put('email_status',{'recnewemail'=>0});      unless ($ENV{'form.block'}) {
 # --------------------------------------------------------------- Render Output          &Apache::lonnet::put('email_status',{'recnewemail'=>0});
     if (!$ENV{'form.display'}) {      }
  $r->print('<html><head><title>EMail and Messaging</title>'.  
   &Apache::loncommon::studentbrowser_javascript().'</head>'.  # ----------------------------------------------------------------- Breadcrumbs
   &Apache::loncommon::bodytag('EMail and Messages').  
   &Apache::loncommon::help_open_faq(12).      &Apache::lonhtmlcommon::clear_breadcrumbs();
   &Apache::loncommon::help_open_bug('Communication Tools'));      &Apache::lonhtmlcommon::add_breadcrumb
           ({href=>"/adm/communicate",
             text=>"Communication/Messages",
             faq=>12,bug=>'Communication Tools',});
   
   # ------------------------------------------------------------------ Get Folder
   
       my $folder=$ENV{'form.folder'};
       unless ($folder) { 
    $folder=''; 
       } else {
    $sqs.='&folder='.&Apache::lonnet::escape($folder);
     }      }
   
   # --------------------------------------------------------------------- Display
   
       $startdis=$ENV{'form.startdis'};
       $startdis--;
       unless ($startdis) { $startdis=0; }
   
       $interdis=$ENV{'form.interdis'};
       unless ($interdis) { $interdis=20; }
       $sqs.='&interdis='.$interdis;
   
       if ($ENV{'form.firstview'}) {
    $startdis=0;
       }
       if ($ENV{'form.lastview'}) {
    $startdis=-1;
       }
       if ($ENV{'form.prevview'}) {
    $startdis--;
       }
       if ($ENV{'form.nextview'}) {
    $startdis++;
       }
       my $postedstartdis=$startdis+1;
       $sqs.='&startdis='.$postedstartdis;
   
   # --------------------------------------------------------------- Render Output
   
     if ($ENV{'form.display'}) {      if ($ENV{'form.display'}) {
  my $msgid=$ENV{'form.display'};   &displaymessage($r,$ENV{'form.display'},$folder);
  &statuschange($msgid,'read');  
  my %message=&Apache::lonnet::get('nohist_email',[$msgid]);  
  my %content=&unpackagemsg($message{$msgid});  
 # info to generate "next" and "previous" buttons  
  my @messages=&sortedmessages();  
  my $counter=0;  
  $r->print('<pre>');  
  my $escmsgid=&Apache::lonnet::escape($msgid);  
  foreach (@messages) {  
     if ($_->[5] eq $escmsgid){  
  last;  
     }  
     $counter++;  
  }  
  $r->print('</pre>');  
  my $number_of_messages = scalar(@messages); #subtract 1 for last index  
 # start output  
  $r->print('<html><head><title>EMail and Messaging</title>');  
  if (defined($content{'baseurl'})) {  
     $r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$content{'baseurl'}\" />");  
  }  
  $r->print(&Apache::loncommon::studentbrowser_javascript().  
   '</head>'.  
   &Apache::loncommon::bodytag('EMail and Messages').  
   &Apache::loncommon::help_open_faq(12).  
   &Apache::loncommon::help_open_bug('Communication Tools'));  
  my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'});  
   
  $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}.  
   '<br /><b>'.&mt('From').':</b> '.  
   &Apache::loncommon::aboutmewrapper(  
      &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),  
      $content{'sendername'},$content{'senderdomain'}).' ('.  
   $content{'sendername'}.' at '.  
   $content{'senderdomain'}.') '.  
   ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}.  
    ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').  
   '<br /><b>'.&mt('Time').':</b> '.$content{'time'}.'<p>'.  
   '<table border=2><tr bgcolor="#FFFFAA"><td>'.&mt('Functions').':</td>'.  
   '<td><a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).$sqs.  
   '"><b>'.&mt('Reply').'</b></a></td>'.  
   '<td><a href="/adm/email?forward='.&Apache::lonnet::escape($msgid).$sqs.  
   '"><b>'.&mt('Forward').'</b></a></td>'.  
   '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs.  
   '"><b>'.&mt('Mark Unread').'</b></a></td>'.  
   '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs.  
   '"><b>Delete</b></a></td>'.  
   '<td><a href="/adm/email?sortedby='.$ENV{'form.sortedby'}.  
   '"><b>'.&mt('Display all Messages').'</b></a></td>');  
  if ($counter > 0){  
     $r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.  
       '"><b>'.&mt('Previous').'</b></a></td>');  
  }  
  if ($counter < $number_of_messages - 1){  
     $r->print('<td><a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.  
       '"><b>'.&mt('Next').'</b></a></td>');  
  }  
  $r->print('</tr></table><p><pre>'.  
   &Apache::lontexconvert::msgtexconverted($content{'message'},1).  
   '</pre><hr>'.$content{'citation'});  
     } elsif ($ENV{'form.replyto'}) {      } elsif ($ENV{'form.replyto'}) {
  &comprep($r,$ENV{'form.replyto'});   &compout($r,'',$ENV{'form.replyto'},undef,undef,$folder);
     } elsif ($ENV{'form.sendreply'}) {  
  if ($ENV{'form.send'}) {  
     my $msgid=$ENV{'form.sendreply'};  
     my %message=&Apache::lonnet::get('nohist_email',[$msgid]);  
     my %content=&unpackagemsg($message{$msgid},1);  
     &statuschange($msgid,'replied');  
     if ((($ENV{'form.critmsg'}) || ($ENV{'form.sendbck'})) &&   
  (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {  
  $r->print(&mt('Sending critical message').': '.  
   &user_crit_msg($content{'sendername'},  
  $content{'senderdomain'},  
  &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),  
  &Apache::lonfeedback::clear_out_html($ENV{'form.message'}),  
  $ENV{'form.sendbck'}));  
     } else {  
  $r->print(&mt('Sending').': '.&user_normal_msg($content{'sendername'},  
        $content{'senderdomain'},  
        &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),  
        &Apache::lonfeedback::clear_out_html($ENV{'form.message'})));  
     }  
  }  
  if ($ENV{'form.displayedcrit'}) {  
     &discrit($r);  
  } else {  
     &disall($r);  
  }  
     } elsif ($ENV{'form.confirm'}) {      } elsif ($ENV{'form.confirm'}) {
    &printheader($r,'','Confirmed Receipt');
  foreach (keys %ENV) {   foreach (keys %ENV) {
     if ($_=~/^form\.rec\_(.*)$/) {      if ($_=~/^form\.rec\_(.*)$/) {
  $r->print('<b>Confirming Receipt:</b> '.   $r->print('<b>'.&mt('Confirming Receipt').':</b> '.
   &user_crit_received($1).'<br>');    &user_crit_received($1).'<br>');
     }      }
     if ($_=~/^form\.reprec\_(.*)$/) {      if ($_=~/^form\.reprec\_(.*)$/) {
  my $msgid=$1;   my $msgid=$1;
  $r->print('<b>Confirming Receipt:</b> '.   $r->print('<b>'.&mt('Confirming Receipt').':</b> '.
   &user_crit_received($msgid).'<br>');    &user_crit_received($msgid).'<br>');
  &comprep($r,$msgid);   &compout($r,'','','',$msgid);
     }      }
  }   }
  &discrit($r);   &discrit($r);
     } elsif ($ENV{'form.critical'}) {      } elsif ($ENV{'form.critical'}) {
    &printheader($r,'','Displaying Critical Messages');
  &discrit($r);   &discrit($r);
     } elsif ($ENV{'form.forward'}) {      } elsif ($ENV{'form.forward'}) {
  &compout($r,$ENV{'form.forward'});   &compout($r,$ENV{'form.forward'},undef,undef,undef,$folder);
     } elsif ($ENV{'form.markread'}) {  
     } elsif ($ENV{'form.markdel'}) {      } elsif ($ENV{'form.markdel'}) {
  &statuschange($ENV{'form.markdel'},'deleted');   &printheader($r,'','Deleted Message');
  &disall($r);   &statuschange($ENV{'form.markdel'},'deleted',$folder);
    &Apache::loncommunicate::menu($r);
    &disall($r,$folder);
       } elsif ($ENV{'form.markedmove'}) {
    my $total=0;
    foreach (keys %ENV) {
       if ($_=~/^form\.delmark_(.*)$/) {
    &movemsg(&Apache::lonnet::unescape($1),$folder,
    $ENV{'form.movetofolder'});
    $total++;
       }
    }
    &printheader($r,'','Moved Messages');
    $r->print('Moved '.$total.' message(s)<p>');
    &Apache::loncommunicate::menu($r);
    &disall($r,$folder);
     } elsif ($ENV{'form.markeddel'}) {      } elsif ($ENV{'form.markeddel'}) {
  my $total=0;   my $total=0;
  foreach (keys %ENV) {   foreach (keys %ENV) {
     if ($_=~/^form\.delmark_(.*)$/) {      if ($_=~/^form\.delmark_(.*)$/) {
  &statuschange(&Apache::lonnet::unescape($1),'deleted');   &statuschange(&Apache::lonnet::unescape($1),'deleted',$folder);
  $total++;   $total++;
     }      }
  }   }
    &printheader($r,'','Deleted Messages');
  $r->print('Deleted '.$total.' message(s)<p>');   $r->print('Deleted '.$total.' message(s)<p>');
  &disall($r);   &Apache::loncommunicate::menu($r);
    &disall($r,$folder);
     } elsif ($ENV{'form.markunread'}) {      } elsif ($ENV{'form.markunread'}) {
    &printheader($r,'','Marked Message as Unread');
  &statuschange($ENV{'form.markunread'},'new');   &statuschange($ENV{'form.markunread'},'new');
  &disall($r);   &Apache::loncommunicate::menu($r);
    &disall($r,$folder);
     } elsif ($ENV{'form.compose'}) {      } elsif ($ENV{'form.compose'}) {
  &compout($r,'',$ENV{'form.compose'});   &compout($r,'','',$ENV{'form.compose'});
     } elsif ($ENV{'form.recordftf'}) {      } elsif ($ENV{'form.recordftf'}) {
  &facetoface($r,$ENV{'form.recordftf'});   &facetoface($r,$ENV{'form.recordftf'});
       } elsif ($ENV{'form.block'}) {
           &examblock($r,$ENV{'form.block'});
     } elsif ($ENV{'form.sendmail'}) {      } elsif ($ENV{'form.sendmail'}) {
  my $sendstatus='';   &sendoffmail($r,$folder);
  if ($ENV{'form.send'}) {   if ($ENV{'form.storebasecomment'}) {
     my %content=();      &storecomment($r);
     undef %content;  
     if ($ENV{'form.forwid'}) {  
  my $msgid=$ENV{'form.forwid'};  
  my %message=&Apache::lonnet::get('nohist_email',[$msgid]);  
  %content=&unpackagemsg($message{$msgid},1);  
  &statuschange($msgid,'forwarded');  
  $ENV{'form.message'}.="\n\n-- Forwarded message --\n\n".  
     $content{'message'};  
     }  
     my %toaddr=();  
     undef %toaddr;  
     if ($ENV{'form.sendmode'} eq 'group') {  
  foreach (keys %ENV) {  
     if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) {  
  $toaddr{$1}='';  
     }  
  }  
     } elsif ($ENV{'form.sendmode'} eq 'upload') {  
  foreach (split(/[\n\r\f]+/,$ENV{'form.upfile'})) {  
     my ($rec,$txt)=split(/\s*\:\s*/,$_);  
     if ($txt) {  
  $rec=~s/\@/\:/;  
  $toaddr{$rec}.=$txt."\n";  
     }  
  }  
     } else {  
  $toaddr{$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}}='';  
     }  
     if ($ENV{'form.additionalrec'}) {  
  foreach (split(/\,/,$ENV{'form.additionalrec'})) {  
     my ($auname,$audom)=split(/\@/,$_);  
     $toaddr{$auname.':'.$audom}='';  
  }  
     }  
     foreach (keys %toaddr) {  
  my ($recuname,$recdomain)=split(/\:/,$_);  
  my $msgtxt=&Apache::lonfeedback::clear_out_html($ENV{'form.message'});  
  if ($toaddr{$_}) { $msgtxt.='<hr>'.$toaddr{$_}; }      
  if ((($ENV{'form.critmsg'}) || ($ENV{'form.sendbck'})) &&   
     (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {  
     $r->print(&mt('Sending critical message').' ...');  
     $sendstatus.=' '.&user_crit_msg($recuname,$recdomain,  
     &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),  
     $msgtxt,  
     $ENV{'form.sendbck'});  
  } else {  
     $r->print(&mt('Sending').' ...');  
     $sendstatus.=' '.&user_normal_msg($recuname,$recdomain,  
       &Apache::lonfeedback::clear_out_html($ENV{'form.subject'}),  
       $msgtxt,  
       $content{'citation'});  
  }  
  $r->print('<br />');  
     }  
  }  
  if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) {  
     $r->print('<br /><font color="green">'.&mt('Completed.').'</font>');  
     if ($ENV{'form.displayedcrit'}) {  
  &discrit($r);  
     } else {  
  &disall($r);  
     }  
  } else {  
     $r->print(  
       '<h2><font color="red">'.&mt('Could not deliver message').'</font></h2>'.  
       &mt('Please use the browser "Back" button and correct the recipient addresses')  
       );  
  }   }
    &disall($r,$folder);
       } elsif ($ENV{'form.newfolder'}) {
    &printheader($r,'','New Folder');
    &makefolder($ENV{'form.newfolder'});
    &Apache::loncommunicate::menu($r);
    &disall($r,$ENV{'form.newfolder'});
       } elsif ($ENV{'form.showcommentbaseurl'}) {
    &storedcommentlisting($r);
     } else {      } else {
  &disall($r);   &printheader($r,'','Display All Messages');
    &Apache::loncommunicate::menu($r);
    &disall($r,$folder);
     }      }
     $r->print('</body></html>');      $r->print('</body></html>');
     return OK;      return OK;

Removed from v.1.87  
changed lines
  Added in v.1.128


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>