Diff for /loncom/interface/lonmsg.pm between versions 1.106 and 1.170

version 1.106, 2004/09/10 06:38:24 version 1.170, 2006/01/09 20:07:27
Line 90  also has a student role in the course, A Line 90  also has a student role in the course, A
   
 Users can ask LON-CAPA to forward messages to conventional e-mail  Users can ask LON-CAPA to forward messages to conventional e-mail
 addresses on their B<PREF> screen, but generally, LON-CAPA messages  addresses on their B<PREF> screen, but generally, LON-CAPA messages
 are much more useful then traditional email can be made to be, even  are much more useful than traditional email can be made to be, even
 with HTML support.  with HTML support.
   
 Right now, this document will cover just how to send a message, since  Right now, this document will cover just how to send a message, since
 it is likely you will not need to programmatically read messages,  it is likely you will not need to programmatically read messages,
 since lonmsg already implements that functionality.  since lonmsg already implements that functionality.
   
   The routines used to package messages and unpackage messages are not
   only used by lonmsg when creating/extracting messages for LON-CAPA's
   internal messaging system, but also by lonnotify.pm which is available
   for use by Domain Coordinators to broadcast standard e-mail to specified
   users in their domain.  The XML packaging used in the two cases is very
   similar.  The differences are the use of <recuser>$uname</recuser> and 
   <recdomain>$udom</recdomain> in stored internal messages, compared 
   with <recipient username="$uname:$udom">$email</recipient> in stored
   Domain Coordinator e-mail for the storage of information about 
   recipients of the message/e-mail.
   
 =head1 FUNCTIONS  =head1 FUNCTIONS
   
 =over 4  =over 4
Line 104  since lonmsg already implements that fun Line 115  since lonmsg already implements that fun
 =cut  =cut
   
 use strict;  use strict;
 use Apache::lonnet();  use Apache::lonnet;
 use vars qw($msgcount);  use vars qw($msgcount);
 use HTML::TokeParser();  use HTML::TokeParser();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
Line 114  use HTML::Entities(); Line 125  use HTML::Entities();
 use Mail::Send;  use Mail::Send;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::loncommunicate;  use Apache::loncommunicate;
   use Apache::lonfeedback;
   use Apache::lonrss();
   
 # 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,
    $recuser,$recdomain,$msgid,$type)=@_;
     $message =&HTML::Entities::encode($message,'<>&"');      $message =&HTML::Entities::encode($message,'<>&"');
     $citation=&HTML::Entities::encode($citation,'<>&"');      $citation=&HTML::Entities::encode($citation,'<>&"');
     $subject =&HTML::Entities::encode($subject,'<>&"');      $subject =&HTML::Entities::encode($subject,'<>&"');
