Diff for /loncom/interface/lonmsg.pm between versions 1.195 and 1.226

version 1.195, 2006/12/28 19:43:24 version 1.226, 2010/05/29 22:39:52
Line 28 Line 28
   
 package Apache::lonmsg;  package Apache::lonmsg;
   
   =pod
   
   =head1 NAME
   
   Apache::lonmsg: supports internal messaging
   
   =head1 SYNOPSIS
   
   lonmsg provides routines for sending messages.
   
   Right now, this document will cover just how to send a message, since
   it is likely you will not need to programmatically read messages,
   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 SUBROUTINES
   
   =over
   
   =pod
   
   =item packagemsg()
   
   Package
   
   =item get_course_context()
   
   =item unpackagemsg()
   
   Unpack message into a hash
   
   =item buildmsgid()
   
   Get info out of msgid
   
   =item unpackmsgid()
   
   =item sendemail()
   
   =item sendnotification()
   
   Send notification emails
   
   =item newmail()
   
   Check for email
   
   =item author_res_msg()
   
   Automated message to the author of a resource
   
   =item * B<author_res_msg($filename, $message)>: Sends message $message to the owner
       of the resource with the URI $filename.
   
   =item retrieve_author_res_msg()
   
   Retrieve author resource messages
   
   =item del_url_author_res_msg()
   
   Delete all author messages related to one URL
   
   =item clear_author_res_msg()
   
   Clear out all author messages in URL path
   
   =item all_url_author_res_msg()
   
   Return hash with URLs for which there is a resource message
   
   =item store_instructor_comment()
   
   Add a comment to the User Notes screen
   
   =item user_crit_msg_raw()
   
   Critical message to a user
   
   =item user_crit_msg()
   
   New routine that respects "forward" and calls old routine
   
   =item * B<user_crit_msg($user, $domain, $subject, $message, $sendback, $nosentstore,$recipid,$attachmenturl)>: 
       Sends a critical message $message to the $user at $domain.  If $sendback
       is true,  a receipt will be sent to the current user when $user receives 
       the message.
   
       Additionally it will check if the user has a Forwarding address
       set, and send the message to that address instead
   
       returns 
         - in array context a list of results for each message that was sent
         - in scalar context a space seperated list of results for each 
              message sent
   
   
   =item user_crit_received()
   
   Critical message received
   
   =item user_normal_msg_raw()
   
   Normal communication
   
   =item user_normal_msg()
   
   New routine that respects "forward" and calls old routine
   
   =item * B<user_normal_msg($user, $domain, $subject, $message, $citation,
          $baseurl, $attachmenturl, $toperm, $sentmessage, $symb, $restitle,
          $error,$nosentstore,$recipid)>:
    Sends a message to the  $user at $domain, with subject $subject and message $message.
   
       Additionally it will check if the user has a Forwarding address
       set, and send the message to that address instead
   
       returns
         - in array context a list of results for each message that was sent
         - in scalar context a space seperated list of results for each
              message sent
   
   =item store_sent_mail()
   
   =item store_recipients()
   
   =item foldersuffix()
   
   =item get_user_folders()
   
   User-defined folders 
   
   =item secapply()
   
   =item B<decide_receiver($feedurl,$author,$question,$course,$policy,$defaultflag)>:
   
   Arguments
     $feedurl - /res/ url of resource (only need if $author is true)
     $author,$question,$course,$policy - all true/false parameters
       if true will attempt to find the addresses of user that should receive
       this type of feedback (author - feedback to author of resource $feedurl,
       $question 'Resource Content Questions', $course 'Course Content Question',
       $policy 'Course Policy')
       (Additionally it also checks $env for whether the corresponding form.<name>
       element exists, for ease of use in a html response context)
      
     $defaultflag - (internal should be left blank) if true gather addresses 
                    that aren't for a section even if I have a section
                    (used for reccursion internally, first we look for
                    addresses for our specific section then we recurse
                    and look for non section addresses)
   
   Returns
     $typestyle - string of html text, describing what addresses were found
     %to - a hash, which keys are addresses of users to send messages to
           the keys will look like   name:domain
   
   =back
   
   =cut
   
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use HTML::TokeParser();  use HTML::TokeParser();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Mail::Send;  use Mail::Send;
   use HTML::Entities;
   use Encode;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
 {  {
Line 43  use LONCAPA qw(:DEFAULT :match); Line 215  use LONCAPA qw(:DEFAULT :match);
     }      }
 }  }
   
 # ===================================================================== Package  
   
 sub packagemsg {  sub packagemsg {
     my ($subject,$message,$citation,$baseurl,$attachmenturl,      my ($subject,$message,$citation,$baseurl,$attachmenturl,
  $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error)=@_;   $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error,$recipid)=@_;
     $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,'<>&"');
     #remove machine specification      #remove machine specification
     $baseurl =~ s|^http://[^/]+/|/|;      $baseurl =~ s|^https?://[^/]+/|/|;
     $baseurl =&HTML::Entities::encode($baseurl,'<>&"');      $baseurl =&HTML::Entities::encode($baseurl,'<>&"');
     #remove machine specification      #remove machine specification
     $attachmenturl =~ s|^http://[^/]+/|/|;      $attachmenturl =~ s|^https?://[^/]+/|/|;
     $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');      $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
     my $course_context;      my $course_context = &get_course_context();
     if (defined($env{'form.replyid'})) {  
         my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=  
                    split(/\:/,&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(/\:/,&unescape($2));  
             $course_context = $origcid;  
             last;  
         }  
     }  
     unless(defined($course_context)) {  
         $course_context = $env{'request.course.id'};  
     }  
     my $now=time;      my $now=time;
     my $msgcount = &get_uniq();      my $msgcount = &get_uniq();
     unless(defined($msgid)) {      unless(defined($msgid)) {
Line 105  sub packagemsg { Line 261  sub packagemsg {
    '<role>'.$env{'request.role'}.'</role>'.     '<role>'.$env{'request.role'}.'</role>'.
    '<resource>'.$env{'request.filename'}.'</resource>'.     '<resource>'.$env{'request.filename'}.'</resource>'.
            '<msgid>'.$msgid.'</msgid>';             '<msgid>'.$msgid.'</msgid>';
       if (defined($env{'form.group'})) {
           $result .= '<group>'.$env{'form.group'}.'</group>';
       }
     if (ref($recuser) eq 'ARRAY') {      if (ref($recuser) eq 'ARRAY') {
         for (my $i=0; $i<@{$recuser}; $i++) {          for (my $i=0; $i<@{$recuser}; $i++) {
             if ($type eq 'dcmail') {              if ($type eq 'dcmail') {
Line 136  sub packagemsg { Line 295  sub packagemsg {
     }      }
     if (defined($symb)) {      if (defined($symb)) {
         $result.= '<symb>'.$symb.'</symb>';          $result.= '<symb>'.$symb.'</symb>';
         if (defined($course_context)) {          if ($course_context ne '') {
             if ($course_context eq $env{'request.course.id'}) {              if ($course_context eq $env{'request.course.id'}) {
                 my $resource_title = &Apache::lonnet::gettitle($symb);                  my $resource_title = &Apache::lonnet::gettitle($symb);
                 if (defined($resource_title)) {                  if (defined($resource_title)) {
Line 145  sub packagemsg { Line 304  sub packagemsg {
             }              }
         }          }
     }      }
       if (defined($recipid)) {
           $result.= '<recipid>'.$recipid.'</recipid>';
       }
       if ($env{'form.can_reply'} eq 'N') {
           $result .= '<noreplies>1</noreplies>';
       }
       if ($env{'form.reply_to_addr'}) {
           my ($replytoname,$replytodom) = split(/:/,$env{'form.reply_to_addr'});
           if (!($replytoname eq $env{'user.name'} && $replytodom eq $env{'user.domain'})) {
               if (&Apache::lonnet::homeserver($replytoname,$replytodom) ne 'no_host') {
                   $result .= '<replytoaddr>'.$env{'form.reply_to_addr'}.'</replytoaddr>';
               }
           }
       }
     return ($msgid,$result);      return ($msgid,$result);
 }  }
   
 # ================================================== Unpack message into a hash  sub get_course_context {
       my $course_context;
       my $msgkey;
       if (defined($env{'form.replyid'})) {
           $msgkey = $env{'form.replyid'};
       } elsif (defined($env{'form.forwid'})) {
           $msgkey = $env{'form.forwid'}
       } elsif (defined($env{'form.multiforwid'})) {
           $msgkey = $env{'form.multiforwid'};
       }
       if ($msgkey ne '') {
           my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
                      split(/\:/,&unescape($msgkey));
           $course_context = $origcid;
       }
       foreach my $key (keys(%env)) {
           if ($key=~/^form\.(rep)?rec\_(.*)$/) {
               my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) =
                                       split(/\:/,&unescape($2));
               $course_context = $origcid;
               last;
           }
       }
       if ($course_context eq '') {
           $course_context = $env{'request.course.id'};
       }
       return $course_context;
   }
   
   
 sub unpackagemsg {  sub unpackagemsg {
     my ($message,$notoken)=@_;      my ($message,$notoken,$noattachmentlink)=@_;
     my %content=();      my %content=();
     my $parser=HTML::TokeParser->new(\$message);      my $parser=HTML::TokeParser->new(\$message);
     my $token;      my $token;
Line 171  sub unpackagemsg { Line 372  sub unpackagemsg {
        }         }
     }      }
     if (!exists($content{'recuser'})) { $content{'recuser'} = []; }      if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
     if ($content{'attachmenturl'}) {      if (($content{'attachmenturl'}) && (!$noattachmentlink)) {
        my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);         my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
        if ($notoken) {         if ($notoken) {
    $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'</tt>';     $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'</tt>';
Line 186  sub unpackagemsg { Line 387  sub unpackagemsg {
     return %content;      return %content;
 }  }
   
 # ======================================================= Get info out of msgid  
   
 sub buildmsgid {  sub buildmsgid {
     my ($now,$subject,$uname,$udom,$msgcount,$course_context,$symb,$error,$pid) = @_;      my ($now,$subject,$uname,$udom,$msgcount,$course_context,$symb,$error,$pid) = @_;
Line 221  sub unpackmsgid { Line 421  sub unpackmsgid {
   
   
 sub sendemail {  sub sendemail {
     my ($to,$subject,$body)=@_;      my ($to,$subject,$body,$to_uname,$to_udom,$user_lh)=@_;
     my %senderemails=&Apache::loncommon::getemails();  
     my $senderaddress='';      my $senderaddress='';
     foreach my $type ('notification','permanentemail','critnotification') {      my $replytoaddress='';
  if ($senderemails{$type}) {      if ($env{'form.can_reply'} eq 'N') {
     $senderaddress=$senderemails{$type};          my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
  }          my $hostname = &Apache::lonnet::hostname($lonhost);
           $replytoaddress = 'do-not-reply@'.$hostname;
       } else {
           my %senderemails;
           my $have_sender;
           if ($env{'form.reply_to_addr'}) {
               my ($replytoname,$replytodom) = split(/:/,$env{'form.reply_to_addr'});
               if (!($replytoname eq $env{'user.name'} && $replytodom eq $env{'user.domain'})) {
                   if (&Apache::lonnet::homeserver($replytoname,$replytodom) ne 'no_host') {
                       %senderemails = 
                           &Apache::loncommon::getemails($replytoname,$replytodom);
                       $have_sender = 1;
                   }
               }
           }
           if (!$have_sender) {
               %senderemails=&Apache::loncommon::getemails();
           }
           foreach my $type ('permanentemail','critnotification','notification') {
               if ($senderemails{$type}) {
                   ($senderaddress) = split(/,/,$senderemails{$type});
                   last if ($senderaddress);
               }
           }
     }      }
     $body=      $body=
     "*** ".&mt('This is an automatic message generated by the LON-CAPA system.')."\n".      "*** ".&mt_user($user_lh,'This is an automatic e-mail generated by the LON-CAPA system.')."\n".
     "*** ".($senderaddress?&mt('You can reply to this message'):&mt('Please do not reply to this address.')."\n*** ".      "*** ".($senderaddress?&mt_user($user_lh,'You can reply to this e-mail'):&mt_user($user_lh,'Please do not reply to this address.')."\n*** ".
     &mt('A reply will not be received by the recipient!'))."\n\n".$body;      &mt_user($user_lh,'A reply will not be received by the recipient!'))."\n\n".$body;
       
     my $msg = new Mail::Send;      my $msg = new Mail::Send;
     $msg->to($to);      $msg->to($to);
     $msg->subject('[LON-CAPA] '.$subject);      $msg->subject('[LON-CAPA] '.$subject);
     if ($senderaddress) { $msg->add('Reply-to',$senderaddress); $msg->add('From',$senderaddress); }      if ($replytoaddress) {
           $msg->add('Reply-to',$replytoaddress);
       }
       if ($senderaddress) {
           $msg->add('From',$senderaddress);
       }
     if (my $fh = $msg->open()) {      if (my $fh = $msg->open()) {
  print $fh $body;   print $fh $body;
  $fh->close;   $fh->close;
Line 249  sub sendnotification { Line 477  sub sendnotification {
     my ($to,$touname,$toudom,$subj,$crit,$text,$msgid)=@_;      my ($to,$touname,$toudom,$subj,$crit,$text,$msgid)=@_;
     my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'};      my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'};
     unless ($sender=~/\w/) {       unless ($sender=~/\w/) { 
  $sender=$env{'user.name'}.'@'.$env{'user.domain'};   $sender=$env{'user.name'}.':'.$env{'user.domain'};
     }      }
     my $critical=($crit?' critical':'');      my $critical=($crit?' critical':'');
   
     $text=~s/\&lt\;/\</gs;      $text=~s/\&lt\;/\</gs;
     $text=~s/\&gt\;/\>/gs;      $text=~s/\&gt\;/\>/gs;
     $text=~s/\<\/*[^\>]+\>//gs;      my $homeserver = &Apache::lonnet::homeserver($touname,$toudom);
     my $url='http://'.      my $protocol = $Apache::lonnet::protocol{$homeserver};
       $Apache::lonnet::hostname{&Apache::lonnet::homeserver($touname,$toudom)}.      $protocol = 'http' if ($protocol ne 'https');
       '/adm/email?username='.$touname.'&domain='.$toudom;      my $url = $protocol.'://'.&Apache::lonnet::hostname($homeserver).
                 '/adm/email?username='.$touname.'&domain='.$toudom.
                 '&display='.&escape($msgid);
     my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,      my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,
         $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid);          $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid);
     my $coursetext;      my ($coursetext,$body,$bodybegin,$bodysubj,$bodyend);
       my $user_lh = &Apache::loncommon::user_lang($touname,$toudom,$fromcid);
     if ($fromcid ne '') {      if ($fromcid ne '') {
         $coursetext = "\n".&mt('Course').': ';          $coursetext = "\n".&mt_user($user_lh,'Course').': ';
         if ($env{'course.'.$fromcid.'.description'} ne '') {          if ($env{'course.'.$fromcid.'.description'} ne '') {
             $coursetext .= $env{'course.'.$fromcid.'.description'};              $coursetext .= $env{'course.'.$fromcid.'.description'};
         } else {          } else {
Line 273  sub sendnotification { Line 505  sub sendnotification {
         }          }
         $coursetext .= "\n\n";          $coursetext .= "\n\n";
     }      }
     my $body = $coursetext.       my @recipients = split(/,/,$to);
                &mt('You received a'.$critical.' message from [_1] in LON-CAPA.',$sender).' '.&mt('The subject is       $bodybegin = $coursetext. 
                  &mt_user($user_lh,
                            'You received a'.$critical.' message from [_1] in LON-CAPA.',$sender).' ';
       $bodysubj = &mt_user($user_lh,'The subject is 
   
  [_1]   [_1]
   
 ',$subj)."\n".  ',$subj)."\n".
 '=== '.&mt('Excerpt')." ============================================================  '=== '.&mt_user($user_lh,'Excerpt')." ============================================================
 $text  ";
       $bodyend = "
 ========================================================================  ========================================================================
   
 ".&mt('Use   ".&mt_user($user_lh,'Use 
   
  [_1]   [_1]
   
 to access the full message.',$url);  to access the full message.',$url);
     &sendemail($to,'New'.$critical.' message from '.$sender,$body);      my %userenv = &Apache::lonnet::get('environment',['notifywithhtml'],$toudom,$touname);
       my $subject = &mt_user($user_lh,"'New' $critical message from ").$sender;
    
       my ($blocked,$blocktext);
       if (!$crit) {
           my %setters;
           my ($startblock,$endblock) = 
               &Apache::loncommon::blockcheck(\%setters,'com',$touname,$toudom);
           if ($startblock && $endblock) {
               $blocked = 1;
               my $showstart = &Apache::lonlocal::locallocaltime($startblock);
               my $showend = &Apache::lonlocal::locallocaltime($endblock);
               $blocktext = &mt_user($user_lh,'LON-CAPA messages sent to you between [_1] and [_2] will be inaccessible until the end of this time period, because you are a student in a course with an active communications block.',$showstart,$showend);
           }
       }
       if ($userenv{'notifywithhtml'} ne '') {
           my @htmlexcerpt = split(/,/,$userenv{'notifywithhtml'});
           my $htmlfree = &make_htmlfree($text);
           foreach my $addr (@recipients) {
               if ($blocked) {
                   $body = $bodybegin."\n".$blocktext."\n".$bodyend;
               } else {
                   my $sendtext;
                   if (!grep/^\Q$addr\E/,@htmlexcerpt) {
                       $sendtext = &htmlfree;
                   } else {
                       $sendtext = $text;
                   }
                   $body = $bodybegin.$bodysubj.$sendtext.$bodyend;
               }
               &sendemail($addr,$subject,$body,$touname,$toudom,$user_lh);
           }
       } else {
           if ($blocked) {
               $body = $bodybegin."\n".$blocktext."\n".$bodyend;
           } else {
               my $htmlfree = &make_htmlfree($text);
               $body = $bodybegin.$bodysubj.$htmlfree.$bodyend;
           }
           &sendemail($to,$subject,$body,$touname,$toudom,$user_lh);
       }
 }  }
 # ============================================================= Check for email  
   sub make_htmlfree {
       my ($text) = @_;
       $text =~ s/\<\/*[^\>]+\>//gs;
       $text = &HTML::Entities::decode($text);
       $text = &Encode::encode('utf8',$text);
       return $text;
   }
   
   sub mynewmail{
    &newmail();
    return $env{'user.mailcheck.lastnewmassagetime'} > $env{'user.mailcheck.lastvisit'};
   }
   
   
 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});
    &Apache::lonnet::appenv({'user.mailcheck.lastnewmassagetime'=> $what{'recnewemail'}});
         if ($what{'recnewemail'}>0) { return 1; }          if ($what{'recnewemail'}>0) { return 1; }
     }      }
     return 0;      return 0;
 }  }
   
 # =============================== Automated message to the author of a resource  
   
 =pod  
   
 =item * B<author_res_msg($filename, $message)>: Sends message $message to the owner  
     of the resource with the URI $filename.  
   
 =cut  
   
 sub author_res_msg {  sub author_res_msg {
     my ($filename,$message)=@_;      my ($filename,$message)=@_;
Line 330  sub author_res_msg { Line 613  sub author_res_msg {
     return 'no_host';      return 'no_host';
 }  }
   
 # =========================================== Retrieve author resource messages  
   
 sub retrieve_author_res_msg {  sub retrieve_author_res_msg {
     my $url=shift;      my $url=shift;
Line 350  sub retrieve_author_res_msg { Line 633  sub retrieve_author_res_msg {
 }  }
   
   
 # =============================== Delete all author messages related to one URL  
   
   
 sub del_url_author_res_msg {  sub del_url_author_res_msg {
     my $url=shift;      my $url=shift;
Line 364  sub del_url_author_res_msg { Line 648  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 {  sub clear_author_res_msg {
     my $url=shift;      my $url=shift;
Line 378  sub clear_author_res_msg { Line 662  sub clear_author_res_msg {
     }      }
     return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);      return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
 }  }
 # ================= Return hash with URLs for which there is a resource message  
   
   
 sub all_url_author_res_msg {  sub all_url_author_res_msg {
     my ($author,$domain)=@_;      my ($author,$domain)=@_;
Line 390  sub all_url_author_res_msg { Line 675  sub all_url_author_res_msg {
     return %returnhash;      return %returnhash;
 }  }
   
 # ====================================== Add a comment to the User Notes screen  
   
 sub store_instructor_comment {  sub store_instructor_comment {
     my ($msg,$uname,$udom) = @_;      my ($msg,$uname,$udom) = @_;
Line 399  sub store_instructor_comment { Line 683  sub store_instructor_comment {
     my $cdom = $env{'course.'.$cid.'.domain'};      my $cdom = $env{'course.'.$cid.'.domain'};
     my $subject= &mt('Record').' ['.$uname.':'.$udom.']';      my $subject= &mt('Record').' ['.$uname.':'.$udom.']';
     my $result = &user_normal_msg_raw($cnum,$cdom,$subject,$msg);      my $result = &user_normal_msg_raw($cnum,$cdom,$subject,$msg);
       if ($result eq 'ok' || $result eq 'con_delayed') {
           
       }
     return $result;      return $result;
 }  }
   
 # ================================================== Critical message to a user  
   
 sub user_crit_msg_raw {  sub user_crit_msg_raw {
     my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;      my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage,
           $nosentstore,$recipid,$attachmenturl)=@_;
 # Check if allowed missing  # Check if allowed missing
     my ($status,$packed_message);      my ($status,$packed_message);
     my $msgid='undefined';      my $msgid='undefined';
Line 413  sub user_crit_msg_raw { Line 700  sub user_crit_msg_raw {
     my $text=$message;      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,$packed_message)=&packagemsg($subject,$message);         ($msgid,$packed_message)=&packagemsg($subject,$message,undef,undef,
                                     $attachmenturl,undef,undef,undef,undef,undef,
                                     undef,undef,$recipid);
        if ($sendback) { $packed_message.='<sendback>true</sendback>'; }         if ($sendback) { $packed_message.='<sendback>true</sendback>'; }
        $status=&Apache::lonnet::critical(         $status=&Apache::lonnet::cput('critical', {$msgid => $packed_message},
            'put:'.$domain.':'.$user.':critical:'.       $domain,$user);
            &escape($msgid).'='.  
            &escape($packed_message),$homeserver);  
         if (defined($sentmessage)) {          if (defined($sentmessage)) {
             $$sentmessage = $packed_message;              $$sentmessage = $packed_message;
         }          }
         if ($env{'request.course.id'} eq '') {          if (!$nosentstore) {
             (undef,my $packed_message_no_citation) =              (undef,my $packed_message_no_citation) =
             &packagemsg($subject,$message,undef,undef,undef,$user,$domain,              &packagemsg($subject,$message,undef,undef,$attachmenturl,$user,
                         $msgid);                          $domain,$msgid);
             if ($status eq 'ok' || $status eq 'con_delayed') {              if ($status eq 'ok' || $status eq 'con_delayed') {
                 &store_sent_mail($msgid,$packed_message_no_citation);                  &store_sent_mail($msgid,$packed_message_no_citation);
             }              }
Line 455  sub user_crit_msg_raw { Line 742  sub user_crit_msg_raw {
     return $status;      return $status;
 }  }
   
 # New routine that respects "forward" and calls old routine  
   
 =pod  
   
 =item * B<user_crit_msg($user, $domain, $subject, $message, $sendback)>: Sends  
     a critical message $message to the $user at $domain. If $sendback is true,  
     a reciept will be sent to the current user when $user recieves the message.  
   
     Additionally it will check if the user has a Forwarding address  
     set, and send the message to that address instead  
   
     returns   
       - in array context a list of results for each message that was sent  
       - in scalar context a space seperated list of results for each   
            message sent  
   
 =cut  
   
 sub user_crit_msg {  sub user_crit_msg {
     my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;      my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage,
           $nosentstore,$recipid,$attachmenturl)=@_;
     my @status;      my @status;
     my %userenv = &Apache::lonnet::get('environment',['msgforward'],      my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                                        $domain,$user);                                         $domain,$user);
Line 484  sub user_crit_msg { Line 756  sub user_crit_msg {
  my ($forwuser,$forwdomain)=split(/\:/,$addr);   my ($forwuser,$forwdomain)=split(/\:/,$addr);
          push(@status,           push(@status,
       &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,        &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,
  $sendback,$toperm,$sentmessage));   $sendback,$toperm,$sentmessage,$nosentstore,
                                    $recipid,$attachmenturl));
        }         }
     } else {       } else { 
  push(@status,   push(@status,
      &user_crit_msg_raw($user,$domain,$subject,$message,$sendback,       &user_crit_msg_raw($user,$domain,$subject,$message,$sendback,
  $toperm,$sentmessage));   $toperm,$sentmessage,$nosentstore,$recipid,
                                   $attachmenturl));
     }      }
     if (wantarray) {      if (wantarray) {
  return @status;   return @status;
Line 497  sub user_crit_msg { Line 771  sub user_crit_msg {
     return join(' ',@status);      return join(' ',@status);
 }  }
   
 # =================================================== Critical message received  
   
 sub user_crit_received {  sub user_crit_received {
     my $msgid=shift;      my $msgid=shift;
     my %message=&Apache::lonnet::get('critical',[$msgid]);      my %message=&Apache::lonnet::get('critical',[$msgid]);
     my %contents=&unpackagemsg($message{$msgid},1);      my %contents=&unpackagemsg($message{$msgid},1);
       my $destname = $contents{'sendername'};
       my $destdom = $contents{'senderdomain'};
       if ($contents{'replytoaddr'}) {
           my ($repname,$repdom) = split(/:/,$contents{'replytoaddr'});
           if (&Apache::lonnet::homeserver($repname,$repdom) ne 'no_host') {
               $destname = $repname;
               $destdom = $repdom;    
           }
       }
     my $status='rec: '.($contents{'sendback'}?      my $status='rec: '.($contents{'sendback'}?
      &user_normal_msg($contents{'sendername'},$contents{'senderdomain'},       &user_normal_msg($destname,$destdom,&mt('Receipt').': '.$env{'user.name'}.
                      &mt('Receipt').': '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.', '.$contents{'subject'},                        ' '.&mt('at').' '.$env{'user.domain'}.', '.
                      &mt('User').' '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.                        $contents{'subject'},&mt('User').' '.$env{'user.name'}.
                      ' acknowledged receipt of message'."\n".'   "'.                        ' '.&mt('at').' '.$env{'user.domain'}.
                      $contents{'subject'}.'"'."\n".&mt('dated').' '.                        ' acknowledged receipt of message'."\n".'   "'.
                      $contents{'time'}.".\n"                        $contents{'subject'}.'"'."\n".&mt('dated').' '.
                      ):'no msg req');                        $contents{'time'}.".\n"
                         ):'no msg req');
     $status.=' trans: '.      $status.=' trans: '.
      &Apache::lonnet::put(       &Apache::lonnet::put(
      'nohist_email',{$contents{'msgid'} => $message{$msgid}});       'nohist_email',{$contents{'msgid'} => $message{$msgid}});
Line 523  sub user_crit_received { Line 806  sub user_crit_received {
     return $status;      return $status;
 }  }
   
 # ======================================================== 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,$crsmsgid,$symb,$restitle,          $toperm,$currid,$newid,$sentmessage,$crsmsgid,$symb,$restitle,
         $error)=@_;          $error,$nosentstore,$recipid)=@_;
 # Check if allowed missing  # Check if allowed missing
     my ($status,$packed_message);      my ($status,$packed_message);
     my $msgid='undefined';      my $msgid='undefined';
Line 539  sub user_normal_msg_raw { Line 823  sub user_normal_msg_raw {
        ($msgid,$packed_message)=         ($msgid,$packed_message)=
                  &packagemsg($subject,$message,$citation,$baseurl,                   &packagemsg($subject,$message,$citation,$baseurl,
                                      $attachmenturl,$user,$domain,$currid,                                       $attachmenturl,$user,$domain,$currid,
                                      undef,$crsmsgid,$symb,$error);                                       undef,$crsmsgid,$symb,$error,$recipid);
   
 # Store in user folder  # Store in user folder
        $status=&Apache::lonnet::critical(         $status=
            'put:'.$domain.':'.$user.':nohist_email:'.     &Apache::lonnet::cput('nohist_email',{$msgid => $packed_message},
            &escape($msgid).'='.   $domain,$user);
            &escape($packed_message),$homeserver);  
 # Save new message received time  # 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  # Into sent-mail folder if sent mail storage required
        unless (($env{'request.course.id'}) &&          if (!$nosentstore) {
                (($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'})))) {  
            (undef,my $packed_message_no_citation) =             (undef,my $packed_message_no_citation) =
                &packagemsg($subject,$message,undef,$baseurl,$attachmenturl,                 &packagemsg($subject,$message,undef,$baseurl,$attachmenturl,
                            $user,$domain,$currid,undef,$crsmsgid,$symb,$error);                             $user,$domain,$currid,undef,$crsmsgid,$symb,$error);
Line 563  sub user_normal_msg_raw { Line 841  sub user_normal_msg_raw {
                &store_sent_mail($msgid,$packed_message_no_citation);                 &store_sent_mail($msgid,$packed_message_no_citation);
            }             }
        }         }
     } else {         if (ref($newid) eq 'SCALAR') {
        $status='no_host';     $$newid = $msgid;
     }         }
     if (defined($newid)) {         if (ref($sentmessage) eq 'SCALAR') {
         $$newid = $msgid;     $$sentmessage = $packed_message;
     }         }
     if (defined($sentmessage)) {  
         $$sentmessage = $packed_message;  
     }  
   
 # Notifications  # Notifications
     my %userenv = &Apache::lonnet::get('environment',['notification',         my %userenv = &Apache::loncommon::getemails($user,$domain);
                                                       'permanentemail'],         if ($userenv{'notification'}) {
                                        $domain,$user);     &sendnotification($userenv{'notification'},$user,$domain,$subject,0,
     if ($userenv{'notification'}) {       $text,$msgid);
  &sendnotification($userenv{'notification'},$user,$domain,$subject,0,         }
   $text,$msgid);         if ($toperm && $userenv{'permanentemail'}) {
     }             if ((!$userenv{'notification'}) || ($userenv{'notification'} ne $userenv{'permanentemail'})) {
     if ($toperm && $userenv{'permanentemail'}) {         &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,0,
  &sendnotification($userenv{'permanentemail'},$user,$domain,$subject,0,             $text,$msgid);
   $text,$msgid);             }
     }         }
     &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);
      } else {
          $status='no_host';
      }
     return $status;      return $status;
 }  }
   
 # New routine that respects "forward" and calls old routine  
   
 =pod  
   
 =item * B<user_normal_msg($user, $domain, $subject, $message, $citation,  
        $baseurl, $attachmenturl, $toperm, $sentmessage, $symb, $restitle, $error)>:  
  Sends a message to the  $user at $domain, with subject $subject and message $message.  
   
 =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,$symb,$restitle,$error)=@_;   $toperm,$sentmessage,$symb,$restitle,$error,$nosentstore,$recipid)=@_;
     my $status='';      my @status;
     my %userenv = &Apache::lonnet::get('environment',['msgforward'],      my %userenv = &Apache::lonnet::get('environment',['msgforward'],
                                        $domain,$user);                                         $domain,$user);
     my $msgforward=$userenv{'msgforward'};      my $msgforward=$userenv{'msgforward'};
     if ($msgforward) {      if ($msgforward) {
         foreach (split(/\,/,$msgforward)) {          foreach (split(/\,/,$msgforward)) {
     my ($forwuser,$forwdomain)=split(/\:/,$_);      my ($forwuser,$forwdomain)=split(/\:/,$_);
     $status.=      push(@status,
         &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,          &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
      $citation,$baseurl,$attachmenturl,$toperm,       $citation,$baseurl,$attachmenturl,$toperm,
      undef,undef,$sentmessage,undef,$symb,$restitle,$error).' ';       undef,undef,$sentmessage,undef,$symb,
                                        $restitle,$error,$nosentstore,$recipid));
         }          }
     } else {      } else {
  $status=&user_normal_msg_raw($user,$domain,$subject,$message,   push(@status,&user_normal_msg_raw($user,$domain,$subject,$message,
      $citation,$baseurl,$attachmenturl,$toperm,       $citation,$baseurl,$attachmenturl,$toperm,
      undef,undef,$sentmessage,undef,$symb,$restitle,$error);       undef,undef,$sentmessage,undef,$symb,
                                        $restitle,$error,$nosentstore,$recipid));
       }
       if (wantarray) {
           return @status;
     }      }
       return join(' ',@status);
   }
   
   sub process_sent_mail {
       my ($msgsubj,$subj_prefix,$numsent,$stamp,$msgname,$msgdom,$msgcount,$context,$pid,$savemsg,$recusers,$recudoms,$baseurl,$attachmenturl,$symb,$error,$senderuname,$senderdom,$recipid) = @_;
       my $sentsubj;
       if ($numsent > 1) {
           $sentsubj = $subj_prefix.' ('.$numsent.' sent) '.$msgsubj;
       } else {
           if ($subj_prefix) {
               $sentsubj = $subj_prefix.' ';
           }
           $sentsubj .= $msgsubj;
       }
       $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"');
       my $sentmsgid = 
           &buildmsgid($stamp,$sentsubj,$msgname,$msgdom,$msgcount,$context,$pid);
       (undef,my $sentmessage) =
           &packagemsg($msgsubj,$savemsg,undef,$baseurl,$attachmenturl,$recusers,
                       $recudoms,$sentmsgid,undef,undef,$symb,$error,$recipid);
       my $status = &store_sent_mail($sentmsgid,$sentmessage,$senderuname,
                                     $senderdom);
     return $status;      return $status;
 }  }
   
 sub store_sent_mail {  sub store_sent_mail {
     my ($msgid,$message) = @_;      my ($msgid,$message,$senderuname,$senderdom) = @_;
     my $status =' '.&Apache::lonnet::critical(      if ($senderuname eq '') {
                'put:'.$env{'user.domain'}.':'.$env{'user.name'}.          $senderuname = $env{'user.name'};
                                           ':nohist_email_sent:'.      }
                &escape($msgid).'='.      if ($senderdom eq '') {
                &escape($message),$env{'user.home'});          $senderdom = $env{'user.domain'};
       }
       my $status =' '.&Apache::lonnet::cput('nohist_email_sent',
     {$msgid => $message},
     $senderdom,$senderuname);
     return $status;      return $status;
 }  }
   
 # =============================================================== Folder suffix  sub store_recipients {
       my ($subject,$sendername,$senderdom,$reciphash) = @_;
       my $context = &get_course_context();
       my $now = time();
       my $msgcount = &get_uniq();
       my $recipid =
           &buildmsgid($now,$subject,$sendername,$senderdom,$msgcount,$context,$$);
       my %recipinfo = (
                            $recipid => $reciphash,
                       );
       my $status = &Apache::lonnet::put('nohist_emailrecip',\%recipinfo,
                                         $senderdom,$sendername); 
       if ($status eq 'ok') {
           return ($recipid,$status);
       } else {
           return (undef,$status);
       }
   }
   
   
 sub foldersuffix {  sub foldersuffix {
     my $folder=shift;      my $folder=shift;
Line 649  sub foldersuffix { Line 965  sub foldersuffix {
     return $suffix;      return $suffix;
 }  }
   
 # ========================================================= User-defined folders   
   
 sub get_user_folders {  sub get_user_folders {
     my ($folder) = @_;      my ($folder) = @_;
Line 666  sub get_user_folders { Line 981  sub get_user_folders {
     return %userfolders;      return %userfolders;
 }  }
   
   sub secapply {
       my $rec=shift;
       my $defaultflag=shift;
       $rec=~s/\s+//g;
       $rec=~s/\@/\:/g;
       my ($adr,$sections_or_groups)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
       if ($sections_or_groups) {
    foreach my $item (split(/\;/,$sections_or_groups)) {
               if (($item eq $env{'request.course.sec'}) ||
                   ($defaultflag && ($item eq '*'))) {
                   return $adr; 
               } elsif ($env{'request.course.groups'}) {
                   my @usersgroups = split(/:/,$env{'request.course.groups'});
                   if (grep(/^\Q$item\E$/,@usersgroups)) {
                       return $adr;
                   }
               } 
           }
       } else {
          return $rec;
       }
       return '';
   }
   
   sub decide_receiver {
       my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
       &Apache::lonenc::check_decrypt(\$feedurl);
       my $typestyle='';
       my %to=();
       if ($env{'form.discuss'} eq 'author' ||$author) {
    $typestyle.='Submitting as Author Feedback<br />';
    $feedurl=~ m{^/res/($LONCAPA::domain_re)/($LONCAPA::username_re)/};
    $to{$2.':'.$1}=1;
       }
       my $cid = $env{'request.course.id'};
       if ($env{'form.discuss'} eq 'question' ||$question) {
    $typestyle.=&mt('Submitting as Question').'<br />';
    foreach my $item (split(/\,/,$env{'course.'.$cid.'.question.email'})) {
       my $rec=&secapply($item,$defaultflag);
       if ($rec) { $to{$rec}=1; }
    } 
       }
       if ($env{'form.discuss'} eq 'course' ||$course) {
    $typestyle.=&mt('Submitting as Comment').'<br />';
    foreach my $item (split(/\,/,$env{'course.'.$cid.'.comment.email'})) {
       my $rec=&secapply($item,$defaultflag);
       if ($rec) { $to{$rec}=1; }
    } 
       }
       if ($env{'form.discuss'} eq 'policy' ||$policy) {
    $typestyle.=&mt('Submitting as Policy Feedback').'<br />';
    foreach my $item (split(/\,/,$env{'course.'.$cid.'.policy.email'})) {
       my $rec=&secapply($item,$defaultflag);
       if ($rec) { $to{$rec}=1; }
    } 
       }
       if ((scalar(%to) eq '0') && (!$defaultflag)) {
    ($typestyle,%to)=
       &decide_receiver($feedurl,$author,$question,$course,$policy,1);
       }
       return ($typestyle,%to);
   }
   
 1;  1;
 __END__  __END__
   

Removed from v.1.195  
changed lines
  Added in v.1.226


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