File:  [LON-CAPA] / loncom / interface / lonmsg.pm
Revision 1.248: download - view: text, annotated - select for diffs
Tue Jan 18 17:33:13 2022 UTC (2 years, 4 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
Bug 6955
 -  If IP-based blocking set in domain config is in effect for user's
    current IP address, and 'Messaging 'is among blocked functions:
   (a) 'Send Feedback' (in course context), for resource(s) which allow it
       is only messaging mechanism available to users with out 'evb' priv.
   (b) Subject and Content for messages sent to instructor(s) via 'Send Feedback'
       are replaced in user's Sent Folder with: "Not shown due to IP block".

    1: # The LearningOnline Network with CAPA
    2: # Routines for messaging
    3: #
    4: # $Id: lonmsg.pm,v 1.248 2022/01/18 17:33:13 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: 
   29: package Apache::lonmsg;
   30: 
   31: =pod
   32: 
   33: =head1 NAME
   34: 
   35: Apache::lonmsg: supports internal messaging
   36: 
   37: =head1 SYNOPSIS
   38: 
   39: lonmsg provides routines for sending messages.
   40: 
   41: Right now, this document will cover just how to send a message, since
   42: it is likely you will not need to programmatically read messages,
   43: since lonmsg already implements that functionality.
   44: 
   45: The routines used to package messages and unpackage messages are not
   46: only used by lonmsg when creating/extracting messages for LON-CAPA's
   47: internal messaging system, but also by lonnotify.pm which is available
   48: for use by Domain Coordinators to broadcast standard e-mail to specified
   49: users in their domain.  The XML packaging used in the two cases is very
   50: similar.  The differences are the use of <recuser>$uname</recuser> and
   51: <recdomain>$udom</recdomain> in stored internal messages, compared
   52: with <recipient username="$uname:$udom">$email</recipient> in stored
   53: Domain Coordinator e-mail for the storage of information about
   54: recipients of the message/e-mail.
   55: 
   56: =head1 SUBROUTINES
   57: 
   58: =over
   59: 
   60: =pod
   61: 
   62: =item packagemsg()
   63: 
   64: Package
   65: 
   66: =item get_course_context()
   67: 
   68: =item unpackagemsg()
   69: 
   70: Unpack message into a hash
   71: 
   72: =item buildmsgid()
   73: 
   74: Get info out of msgid
   75: 
   76: =item unpackmsgid()
   77: 
   78: =item sendemail()
   79: 
   80: =item sendnotification()
   81: 
   82: Send notification emails
   83: 
   84: =item newmail()
   85: 
   86: Check for email
   87: 
   88: =item author_res_msg()
   89: 
   90: Automated message to the author of a resource
   91: 
   92: =item * B<author_res_msg($filename, $message)>: Sends message $message to the owner
   93:     of the resource with the URI $filename.
   94: 
   95: =item retrieve_author_res_msg()
   96: 
   97: Retrieve author resource messages
   98: 
   99: =item del_url_author_res_msg()
  100: 
  101: Delete all author messages related to one URL
  102: 
  103: =item clear_author_res_msg()
  104: 
  105: Clear out all author messages in URL path
  106: 
  107: =item all_url_author_res_msg()
  108: 
  109: Return hash with URLs for which there is a resource message
  110: 
  111: =item store_instructor_comment()
  112: 
  113: Add a comment to the User Notes screen
  114: 
  115: =item user_crit_msg_raw()
  116: 
  117: Critical message to a user
  118: 
  119: =item user_crit_msg()
  120: 
  121: New routine that respects "forward" and calls old routine
  122: 
  123: =item * B<user_crit_msg($user, $domain, $subject, $message, $sendback, $toperm, $sentmessage, $nosentstore, $recipid, $attachmenturl, $permresults, $senthide)>: 
  124:     Sends a critical message $message to the $user at $domain.  If $sendback
  125:     is true,  a receipt will be sent to the current user when $user receives 
  126:     the message.
  127: 
  128:     Additionally it will check if the user has a Forwarding address
  129:     set, and send the message to that address instead
  130: 
  131:     returns 
  132:       - in array context a list of results for each message that was sent
  133:       - in scalar context a space seperated list of results for each 
  134:            message sent
  135: 
  136: 
  137: =item user_crit_received()
  138: 
  139: Critical message received
  140: 
  141: =item user_normal_msg_raw()
  142: 
  143: Normal communication
  144: 
  145: =item user_normal_msg()
  146: 
  147: New routine that respects "forward" and calls old routine
  148: 
  149: =item * B<user_normal_msg($user, $domain, $subject, $message, $citation,
  150:        $baseurl, $attachmenturl, $toperm, $sentmessage, $symb, $restitle,
  151:        $error,$nosentstore,$recipid,$permresults,$senthide)>:
  152:  Sends a message to the  $user at $domain, with subject $subject and message $message.
  153: 
  154:     Additionally it will check if the user has a Forwarding address
  155:     set, and send the message to that address instead
  156: 
  157:     returns
  158:       - in array context a list of results for each message that was sent
  159:       - in scalar context a space seperated list of results for each
  160:            message sent
  161: 
  162: =item store_sent_mail()
  163: 
  164: =item store_recipients()
  165: 
  166: =item foldersuffix()
  167: 
  168: =item get_user_folders()
  169: 
  170: User-defined folders 
  171: 
  172: =item secapply()
  173: 
  174: =item B<decide_receiver($feedurl,$author,$question,$course,$policy,$defaultflag)>:
  175: 
  176: Arguments
  177:   $feedurl - /res/ url of resource (only need if $author is true)
  178:   $author,$question,$course,$policy - all true/false parameters
  179:     if true will attempt to find the addresses of user that should receive
  180:     this type of feedback (author - feedback to author of resource $feedurl,
  181:     $question 'Resource Content Questions', $course 'Course Content Question',
  182:     $policy 'Course Policy')
  183:     (Additionally it also checks $env for whether the corresponding form.<name>
  184:     element exists, for ease of use in a html response context)
  185:    
  186:   $defaultflag - (internal should be left blank) if true gather addresses 
  187:                  that aren't for a section even if I have a section
  188:                  (used for reccursion internally, first we look for
  189:                  addresses for our specific section then we recurse
  190:                  and look for non section addresses)
  191: 
  192: Returns
  193:   $typestyle - string of html text, describing what addresses were found
  194:   %to - a hash, which keys are addresses of users to send messages to
  195:         the keys will look like   name:domain
  196: 
  197: =back
  198: 
  199: =cut
  200: 
  201: use strict;
  202: use Apache::lonnet;
  203: use Apache::loncommon;
  204: use HTML::TokeParser();
  205: use Apache::lonlocal;
  206: use HTML::Entities;
  207: use Encode;
  208: use LONCAPA qw(:DEFAULT :match);
  209: 
  210: {
  211:     my $uniq;
  212:     sub get_uniq {
  213: 	$uniq++;
  214: 	return $uniq;
  215:     }
  216: }
  217: 
  218: 
  219: 
  220: sub packagemsg {
  221:     my ($subject,$message,$citation,$baseurl,$attachmenturl,$recuser,$recdomain,
  222: 	$msgid,$type,$crsmsgid,$symb,$error,$recipid,$senthide,$origmsgid)=@_;
  223:     $message =&HTML::Entities::encode($message,'<>&"');
  224:     $citation=&HTML::Entities::encode($citation,'<>&"');
  225:     $subject =&HTML::Entities::encode($subject,'<>&"');
  226:     #remove machine specification
  227:     $baseurl =~ s|^https?://[^/]+/|/|;
  228:     $baseurl =&HTML::Entities::encode($baseurl,'<>&"');
  229:     #remove machine specification
  230:     $attachmenturl =~ s|^https?://[^/]+/|/|;
  231:     $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
  232:     if ($senthide) {
  233:         foreach my $item ($subject,$message) {
  234:             if ($item ne '') {
  235:                 $item = 'Not shown due to IP block';
  236:             }
  237:         }
  238:         if ($attachmenturl ne '') {
  239:             $attachmenturl = '';
  240:         }
  241:         if ($citation ne '') {
  242:             $citation = '';
  243:         }
  244:         if ($msgid ne '') {
  245:             $msgid = '';
  246:         }
  247:     }
  248:     my $course_context = &get_course_context();
  249:     my $now=time;
  250:     my $ip = &Apache::lonnet::get_requestor_ip();
  251:     my $msgcount = &get_uniq();
  252:     unless(defined($msgid)) {
  253:         $msgid = &buildmsgid($now,$subject,$env{'user.name'},$env{'user.domain'},
  254:                            $msgcount,$course_context,$symb,$error,$$);
  255:     }
  256:     my $result = '<sendername>'.$env{'user.name'}.'</sendername>'.
  257:            '<senderdomain>'.$env{'user.domain'}.'</senderdomain>'.
  258:            '<subject>'.$subject.'</subject>'.
  259:            '<time>'.&Apache::lonlocal::locallocaltime($now).'</time>';
  260:     if (defined($crsmsgid)) {
  261:         $result.= '<courseid>'.$course_context.'</courseid>'.
  262:                   '<coursesec>'.$env{'request.course.sec'}.'</coursesec>'.
  263:                   '<msgid>'.$msgid.'</msgid>'.
  264:                   '<coursemsgid>'.$crsmsgid.'</coursemsgid>'.
  265:                   '<message>'.$message.'</message>';
  266:         return ($msgid,$result);
  267:     }
  268:     $result .= '<servername>'.$ENV{'SERVER_NAME'}.'</servername>'.
  269:            '<host>'.$ENV{'HTTP_HOST'}.'</host>'.
  270: 	   '<client>'.$ip.'</client>'.
  271: 	   '<browsertype>'.$env{'browser.type'}.'</browsertype>'.
  272: 	   '<browseros>'.$env{'browser.os'}.'</browseros>'.
  273: 	   '<browserversion>'.$env{'browser.version'}.'</browserversion>'.
  274:            '<browsermathml>'.$env{'browser.mathml'}.'</browsermathml>'.
  275: 	   '<browserraw>'.$ENV{'HTTP_USER_AGENT'}.'</browserraw>'.
  276: 	   '<courseid>'.$course_context.'</courseid>'.
  277: 	   '<coursesec>'.$env{'request.course.sec'}.'</coursesec>'.
  278: 	   '<role>'.$env{'request.role'}.'</role>'.
  279: 	   '<resource>'.$env{'request.filename'}.'</resource>'.
  280:            '<msgid>'.$msgid.'</msgid>';
  281:     if (defined($env{'form.group'})) {
  282:         $result .= '<group>'.$env{'form.group'}.'</group>';
  283:     }
  284:     if (ref($recuser) eq 'ARRAY') {
  285:         for (my $i=0; $i<@{$recuser}; $i++) {
  286:             if ($type eq 'dcmail') {
  287:                 my ($username,$email) = split(/:/,$$recuser[$i]);
  288:                 $username = &unescape($username);
  289:                 $email = &unescape($email);
  290:                 $username = &HTML::Entities::encode($username,'<>&"');
  291:                 $email = &HTML::Entities::encode($email,'<>&"');
  292:                 $result .= '<recipient username="'.$username.'">'.
  293:                                             $email.'</recipient>';
  294:             } else {
  295:                 $result .= '<recuser>'.$$recuser[$i].'</recuser>'.
  296:                            '<recdomain>'.$$recdomain[$i].'</recdomain>';
  297:             }
  298:         }
  299:     } else {
  300:         $result .= '<recuser>'.$recuser.'</recuser>'.
  301:                    '<recdomain>'.$recdomain.'</recdomain>';
  302:     }
  303:     $result .= '<message>'.$message.'</message>';
  304:     if (defined($citation)) {
  305: 	$result.='<citation>'.$citation.'</citation>';
  306:     }
  307:     if (defined($baseurl)) {
  308: 	$result.= '<baseurl>'.$baseurl.'</baseurl>';
  309:     }
  310:     if (defined($attachmenturl)) {
  311: 	$result.= '<attachmenturl>'.$attachmenturl.'</attachmenturl>';
  312:     }
  313:     if (defined($symb)) {
  314:         $result.= '<symb>'.$symb.'</symb>';
  315:         if ($course_context ne '') {
  316:             if ($course_context eq $env{'request.course.id'}) {
  317:                 my $resource_title = &Apache::lonnet::gettitle($symb);
  318:                 if (defined($resource_title)) {
  319:                     $result .= '<resource_title>'.$resource_title.'</resource_title>';
  320:                 }
  321:             }
  322:         }
  323:     }
  324:     if (defined($recipid)) {
  325:         $result.= '<recipid>'.$recipid.'</recipid>';
  326:     }
  327:     if ($env{'form.can_reply'} eq 'N') {
  328:         $result .= '<noreplies>1</noreplies>';
  329:     }
  330:     if ($env{'form.reply_to_addr'}) {
  331:         my ($replytoname,$replytodom) = split(/:/,$env{'form.reply_to_addr'});
  332:         if (!($replytoname eq $env{'user.name'} && $replytodom eq $env{'user.domain'})) {
  333:             if (&Apache::lonnet::homeserver($replytoname,$replytodom) ne 'no_host') {
  334:                 $result .= '<replytoaddr>'.$env{'form.reply_to_addr'}.'</replytoaddr>';
  335:             }
  336:         }
  337:     }
  338:     if ($senthide) {
  339:         $result .= '<senthide>$origmsgid</senthide>';
  340:     }
  341:     return ($msgid,$result);
  342: }
  343: 
  344: sub get_course_context {
  345:     my $course_context;
  346:     my $msgkey;
  347:     if (defined($env{'form.replyid'})) {
  348:         $msgkey = $env{'form.replyid'};
  349:     } elsif (defined($env{'form.forwid'})) {
  350:         $msgkey = $env{'form.forwid'}
  351:     } elsif (defined($env{'form.multiforwid'})) {
  352:         $msgkey = $env{'form.multiforwid'};
  353:     }
  354:     if ($msgkey ne '') {
  355:         my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
  356:                    split(/\:/,&unescape($msgkey));
  357:         $course_context = $origcid;
  358:     }
  359:     foreach my $key (keys(%env)) {
  360:         if ($key=~/^form\.(rep)?rec\_(.*)$/) {
  361:             my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) =
  362:                                     split(/\:/,&unescape($2));
  363:             $course_context = $origcid;
  364:             last;
  365:         }
  366:     }
  367:     if ($course_context eq '') {
  368:         $course_context = $env{'request.course.id'};
  369:     }
  370:     return $course_context;
  371: }
  372: 
  373: 
  374: sub unpackagemsg {
  375:     my ($message,$notoken,$noattachmentlink)=@_;
  376:     my %content=();
  377:     my $parser=HTML::TokeParser->new(\$message);
  378:     my $token;
  379:     while ($token=$parser->get_token) {
  380:        if ($token->[0] eq 'S') {
  381: 	   my $entry=$token->[1];
  382:            my $value=$parser->get_text('/'.$entry);
  383:            if (($entry eq 'recuser') || ($entry eq 'recdomain')) {
  384:                push(@{$content{$entry}},$value);
  385:            } elsif ($entry eq 'recipient') {
  386:                my $username = $token->[2]{'username'};
  387:                $username = &HTML::Entities::decode($username,'<>&"');
  388:                $content{$entry}{$username} = $value;
  389:            } else {
  390:                $content{$entry}=$value;
  391:            }
  392:        }
  393:     }
  394:     if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
  395:     if (($content{'attachmenturl'}) && (!$noattachmentlink)) {
  396:        my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
  397:        if ($notoken) {
  398: 	   $content{'message'}.='<p>'.&mt('Attachment').': <tt>'.$fname.'</tt>';
  399:        } else {
  400: 	   &Apache::lonnet::allowuploaded('/adm/msg',
  401: 					  $content{'attachmenturl'});
  402: 	   $content{'message'}.='<p>'.&mt('Attachment').
  403: 	       ': <a href="'.$content{'attachmenturl'}.'"><tt>'.
  404: 	       $fname.'</tt></a>';
  405:        }
  406:     }
  407:     return %content;
  408: }
  409: 
  410: 
  411: sub buildmsgid {
  412:     my ($now,$subject,$uname,$udom,$msgcount,$course_context,$symb,$error,$pid) = @_;
  413:     $subject=&escape($subject);
  414:     $symb = &escape($symb);
  415:     return(&escape($now.':'.$subject.':'.$uname.':'.
  416:            $udom.':'.$msgcount.':'.$course_context.':'.$pid.':'.$symb.':'.$error));
  417: }
  418: 
  419: sub unpackmsgid {
  420:     my ($msgid,$folder,$skipstatus,$status_cache,$onlycid)=@_;
  421:     $msgid=&unescape($msgid);
  422:     my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid,
  423:         $processid,$symb,$error) = split(/\:/,&unescape($msgid));
  424:     if (!defined($processid)) { $fromcid = ''; }
  425:     if (($onlycid) && ($onlycid ne $fromcid)) {
  426:         return ($sendtime,'',$fromname,$fromdomain,'',$fromcid,'',$error);
  427:     }
  428:     $shortsubj = &unescape($shortsubj);
  429:     $shortsubj = &HTML::Entities::decode($shortsubj);
  430:     $symb = &unescape($symb);
  431:     my %status=();
  432:     unless ($skipstatus) {
  433: 	if (ref($status_cache)) {
  434: 	    $status{$msgid} = $status_cache->{$msgid};
  435: 	} else {
  436: 	    my $suffix=&foldersuffix($folder);
  437: 	    %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
  438: 	}
  439: 	if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
  440:         unless ($status{$msgid}) { $status{$msgid}='new'; }
  441:     }
  442:     return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid,$symb,$error);
  443: }
  444: 
  445: 
  446: sub sendemail {
  447:     my ($to,$subject,$body,$to_uname,$to_udom,$user_lh,$attachmenturl)=@_;
  448:     my $senderaddress='';
  449:     my $replytoaddress='';
  450:     my $msgsent;
  451:     if ($env{'form.can_reply'} eq 'N') {
  452:         my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
  453:         my $hostname = &Apache::lonnet::hostname($lonhost);
  454:         $replytoaddress = 'do-not-reply@'.$hostname;
  455:     } else {
  456:         my %senderemails;
  457:         my $have_sender;
  458:         if ($env{'form.reply_to_addr'}) {
  459:             my ($replytoname,$replytodom) = split(/:/,$env{'form.reply_to_addr'});
  460:             if (!($replytoname eq $env{'user.name'} && $replytodom eq $env{'user.domain'})) {
  461:                 if (&Apache::lonnet::homeserver($replytoname,$replytodom) ne 'no_host') {
  462:                     %senderemails = 
  463:                         &Apache::loncommon::getemails($replytoname,$replytodom);
  464:                     $have_sender = 1;
  465:                 }
  466:             }
  467:         }
  468:         if (!$have_sender) {
  469:             %senderemails=&Apache::loncommon::getemails();
  470:         }
  471:         foreach my $type ('permanentemail','critnotification','notification') {
  472:             if ($senderemails{$type}) {
  473:                 ($senderaddress) = split(/,/,$senderemails{$type});
  474:                 last if ($senderaddress);
  475:             }
  476:         }
  477:     }
  478:     $body=
  479:     "*** ".&mt_user($user_lh,'This is an automatic e-mail generated by the LON-CAPA system.')."\n".
  480:     "*** ".($senderaddress?&mt_user($user_lh,'You can reply to this e-mail'):&mt_user($user_lh,'Please do not reply to this address.')."\n*** ".
  481:     &mt_user($user_lh,'A reply will not be received by the recipient!'))."\n\n".$body;
  482:     
  483:     $attachmenturl = &Apache::lonnet::filelocation("",$attachmenturl);
  484:     my $filesize = (stat($attachmenturl))[7];
  485:     if ($filesize > 1048576) {
  486:         # Don't send if it exceeds 1 MB.
  487:         print '<p><span class="LC_error">' 
  488:             .&mt('Email not sent.  Attachment exceeds permitted length.')
  489:             .'</span><br /></p>';
  490:     } else {
  491:         # Otherwise build and send the email
  492:         $subject = '[LON-CAPA] '.$subject;
  493:         &Apache::loncommon::mime_email($senderaddress,$replytoaddress,$to,
  494:                                        $subject,$body,'','',$attachmenturl,'','');
  495:         $msgsent = 1;
  496:     }
  497:     return $msgsent;
  498: }
  499: 
  500: # ==================================================== Send notification emails
  501: 
  502: sub sendnotification {
  503:     my ($to,$touname,$toudom,$subj,$crit,$text,$msgid,$attachmenturl)=@_;
  504:     my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'};
  505:     unless ($sender=~/\w/) { 
  506: 	$sender=$env{'user.name'}.':'.$env{'user.domain'};
  507:     }
  508:     my $critical=($crit?' critical':'');
  509:     my $numsent = 0;
  510: 
  511:     $text=~s/\&lt\;/\</gs;
  512:     $text=~s/\&gt\;/\>/gs;
  513:     my $homeserver = &Apache::lonnet::homeserver($touname,$toudom);
  514:     my $hostname = &Apache::lonnet::hostname($homeserver);
  515:     my $protocol = $Apache::lonnet::protocol{$homeserver};
  516:     $protocol = 'http' if ($protocol ne 'https');
  517: #FIXME
  518:     my $url = $protocol.'://'.$hostname.
  519:               '/adm/email?username='.$touname.'&domain='.$toudom.
  520:               '&display='.&escape($msgid);
  521:     my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,
  522:         $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid);
  523:     my ($coursetext,$body,$bodybegin,$bodysubj,$bodyend);
  524:     my $user_lh = &Apache::loncommon::user_lang($touname,$toudom,$fromcid);
  525:     if ($fromcid ne '') {
  526:         $coursetext = "\n".&mt_user($user_lh,'Course').': ';
  527:         if ($env{'course.'.$fromcid.'.description'} ne '') {
  528:             $coursetext .= $env{'course.'.$fromcid.'.description'};
  529:         } else {
  530:             my %coursehash = &Apache::lonnet::coursedescription($fromcid,);
  531:             if ($coursehash{'description'} ne '') {
  532:                 $coursetext .= $coursehash{'description'};
  533:             }
  534:         }
  535:         $coursetext .= "\n\n";
  536:     }
  537:     my @recipients = split(/,/,$to);
  538:     $bodybegin = $coursetext. 
  539:                &mt_user($user_lh,
  540:                          'You received a'.$critical.' message from [_1] in LON-CAPA.',$sender).' ';
  541:     $bodysubj = &mt_user($user_lh,'The subject is 
  542: 
  543:  [_1]
  544: 
  545: ',$subj)."\n".
  546: '=== '.&mt_user($user_lh,'Excerpt')." ============================================================
  547: ";
  548:     $bodyend = "
  549: ========================================================================
  550: 
  551: ".&mt_user($user_lh,'Use 
  552: 
  553:  [_1]
  554: 
  555: to access the full message.',$url);
  556:     my %userenv = &Apache::lonnet::get('environment',['notifywithhtml'],$toudom,$touname);
  557:     my $subject = &mt_user($user_lh,"'New'$critical message from [_1]",$sender);
  558:     unless ($subj eq '') {
  559:         $subject = $subj;
  560:     }
  561:  
  562:     my ($blocked,$blocktext,$clientip);
  563:     $clientip = &Apache::lonnet::get_requestor_ip();
  564:     if (!$crit) {
  565:         my %setters;
  566:         my ($startblock,$endblock,$triggerblock,$by_ip,$blockdom) = 
  567:             &Apache::loncommon::blockcheck(\%setters,'com',$clientip,$touname,$toudom);
  568:         if ($startblock && $endblock) {
  569:             $blocked = 1;
  570:             my $showstart = &Apache::lonlocal::locallocaltime($startblock);
  571:             my $showend = &Apache::lonlocal::locallocaltime($endblock);
  572:             $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);
  573:         } elsif ($by_ip) {
  574:             $blocked = 1;
  575:             $blocktext = &mt_user($user_lh,'LON-CAPA messages sent to you will be inaccessible from your IP address [_1], because communication is being blocked for certain IP address(es).',$clientip);
  576:         }
  577:     }
  578:     if ($userenv{'notifywithhtml'} ne '') {
  579:         my @htmlexcerpt = split(/,/,$userenv{'notifywithhtml'});
  580:         my $htmlfree = &make_htmlfree($text);
  581:         foreach my $addr (@recipients) {
  582:             if ($blocked) {
  583:                 $body = $bodybegin."\n".$blocktext."\n".$bodyend;
  584:             } else {
  585:                 my $sendtext;
  586:                 if (!grep/^\Q$addr\E/,@htmlexcerpt) {
  587:                     $sendtext = $htmlfree;
  588:                 } else {
  589:                     $sendtext = $text;
  590:                 }
  591:                 $body = $bodybegin.$bodysubj.$sendtext.$bodyend;
  592:             }
  593:             if (&sendemail($addr,$subject,$body,$touname,$toudom,$user_lh,$attachmenturl)) {
  594:                 $numsent ++;
  595:             }
  596:         }
  597:     } else {
  598:         if ($blocked) {
  599:             $body = $bodybegin."\n".$blocktext."\n".$bodyend;
  600:         } else {
  601:             my $htmlfree = &make_htmlfree($text);
  602:             $body = $bodybegin.$bodysubj.$htmlfree.$bodyend;
  603:         }
  604:         if (&sendemail($to,$subject,$body,$touname,$toudom,$user_lh,$attachmenturl)) {
  605:             $numsent ++;
  606:         }
  607:     }
  608:     return $numsent;
  609: }
  610: 
  611: sub make_htmlfree {
  612:     my ($text) = @_;
  613:     $text =~ s/\<\/*[^\>]+\>//gs;
  614:     $text = &HTML::Entities::decode($text);
  615:     $text = &Encode::encode('utf8',$text);
  616:     return $text;
  617: }
  618: 
  619: sub mynewmail{
  620: 	&newmail();
  621: 	return $env{'user.mailcheck.lastnewmessagetime'} > $env{'user.mailcheck.lastvisit'};
  622: }
  623: 
  624: 
  625: sub newmail {
  626:     if ((time-$env{'user.mailcheck.time'})>300) {
  627:         my %what=&Apache::lonnet::get('email_status',['recnewemail']);
  628:         &Apache::lonnet::appenv({'user.mailcheck.time'=>time});
  629: 		&Apache::lonnet::appenv({'user.mailcheck.lastnewmessagetime'=> $what{'recnewemail'}});
  630:         if ($what{'recnewemail'}>0) { return 1; }
  631:     }
  632:     return 0;
  633: }
  634: 
  635: 
  636: 
  637: sub author_res_msg {
  638:     my ($filename,$message)=@_;
  639:     unless ($message) { return 'empty'; }
  640:     $filename=&Apache::lonnet::declutter($filename);
  641:     my ($domain,$author,@dummy)=split(/\//,$filename);
  642:     my $homeserver=&Apache::lonnet::homeserver($author,$domain);
  643:     if ($homeserver ne 'no_host') {
  644:        my $id=unpack("%32C*",$message);
  645:        $message .= " <p>This error occurred on machine ".
  646: 	   $Apache::lonnet::perlvar{'lonHostID'}."</p>";
  647:        my $msgid;
  648:        ($msgid,$message)=&packagemsg($filename,$message);
  649:        return &Apache::lonnet::reply('put:'.$domain.':'.$author.
  650:          ':nohist_res_msgs:'.
  651:           &escape($filename.'_'.$id).'='.
  652:           &escape($message),$homeserver);
  653:     }
  654:     return 'no_host';
  655: }
  656: 
  657: 
  658: 
  659: sub retrieve_author_res_msg {
  660:     my $url=shift;
  661:     $url=&Apache::lonnet::declutter($url);
  662:     my ($domain,$author)=($url=~/^($match_domain)\/($match_username)\//);
  663:     my %errormsgs=&Apache::lonnet::dump('nohist_res_msgs',$domain,$author);
  664:     my $msgs='';
  665:     foreach my $msg (keys(%errormsgs)) {
  666: 	if ($msg =~ /^\Q$url\E\_\d+$/) {
  667: 	    my %content=&unpackagemsg($errormsgs{$msg});
  668: 	    $msgs.='<p><img src="/adm/lonMisc/bomb.gif" /><b>'.
  669: 		$content{'time'}.'</b>: '.$content{'message'}.
  670: 		'<br /></p>';
  671: 	}
  672:     } 
  673:     return $msgs;     
  674: }
  675: 
  676: 
  677: 
  678: 
  679: 
  680: sub del_url_author_res_msg {
  681:     my $url=shift;
  682:     $url=&Apache::lonnet::declutter($url);
  683:     my ($domain,$author)=($url=~/^($match_domain)\/($match_username)\//);
  684:     my @delmsgs=();
  685:     foreach my $msg (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
  686: 	if ($msg =~ /^\Q$url\E\_\d+$/) {
  687: 	    push (@delmsgs,$msg);
  688: 	}
  689:     }
  690:     return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
  691: }
  692: 
  693: 
  694: sub clear_author_res_msg {
  695:     my $url=shift;
  696:     $url=&Apache::lonnet::declutter($url);
  697:     my ($domain,$author)=($url=~/^($match_domain)\/($match_username)\//);
  698:     my @delmsgs=();
  699:     foreach my $msg (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
  700: 	if ($msg =~ /^\Q$url\E/) {
  701: 	    push (@delmsgs,$msg);
  702: 	}
  703:     }
  704:     return &Apache::lonnet::del('nohist_res_msgs',\@delmsgs,$domain,$author);
  705: }
  706: 
  707: 
  708: 
  709: sub all_url_author_res_msg {
  710:     my ($author,$domain)=@_;
  711:     my %returnhash=();
  712:     foreach my $msg (&Apache::lonnet::getkeys('nohist_res_msgs',$domain,$author)) {
  713: 	$msg =~ /^(.+)\_\d+/;
  714: 	$returnhash{$1}=1;
  715:     }
  716:     return %returnhash;
  717: }
  718: 
  719: 
  720: sub store_instructor_comment {
  721:     my ($msg,$uname,$udom) = @_;
  722:     my $cid  = $env{'request.course.id'};
  723:     my $cnum = $env{'course.'.$cid.'.num'};
  724:     my $cdom = $env{'course.'.$cid.'.domain'};
  725:     my $subject= &mt('Record').' ['.$uname.':'.$udom.']';
  726:     my $result = &user_normal_msg_raw($cnum,$cdom,$subject,$msg);
  727:     if ($result eq 'ok' || $result eq 'con_delayed') {
  728:         
  729:     }
  730:     return $result;
  731: }
  732: 
  733: 
  734: sub user_crit_msg_raw {
  735:     my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage,
  736:         $nosentstore,$recipid,$attachmenturl,$permresults,$senthide)=@_;
  737: # Check if allowed missing
  738:     my ($status,$packed_message);
  739:     my $msgid='undefined';
  740:     unless (($message)&&($user)&&($domain)) { $status='empty'; };
  741:     my $text=$message;
  742:     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
  743:     if ($homeserver ne 'no_host') {
  744:        ($msgid,$packed_message)=&packagemsg($subject,$message,undef,undef,
  745:                                   $attachmenturl,undef,undef,undef,undef,undef,
  746:                                   undef,undef,$recipid);
  747:        if ($sendback) { $packed_message.='<sendback>true</sendback>'; }
  748:        $status=&Apache::lonnet::cput('critical', {$msgid => $packed_message},
  749: 				     $domain,$user);
  750:         if (defined($sentmessage)) {
  751:             $$sentmessage = $packed_message;
  752:         }
  753:         if (!$nosentstore) {
  754:             my ($sentmsgid,$packed_message_no_citation) =
  755:             &packagemsg($subject,$message,undef,undef,$attachmenturl,$user,
  756:                         $domain,$msgid,undef,undef,undef,undef,undef,$senthide,$msgid);
  757:             if ($status eq 'ok' || $status eq 'con_delayed') {
  758:                 if ($senthide && $sentmsgid) {
  759:                     &store_sent_mail($sentmsgid,$packed_message_no_citation);
  760:                 } else {
  761:                     &store_sent_mail($msgid,$packed_message_no_citation);
  762:                 }
  763:             }
  764:         }
  765:     } else {
  766:        $status='no_host';
  767:     }
  768: 
  769: # Notifications
  770:     my %userenv = &Apache::loncommon::getemails($user,$domain);
  771:     my $critnotify = $userenv{'critnotification'};
  772:     my $permemail = $userenv{'permanentemail'};
  773:     my $numcrit = 0;
  774:     my $numperm = 0;
  775:     my $permlogmsgstatus;
  776:     if ($critnotify) {
  777:         $numcrit = &sendnotification($critnotify,$user,$domain,$subject,1,$text,$msgid,$attachmenturl);
  778:     }
  779:     if ($toperm && $permemail) {
  780:         if ($critnotify && $numcrit) {
  781:             if (grep(/^\Q$permemail\E/,split(/,/,$critnotify))) {
  782:                 $numperm = 1;
  783:             }
  784:         }
  785:         unless ($numperm) {
  786:             $numperm = &sendnotification($permemail,$user,$domain,$subject,1,$text,$msgid,$attachmenturl);
  787:         }
  788:     }
  789:     if ($toperm) {
  790:         $permlogmsgstatus = '. Perm. email log status '.
  791:                             &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},$env{'user.home'},
  792:                                                  "Perm. e-mail count $numperm for $user at $domain");
  793:         if (ref($permresults) eq 'HASH') {
  794:             $permresults->{"$user:$domain"} = $numperm;
  795:         }
  796:     }
  797: # Log this
  798:     &Apache::lonnet::logthis(
  799:       'Sending critical '.$msgid.
  800:       ', log status: '.
  801:       &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
  802:                          $env{'user.home'},
  803:       'Sending critical '.$msgid.' to '.$user.' at '.$domain.' with status '
  804:       .$status).$permlogmsgstatus);
  805:     return $status;
  806: }
  807: 
  808: 
  809: 
  810: sub user_crit_msg {
  811:     my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage,
  812:         $nosentstore,$recipid,$attachmenturl,$permresults,$senthide)=@_;
  813:     my @status;
  814:     my %userenv = &Apache::lonnet::get('environment',['msgforward'],
  815:                                        $domain,$user);
  816:     my $msgforward=$userenv{'msgforward'};
  817:     if ($msgforward) {
  818:        foreach my $addr (split(/\,/,$msgforward)) {
  819: 	 my ($forwuser,$forwdomain)=split(/\:/,$addr);
  820:          push(@status,
  821: 	      &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,
  822: 				 $sendback,$toperm,$sentmessage,$nosentstore,
  823:                                  $recipid,$attachmenturl,$permresults,$senthide));
  824:        }
  825:     } else { 
  826: 	push(@status,
  827: 	     &user_crit_msg_raw($user,$domain,$subject,$message,$sendback,
  828: 				$toperm,$sentmessage,$nosentstore,$recipid,
  829:                                 $attachmenturl,$permresults,$senthide));
  830:     }
  831:     if (wantarray) {
  832: 	return @status;
  833:     }
  834:     return join(' ',@status);
  835: }
  836: 
  837: 
  838: sub user_crit_received {
  839:     my $msgid=shift;
  840:     my %message=&Apache::lonnet::get('critical',[$msgid]);
  841:     my %contents=&unpackagemsg($message{$msgid},1);
  842:     my $destname = $contents{'sendername'};
  843:     my $destdom = $contents{'senderdomain'};
  844:     if ($contents{'replytoaddr'}) {
  845:         my ($repname,$repdom) = split(/:/,$contents{'replytoaddr'});
  846:         if (&Apache::lonnet::homeserver($repname,$repdom) ne 'no_host') {
  847:             $destname = $repname;
  848:             $destdom = $repdom;    
  849:         }
  850:     }
  851:     my $status='rec: '.($contents{'sendback'}?
  852:      &user_normal_msg($destname,$destdom,&mt('Receipt').': '.$env{'user.name'}.
  853:                       ' '.&mt('at').' '.$env{'user.domain'}.', '.
  854:                       $contents{'subject'},&mt('User').' '.$env{'user.name'}.
  855:                       ' '.&mt('at').' '.$env{'user.domain'}.
  856:                       ' acknowledged receipt of message'."\n".'   "'.
  857:                       $contents{'subject'}.'"'."\n".&mt('dated').' '.
  858:                       $contents{'time'}.".\n"
  859:                       ):'no msg req');
  860:     $status.=' trans: '.
  861:      &Apache::lonnet::put(
  862:      'nohist_email',{$contents{'msgid'} => $message{$msgid}});
  863:     $status.=' del: '.
  864:      &Apache::lonnet::del('critical',[$contents{'msgid'}]);
  865:     &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
  866:                          $env{'user.home'},'Received critical message '.
  867:                          $contents{'msgid'}.
  868:                          ', '.$status);
  869:     return $status;
  870: }
  871: 
  872: 
  873: 
  874: 
  875: sub user_normal_msg_raw {
  876:     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
  877:         $toperm,$currid,$newid,$sentmessage,$crsmsgid,$symb,$restitle,
  878:         $error,$nosentstore,$recipid,$permresults,$senthide)=@_;
  879: # Check if allowed missing
  880:     my ($status,$packed_message);
  881:     my $msgid='undefined';
  882:     my $text=$message;
  883:     unless (($message)&&($user)&&($domain)) { $status='empty'; };
  884:     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
  885:     if ($homeserver ne 'no_host') {
  886:        ($msgid,$packed_message)=
  887: 	                 &packagemsg($subject,$message,$citation,$baseurl,
  888:                                      $attachmenturl,$user,$domain,$currid,
  889:                                      undef,$crsmsgid,$symb,$error,$recipid);
  890: 
  891: # Store in user folder
  892:        $status=
  893: 	   &Apache::lonnet::cput('nohist_email',{$msgid => $packed_message},
  894: 				 $domain,$user);
  895: # Save new message received time
  896:        &Apache::lonnet::put
  897:                          ('email_status',{'recnewemail'=>time},$domain,$user);
  898: # Into sent-mail folder if sent mail storage required
  899:        if (!$nosentstore) {
  900:            my ($sentmsgid,$packed_message_no_citation) =
  901:                &packagemsg($subject,$message,undef,$baseurl,$attachmenturl,
  902:                            $user,$domain,$currid,undef,$crsmsgid,$symb,$error,
  903:                            undef,$senthide,$msgid);
  904:            if ($status eq 'ok' || $status eq 'con_delayed') {
  905:                if ($senthide && $sentmsgid) {
  906:                    &store_sent_mail($sentmsgid,$packed_message_no_citation);
  907:                } else {
  908:                    &store_sent_mail($msgid,$packed_message_no_citation);
  909:                }
  910:            }
  911:        }
  912:        if (ref($newid) eq 'SCALAR') {
  913: 	   $$newid = $msgid;
  914:        }
  915:        if (ref($sentmessage) eq 'SCALAR') {
  916: 	   $$sentmessage = $packed_message;
  917:        }
  918: # Notifications
  919:        my %userenv = &Apache::loncommon::getemails($user,$domain);
  920:        my $notify = $userenv{'notification'};
  921:        my $permemail = $userenv{'permanentemail'};
  922:        my $numnotify = 0;
  923:        my $numperm = 0;
  924:        my $permlogmsgstatus;
  925:        if ($notify) {
  926:            $numnotify = &sendnotification($notify,$user,$domain,$subject,0,$text,$msgid,$attachmenturl);
  927:        }
  928:        if ($toperm && $permemail) {
  929:            if ($notify && $numnotify) {
  930:                if (grep(/^\Q$permemail\E/,split(/,/,$notify))) {
  931:                    $numperm = 1;
  932:                }
  933:            }
  934:            unless ($numperm) {
  935:                $numperm = &sendnotification($permemail,$user,$domain,$subject,0,
  936:                                             $text,$msgid,$attachmenturl);
  937:            }
  938:        }
  939:        if ($toperm) {
  940:            $permlogmsgstatus = '. Perm. email log status '.
  941:                          &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},$env{'user.home'},
  942:                                               "Perm. e-mail count $numperm for $user at $domain");
  943:            if (ref($permresults) eq 'HASH') {
  944:                $permresults->{"$user:$domain"} = $numperm;
  945:            }
  946:        }
  947:        &Apache::lonnet::log($env{'user.domain'},$env{'user.name'},
  948: 			    $env{'user.home'},
  949: 			    'Sending '.$msgid.' to '.$user.' at '.$domain.' with status '.$status.
  950:                             $permlogmsgstatus);
  951:    } else {
  952:        $status='no_host';
  953:    }
  954:     return $status;
  955: }
  956: 
  957: sub user_normal_msg {
  958:     my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
  959: 	$toperm,$sentmessage,$symb,$restitle,$error,$nosentstore,$recipid,
  960:         $permresults,$senthide)=@_;
  961:     my @status;
  962:     my %userenv = &Apache::lonnet::get('environment',['msgforward'],
  963:                                        $domain,$user);
  964:     my $msgforward=$userenv{'msgforward'};
  965:     if ($msgforward) {
  966:         foreach my $fwd (split(/\,/,$msgforward)) {
  967: 	    my ($forwuser,$forwdomain)=split(/\:/,$fwd);
  968: 	    push(@status,
  969: 	        &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
  970: 				     $citation,$baseurl,$attachmenturl,$toperm,
  971: 				     undef,undef,$sentmessage,undef,$symb,
  972:                                      $restitle,$error,$nosentstore,$recipid,
  973:                                      $permresults,$senthide));
  974:         }
  975:     } else {
  976: 	push(@status,&user_normal_msg_raw($user,$domain,$subject,$message,
  977: 				     $citation,$baseurl,$attachmenturl,$toperm,
  978: 				     undef,undef,$sentmessage,undef,$symb,
  979:                                      $restitle,$error,$nosentstore,$recipid,
  980:                                      $permresults,$senthide));
  981:     }
  982:     if (wantarray) {
  983:         return @status;
  984:     }
  985:     return join(' ',@status);
  986: }
  987: 
  988: sub process_sent_mail {
  989:     my ($msgsubj,$subj_prefix,$numsent,$stamp,$msgname,$msgdom,$msgcount,
  990:         $context,$pid,$savemsg,$recusers,$recudoms,$baseurl,$attachmenturl,
  991:         $symb,$error,$senderuname,$senderdom,$recipid) = @_;
  992:     my $sentsubj;
  993:     if ($numsent > 1) {
  994:         $sentsubj = $subj_prefix.' ('.$numsent.' sent) '.$msgsubj;
  995:     } else {
  996:         if ($subj_prefix) {
  997:             $sentsubj = $subj_prefix.' ';
  998:         }
  999:         $sentsubj .= $msgsubj;
 1000:     }
 1001:     $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"');
 1002:     my $sentmsgid = 
 1003:         &buildmsgid($stamp,$sentsubj,$msgname,$msgdom,$msgcount,$context,$pid);
 1004:     (undef,my $sentmessage) =
 1005:         &packagemsg($msgsubj,$savemsg,undef,$baseurl,$attachmenturl,$recusers,
 1006:                     $recudoms,$sentmsgid,undef,undef,$symb,$error,$recipid);
 1007:     my $status = &store_sent_mail($sentmsgid,$sentmessage,$senderuname,
 1008:                                   $senderdom);
 1009:     return $status;
 1010: }
 1011: 
 1012: sub store_sent_mail {
 1013:     my ($msgid,$message,$senderuname,$senderdom) = @_;
 1014:     if ($senderuname eq '') {
 1015:         $senderuname = $env{'user.name'};
 1016:     }
 1017:     if ($senderdom eq '') {
 1018:         $senderdom = $env{'user.domain'};
 1019:     }
 1020:     my $status =' '.&Apache::lonnet::cput('nohist_email_sent',
 1021: 					  {$msgid => $message},
 1022: 					  $senderdom,$senderuname);
 1023:     return $status;
 1024: }
 1025: 
 1026: sub store_recipients {
 1027:     my ($subject,$sendername,$senderdom,$reciphash) = @_;
 1028:     my $context = &get_course_context();
 1029:     my $now = time();
 1030:     my $msgcount = &get_uniq();
 1031:     my $recipid =
 1032:         &buildmsgid($now,$subject,$sendername,$senderdom,$msgcount,$context,$$);
 1033:     my %recipinfo = (
 1034:                          $recipid => $reciphash,
 1035:                     );
 1036:     my $status = &Apache::lonnet::put('nohist_emailrecip',\%recipinfo,
 1037:                                       $senderdom,$sendername); 
 1038:     if ($status eq 'ok') {
 1039:         return ($recipid,$status);
 1040:     } else {
 1041:         return (undef,$status);
 1042:     }
 1043: }
 1044: 
 1045: 
 1046: sub foldersuffix {
 1047:     my $folder=shift;
 1048:     unless ($folder) { return ''; }
 1049:     my $suffix;
 1050:     my %folderhash = &get_user_folders($folder);
 1051:     if (ref($folderhash{$folder}) eq 'HASH') {
 1052:         $suffix = '_'.&escape($folderhash{$folder}{'id'});
 1053:     } else {
 1054:         $suffix = '_'.&escape($folder);
 1055:     }
 1056:     return $suffix;
 1057: }
 1058: 
 1059: 
 1060: sub get_user_folders {
 1061:     my ($folder) = @_;
 1062:     my %userfolders = 
 1063:           &Apache::lonnet::dump('email_folders',undef,undef,$folder);
 1064:     my $lock = "\0".'lock_counter'; # locks db while counter incremented
 1065:     my $counter = "\0".'idcount';   # used in suffix for email db files
 1066:     if (defined($userfolders{$lock})) {
 1067:         delete($userfolders{$lock});
 1068:     }
 1069:     if (defined($userfolders{$counter})) {
 1070:         delete($userfolders{$counter});
 1071:     }
 1072:     return %userfolders;
 1073: }
 1074: 
 1075: sub secapply {
 1076:     my $rec=shift;
 1077:     my $defaultflag=shift;
 1078:     $rec=~s/\s+//g;
 1079:     unless ($rec =~ /\:/) {
 1080:         $rec=~s/\@/\:/g;
 1081:     }
 1082:     my ($adr,$sections_or_groups)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
 1083:     if ($sections_or_groups) {
 1084: 	foreach my $item (split(/\;/,$sections_or_groups)) {
 1085:             if (($item eq $env{'request.course.sec'}) ||
 1086:                 ($defaultflag && ($item eq '*'))) {
 1087:                 return $adr; 
 1088:             } elsif ($env{'request.course.groups'}) {
 1089:                 my @usersgroups = split(/:/,$env{'request.course.groups'});
 1090:                 if (grep(/^\Q$item\E$/,@usersgroups)) {
 1091:                     return $adr;
 1092:                 }
 1093:             } 
 1094:         }
 1095:     } else {
 1096:        return $rec;
 1097:     }
 1098:     return '';
 1099: }
 1100: 
 1101: sub decide_receiver {
 1102:     my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
 1103:     &Apache::lonenc::check_decrypt(\$feedurl);
 1104:     my $typestyle='';
 1105:     my %to=();
 1106:     if ($env{'form.discuss'} eq 'author' ||$author) {
 1107: 	$typestyle.='Submitting as Author Feedback<br />';
 1108: 	$feedurl=~ m{^/res/($LONCAPA::domain_re)/($LONCAPA::username_re)/};
 1109: 	$to{$2.':'.$1}=1;
 1110:     }
 1111:     my $cid = $env{'request.course.id'};
 1112:     if ($env{'form.discuss'} eq 'question' ||$question) {
 1113: 	$typestyle.=&mt('Submitting as Question').'<br />';
 1114: 	foreach my $item (split(/\,/,$env{'course.'.$cid.'.question.email'})) {
 1115: 	    my $rec=&secapply($item,$defaultflag);
 1116: 	    if ($rec) { $to{$rec}=1; }
 1117: 	} 
 1118:     }
 1119:     if ($env{'form.discuss'} eq 'course' ||$course) {
 1120: 	$typestyle.=&mt('Submitting as Comment').'<br />';
 1121: 	foreach my $item (split(/\,/,$env{'course.'.$cid.'.comment.email'})) {
 1122: 	    my $rec=&secapply($item,$defaultflag);
 1123: 	    if ($rec) { $to{$rec}=1; }
 1124: 	} 
 1125:     }
 1126:     if ($env{'form.discuss'} eq 'policy' ||$policy) {
 1127: 	$typestyle.=&mt('Submitting as Policy Feedback').'<br />';
 1128: 	foreach my $item (split(/\,/,$env{'course.'.$cid.'.policy.email'})) {
 1129: 	    my $rec=&secapply($item,$defaultflag);
 1130: 	    if ($rec) { $to{$rec}=1; }
 1131: 	} 
 1132:     }
 1133:     if ((scalar(%to) eq '0') && (!$defaultflag)) {
 1134: 	($typestyle,%to)=
 1135: 	    &decide_receiver($feedurl,$author,$question,$course,$policy,1);
 1136:     }
 1137:     return ($typestyle,%to);
 1138: }
 1139: 
 1140: 1;
 1141: __END__
 1142: 

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