Line 131  sub packagemsg { Line 147  sub packagemsg {
     #remove machine specification      #remove machine specification
     $attachmenturl =~ s|^http://[^/]+/|/|;      $attachmenturl =~ s|^http://[^/]+/|/|;
     $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');      $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
       my $course_context;
       if (defined($env{'form.replyid'})) {
           my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
                      split(/\:/,&Apache::lonnet::unescape($env{'form.replyid'}));
           $course_context = $origcid;
       }
       foreach my $key (keys(%env)) {
           if ($key=~/^form\.(rep)?rec\_(.*)$/) {
               my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) =
                                       split(/\:/,&Apache::lonnet::unescape($2));
               $course_context = $origcid;
               last;
           }
       }
       unless(defined($course_context)) {
           $course_context = $env{'request.course.id'};
       }
     my $now=time;      my $now=time;
     $msgcount++;      $msgcount++;
     my $partsubj=$subject;      unless(defined($msgid)) {
     $partsubj=&Apache::lonnet::escape($partsubj);          $msgid = &buildmsgid($now,$subject,$env{'user.name'},$env{'user.domain'},
     my $msgid=&Apache::lonnet::escape(                              $msgcount,$course_context,$$);
            $now.':'.$partsubj.':'.$ENV{'user.name'}.':'.      }
            $ENV{'user.domain'}.':'.$msgcount.':'.$$);      my $result='<sendername>'.$env{'user.name'}.'</sendername>'.
     my $result='<sendername>'.$ENV{'user.name'}.'</sendername>'.             '<senderdomain>'.$env{'user.domain'}.'</senderdomain>'.
            '<senderdomain>'.$ENV{'user.domain'}.'</senderdomain>'.  
            '<subject>'.$subject.'</subject>'.             '<subject>'.$subject.'</subject>'.
    '<time>'.&Apache::lonlocal::locallocaltime($now).'</time>'.     '<time>'.&Apache::lonlocal::locallocaltime($now).'</time>'.
    '<servername>'.$ENV{'SERVER_NAME'}.'</servername>'.     '<servername>'.$ENV{'SERVER_NAME'}.'</servername>'.
            '<host>'.$ENV{'HTTP_HOST'}.'</host>'.             '<host>'.$ENV{'HTTP_HOST'}.'</host>'.
    '<client>'.$ENV{'REMOTE_ADDR'}.'</client>'.     '<client>'.$ENV{'REMOTE_ADDR'}.'</client>'.
    '<browsertype>'.$ENV{'browser.type'}.'</browsertype>'.     '<browsertype>'.$env{'browser.type'}.'</browsertype>'.
    '<browseros>'.$ENV{'browser.os'}.'</browseros>'.     '<browseros>'.$env{'browser.os'}.'</browseros>'.
    '<browserversion>'.$ENV{'browser.version'}.'</browserversion>'.     '<browserversion>'.$env{'browser.version'}.'</browserversion>'.
            '<browsermathml>'.$ENV{'browser.mathml'}.'</browsermathml>'.             '<browsermathml>'.$env{'browser.mathml'}.'</browsermathml>'.
    '<browserraw>'.$ENV{'HTTP_USER_AGENT'}.'</browserraw>'.     '<browserraw>'.$ENV{'HTTP_USER_AGENT'}.'</browserraw>'.
    '<courseid>'.$ENV{'request.course.id'}.'</courseid>'.     '<courseid>'.$course_context.'</courseid>'.
    '<coursesec>'.$ENV{'request.course.sec'}.'</coursesec>'.     '<coursesec>'.$env{'request.course.sec'}.'</coursesec>'.
    '<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>';
    '<message>'.$message.'</message>';      if (ref($recuser) eq 'ARRAY') {
           for (my $i=0; $i<@{$recuser}; $i++) {
               if ($type eq 'dcmail') {
                   my ($username,$email) = split(/:/,$$recuser[$i]);
                   $username = &Apache::lonnet::unescape($username);
                   $email = &Apache::lonnet::unescape($email);
                   $username = &HTML::Entities::encode($username,'<>&"');
                   $email = &HTML::Entities::encode($email,'<>&"');
                   $result .= '<recipient username="'.$username.'">'.
                                               $email.'</recipient>';
               } else {
                   $result .= '<recuser>'.$$recuser[$i].'</recuser>'.
                              '<recdomain>'.$$recdomain[$i].'</recdomain>';
               }
           }
       } else {
           $result .= '<recuser>'.$recuser.'</recuser>'.
                      '<recdomain>'.$recdomain.'</recdomain>';
       }
       $result .= '<message>'.$message.'</message>';
     if (defined($citation)) {      if (defined($citation)) {
  $result.='<citation>'.$citation.'</citation>';   $result.='<citation>'.$citation.'</citation>';
     }      }
Line 180  sub unpackagemsg { Line 230  sub unpackagemsg {
        if ($token->[0] eq 'S') {         if ($token->[0] eq 'S') {
    my $entry=$token->[1];     my $entry=$token->[1];
            my $value=$parser->get_text('/'.$entry);             my $value=$parser->get_text('/'.$entry);
            $content{$entry}=$value;             if (($entry eq 'recuser') || ($entry eq 'recdomain')) {
                  push(@{$content{$entry}},$value);
              } elsif ($entry eq 'recipient') {
                  my $username = $token->[2]{'username'};
                  $username = &HTML::Entities::decode($username,'<>&"');
                  $content{$entry}{$username} = $value;
              } else {
                  $content{$entry}=$value;
              }
        }         }
     }      }
       if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
     if ($content{'attachmenturl'}) {      if ($content{'attachmenturl'}) {
        my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);         my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
        if ($notoken) {         if ($notoken) {
Line 200  sub unpackagemsg { Line 259  sub unpackagemsg {
   
 # ======================================================= Get info out of msgid  # ======================================================= Get info out of msgid
   
   sub buildmsgid {
       my ($now,$subject,$uname,$udom,$msgcount,$course_context,$pid) = @_;
       $subject=&Apache::lonnet::escape($subject);
       return(&Apache::lonnet::escape($now.':'.$subject.':'.$uname.':'.
              $udom.':'.$msgcount.':'.$course_context.':'.$pid));
   }
   
 sub unpackmsgid {  sub unpackmsgid {
     my ($msgid,$folder)=@_;      my ($msgid,$folder,$skipstatus,$status_cache)=@_;
     $msgid=&Apache::lonnet::unescape($msgid);      $msgid=&Apache::lonnet::unescape($msgid);
     my $suffix=&foldersuffix($folder);      my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid,
     my ($sendtime,$shortsubj,$fromname,$fromdomain)=split(/\:/,                       $processid)=split(/\:/,&Apache::lonnet::unescape($msgid));
                           &Apache::lonnet::unescape($msgid));      if (!defined($processid)) { $fromcid = ''; }
     my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);      my %status=();
     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }      unless ($skipstatus) {
     unless ($status{$msgid}) { $status{$msgid}='new'; }   if (ref($status_cache)) {
     return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid});      $status{$msgid} = $status_cache->{$msgid};
 }    } else {
       my $suffix=&foldersuffix($folder);
       %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
    }
    if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
           unless ($status{$msgid}) { $status{$msgid}='new'; }
       }
       return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid);
   }
   
   
 sub sendemail {  sub sendemail {
Line 221  sub sendemail { Line 295  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);
     my %oldENV=%ENV;  
     undef(%ENV);  
     if (my $fh = $msg->open()) {      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
   
 sub sendnotification {  sub sendnotification {
     my ($to,$touname,$toudom,$subj,$crit)=@_;      my ($to,$touname,$toudom,$subj,$crit,$text)=@_;
     my $sender=$ENV{'environment.firstname'}.' '.$ENV{'environment.lastname'};      my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'};
       unless ($sender=~/\w/) { 
    $sender=$env{'user.name'}.'@'.$env{'user.domain'};
       }
     my $critical=($crit?' critical':'');      my $critical=($crit?' critical':'');
       $text=~s/\&lt\;/\</gs;
       $text=~s/\&gt\;/\>/gs;
       $text=~s/\<\/*[^\>]+\>//gs;
     my $url='http://'.      my $url='http://'.
       $Apache::lonnet::hostname{&Apache::lonnet::homeserver($touname,$toudom)}.        $Apache::lonnet::hostname{&Apache::lonnet::homeserver($touname,$toudom)}.
       '/adm/email?username='.$touname.'&domain='.$toudom;        '/adm/email?username='.$touname.'&domain='.$toudom;
Line 245  You received a$critical message from $se Line 321  You received a$critical message from $se
   
  $subj   $subj
   
   === Excerpt ============================================================
   $text
   ========================================================================
   
 Use  Use
   
  $url   $url
   
 to access this message.  to access the full message.
 ENDMSG  ENDMSG
     &sendemail($to,'New'.$critical.' message from '.$sender,$body);      &sendemail($to,'New'.$critical.' message from '.$sender,$body);
 }  }
 # ============================================================= Check for email  # ============================================================= Check for email
   
 sub newmail {  sub newmail {
     if ((time-$ENV{'user.mailcheck.time'})>300) {      if ((time-$env{'user.mailcheck.time'})>300) {
         my %what=&Apache::lonnet::get('email_status',['recnewemail']);          my %what=&Apache::lonnet::get('email_status',['recnewemail']);
         &Apache::lonnet::appenv('user.mailcheck.time'=>time);          &Apache::lonnet::appenv('user.mailcheck.time'=>time);
         if ($what{'recnewemail'}>0) { return 1; }          if ($what{'recnewemail'}>0) { return 1; }
Line 325  sub del_url_author_res_msg { Line 405  sub del_url_author_res_msg {
     }      }
     return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);      return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
 }  }
   # =================================== Clear out all author messages in URL path
   
   sub clear_author_res_msg {
       my $url=shift;
       $url=&Apache::lonnet::declutter($url);
       my ($domain,$author)=($url=~/^(\w+)\/(\w+)\//);
       my @delmsgs=();
       foreach (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
    if ($_=~/^\Q$url\E/) {
       push (@delmsgs,$_);
    }
       }
       return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
   }
 # ================= Return hash with URLs for which there is a resource message  # ================= Return hash with URLs for which there is a resource message
   
 sub all_url_author_res_msg {  sub all_url_author_res_msg {
Line 341  sub all_url_author_res_msg { Line 434  sub all_url_author_res_msg {
 # ================================================== Critical message to a user  # ================================================== Critical message to a user
   
 sub user_crit_msg_raw {  sub user_crit_msg_raw {
     my ($user,$domain,$subject,$message,$sendback)=@_;      my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;
 # Check if allowed missing  # Check if allowed missing
     my $status='';      my $status='';
     my $msgid='undefined';      my $msgid='undefined';
     unless (($message)&&($user)&&($domain)) { $status='empty'; };      unless (($message)&&($user)&&($domain)) { $status='empty'; };
       my $text=$message;
     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);         ($msgid,$message)=&packagemsg($subject,$message);
Line 354  sub user_crit_msg_raw { Line 448  sub user_crit_msg_raw {
            'put:'.$domain.':'.$user.':critical:'.             'put:'.$domain.':'.$user.':critical:'.
            &Apache::lonnet::escape($msgid).'='.             &Apache::lonnet::escape($msgid).'='.
            &Apache::lonnet::escape($message),$homeserver);             &Apache::lonnet::escape($message),$homeserver);
        if ($ENV{'request.course.id'}) {          if (defined($sentmessage)) {
           &user_normal_msg_raw(              $$sentmessage = $message;
             $ENV{'course.'.$ENV{'request.course.id'}.'.num'},          }
             $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},  
             'Critical ['.$user.':'.$domain.']',  
     $message);  
        }  
     } else {      } else {
        $status='no_host';         $status='no_host';
     }      }
 # Notifications  # Notifications
     my %userenv = &Apache::lonnet::get('environment',['critnotification'],      my %userenv = &Apache::lonnet::get('environment',['critnotification',
                                                         'permanentemail'],
                                        $domain,$user);                                         $domain,$user);
     if ($userenv{'critnotification'}) {      if ($userenv{'critnotification'}) {
       &sendnotification($userenv{'critnotification'},$user,$domain,$subject,1);        &sendnotification($userenv{'critnotification'},$user,$domain,$subject,1,
    $text);
       }
       if ($toperm && $userenv{'permanentemail'}) {
         &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,1,
    $text);
     }      }
 # Log this  # Log this
     &Apache::lonnet::logthis(      &Apache::lonnet::logthis(
       'Sending critical email '.$msgid.        'Sending critical email '.$msgid.
       ', log status: '.        ', log status: '.
       &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'},        &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                          $ENV{'user.home'},                           $env{'user.home'},
       'Sending critical '.$msgid.' to '.$user.' at '.$domain.' with status: '        'Sending critical '.$msgid.' to '.$user.' at '.$domain.' with status: '
       .$status));        .$status));
     return $status;      return $status;
Line 392  sub user_crit_msg_raw { Line 488  sub user_crit_msg_raw {
 =cut  =cut
   
 sub user_crit_msg {  sub user_crit_msg {
     my ($user,$domain,$subject,$message,$sendback)=@_;      my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;
     my $status='';      my $status='';
     my %userenv = &Apache::lonnet::get('environment',['msgforward'],      my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                                        $domain,$user);                                         $domain,$user);
Line 402  sub user_crit_msg { Line 498  sub user_crit_msg {
  my ($forwuser,$forwdomain)=split(/\:/,$_);   my ($forwuser,$forwdomain)=split(/\:/,$_);
          $status.=           $status.=
    &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,     &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,
                 $sendback).' ';                  $sendback,$toperm,$sentmessage).' ';
        }         }
     } else {       } else { 
  $status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback);   $status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage);
     }      }
     return $status;      return $status;
 }  }
Line 418  sub user_crit_received { Line 514  sub user_crit_received {
     my %contents=&unpackagemsg($message{$msgid},1);      my %contents=&unpackagemsg($message{$msgid},1);
     my $status='rec: '.($contents{'sendback'}?      my $status='rec: '.($contents{'sendback'}?
      &user_normal_msg($contents{'sendername'},$contents{'senderdomain'},       &user_normal_msg($contents{'sendername'},$contents{'senderdomain'},
                      &mt('Receipt').': '.$ENV{'user.name'}.' '.&mt('at').' '.$ENV{'user.domain'}.', '.$contents{'subject'},                       &mt('Receipt').': '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.', '.$contents{'subject'},
                      &mt('User').' '.$ENV{'user.name'}.' '.&mt('at').' '.$ENV{'user.domain'}.                       &mt('User').' '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.
                      ' acknowledged receipt of message'."\n".'   "'.                       ' acknowledged receipt of message'."\n".'   "'.
                      $contents{'subject'}.'"'."\n".&mt('dated').' '.                       $contents{'subject'}.'"'."\n".&mt('dated').' '.
                      $contents{'time'}.".\n"                       $contents{'time'}.".\n"
Line 429  sub user_crit_received { Line 525  sub user_crit_received {
      'nohist_email',{$contents{'msgid'} => $message{$msgid}});       'nohist_email',{$contents{'msgid'} => $message{$msgid}});
     $status.=' del: '.      $status.=' del: '.
      &Apache::lonnet::del('critical',[$contents{'msgid'}]);       &Apache::lonnet::del('critical',[$contents{'msgid'}]);
     &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'},      &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                          $ENV{'user.home'},'Received critical message '.                           $env{'user.home'},'Received critical message '.
                          $contents{'msgid'}.                           $contents{'msgid'}.
                          ', '.$status);                           ', '.$status);
     return $status;      return $status;
Line 439  sub user_crit_received { Line 535  sub user_crit_received {
 # ======================================================== Normal communication  # ======================================================== Normal communication
   
 sub user_normal_msg_raw {  sub user_normal_msg_raw {
     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl)=@_;      my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
    $toperm,$currid,$newid,$sentmessage)=@_;
 # Check if allowed missing  # Check if allowed missing
     my $status='';      my $status='';
     my $msgid='undefined';      my $msgid='undefined';
       my $text=$message;
     unless (($message)&&($user)&&($domain)) { $status='empty'; };      unless (($message)&&($user)&&($domain)) { $status='empty'; };
     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,$currid);
   # 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 unless a broadcast message or critical message
          unless (($env{'request.course.id'}) && 
                  (($env{'form.sendmode'} eq 'group')  || 
                  (($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
                  (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
       '/'.$env{'request.course.sec'})))) {
              $status .= &store_sent_mail($msgid,$message);
          }
     } else {      } else {
        $status='no_host';         $status='no_host';
     }      }
       if (defined($newid)) {
           $$newid = $msgid;
       }
       if (defined($sentmessage)) {
           $$sentmessage = $message;
       }
   
 # Notifications  # Notifications
     my %userenv = &Apache::lonnet::get('environment',['notification'],      my %userenv = &Apache::lonnet::get('environment',['notification',
                                                         'permanentemail'],
                                        $domain,$user);                                         $domain,$user);
     if ($userenv{'notification'}) {      if ($userenv{'notification'}) {
  &sendnotification($userenv{'notification'},$user,$domain,$subject,0);   &sendnotification($userenv{'notification'},$user,$domain,$subject,0,
     $text);
       }
       if ($toperm && $userenv{'permanentemail'}) {
         &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,0,
    $text);
     }      }
     &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'},      &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
                          $ENV{'user.home'},                           $env{'user.home'},
       'Sending '.$msgid.' to '.$user.' at '.$domain.' with status: '.$status);        'Sending '.$msgid.' to '.$user.' at '.$domain.' with status: '.$status);
     return $status;      return $status;
 }  }
Line 480  sub user_normal_msg_raw { Line 602  sub user_normal_msg_raw {
 =cut  =cut
   
 sub user_normal_msg {  sub user_normal_msg {
     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl)=@_;      my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
    $toperm,$sentmessage)=@_;
     my $status='';      my $status='';
     my %userenv = &Apache::lonnet::get('environment',['msgforward'],      my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                                        $domain,$user);                                         $domain,$user);
Line 490  sub user_normal_msg { Line 613  sub user_normal_msg {
  my ($forwuser,$forwdomain)=split(/\:/,$_);   my ($forwuser,$forwdomain)=split(/\:/,$_);
          $status.=           $status.=
   &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,    &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
        $citation,$baseurl,$attachmenturl).' ';   $citation,$baseurl,$attachmenturl,$toperm,undef,undef,$sentmessage).' ';
        }         }
     } else {       } else { 
  $status=&user_normal_msg_raw($user,$domain,$subject,$message,   $status=&user_normal_msg_raw($user,$domain,$subject,$message,
      $citation,$baseurl,$attachmenturl);      $citation,$baseurl,$attachmenturl,$toperm,undef,undef,$sentmessage);
     }      }
     return $status;      return $status;
 }  }
   
   sub store_sent_mail {
       my ($msgid,$message) = @_;
           my $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'});
       return $status;
   }
   
 # ============================================================ List all folders  # ============================================================ List all folders
   
Line 507  sub folderlist { Line 639  sub folderlist {
     my @allfolders=&Apache::lonnet::getkeys('email_folders');      my @allfolders=&Apache::lonnet::getkeys('email_folders');
     if ($allfolders[0]=~/^error:/) { @allfolders=(); }      if ($allfolders[0]=~/^error:/) { @allfolders=(); }
     return '<form method="post" action="/adm/email">'.      return '<form method="post" action="/adm/email">'.
  '<input type="submit" value="'.&mt('View Folder').'" />'.   &mt('Folder').': '.
  &Apache::loncommon::select_form($folder,'folder',   &Apache::loncommon::select_form($folder,'folder',
      ('' => &mt('INBOX'),'trash' => &mt('TRASH'),       ('' => &mt('INBOX'),'trash' => &mt('TRASH'),
         'new' => &mt('New Messages Only'),
                                 'critical' => &mt('Critical'),
       'sent' => &mt('Sent Messages'),        'sent' => &mt('Sent Messages'),
       map { $_ => $_ } @allfolders)).        map { $_ => $_ } @allfolders)).
  '<a href="/adm/email?critical=display">'.        ' '.&mt('Show').
     &mt('View Critical Messages').'</a>'.        '<select name="interdis">'.
         '</form>';        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
      &mt('Page').': '. 
      '<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('Showing messages [_1] through [_2] of [_3]',$first,$finish,$total).'</form>';
 }  }
   
 # =============================================================== Folder suffix  # =============================================================== Folder suffix
   
 sub foldersuffix {  sub foldersuffix {
Line 539  sub statuschange { Line 693  sub statuschange {
     if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {      if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {
  &Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});   &Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
     }      }
       if ($newstatus eq 'deleted') {
          &movemsg(&Apache::lonnet::unescape($msgid),$folder,'trash');
      }
 }  }
   
 # ============================================================= Make new folder  # ============================================================= Make new folder
   
 sub makefolder {  sub makefolder {
     my ($newfolder)=@_;      my ($newfolder)=@_;
       if (($newfolder eq 'sent')
        || ($newfolder eq 'critical')
        || ($newfolder eq 'trash')
        || ($newfolder eq 'new')) { return; }
     &Apache::lonnet::put('email_folders',{$newfolder => time});      &Apache::lonnet::put('email_folders',{$newfolder => time});
 }  }
   
Line 552  sub makefolder { Line 713  sub makefolder {
   
 sub movemsg {  sub movemsg {
     my ($msgid,$srcfolder,$trgfolder)=@_;      my ($msgid,$srcfolder,$trgfolder)=@_;
       if ($srcfolder eq 'new') { $srcfolder=''; }
     my $srcsuffix=&foldersuffix($srcfolder);      my $srcsuffix=&foldersuffix($srcfolder);
     my $trgsuffix=&foldersuffix($trgfolder);      my $trgsuffix=&foldersuffix($trgfolder);
     my $srcstatus=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);  
     my $trgstatus=$srcstatus;  # Copy message
     if ($trgstatus eq 'deleted') { $trgstatus='read'; }      my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]);
     &Apache::lonnet::put(      &Apache::lonnet::put('nohist_email'.$trgsuffix,{$msgid => $message{$msgid}});
      'nohist_email'.$trgsuffix,{$msgid =>   
      &Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid])});  # Copy status
     &statuschange($msgid,$trgstatus,$trgfolder);      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('nohist_email'.$srcsuffix,[$msgid]);
     &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);      &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
 }  }
Line 569  sub movemsg { Line 735  sub movemsg {
   
 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 All',
             'cfs' => 'Check for Section/Group',              'cfs' => 'Check Section/Group',
             'cfn' => 'Check for None');              'cfn' => 'Uncheck All');
     $r->print(<<ENDDISHEADER);      $r->print(<<ENDDISHEADER);
 <input type="hidden" name="sendmode" value="group" />  <input type="hidden" name="sendmode" value="group" />
 <script>  <script>
Line 610  sub discourse { Line 773  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) {      my $sort = sub {
         my ($end,$start)=split(/\:/,$courselist{$_});   my $aname=lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]);
         my $active=1;   if (!$aname) { $aname=$a; }
         if (($end) && ($now>$end)) { $active=0; }   my $bname=lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]);
         if ($active) {   if (!$bname) { $bname=$b; }
            my ($sname,$sdom)=split(/\:/,$_);   return $aname cmp $bname;
            my %reply=&Apache::lonnet::get('environment',      };
               ['firstname','middlename','lastname','generation'],      foreach my $student (sort $sort (keys(%{$classlist}))) {
               $sdom,$sname);   my $info=$classlist->{$student};
            my $section=&Apache::lonnet::usection          my ($sname,$sdom,$status,$fullname,$section) =
        ($sdom,$sname,$ENV{'request.course.id'});              (@{$info}[&Apache::loncoursedata::CL_SNAME(),
            $r->print(                        &Apache::loncoursedata::CL_SDOM(),
         '<br><input type=checkbox name="send_to_&&&'.$section.'&&&_'.$_.'"> '.                        &Apache::loncoursedata::CL_STATUS(),
       $reply{'firstname'}.' '.                         &Apache::loncoursedata::CL_FULLNAME(),
                       $reply{'middlename'}.' '.                        &Apache::loncoursedata::CL_SECTION()]);
                       $reply{'lastname'}.' '.          next if ($status ne 'Active');
                       $reply{'generation'}.   next if ($env{'request.course.sec'} &&
                       ' ('.$_.') '.$section);   $section ne $env{'request.course.sec'});
         }           my $key = 'send_to_&&&'.$section.'&&&_'.$student;
           if (! defined($fullname) || $fullname eq '') { $fullname = $sname; }
           $r->print('<tr><td><label>'.
                     qq{<input type="checkbox" name="$key" />}.('&nbsp;'x2).
                     $fullname.'</label></td><td>'.$sname.'@'.$sdom.'</td><td>'.$section.
                     '</td></tr>');
     }      }
       $r->print('</table>');
 }  }
   
 # ==================================================== Display Critical Message  # ==================================================== Display Critical Message
Line 654  ENDDISHEADER Line 824  ENDDISHEADER
 sub discrit {  sub discrit {
     my $r=shift;      my $r=shift;
     my $header = '<h1><font color=red>'.&mt('Critical Messages').'</font></h1>'.      my $header = '<h1><font color=red>'.&mt('Critical Messages').'</font></h1>'.
         '<form action=/adm/email method=post>'.          '<form action="/adm/email" method="POST">'.
         '<input type=hidden name=confirm value=true>';          '<input type="hidden" name="confirm" value="true" />';
     my %what=&Apache::lonnet::dump('critical');      my %what=&Apache::lonnet::dump('critical');
     my $result = '';      my $result = '';
     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 /><pre>'.
               &Apache::lontexconvert::msgtexconverted($content{'message'}).                &Apache::lontexconvert::msgtexconverted($content{'message'}).
             '</blockquote><small>'.              '</pre><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').
             '</small><br />'.              '</small><br />'.
             '<input type=submit name="rec_'.$_.'" value="'.&mt('Confirm Receipt').'">'.              '<input type="submit" name="rec_'.$_.'" value="'.&mt('Confirm Receipt').'" />'.
             '<input type=submit name="reprec_'.$_.'" '.              '<input type="submit" name="reprec_'.$_.'" '.
                   'value="'.&mt('Confirm Receipt and Reply').'">';                    'value="'.&mt('Confirm Receipt and Reply').'" />';
     }      }
     # Check to see if there were any messages.      # Check to see if there were any messages.
     if ($result eq '') {      if ($result eq '') {
Line 686  $content{'sendername'}.'@'. Line 855  $content{'sendername'}.'@'.
         $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>');
 }  }
   
 sub sortedmessages {  sub sortedmessages {
Line 695  sub sortedmessages { Line 864  sub sortedmessages {
     my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);      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;
       my %descriptions;
       my %status_cache = 
    &Apache::lonnet::get('email_status'.&foldersuffix($folder),\@messages);
     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,$fromcid)=
     &Apache::lonmsg::unpackmsgid($msgid);      &Apache::lonmsg::unpackmsgid($msgid,$folder,undef,
    \%status_cache);
           my $description = &get_course_desc($fromcid,\%descriptions);
  my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,   my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
      $msgid);       $msgid,$description);
         # Check whether message was sent during blocking period.          # Check whether message was sent during blocking period.
         if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {          if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {
             my $escid = &Apache::lonnet::unescape($msgid);              my $escid = &Apache::lonnet::unescape($msgid);
Line 712  sub sortedmessages { Line 886  sub sortedmessages {
     }      }
     #default sort      #default sort
     @temp = sort  {$a->[0] <=> $b->[0]} @temp;          @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
     if ($ENV{'form.sortedby'} eq "date"){      if ($env{'form.sortedby'} eq "date"){
         @temp = sort  {$a->[0] <=> $b->[0]} @temp;              @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
     }      }
     if ($ENV{'form.sortedby'} eq "revdate"){      if ($env{'form.sortedby'} eq "revdate"){
     @temp = sort  {$b->[0] <=> $a->[0]} @temp;       @temp = sort  {$b->[0] <=> $a->[0]} @temp; 
     }      }
     if ($ENV{'form.sortedby'} eq "user"){      if ($env{'form.sortedby'} eq "user"){
  @temp = sort  {lc($a->[2]) cmp lc($b->[2])} @temp;   @temp = sort  {lc($a->[2]) cmp lc($b->[2])} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "revuser"){      if ($env{'form.sortedby'} eq "revuser"){
  @temp = sort  {lc($b->[2]) cmp lc($a->[2])} @temp;   @temp = sort  {lc($b->[2]) cmp lc($a->[2])} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "domain"){      if ($env{'form.sortedby'} eq "domain"){
         @temp = sort  {$a->[3] cmp $b->[3]} @temp;          @temp = sort  {$a->[3] cmp $b->[3]} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "revdomain"){      if ($env{'form.sortedby'} eq "revdomain"){
         @temp = sort  {$b->[3] cmp $a->[3]} @temp;          @temp = sort  {$b->[3] cmp $a->[3]} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "subject"){      if ($env{'form.sortedby'} eq "subject"){
         @temp = sort  {lc($a->[1]) cmp lc($b->[1])} @temp;          @temp = sort  {lc($a->[1]) cmp lc($b->[1])} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "revsubject"){      if ($env{'form.sortedby'} eq "revsubject"){
         @temp = sort  {lc($b->[1]) cmp lc($a->[1])} @temp;          @temp = sort  {lc($b->[1]) cmp lc($a->[1])} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "status"){      if ($env{'form.sortedby'} eq "course"){
           @temp = sort  {lc($a->[6]) cmp lc($b->[6])} @temp;
       }
       if ($env{'form.sortedby'} eq "revcourse"){
           @temp = sort  {lc($b->[6]) cmp lc($a->[6])} @temp;
       }
       if ($env{'form.sortedby'} eq "status"){
         @temp = sort  {$a->[4] cmp $b->[4]} @temp;          @temp = sort  {$a->[4] cmp $b->[4]} @temp;
     }      }
     if ($ENV{'form.sortedby'} eq "revstatus"){      if ($env{'form.sortedby'} eq "revstatus"){
         @temp = sort  {$b->[4] cmp $a->[4]} @temp;          @temp = sort  {$b->[4] cmp $a->[4]} @temp;
     }      }
     return @temp;      return @temp;
 }  }
   
   sub get_course_desc {
       my ($fromcid,$descriptions) = @_;
       my $description;
       if (!$fromcid) {
           return $description;
       } else {
           if (defined($$descriptions{$fromcid})) {
               $description = $$descriptions{$fromcid};
           } else {
               if (defined($env{'course.'.$fromcid.'.description'})) {
                   $description = $env{'course.'.$fromcid.'.description'};
               } else {
                   my %courseinfo=&Apache::lonnet::coursedescription($fromcid);                $description = $courseinfo{'description'};
                   $description = $courseinfo{'description'};
               }
               $$descriptions{$fromcid} = $description;
           }
           return $description;
       }
   }
   
   # ======================================================== Display new messages
   
   
   sub disnew {
       my $r=shift;
       my %lt=&Apache::lonlocal::texthash(
          'nm' => 'New Messages',
          'su' => 'Subject',
                                          'co' => 'Course',
          'da' => 'Date',
          'us' => 'Username',
          'op' => 'Open',
          'do' => 'Domain'
          );
       my @msgids = sort(&Apache::lonnet::getkeys('nohist_email'));
       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);
       my %status_cache = 
    &Apache::lonnet::get('email_status',\@msgids);
       my %descriptions;
       foreach (@msgids) {
    my $msgid=&Apache::lonnet::escape($_);
           my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
       &Apache::lonmsg::unpackmsgid($msgid,undef,undef,\%status_cache);
           if (defined($sendtime) && $sendtime!~/error/) {
               my $description = &get_course_desc($fromcid,\%descriptions);
               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    => $msgid,
                           sendtime => $sendtime,
                           shortsub => &Apache::lonnet::unescape($shortsubj),
                           from     => $fromname,
                           fromdom  => $fromdom,
                           course   => $description 
                           }
                   }
               }
           }
       }
       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><th>$lt{'co'}</th></tr>
   TABLEHEAD
           foreach my $msg (@newmsgs) {
               $r->print(<<"ENDLINK");
   <tr class="new" bgcolor="#FFBB77" onMouseOver="javascript:style.backgroundColor='#DD9955'" 
   onMouseOut="javascript:style.backgroundColor='#FFBB77'">
   <td><a href="/adm/email?dismode=new&display=$msg->{'msgid'}">$lt{'op'}</a></td>
   ENDLINK
               foreach ('sendtime','from','fromdom','shortsub','course') {
                   $r->print("<td>$msg->{$_}</td>");
               }
               $r->print("</td></tr>");
           }
           $r->print('</table>'.&Apache::loncommon::endbodytag().'</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,$folder)=@_;      my ($r,$folder)=@_;
       $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 %blocked = ();
     my %setters = ();      my %setters = ();
     my $startblock;      my $startblock;
Line 776  sub disall { Line 1080  sub disall {
     }      }
 </script>  </script>
 ENDDISHEADER  ENDDISHEADER
     $r->print('<h2>'.&mt('Display All Messages').'</h2>'.      my $fsqs='&folder='.$folder;
       &folderlist($folder).      my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
       '<form method="post" name="disall" action="/adm/email">'.      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>');        '<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 "revcourse") {
  $r->print('<a href = "?sortedby=status">'.&mt('Status').'</th>');          $r->print('<a href = "?sortedby=course'.$fsqs.'">'.&mt('Course').'</a>');
     } else {      } else {
       $r->print('<a href = "?sortedby=revstatus">'.&mt('Status').'</th>');          $r->print('<a href = "?sortedby=revcourse'.$fsqs.'">'.&mt('Course').'</a>');
     }      }
     $r->print('</tr>');      $r->print('</th><th>');
     my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);      if ($env{'form.sortedby'} eq "revstatus") {
     foreach (@temp){   $r->print('<a href = "?sortedby=status'.$fsqs.'">'.&mt('Status').'</a></th>');
  my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @$_;      } else {
         $r->print('<a href = "?sortedby=revstatus'.$fsqs.'">'.&mt('Status').'</a></th>');
       }
       $r->print("</tr>\n");
       for (my $n=$firstdis;$n<=$lastdis;$n++) {
    my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID,$description)= @{$temp[$n]};
  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" onMouseOver="javascript:style.backgroundColor=\'#DD9955\'"  onMouseOut="javascript:style.backgroundColor=\'#FFBB77\'">');
     } elsif ($status eq 'read') {      } elsif ($status eq 'read') {
  $r->print('<tr bgcolor="#BBBB77">');   $r->print('<tr bgcolor="#BBBB77" onMouseOver="javascript:style.backgroundColor=\'#999944\'"  onMouseOut="javascript:style.backgroundColor=\'#BBBB77\'">');
     } elsif ($status eq 'replied') {      } elsif ($status eq 'replied') {
  $r->print('<tr bgcolor="#AAAA88">');    $r->print('<tr bgcolor="#AAAA88" onMouseOver="javascript:style.backgroundColor=\'#888855\'"  onMouseOut="javascript:style.backgroundColor=\'#AAAA88\'">'); 
     } else {      } else {
  $r->print('<tr bgcolor="#99BBBB">');   $r->print('<tr bgcolor="#99BBBB" onMouseOver="javascript:style.backgroundColor=\'#669999\'"  onMouseOut="javascript:style.backgroundColor=\'#99BBBB\'">');
     }      }
     $r->print('<td></a><input type=checkbox name="delmark_'.$origID.'" /></td><td><a href="/adm/email?display='.$origID.$sqs.       $r->print('<td><input type="checkbox" name="delmark_'.$origID.'" /></td><td><a href="/adm/email?display='.$origID.$sqs. 
       '">'.&mt('Open').'</a></td><td>'.        '">'.&mt('Open').'</a></td><td>'.
       ($folder ne 'trash'?'<a href="/adm/email?markdel='.$origID.$sqs.        ($folder ne 'trash'?'<a href="/adm/email?markdel='.$origID.$sqs.
       '">'.&mt('Delete'):'&nbsp').'</td>'.        '">'.&mt('Delete'):'&nbsp').'</a></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>');                        $description.'</td><td>'.$status.'</td></tr>'."\n");
  } elsif ($status eq 'deleted') {   } elsif ($status eq 'deleted') {
 # purge  # purge
     &movemsg($origID,$folder,'trash');      &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'}.'" />');
     if ($folder ne 'trash') {      if ($folder ne 'trash') {
  $r->print(   $r->print(
       '<p><input type="submit" name="markeddel" value="'.&mt('Delete Checked').'" /></p>');        '<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').'" />');      $r->print('<p><input type="submit" name="markedmove" value="'.&mt('Move Checked to Folder').'" />');
     my @allfolders=&Apache::lonnet::getkeys('email_folders');      my @allfolders=&Apache::lonnet::getkeys('email_folders');
     if ($allfolders[0]=~/^error:/) { @allfolders=(); }      if ($allfolders[0]=~/^error:/) { @allfolders=(); }
     $r->print(      $r->print(
  &Apache::loncommon::select_form('','movetofolder',   &Apache::loncommon::select_form('','movetofolder',
      ( map { $_ => $_ } @allfolders))       ( map { $_ => $_ } @allfolders))
       );        );
     $r->print('<input type="hidden" name="folder" value="'.$folder.'" /></form>');      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) {      if ($numblocked > 0) {
         my $beginblock = &Apache::lonlocal::locallocaltime($startblock);          my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
         my $finishblock = &Apache::lonlocal::locallocaltime($endblock);          my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
Line 864  $r->print('<p><input type="submit" name= Line 1189  $r->print('<p><input type="submit" name=
 # ============================================================== Compose output  # ============================================================== Compose output
   
 sub compout {  sub compout {
     my ($r,$forwarding,$replying,$broadcast,$replycrit)=@_;      my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_;
       my $suffix=&foldersuffix($folder);
   
     if ($broadcast eq 'individual') {      if ($broadcast eq 'individual') {
  &printheader($r,'/adm/email?compose=individual',   &printheader($r,'/adm/email?compose=individual',
Line 895  sub compout { Line 1221  sub compout {
     my $dispcrit='';      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 903  sub compout { Line 1230  sub compout {
        'ca' => 'Cancel',         'ca' => 'Cancel',
        'ma' => 'Mail');         'ma' => 'Mail');
   
     if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
       '/'.$env{'request.course.sec'})) {
  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 .    '<p><label><input type="checkbox" name="critmsg" /> '.&mt('Send as critical message').'</label> ' . $crithelp . 
  '<br>'.   '</p><p>'.
  '<input type="checkbox" name="sendbck" /> '.&mt('Send as critical message').'  ' .   '<label><input type="checkbox" name="sendbck" /> '.&mt('Send as critical message').'  ' .
  &mt('and return receipt') . $crithelp . '<p>';   &mt('and return receipt') . '</label>' . $crithelp . 
      }   '</p><p><label><input type="checkbox" name="permanent" /> '.
   &mt('Send copy to permanent email address (if known)').'</label></p>'.
   '<!-- <p><label><input type="checkbox" name="rsspost" /> '.
     &mt('Include in course RSS newsfeed').'</label></p>-->';      }
     my %message;      my %message;
     my %content;      my %content;
     my $defdom=$ENV{'user.domain'};      my $defdom=$env{'user.domain'};
     if ($forwarding) {      if ($forwarding) {
  %message=&Apache::lonnet::get('nohist_email',[$forwarding]);   %message=&Apache::lonnet::get('nohist_email'.$suffix,[$forwarding]);
  %content=&unpackagemsg($message{$forwarding});   %content=&unpackagemsg($message{$forwarding},$folder);
  $dispcrit.='<input type="hidden" name="forwid" value="'.   $dispcrit.='<input type="hidden" name="forwid" value="'.
     $forwarding.'" />';      $forwarding.'" />';
  $func=&mt('Forward');   $func=&mt('Forward');
Line 924  sub compout { Line 1256  sub compout {
  $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'}).'" />';
    }
     }      }
     if ($replying) {      if ($replying) {
  %message=&Apache::lonnet::get('nohist_email',[$replying]);   %message=&Apache::lonnet::get('nohist_email'.$suffix,[$replying]);
  %content=&unpackagemsg($message{$replying});   %content=&unpackagemsg($message{$replying},$folder);
  $dispcrit.='<input type="hidden" name="replyid" value="'.   $dispcrit.='<input type="hidden" name="replyid" value="'.
     $replying.'" />';      $replying.'" />';
  $func=&mt('Replying to');   $func=&mt('Send Reply to');
   
  $dissub=&mt('Reply').': '.$content{'subject'};          $dissub=&mt('Reply').': '.$content{'subject'};       
  $dismsg='> '.$content{'message'};   $dismsg='> '.$content{'message'};
  $dismsg=~s/\r/\n/g;   $dismsg=~s/\r/\n/g;
  $dismsg=~s/\f/\n/g;   $dismsg=~s/\f/\n/g;
  $dismsg=~s/\n+/\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.='<label><input type="checkbox" name="storebasecomment" />'.&mt('Store message for re-use').
       '</label> <a href="/adm/email?showcommentbaseurl='.
       &Apache::lonnet::escape($content{'baseurl'}).'" target="comments">'.
       &mt('Show re-usable messages').'</a><br />';
       }
    }
     }      }
     if ($ENV{'form.recdom'}) { $defdom=$ENV{'form.recdom'}; }      my $citation=&displayresource(%content);
       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".
Line 959  sub compout { Line 1304  sub compout {
     my $selectlink=&Apache::loncommon::selectstudent_link      my $selectlink=&Apache::loncommon::selectstudent_link
     ('compemail','recuname','recdomain');      ('compemail','recuname','recdomain');
     $r->print(<<"ENDREC");      $r->print(<<"ENDREC");
 <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
Line 974  ENDREC Line 1319  ENDREC
 <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="15" wrap="hard">$dismsg  <textarea name="message" id="message" cols="80" rows="15" wrap="hard">$dismsg
 </textarea></p><br />  </textarea></p><br />
 $dispcrit  $dispcrit
   $disbase
   <input type="hidden" name="folder" value="$folder" />
   <input type="hidden" name="dismode" value="$dismode" />
 <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);
Line 989  ENDCOMP Line 1338  ENDCOMP
 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" id="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 1009  $dispcrit Line 1358  $dispcrit
 ENDUPLOAD  ENDUPLOAD
     }      }
     if ($broadcast eq 'group') {      if ($broadcast eq 'group') {
        &discourse;         &discourse($r);
     }      }
     $r->print('</form>');      $r->print('</form>'.
         &Apache::lonfeedback::generate_preview_button('compemail','message').
         &Apache::lonhtmlcommon::htmlareaselectactive('message'));
 }  }
   
 # ---------------------------------------------------- Display all face to face  # ---------------------------------------------------- Display all face to face
   
 sub retrieve_instructor_comments {  sub retrieve_instructor_comments {
     my ($user,$domain)=@_;      my ($user,$domain)=@_;
     my $target=$ENV{'form.grade_target'};      my $target=$env{'form.grade_target'};
     if (! $ENV{'request.course.id'}) { return; }      if (! $env{'request.course.id'}) { return; }
     if (! &Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      if (! &Apache::lonnet::allowed('srm',$env{'request.course.id'})
    && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
         '/'.$env{'request.course.sec'})) {
  return;   return;
     }      }
     my %records=&Apache::lonnet::dump('nohist_email',      my %records=&Apache::lonnet::dump('nohist_email',
  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},   $env{'course.'.$env{'request.course.id'}.'.domain'},
  $ENV{'course.'.$ENV{'request.course.id'}.'.num'},   $env{'course.'.$env{'request.course.id'}.'.num'},
                          '%255b'.$user.'%253a'.$domain.'%255d');                           '%255b'.$user.'%253a'.$domain.'%255d');
     my $result='';      my $result='';
     foreach (sort(keys(%records))) {      foreach (sort(keys(%records))) {
         my %content=&unpackagemsg($records{$_});          my %content=&unpackagemsg($records{$_});
         next if ($content{'senderdomain'} eq '');          next if ($content{'senderdomain'} eq '');
         next if ($content{'subject'} !~ /^Record/);          next if ($content{'subject'} !~ /^Record/);
         # $content{'message'}=~s/\n/\<br\>/g;   # &Apache::lonfeedback::newline_to_br(\$content{'message'});
         $result.='Recorded by '.   $result.='Recorded by '.
             $content{'sendername'}.'@'.$content{'senderdomain'}."\n";              $content{'sendername'}.'@'.$content{'senderdomain'}."\n";
         $result.=          $result.=
             &Apache::lontexconvert::msgtexconverted($content{'message'})."\n";              &Apache::lontexconvert::msgtexconverted($content{'message'})."\n";
Line 1043  sub retrieve_instructor_comments { Line 1396  sub retrieve_instructor_comments {
   
 sub disfacetoface {  sub disfacetoface {
     my ($r,$user,$domain)=@_;      my ($r,$user,$domain)=@_;
     my $target=$ENV{'form.grade_target'};      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'})) {      if  (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
          '/'.$env{'request.course.sec'})) {
    $r->print('Not allowed');
  return;   return;
     }      }
     my %records=&Apache::lonnet::dump('nohist_email',      my %records=&Apache::lonnet::dump('nohist_email',
  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},   $env{'course.'.$env{'request.course.id'}.'.domain'},
  $ENV{'course.'.$ENV{'request.course.id'}.'.num'},   $env{'course.'.$env{'request.course.id'}.'.num'},
                          '%255b'.$user.'%253a'.$domain.'%255d');                           '%255b'.$user.'%253a'.$domain.'%255d');
     my $result='';      my $result='';
     foreach (sort keys %records) {      foreach (sort keys %records) {
         my %content=&unpackagemsg($records{$_});          my %content=&unpackagemsg($records{$_});
         next if ($content{'senderdomain'} eq '');          next if ($content{'senderdomain'} eq '');
         $content{'message'}=~s/\n/\<br\>/g;   &Apache::lonfeedback::newline_to_br(\$content{'message'});
         if ($content{'subject'}=~/^Record/) {          if ($content{'subject'}=~/^Record/) {
     $result.='<h3>'.&mt('Record').'</h3>';      $result.='<h3>'.&mt('Record').'</h3>';
         } elsif ($content{'subject'}=~/^Broadcast/) {          } elsif ($content{'subject'}=~/^Broadcast/) {
             $result .='<h3>'.&mt('Broadcast Message').'</h3>';              $result .='<h3>'.&mt('Broadcast Message').'</h3>';
               if ($content{'subject'}=~/^Broadcast\./) {
                   %content=&unpackagemsg($content{'message'});
                   $content{'message'}=
                       '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'.
                       $content{'message'};
               }    
         } else {          } else {
             $result.='<h3>'.&mt('Critical Message').'</h3>';              $result.='<h3>'.&mt('Critical Message').'</h3>';
             %content=&unpackagemsg($content{'message'});              %content=&unpackagemsg($content{'message'});
Line 1073  sub disfacetoface { Line 1435  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 /><pre>'.
               &Apache::lontexconvert::msgtexconverted($content{'message'}).                &Apache::lontexconvert::msgtexconverted($content{'message'}).
       '</blockquote>';        '</pre>';
      }       }
     # Check to see if there were any messages.      # Check to see if there were any messages.
     if ($result eq '') {      if ($result eq '') {
Line 1093  $content{'sendername'}.'@'. Line 1455  $content{'sendername'}.'@'.
   
 sub facetoface {  sub facetoface {
     my ($r,$stage)=@_;      my ($r,$stage)=@_;
     unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
         '/'.$env{'request.course.sec'})) {
    $r->print('Not allowed');
  return;   return;
     }      }
     &printheader($r,      &printheader($r,
Line 1101  sub facetoface { Line 1466  sub facetoface {
  "User Notes, Face-to-Face, Critical Messages, Broadcast Messages");   "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'}; }
   
     my $defdom=$ENV{'user.domain'};      my $defdom=$env{'user.domain'};
 # already filled in  # already filled in
     if ($ENV{'form.recdomain'}) { $defdom=$ENV{'form.recdomain'}; }      if ($env{'form.recdomain'}) { $defdom=$env{'form.recdomain'}; }
 # generate output  # generate output
     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
Line 1122  sub facetoface { Line 1487  sub facetoface {
 <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>$lt{'user'}:</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="$lt{'subm'}" /></td>  <input type="submit" value="$lt{'subm'}" /></td>
Line 1133  $stdbrws Line 1498  $stdbrws
 </form>  </form>
 ENDTREC  ENDTREC
     if (($stage ne 'query') &&      if (($stage ne 'query') &&
         ($ENV{'form.recdomain'}) && ($ENV{'form.recuname'})) {          ($env{'form.recdomain'}) && ($env{'form.recuname'})) {
         chomp($ENV{'form.newrecord'});          chomp($env{'form.newrecord'});
         if ($ENV{'form.newrecord'}) {          if ($env{'form.newrecord'}) {
              my $recordtxt = $env{'form.newrecord'};
            &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'},
             &mt('Record').              &mt('Record').
      ' ['.$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}.']',       ' ['.$env{'form.recuname'}.':'.$env{'form.recdomain'}.']',
     $ENV{'form.newrecord'});      $recordtxt);
         }          }
         $r->print('<h3>'.&Apache::loncommon::plainname($ENV{'form.recuname'},          $r->print('<h3>'.&Apache::loncommon::plainname($env{'form.recuname'},
      $ENV{'form.recdomain'}).'</h3>');       $env{'form.recdomain'}).'</h3>');
         &disfacetoface($r,$ENV{'form.recuname'},$ENV{'form.recdomain'});          &disfacetoface($r,$env{'form.recuname'},$env{'form.recdomain'});
  $r->print(<<ENDRHEAD);   $r->print(<<ENDRHEAD);
 <form method="post" action="/adm/email">  <form method="post" action="/adm/email">
 <input name="recdomain" value="$ENV{'form.recdomain'}" type="hidden" />  <input name="recdomain" value="$env{'form.recdomain'}" type="hidden" />
 <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 />$lt{'newr'}<br />  <hr />$lt{'newr'}<br />
Line 1166  ENDBFORM Line 1532  ENDBFORM
   
 sub examblock {  sub examblock {
     my ($r,$action) = @_;      my ($r,$action) = @_;
     unless ($ENV{'request.course.id'}) { return;}      unless ($env{'request.course.id'}) { return;}
     unless (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) { $r->print('Not allowed'); }      if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
         '/'.$env{'request.course.sec'})) {
    $r->print('Not allowed');
    return;
       }
     my %lt=&Apache::lonlocal::texthash(      my %lt=&Apache::lonlocal::texthash(
             'comb' => 'Communication Blocking',              'comb' => 'Communication Blocking',
             'cbds' => 'Communication blocking during scheduled exams',              'cbds' => 'Communication blocking during scheduled exams',
Line 1207  sub examblock { Line 1578  sub examblock {
         $r->print($lt{'ncbc'}.'<br /><br />');          $r->print($lt{'ncbc'}.'<br /><br />');
     }      }
     &display_addblocker_table($r,$parmcount,\%ltext);      &display_addblocker_table($r,$parmcount,\%ltext);
       my $endbody=&Apache::loncommon::endbodytag();
     $r->print(<<"END");      $r->print(<<"END");
 <br />  <br />
 <input type="hidden" name="blocktotal" value="$blockcount" />  <input type="hidden" name="blocktotal" value="$blockcount" />
 <input type ="submit" value="Save Changes" />  <input type ="submit" value="Save Changes" />
 </form>  </form>
 </body>  $endbody
 </html>  </html>
 END  END
     return;      return;
Line 1236  sub blockstore { Line 1608  sub blockstore {
     my $addtotal = 0;      my $addtotal = 0;
     my %blocking = ();      my %blocking = ();
     $r->print('<h3>'.$lt{'head'}.'</h3>');      $r->print('<h3>'.$lt{'head'}.'</h3>');
     foreach (keys %ENV) {      foreach (keys %env) {
         if ($_ =~ m/^form\.modify_(\w+)$/) {          if ($_ =~ m/^form\.modify_(\w+)$/) {
             $adds{$1} = $1;              $adds{$1} = $1;
             $removals{$1} = $1;              $removals{$1} = $1;
Line 1254  sub blockstore { Line 1626  sub blockstore {
     }      }
   
     foreach (keys %removals) {      foreach (keys %removals) {
         my $hashkey = $ENV{'form.key_'.$_};          my $hashkey = $env{'form.key_'.$_};
         &Apache::lonnet::del('comm_block',["$hashkey"],          &Apache::lonnet::del('comm_block',["$hashkey"],
                          $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                           $env{'course.'.$env{'request.course.id'}.'.domain'},
                          $ENV{'course.'.$ENV{'request.course.id'}.'.num'}                           $env{'course.'.$env{'request.course.id'}.'.num'}
                          );                           );
     }      }
     foreach (keys %adds) {      foreach (keys %adds) {
         unless ( defined($cancels{$_}) ) {          unless ( defined($cancels{$_}) ) {
             my ($newstart,$newend) = &get_dates_from_form($_);              my ($newstart,$newend) = &get_dates_from_form($_);
             my $newkey = $newstart.'____'.$newend;              my $newkey = $newstart.'____'.$newend;
             $blocking{$newkey} = $ENV{'user.name'}.'@'.$ENV{'user.domain'}.':'.$ENV{'form.title_'.$_};              $blocking{$newkey} = $env{'user.name'}.'@'.$env{'user.domain'}.':'.$env{'form.title_'.$_};
         }          }
     }      }
     if ($addtotal + $modtotal > 0) {      if ($addtotal + $modtotal > 0) {
         &Apache::lonnet::put('comm_block',\%blocking,          &Apache::lonnet::put('comm_block',\%blocking,
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.num'}                       $env{'course.'.$env{'request.course.id'}.'.num'}
                      );                       );
     }      }
     my $chgestotal = $canceltotal + $modtotal + $addtotal;      my $chgestotal = $canceltotal + $modtotal + $addtotal;
Line 1304  sub get_blockdates { Line 1676  sub get_blockdates {
     my ($records,$blockcount) = @_;      my ($records,$blockcount) = @_;
     $$blockcount = 0;      $$blockcount = 0;
     %{$records} = &Apache::lonnet::dump('comm_block',      %{$records} = &Apache::lonnet::dump('comm_block',
                          $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                           $env{'course.'.$env{'request.course.id'}.'.domain'},
                          $ENV{'course.'.$ENV{'request.course.id'}.'.num'}                           $env{'course.'.$env{'request.course.id'}.'.num'}
                          );                           );
     $$blockcount = keys %{$records};      $$blockcount = keys %{$records};
                                                                                                                                                                                                                             
Line 1323  sub display_blocker_status { Line 1695  sub display_blocker_status {
     my @bgcols = ("#eeeeee","#dddddd");      my @bgcols = ("#eeeeee","#dddddd");
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $color = &Apache::loncommon::designparm($function.'.tabbg',      my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'modi' => 'Modify',          'modi' => 'Modify',
         'canc' => 'Cancel',          'canc' => 'Cancel',
Line 1358  END Line 1730  END
        <tr bgcolor="$bgcols[$iter]">         <tr bgcolor="$bgcols[$iter]">
         <td>$$ltext{'star'}:&nbsp;$startform<br/>$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>          <td>$$ltext{'star'}:&nbsp;$startform<br/>$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
         <td>$settername</td>          <td>$settername</td>
         <td><input type="text" name="title_$parmcount" size="15" value="$title"/><input type="hidden" name="key_$parmcount" value="$_"></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"/>          <td><label>$lt{'modi'}?&nbsp;<input type="checkbox" name="modify_$parmcount" /></label><br /><label>$lt{'canc'}?&nbsp;&nbsp;<input type="checkbox" name="cancel_$parmcount" /></label>
        </tr>         </tr>
 END  END
         $parmcount ++;          $parmcount ++;
Line 1389  sub display_addblocker_table { Line 1761  sub display_addblocker_table {
     my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);      my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $color = &Apache::loncommon::designparm($function.'.tabbg',      my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'addb' => 'Add block',          'addb' => 'Add block',
         'exam' => 'e.g., Exam 1',          'exam' => 'e.g., Exam 1',
Line 1411  sub display_addblocker_table { Line 1783  sub display_addblocker_table {
        </tr>         </tr>
        <tr bgcolor="#eeeeee">         <tr bgcolor="#eeeeee">
         <td>$$ltext{'star'}:&nbsp;$startform<br />$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>          <td>$$ltext{'star'}:&nbsp;$startform<br />$$ltext{'endd'}:&nbsp;&nbsp;$endform</td>
         <td><input type="text" name="title_$parmcount" size="15" value=""/></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>          <td><label>$lt{'addb'}?&nbsp;<input type="checkbox" name="add_$parmcount" value="1" /></label></td>
        </tr>         </tr>
       </table>        </table>
      </td>       </td>
Line 1432  sub blockcheck { Line 1804  sub blockcheck {
     my @staffcses = ();      my @staffcses = ();
     $$startblock = 0;      $$startblock = 0;
     $$endblock = 0;      $$endblock = 0;
     foreach (keys %ENV) {      foreach (keys %env) {
         if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) {          if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) {
             my $role = $1;              my $role = $1;
             my $cse = $2;              my $cse = $2;
             $cse =~ s|/|_|;              $cse =~ s|/|_|;
             if ($ENV{$_} =~ m/^(\d*)\.(\d*)$/) {              if ($env{$_} =~ m/^(\d*)\.(\d*)$/) {
                 unless (($2 > 0 && $2 < time) || ($1 > time)) {                  unless (($2 > 0 && $2 < time) || ($1 > time)) {
                     if ($role eq 'st') {                      if ($role eq 'st') {
                         push @livecses, $cse;                          push @livecses, $cse;
Line 1449  sub blockcheck { Line 1821  sub blockcheck {
                 }                  }
             }              }
         } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) {           } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) { 
             my $rolepriv = $ENV{'user.role..rolesdef_'.$3};              my $rolepriv = $env{'user.role..rolesdef_'.$3};
         }          }
     }      }
     # Retrieve blocking times and identity of blocker for active courses for students.      # Retrieve blocking times and identity of blocker for active courses for students.
     if (@livecses > 0) {      if (@livecses > 0) {
         foreach my $cse (@livecses) {          foreach my $cse (@livecses) {
             my ($cdom,$crs) = split/_/,$cse;              my ($cdom,$crs) = split/_/,$cse;
             if ( (grep/^$cse$/,@staffcses) && ($ENV{'request.role'} !~ m-^st\./$cdom/$crs$-) ) {              if ( (grep/^$cse$/,@staffcses) && ($env{'request.role'} !~ m-^st\./$cdom/$crs$-) ) {
                 next;                  next;
             } else {              } else {
                 %{$$setters{$cse}} = ();                  %{$$setters{$cse}} = ();
Line 1487  sub build_block_table { Line 1859  sub build_block_table {
     my ($r,$startblock,$endblock,$setters) = @_;      my ($r,$startblock,$endblock,$setters) = @_;
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $color = &Apache::loncommon::designparm($function.'.tabbg',      my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'cacb' => 'Currently active communication blocks',          'cacb' => 'Currently active communication blocks',
         'cour' => 'Course',          'cour' => 'Course',
Line 1538  sub displaymessage { Line 1910  sub displaymessage {
     my $numblocked = 0;      my $numblocked = 0;
 # info to generate "next" and "previous" buttons and check if message is blocked  # info to generate "next" and "previous" buttons and check if message is blocked
     &blockcheck(\%setters,\$startblock,\$endblock);      &blockcheck(\%setters,\$startblock,\$endblock);
     my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked);      my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
     if ( $blocked{$msgid} eq 'ON' ) {      if ( $blocked{$msgid} eq 'ON' ) {
         &printheader($r,'/adm/email',&mt('Display a Message'));          &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.'));          $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);          &build_block_table($r,$startblock,$endblock,\%setters);
         return;          return;
     }      }
     &statuschange($msgid,'read');      &statuschange($msgid,'read',$folder);
     my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);      my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
     my %content=&unpackagemsg($message{$msgid});      my %content=&unpackagemsg($message{$msgid});
   
     my $counter=0;      my $counter=0;
     $r->print('<pre>');      $r->print('<pre>');
     my $escmsgid=&Apache::lonnet::escape($msgid);      my $escmsgid=&Apache::lonnet::escape($msgid);
Line 1571  sub displaymessage { Line 1944  sub displaymessage {
       '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs.        '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).$sqs.
       '"><b>'.&mt('Mark Unread').'</b></a></td>'.        '"><b>'.&mt('Mark Unread').'</b></a></td>'.
       '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs.        '<td><a href="/adm/email?markdel='.&Apache::lonnet::escape($msgid).$sqs.
       '"><b>Delete</b></a></td>'.        '"><b>'.&mt('Delete').'</b></a></td>'.
       '<td><a href="/adm/email?sortedby='.$ENV{'form.sortedby'}.        '<td><a href="/adm/email?'.$sqs.
       '"><b>'.&mt('Display all Messages').'</b></a></td>');        ($env{'form.dismode'} eq 'new'?'&folder=new':'').
         '"><b>'.&mt('Back to Folder Display').'</b></a></td>');
     if ($counter > 0){      if ($counter > 0){
  $r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.   $r->print('<td><a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.
   '"><b>'.&mt('Previous').'</b></a></td>');    '"><b>'.&mt('Previous').'</b></a></td>');
Line 1583  sub displaymessage { Line 1957  sub displaymessage {
   '"><b>'.&mt('Next').'</b></a></td>');    '"><b>'.&mt('Next').'</b></a></td>');
     }      }
     $r->print('</tr></table>');      $r->print('</tr></table>');
       if ($env{'user.adv'}) {
    $r->print('<table border="2" width="100%"><tr bgcolor="#FFAAAA"><td>'.&mt('Currently available actions (will open extra window)').':</td>');
    my $symb=&Apache::lonnet::symbread($content{'baseurl'});      
    if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
    $r->print('<td><b>'.&Apache::loncommon::track_student_link(&mt('View recent activity'),$content{'sendername'},$content{'senderdomain'},'check').'</b></td>');
       }
    if (&Apache::lonnet::allowed('opa',$env{'request.course.id'}) && $symb) {
       $r->print('<td><b>'.&Apache::loncommon::pprmlink(&mt('Set/Change parameters'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
    }
    if (&Apache::lonnet::allowed('mgr',$env{'request.course.id'}) && $symb) {
       $r->print('<td><b>'.&Apache::loncommon::pgrdlink(&mt('Set/Change grades'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
    }
    $r->print('</tr></table>');
       }
       my $tolist;
       my @recipients = ();
       for (my $i=0; $i<@{$content{'recuser'}}; $i++) {
           $recipients[$i] =  &Apache::loncommon::aboutmewrapper(
              &Apache::loncommon::plainname($content{'recuser'}[$i],
                                         $content{'recdomain'}[$i]),
                 $content{'recuser'}[$i],$content{'recdomain'}[$i]).
          ' ('.$content{'recuser'}[$i].' at '.$content{'recdomain'}[$i].') ';
       }
       $tolist = join(', ',@recipients);
     $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}.      $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'}.
       '<br /><b>'.&mt('From').':</b> '.        ($folder ne 'sent'?'<br /><b>'.&mt('From').':</b> '.
       &Apache::loncommon::aboutmewrapper(        &Apache::loncommon::aboutmewrapper(
  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),   &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
  $content{'sendername'},$content{'senderdomain'}).' ('.   $content{'sendername'},$content{'senderdomain'}).' ('.
       $content{'sendername'}.' at '.        $content{'sendername'}.' at '.
       $content{'senderdomain'}.') '.        $content{'senderdomain'}.') ':'<br /><b>'.&mt('To').':</b> '.
                 $tolist).
       ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}.        ($content{'courseid'}?'<br /><b>'.&mt('Course').':</b> '.$courseinfo{'description'}.
        ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').         ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').
       '<br /><b>'.&mt('Time').':</b> '.$content{'time'}.        '<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>'.        '<p><pre>'.
       &Apache::lontexconvert::msgtexconverted($content{'message'},1).        &Apache::lontexconvert::msgtexconverted($content{'message'},1).
       '</pre><hr />'.$content{'citation'}.'</p>');        '</pre><hr />'.&displayresource(%content).'</p>');
     return;         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  # ================================================================== The Header
   
 sub header {  sub header {
     my ($r,$title,$baseurl)=@_;      my ($r,$title,$baseurl)=@_;
     $r->print('<html><head><title>Communication and Messages</title>');      $r->print(&Apache::lonxml::xmlbegin().
         '<head>'.&Apache::lonxml::fontsettings().
         '<title>Communication and Messages</title>'.
         &Apache::lonhtmlcommon::htmlareaheaders());
     if ($baseurl) {      if ($baseurl) {
  $r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$baseurl\" />");   $r->print("<base href=\"http://$ENV{'SERVER_NAME'}/$baseurl\" />");
     }      }
Line 1624  sub printheader { Line 2062  sub printheader {
     &header($r,$title,$baseurl);      &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(&Apache::lonxml::xmlbegin().'<head>'.
         &Apache::lonxml::fontsettings().'</head><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='';
       my %specialmsg_status;
       my $numspecial = 0;
       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}='';
       }
    }
   
           my $savemsg;
           my $msgtype;
           my %sentmessage;
           if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
               (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
        || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
    '/'.$env{'request.course.sec'})
        )) {
               $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'},1);
               $msgtype = 'critical';
           } else {
               $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'});
           }
   
    foreach (keys %toaddr) {
       my ($recuname,$recdomain)=split(/\:/,$_);
               my $msgtxt = $savemsg;
       if ($toaddr{$_}) { $msgtxt.='<hr />'.$toaddr{$_}; }
       my $thismsg;
       if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) && 
    (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
        '/'.$env{'request.course.sec'}))) {
    $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'},$env{'form.permanent'},\$sentmessage{$_});
       } else {
    $r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': ');
    $thismsg=&user_normal_msg($recuname,$recdomain,
     &Apache::lonfeedback::clear_out_html($env{'form.subject'}),
     $msgtxt,
     $content{'citation'},undef,undef,$env{'form.permanent'},\$sentmessage{$_});
               }
       if (($env{'request.course.id'}) && (($msgtype eq 'critical') || 
                                            ($env{'form.sendmode'} eq 'group'))) {
           $specialmsg_status{$recuname.':'.$recdomain}  = $thismsg;
                   if ($thismsg eq 'ok') {
                       $numspecial ++;
                   }
       }
       $r->print($thismsg.'<br />');
       $sendstatus.=' '.$thismsg;
    }
           if (($env{'request.course.id'}) && (($env{'form.sendmode'} eq 'group')
                                                 || ($msgtype eq 'critical'))) {
               my $subj_prefix;
               if ($msgtype eq 'critical') {
                   $subj_prefix = 'Critical.';
               } else {
                   $subj_prefix = 'Broadcast.';
               }
               my ($specialmsgid,$specialresult);
               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               my $course_str = &Apache::lonnet::escape('['.$cnum.':'.$cdom.']');
   
               if ($numspecial) {
                   $specialresult = &user_normal_msg_raw($cnum,$cdom,$subj_prefix.
                       ' '.$course_str,$savemsg,undef,undef,undef,
                       undef,undef,\$specialmsgid);
                   $specialmsgid = &Apache::lonnet::unescape($specialmsgid);
               }
               if ($specialresult eq 'ok') {
                   my $record_sent;
                   my @recusers = ();
                   my @recudoms = ();
                   my ($stamp,$msgsubj,$msgname,$msgdom,$msgcount,$context,$pid) = 
                               split(/\:/,&Apache::lonnet::unescape($specialmsgid));
                   foreach my $recipient (sort(keys(%toaddr))) {
                       if ($specialmsg_status{$recipient} eq 'ok') {
                           my $usersubj = $subj_prefix.'['.$recipient.']';
                           my $usermsgid = &buildmsgid($stamp,$usersubj,$msgname,
                                                 $msgdom,$msgcount,$context,$pid);
                           &user_normal_msg_raw($cnum,$cdom,$subj_prefix.
                           ' ['.$recipient.']',$sentmessage{$recipient},
                           undef,undef,undef,undef,$usermsgid);
                           my ($uname,$udom) = split/:/,$recipient;
                           push(@recusers,$uname);
                           push(@recudoms,$udom);
                       }
                   }
                   if (@recusers) {
                       my $specialmessage;
                       my $sentsubj = $subj_prefix.' ('.$numspecial.' sent) '.
                       &Apache::lonfeedback::clear_out_html($env{'form.subject'});
                       $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"');
                       my $sentmsgid = &buildmsgid($stamp,$sentsubj,$msgname,
                                                 $msgdom,$msgcount,$context,$pid);
                       ($specialmsgid,$specialmessage) =
                            &packagemsg(&Apache::lonfeedback::clear_out_html(
                                $env{'form.subject'}),$savemsg,undef,undef,undef,
                                               \@recusers,\@recudoms,$sentmsgid);
                       $record_sent = &store_sent_mail($specialmsgid,$specialmessage);
                   }
               } else {
                   &Apache::lonnet::logthis('Failed to create record of critical message or broadcast in '.$env{'course.'.$env{'request.course.id'}.'.num'}.' at '.$env{'course.'.$env{'request.course.id'}.'.domain'}.' - no msgid generated');
               }
           }
       } 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
   
Line 1641  sub handler { Line 2284  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','block','folder']);           'recordftf','sortedby','block','folder','startdis','interdis',
     $sqs='&sortedby='.$ENV{'form.sortedby'};   'showcommentbaseurl','dismode']);
       $sqs='&sortedby='.$env{'form.sortedby'};
   
 # ------------------------------------------------------ They checked for email  # ------------------------------------------------------ They checked for email
     unless ($ENV{'form.block'}) {      unless ($env{'form.block'}) {
         &Apache::lonnet::put('email_status',{'recnewemail'=>0});          &Apache::lonnet::put('email_status',{'recnewemail'=>0});
     }      }
   
Line 1658  sub handler { Line 2303  sub handler {
   
 # ------------------------------------------------------------------ Get Folder  # ------------------------------------------------------------------ Get Folder
   
     my $folder=$ENV{'form.folder'};      my $folder=$env{'form.folder'};
     unless ($folder) {       unless ($folder) { 
  $folder='';    $folder=''; 
     } else {      } else {
  $sqs='&folder='.&Apache::lonnet::escape($folder);   $sqs.='&folder='.&Apache::lonnet::escape($folder);
       }
   # ------------------------------------------------------------ Get Display Mode
   
       my $dismode=$env{'form.dismode'};
       unless ($dismode) { 
    $dismode=''; 
       } else {
    $sqs.='&dismode='.&Apache::lonnet::escape($dismode);
     }      }
   
   # --------------------------------------------------------------------- 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  # --------------------------------------------------------------- Render Output
   
     if ($ENV{'form.display'}) {      if ($env{'form.display'}) {
  &displaymessage($r,$ENV{'form.display'},$folder);   &displaymessage($r,$env{'form.display'},$folder);
     } elsif ($ENV{'form.replyto'}) {      } elsif ($env{'form.replyto'}) {
  &compout($r,'',$ENV{'form.replyto'});   &compout($r,'',$env{'form.replyto'},undef,undef,$folder,$dismode);
     } elsif ($ENV{'form.confirm'}) {      } elsif ($env{'form.confirm'}) {
  &printheader($r,'','Confirmed Receipt');   &printheader($r,'','Confirmed Receipt');
  foreach (keys %ENV) {   foreach (keys %env) {
     if ($_=~/^form\.rec\_(.*)$/) {      if ($_=~/^form\.rec\_(.*)$/) {
  $r->print('<b>'.&mt('Confirming Receipt').':</b> '.   $r->print('<b>'.&mt('Confirming Receipt').':</b> '.
   &user_crit_received($1).'<br>');    &user_crit_received($1).'<br>');
Line 1686  sub handler { Line 2364  sub handler {
     }      }
  }   }
  &discrit($r);   &discrit($r);
     } elsif ($ENV{'form.critical'}) {      } elsif ($env{'form.critical'}) {
  &printheader($r,'','Displaying Critical Messages');   &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.markdel'}) {      } elsif ($env{'form.markdel'}) {
  &printheader($r,'','Deleted Message');   &printheader($r,'','Deleted Message');
  &statuschange($ENV{'form.markdel'},'deleted',$folder);   &statuschange($env{'form.markdel'},'deleted',$folder);
  &disall($r,$folder);   &Apache::loncommunicate::menu($r);
     } elsif ($ENV{'form.markedmove'}) {   &disall($r,($folder?$folder:$dismode));
       } elsif ($env{'form.markedmove'}) {
  my $total=0;   my $total=0;
  foreach (keys %ENV) {   foreach (keys %env) {
     if ($_=~/^form\.delmark_(.*)$/) {      if ($_=~/^form\.delmark_(.*)$/) {
  &movemsg(&Apache::lonnet::unescape($1),$folder,   &movemsg(&Apache::lonnet::unescape($1),$folder,
  $ENV{'form.movetofolder'});   $env{'form.movetofolder'});
  $total++;   $total++;
     }      }
  }   }
  &printheader($r,'','Moved Messages');   &printheader($r,'','Moved Messages');
  $r->print('Moved '.$total.' message(s)<p>');   $r->print('Moved '.$total.' message(s)<p>');
  &disall($r,$folder);   &Apache::loncommunicate::menu($r);
     } elsif ($ENV{'form.markeddel'}) {   &disall($r,($folder?$folder:$dismode));
       } 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');   &printheader($r,'','Deleted Messages');
  $r->print('Deleted '.$total.' message(s)<p>');   $r->print('Deleted '.$total.' message(s)<p>');
  &disall($r,$folder);   &Apache::loncommunicate::menu($r);
     } elsif ($ENV{'form.markunread'}) {   &disall($r,($folder?$folder:$dismode));
       } elsif ($env{'form.markunread'}) {
  &printheader($r,'','Marked Message as Unread');   &printheader($r,'','Marked Message as Unread');
  &statuschange($ENV{'form.markunread'},'new');   &statuschange($env{'form.markunread'},'new');
  &disall($r,$folder);   &Apache::loncommunicate::menu($r);
     } elsif ($ENV{'form.compose'}) {   &disall($r,($folder?$folder:$dismode));
  &compout($r,'','',$ENV{'form.compose'});      } elsif ($env{'form.compose'}) {
     } elsif ($ENV{'form.recordftf'}) {   &compout($r,'','',$env{'form.compose'});
  &facetoface($r,$ENV{'form.recordftf'});      } elsif ($env{'form.recordftf'}) {
     } elsif ($ENV{'form.block'}) {   &facetoface($r,$env{'form.recordftf'});
         &examblock($r,$ENV{'form.block'});      } elsif ($env{'form.block'}) {
     } elsif ($ENV{'form.sendmail'}) {          &examblock($r,$env{'form.block'});
  my $sendstatus='';      } elsif ($env{'form.sendmail'}) {
  if ($ENV{'form.send'}) {   &sendoffmail($r,$folder);
     &printheader($r,'','Messages being sent.');   if ($env{'form.storebasecomment'}) {
     $r->rflush();      &storecomment($r);
     my %content=();  
     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'};  
     }  
     if ($ENV{'form.replyid'}) {  
  my $msgid=$ENV{'form.replyid'};  
  my %message=&Apache::lonnet::get('nohist_email',[$msgid]);  
  %content=&unpackagemsg($message{$msgid},1);  
  &statuschange($msgid,'replied');  
     }  
     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{$_}; }  
  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*)*$/) {   if (($env{'form.rsspost'}) && ($env{'request.course.id'})) {
     $r->print('<br /><font color="green">'.&mt('Completed.').'</font>');      &Apache::lonrss::addentry($env{'course.'.$env{'request.course.id'}.'.num'},
     if ($ENV{'form.displayedcrit'}) {        $env{'course.'.$env{'request.course.id'}.'.domain'},
  &discrit($r);        'Course_Announcements',
     } else {        $env{'form.subject'},
  &Apache::loncommunicate::menu($r);        $env{'form.message'},'/adm/communicate','public');
     }  
  } 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')  
       );  
  }   }
     } elsif ($ENV{'form.newfolder'}) {   &disall($r,($folder?$folder:$dismode));
       } elsif ($env{'form.newfolder'}) {
  &printheader($r,'','New Folder');   &printheader($r,'','New Folder');
  &makefolder($ENV{'form.newfolder'});   &makefolder($env{'form.newfolder'});
  &disall($r,$ENV{'form.newfolder'});   &Apache::loncommunicate::menu($r);
    &disall($r,$env{'form.newfolder'});
       } elsif ($env{'form.showcommentbaseurl'}) {
    &storedcommentlisting($r);
     } else {      } else {
  &printheader($r,'','Display All Messages');   &printheader($r,'','Display All Messages');
  &disall($r,$folder);   &Apache::loncommunicate::menu($r); 
    &disall($r,($folder?$folder:$dismode));
     }      }
     $r->print('</body></html>');      $r->print(&Apache::loncommon::endbodytag().'</html>');
     return OK;      return OK;
 }  }
 # ================================================= Main program, reset counter  # ================================================= Main program, reset counter

Removed from v.1.106  
changed lines
  Added in v.1.170


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