Annotation of loncom/interface/lonmsgdisplay.pm, revision 1.120

1.1       albertel    1: # The LearningOnline Network with CAPA
                      2: # Routines for messaging display
                      3: #
1.120   ! kaisler     4: # $Id: lonmsgdisplay.pm,v 1.119 2009/03/27 16:18:04 bisitz Exp $
1.1       albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
                     28: 
                     29: 
                     30: package Apache::lonmsgdisplay;
                     31: 
                     32: =pod
                     33: 
                     34: =head1 NAME
                     35: 
1.69      raeburn    36: Apache::lonmsgdisplay: supports internal messaging
1.1       albertel   37: 
                     38: =head1 SYNOPSIS
                     39: 
1.69      raeburn    40: lonmsgdisplay provides a handler to allow users to read, send, 
                     41: and delete messages, and to create and delete message folders,
                     42: and to move messages between folders.
1.1       albertel   43: 
                     44: =head1 OVERVIEW
                     45: 
                     46: =head2 Messaging Overview
                     47: 
                     48: X<messages>LON-CAPA provides an internal messaging system similar to
                     49: email, but customized for LON-CAPA's usage. LON-CAPA implements its
                     50: own messaging system, rather then building on top of email, because of
                     51: the features LON-CAPA messages can offer that conventional e-mail can
                     52: not:
                     53: 
                     54: =over 4
                     55: 
                     56: =item * B<Critical messages>: A message the recipient B<must>
                     57: acknowlegde receipt of before they are allowed to continue using the
                     58: system, preventing a user from claiming they never got a message
                     59: 
                     60: =item * B<Receipts>: LON-CAPA can reliably send reciepts informing the
                     61: sender that it has been read; again, useful for preventing students
                     62: from claiming they did not see a message. (While conventional e-mail
                     63: has some reciept support, it's sporadic, e-mail client-specific, and
                     64: generally the receiver can opt to not send one, making it useless in
                     65: this case.)
                     66: 
                     67: =item * B<Context>: LON-CAPA knows about the sender, such as where
                     68: they are in a course. When a student mails an instructor asking for
                     69: help on the problem, the instructor receives not just the student's
                     70: question, but all submissions the student has made up to that point,
                     71: the user's rendering of the problem, and the complete view the student
                     72: saw of the resource, including discussion up to that point. Finally,
                     73: the instructor is reading all of this inside of LON-CAPA, not their
                     74: email program, so they have full access to LON-CAPA's grading
                     75: interface, or other features they may wish to use in response to the
                     76: student's query.
                     77: 
1.50      raeburn    78: =item * B<Blocking>: LON-CAPA can block selected communication 
                     79: features for students during an online exam. A course coordinator or
1.1       albertel   80: instructor can set an open and close date/time for scheduled online
                     81: exams in a course. If a user uses the LON-CAPA internal messaging 
                     82: system to display e-mails during the scheduled blocking event,  
                     83: display of all e-mail sent during the blocking period will be 
                     84: suppressed, and a message of explanation, including details of the 
                     85: currently active blocking periods will be displayed instead. A user 
                     86: who has a course coordinator or instructor role in a course will be
                     87: unaffected by any blocking periods for the course, unless the user
                     88: also has a student role in the course, AND has selected the student role.
                     89: 
                     90: =back
                     91: 
                     92: Users can ask LON-CAPA to forward messages to conventional e-mail
                     93: addresses on their B<PREF> screen, but generally, LON-CAPA messages
                     94: are much more useful than traditional email can be made to be, even
                     95: with HTML support.
                     96: 
                     97: =cut
                     98: 
                     99: use strict;
                    100: use Apache::lonnet;
                    101: use HTML::TokeParser();
                    102: use Apache::Constants qw(:common);
                    103: use Apache::loncommon();
1.67      www       104: use Apache::lonhtmlcommon();
1.1       albertel  105: use Apache::lontexconvert();
                    106: use HTML::Entities();
                    107: use Apache::lonlocal;
                    108: use Apache::loncommunicate;
                    109: use Apache::lonfeedback;
                    110: use Apache::lonrss();
1.27      albertel  111: use Apache::lonselstudent();
1.29      www       112: use lib '/home/httpd/lib/perl/';
                    113: use LONCAPA;
1.1       albertel  114: 
                    115: # Querystring component with sorting type
                    116: my $sqs;
                    117: my $startdis;
                    118: 
                    119: # ============================================================ List all folders
                    120: 
                    121: sub folderlist {
1.53      raeburn   122:     my ($folder,$msgstatus) = @_;
1.46      raeburn   123:     my %lt = &Apache::lonlocal::texthash(
                    124:                 actn => 'Action',
                    125:                 fold => 'Folder',
                    126:                 show => 'Show',
1.53      raeburn   127:                 status => 'Message Status',
1.46      raeburn   128:                 go   => 'Go',
1.50      raeburn   129:                 nnff => 'New Name for Folder',
                    130:                 newn => 'New Name',
                    131:                 thfm => 'The folder may not be renamed',
                    132:                 fmnb => 'folder may not be renamed as it is a folder provided by the system.',
                    133:                 asth => 'as this name is already in use for a system-provided or user-defined folder.',
                    134:                 the => 'The',
                    135:                 tnfm => 'The new folder may not be named',
                    136: 
1.46      raeburn   137:     );
                    138: 
1.120   ! kaisler   139: 	# set se lastvisit for the new mail check in the toplevel menu
        !           140: 	&Apache::lonnet::appenv({'user.mailcheck.lastvisit'=>time});
        !           141: 
1.46      raeburn   142:     my %actions = &Apache::lonlocal::texthash(
                    143:                                 view => 'View Folder',
                    144:                                 rename => 'Rename Folder',
                    145:                                 delete => 'Delete Folder',
                    146:     );
                    147:     $actions{'select_form_order'} = ['view','rename','delete'];
                    148: 
1.53      raeburn   149:     my %statushash = &get_msgstatus_types();
                    150: 
                    151:     $statushash{'select_form_order'} = ['','new','read','replied','forwarded'];
                    152: 
1.46      raeburn   153:     my %permfolders = &get_permanent_folders();
                    154:     my $permlist = join("','",sort(keys(%permfolders)));
                    155:     my ($permlistkeys,$permlistvals);
                    156:     foreach my $key (sort(keys(%permfolders))) {
                    157:         $permlistvals .= $permfolders{$key}."','";
                    158:         $permlistkeys .= $key."','";
                    159:     }
                    160:     $permlistvals =~ s/','$//;
                    161:     $permlistkeys =~ s/','$//;
                    162:     my %gotfolders = &Apache::lonmsg::get_user_folders();
                    163:     my %userfolders;
                    164: 
                    165:     foreach my $key (keys(%gotfolders)) {
1.54      albertel  166:         $key =~ s/(['"])/\$1/g; #' stupid emacs
1.46      raeburn   167:         $userfolders{$key} = $key;
                    168:     }
                    169:     my @userorder = sort(keys(%userfolders));
                    170:     my %formhash = (%permfolders,%userfolders);
                    171:     my $folderlist = join("','",@userorder);
                    172:     $folderlist .= "','".$permlistvals;
                    173: 
1.53      raeburn   174:     $formhash{'select_form_order'} = ['','critical',@userorder,'sent','trash'];
1.46      raeburn   175:     my $output = qq|<script type="text/javascript">
                    176: function folder_choice(targetform,caller) {
                    177:     var permfolders_keys = new Array('$permlistkeys');
                    178:     var permfolders_vals = new Array('$permlistvals');
                    179:     var allfolders = new Array('$folderlist');
                    180:     if (caller == 'change') {
                    181:         if (targetform.folderaction.options[targetform.folderaction.selectedIndex].value == 'rename') {
                    182:             for (var i=0; i<permfolders_keys.length; i++) {
                    183:                 if (permfolders_keys[i] == targetform.folder.value) {
1.50      raeburn   184:                     alert("$lt{'the'} '"+permfolders_vals[i]+"' $lt{'fmnb'}");
1.46      raeburn   185:                     return;
                    186:                 }
                    187:             }
1.50      raeburn   188:             var foldername=prompt('$lt{'nnff'}','$lt{'newn'}');
1.46      raeburn   189:             if (foldername) {
                    190:                 targetform.renamed.value=foldername;
                    191:                 for (var i=0; i<allfolders.length; i++) {
                    192:                     if (allfolders[i] == foldername) {
1.50      raeburn   193:                         alert("$lt{'thfm'} '"+foldername+"' $lt{'asth'}");
1.46      raeburn   194:                         return;
                    195:                     }
                    196:                 }
                    197:                 targetform.submit();
                    198:             }
                    199:         }
                    200:         else {
                    201:             targetform.submit();
                    202:         }
                    203:     }
                    204:     if (caller == 'new') {
                    205:         var newname=targetform.newfolder.value;
                    206:         if (newname) {
                    207:             for (var i=0; i<allfolders.length; i++) {
                    208:                 if (allfolders[i] == newname) {
1.50      raeburn   209:                     alert("$lt{'tnfm'} '"+newname+"' $lt{'asth'}");
1.46      raeburn   210:                     return;
                    211:                 }
                    212:             }
                    213:             targetform.submit();
                    214:         }
                    215:     }
                    216: }
                    217: </script>|;
1.57      albertel  218:     my %show = ('select_form_order' => [10,20,50,100,200],
                    219: 		map {$_=>$_} (10,20,50,100,200));
                    220: 		
                    221: 		   
1.46      raeburn   222:     $output .= '
                    223: <form method="post" action="/adm/email" name="folderlist">
                    224: <table border="0" cellspacing="2" cellpadding="2">
                    225:  <tr>
                    226:   <td align="left">
                    227:    <table border="0" cellspacing="2" cellpadding="2">
                    228:     <tr>
                    229:      <td align="center"><b>'.$lt{'fold'}.'</b><br />'."\n".
1.47      albertel  230:          &Apache::loncommon::select_form($folder,'folder',%formhash).'
1.46      raeburn   231:      </td>
1.57      albertel  232:      <td align="center"><b>'.$lt{'show'}.'</b><br />'."\n".
                    233:          &Apache::loncommon::select_form($env{'form.interdis'},'interdis',
                    234: 					 %show).'
1.46      raeburn   235:      </td>
1.53      raeburn   236:      <td align="center"><b>'.$lt{'status'}.'</b><br />'."\n".
                    237:        &Apache::loncommon::select_form($msgstatus,'msgstatus',%statushash).'
                    238:      </td>
1.46      raeburn   239:      <td align="center"><b>'.$lt{'actn'}.'</b><br />'.
1.47      albertel  240:          &Apache::loncommon::select_form('view','folderaction',%actions).'
1.46      raeburn   241:      </td><td><br />'.
                    242:     '<input type="button" value="'.$lt{'go'}.'" onClick="javascript:folder_choice(this.form,'."'change'".');" />
                    243:      </td>
                    244:     </tr>
                    245:    </table>
                    246:   </td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                    247:   <td align="right">
                    248:    <table><tr><td><br />
1.100     schafran  249:     <input type="button" value="'.&mt('New Folder').
1.46      raeburn   250:     '" onClick="javascript:folder_choice(this.form,'."'new'".');" /></td>'.
1.100     schafran  251:     '<td align="center"><b>'.&mt('Name').'</b><br />'.
1.46      raeburn   252:     '<input type="text" size="15" name="newfolder" value="" />
                    253:     </td></tr></table>
                    254:   </td>
                    255:  </tr>
                    256: </table>'."\n".
1.1       albertel  257:     '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" />'.
1.46      raeburn   258:     '<input type="hidden" name="renamed" value="" />'.
1.53      raeburn   259:         ($folder=~/^critical/?'</form>':'');
1.46      raeburn   260:     return $output;
                    261: }
                    262: 
                    263: sub get_permanent_folders {
1.47      albertel  264:     my %permfolders = 
                    265: 	&Apache::lonlocal::texthash(''         => 'INBOX',
                    266: 				    'trash'    => 'TRASH',
                    267: 				    'critical' => 'Critical',
                    268: 				    'sent'     => 'Sent Messages',
                    269: 				    );
1.46      raeburn   270:     return %permfolders;
1.1       albertel  271: }
                    272: 
1.53      raeburn   273: sub get_msgstatus_types {
                    274:     my %statushash = &Apache::lonlocal::texthash(
                    275:                                 '' => 'Any',
                    276:                                 new => 'Unread',
                    277:                                 read => 'Read',
                    278:                                 replied => 'Replied to',
                    279:                                 forwarded => 'Forwarded',
                    280:     );
                    281:     return %statushash;
                    282: }
                    283: 
1.1       albertel  284: sub scrollbuttons {
1.53      raeburn   285:     my ($start,$maxdis,$first,$finish,$total,$msgstatus)=@_;
1.1       albertel  286:     unless ($total>0) { return ''; }
                    287:     $start++; $maxdis++;$first++;$finish++;
1.53      raeburn   288: 
                    289:     my %statushash = &get_msgstatus_types();
                    290:     my $status;
                    291:     if ($msgstatus eq '') {
                    292:         $status = &mt('All');
                    293:     } else {
                    294:         $status = $statushash{$msgstatus};
                    295:     }
1.1       albertel  296:     return
1.53      raeburn   297:    '<b>'.&mt('Page').'</b>: '. 
1.1       albertel  298:    '<input type="submit" name="firstview" value="'.&mt('First').'" />'.
                    299:    '<input type="submit" name="prevview" value="'.&mt('Previous').'" />'.
                    300:    '<input type="text" size="5" name="startdis" value="'.$start.'" onChange="this.form.submit()" /> of '.$maxdis.
                    301:    '<input type="submit" name="nextview" value="'.&mt('Next').'" />'.
                    302:    '<input type="submit" name="lastview" value="'.&mt('Last').'" /><br />'.
1.53      raeburn   303:    &mt('<b>[_1] messages</b>: showing messages [_2] through [_3] of [_4].',$status,$first,$finish,$total).'</form>';
1.1       albertel  304: }
                    305: # =============================================================== Status Change
                    306: 
                    307: sub statuschange {
                    308:     my ($msgid,$newstatus,$folder)=@_;
1.3       albertel  309:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
1.1       albertel  310:     my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
                    311:     if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
                    312:     unless ($status{$msgid}) { $status{$msgid}='new'; }
                    313:     unless (($status{$msgid} eq 'replied') || 
                    314:             ($status{$msgid} eq 'forwarded')) {
                    315: 	&Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
                    316:     }
                    317:     if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {
                    318: 	&Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
                    319:     }
                    320:     if ($newstatus eq 'deleted') {
1.9       albertel  321: 	return &movemsg($msgid,$folder,'trash');
                    322:     }
                    323:     return ;
1.1       albertel  324: }
                    325: 
                    326: # ============================================================= Make new folder
                    327: 
                    328: sub makefolder {
1.46      raeburn   329:     my ($newfolder) = @_;
                    330:     my %permfolders = &get_permanent_folders();
                    331:     my %userfolders = &Apache::lonmsg::get_user_folders();
                    332:     my ($outcome,$warning);
                    333:     if (defined($userfolders{$newfolder})) {
                    334:         return &mt('The folder name: "[_1]" is already in use for an existing folder.',$newfolder);
                    335:     }
                    336:     foreach my $perm (keys(%permfolders)) {
                    337:         if ($permfolders{$perm} eq $newfolder) {
                    338:             return &mt('The folder name: "[_1]" is already used for one of the folders automatically generated by the system.',$newfolder);
                    339:         }
                    340:     } 
                    341:     if (&get_msgfolder_lock() eq 'ok') {
                    342:         my %counter_hash = &Apache::lonnet::get('email_folders',["\0".'idcount']);
                    343:         my $lastcount = $counter_hash{"\0".'idcount'};
                    344:         my $folder_id = $lastcount + 1;
                    345:         while (defined($userfolders{$folder_id})) {
                    346:             $folder_id ++;
                    347:         }
1.47      albertel  348:         my %folderinfo = ( id      => $folder_id,
                    349:                            created => time, );
1.46      raeburn   350:         $outcome =  
1.47      albertel  351: 	    &Apache::lonnet::put('email_folders',{$newfolder => \%folderinfo,
                    352: 						  "\0".'idcount' => $folder_id});
1.46      raeburn   353:         my $releaseresult = &release_msgfolder_lock();
                    354:         if ($releaseresult ne 'ok') {
                    355:             $warning = $releaseresult;
                    356:         }
                    357:     } else {
1.47      albertel  358:         $outcome = 
1.104     raeburn   359: 	    &mt('Error - could not obtain lock on message folders record.');
1.46      raeburn   360:     }
                    361:     return ($outcome,$warning);
1.1       albertel  362: }
                    363: 
1.46      raeburn   364: # ============================================================= Delete folder
                    365: 
                    366: sub deletefolder {
                    367:     my ($folder)=@_;
                    368:     my %permfolders = &get_permanent_folders();
                    369:     if (defined($permfolders{$folder})) {
1.56      albertel  370:         return &mt('The folder "[_1]" may not be deleted',$folder); 
1.46      raeburn   371:     }
                    372:     my %userfolders = &Apache::lonmsg::get_user_folders();
                    373:     if (!defined($userfolders{$folder})) {
1.56      albertel  374:         return &mt('The folder "[_1]" does not exist so deletion is not required.',
1.46      raeburn   375:                    $folder);
                    376:     }
                    377:     # check folder is empty;
                    378:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
                    379:     my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
                    380:     if (@messages > 0) {
1.56      albertel  381:         return &mt('The folder "[_1]" contains messages so it may not be deleted.',$folder).
1.46      raeburn   382:                '<br />'.
                    383:                &mt('Delete or move the messages to a different folder first.');
                    384:     }
                    385:     my $delresult = &Apache::lonnet::del('email_folders',[$folder]);
                    386:     return $delresult;
                    387: }
                    388: 
                    389: sub renamefolder {
                    390:     my ($folder) = @_;
                    391:     my $newname = $env{'form.renamed'};
                    392:     my %permfolders = &get_permanent_folders();
                    393:     if ($env{'form.renamed'} eq '') {
                    394:         return &mt('The folder "[_1]" may not be renamed to "[_2]" as the new name you requested is an invalid name.',$folder,$newname);
                    395:     }
1.73      raeburn   396:     if (defined($permfolders{$folder})) {
                    397:         return &mt('The folder "[_1]" may not be renamed as it is a folder provided by the system.',$folder);
                    398:     }
1.46      raeburn   399:     if (defined($permfolders{$newname})) {
                    400:         return &mt('The folder "[_1]" may not be renamed to "[_2]" as the new name you requested is reserved for folders provided automatically by the system.',$folder,$newname);
                    401:     }
                    402:     my %userfolders = &Apache::lonmsg::get_user_folders();
                    403:     if (defined($userfolders{$newname})) {
                    404:         return &mt('The folder "[_1]" may not be renamed to "[_2]" because the new name you requested is already being used for an existing folder.',$folder,$newname);
                    405:     }
                    406:     if (!defined($userfolders{$folder})) {
                    407:         return &mt('The folder "[_1]" could not be renamed to "[_2]" because the folder does not exist.',$folder,$newname);
                    408:     }
                    409:     my %folderinfo;
                    410:     if (ref($userfolders{$folder}) eq 'HASH') {
                    411:         %folderinfo = %{$userfolders{$folder}};
                    412:     } else {
1.47      albertel  413:         %folderinfo = ( id      => $folder,
                    414:                         created => $userfolders{$folder},);
1.46      raeburn   415:     }
                    416:     my $outcome =
                    417:      &Apache::lonnet::put('email_folders',{$newname => \%folderinfo});
                    418:     if ($outcome eq 'ok') {
                    419:         $outcome = &Apache::lonnet::del('email_folders',[$folder]);
                    420:     }
                    421:     return $outcome;
                    422: }
                    423: 
                    424: sub get_msgfolder_lock {
                    425:     # get lock for mail folder counter.
1.47      albertel  426:     my $lockhash = { "\0".'lock_counter' => time, };
1.46      raeburn   427:     my $tries = 0;
                    428:     my $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
                    429:     while (($gotlock ne 'ok') && $tries <3) {
                    430:         $tries ++;
1.47      albertel  431:         sleep(1);
1.46      raeburn   432:         $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
                    433:     }
                    434:     return $gotlock;
                    435: }
                    436: 
                    437: sub release_msgfolder_lock {
                    438:     #  remove lock
                    439:     my @del_lock = ("\0".'lock_counter');
                    440:     my $dellockoutcome=&Apache::lonnet::del('email_folders',\@del_lock);
                    441:     if ($dellockoutcome ne 'ok') {
                    442:         return ('<br />'.&mt('Warning: failed to release lock for counter').'<br />');
                    443:     } else {
                    444:         return 'ok';
                    445:     }
                    446: }
                    447: 
                    448: 
1.1       albertel  449: # ======================================================== Move between folders
                    450: 
                    451: sub movemsg {
                    452:     my ($msgid,$srcfolder,$trgfolder)=@_;
                    453:     if ($srcfolder eq 'new') { $srcfolder=''; }
1.3       albertel  454:     my $srcsuffix=&Apache::lonmsg::foldersuffix($srcfolder);
                    455:     my $trgsuffix=&Apache::lonmsg::foldersuffix($trgfolder);
1.9       albertel  456:     if ($srcsuffix eq $trgsuffix) {
                    457: 	return (0,&mt('Message not moved, Attempted to move message to the same folder as it already is in.'));
                    458:     }
1.1       albertel  459: 
                    460: # Copy message
                    461:     my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]);
1.9       albertel  462:     if (!exists($message{$msgid}) || $message{$msgid} eq '') {
1.32      albertel  463: 	if (&Apache::lonnet::error(%message)) {
1.9       albertel  464: 	    return (0,&mt('Message not moved, A network error occurred.'));
                    465: 	} else {
                    466: 	    return (0,&mt('Message not moved as the message is no longer in the source folder.'));
                    467: 	}
                    468:     }
                    469: 
                    470:     my $result =&Apache::lonnet::put('nohist_email'.$trgsuffix,
                    471: 				     {$msgid => $message{$msgid}});
1.32      albertel  472:     if (&Apache::lonnet::error($result)) {
1.9       albertel  473: 	return (0,&mt('Message not moved, A network error occurred.'));
                    474:     }
1.1       albertel  475: 
                    476: # Copy status
                    477:     unless ($trgfolder eq 'trash') {
1.9       albertel  478:        	my %status=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);
                    479: 	# a non-existant status is the mark of an unread msg
1.32      albertel  480: 	if (&Apache::lonnet::error(%status)) {
1.9       albertel  481: 	    return (0,&mt('Message copied to new folder but status was not, A network error occurred.'));
                    482: 	}
                    483: 	my $result=&Apache::lonnet::put('email_status'.$trgsuffix,
                    484: 					{$msgid => $status{$msgid}});
1.32      albertel  485: 	if (&Apache::lonnet::error($result)) {
1.9       albertel  486: 	    return (0,&mt('Message copied to new folder but status was not, A network error occurred.'));
                    487: 	}
1.1       albertel  488:     }
1.9       albertel  489: 
1.1       albertel  490: # Delete orginals
1.9       albertel  491:     my $result_del_msg = 
                    492: 	&Apache::lonnet::del('nohist_email'.$srcsuffix,[$msgid]);
                    493:     my $result_del_stat =
                    494: 	&Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
1.32      albertel  495:     if (&Apache::lonnet::error($result_del_msg)) {
1.9       albertel  496: 	return (0,&mt('Message copied, but unable to delete the original from the source folder.'));
                    497:     }
1.32      albertel  498:     if (&Apache::lonnet::error($result_del_stat)) {
1.9       albertel  499: 	return (0,&mt('Message copied, but unable to delete the original status from the source folder.'));
                    500:     }
                    501: 
                    502:     return (1);
1.1       albertel  503: }
                    504: 
                    505: # ======================================================= Display a course list
                    506: 
                    507: sub discourse {
1.95      raeburn   508:     my ($statushash) = @_;
                    509:     my ($result,$active,$previous,$future);
1.25      foxr      510:     my ($course_personnel,
                    511: 	$current_members,
                    512: 	$expired_members,
1.28      foxr      513: 	$future_members) = 
                    514: 	    &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
1.25      foxr      515:     unshift @$current_members, (@$course_personnel);
                    516:     my %defaultUsers;
1.40      albertel  517:     
1.87      bisitz    518:     my $tmptext;
                    519:     if ($tmptext = &Apache::lonselstudent::render_student_list($current_members,
1.95      raeburn   520:                                                                "activeusers",
1.87      bisitz    521:                                                                "current",
                    522:                                                                \%defaultUsers,
1.95      raeburn   523:                                                                1,"selectedusers",1,'email')
1.87      bisitz    524:        ) {
1.95      raeburn   525:        $result .= '<fieldset id="LC_activeusers"><legend><b>'.&mt('Bcc: course members with current access').'</b></legend><form name="activeusers">';
                    526:        $result .= $tmptext.'</form></fieldset><br />';
                    527:        if (ref($statushash) eq 'HASH') {
                    528:            $statushash->{'active'} = 1;
                    529:        }
1.87      bisitz    530:     }
                    531:     if ($tmptext = &Apache::lonselstudent::render_student_list($expired_members,
1.95      raeburn   532:                                                                "previoususers",
1.87      bisitz    533:                                                                "expired",
                    534:                                                                \%defaultUsers,
1.95      raeburn   535:                                                                1, "selectedusers",0,'email')
1.87      bisitz    536:        ) {
1.95      raeburn   537:        $result .= '<fieldset id="LC_previoususers"><legend><b>'.&mt('Bcc: course members with expired access').'</b></legend><form name="previoususers">';
                    538:        $result .= $tmptext.'</form></fieldset><br />';
                    539:        if (ref($statushash) eq 'HASH') {
                    540:            $statushash->{'previous'} = 1;
                    541:        }
                    542: 
1.87      bisitz    543:     }
                    544:     if ($tmptext = &Apache::lonselstudent::render_student_list($future_members,
1.95      raeburn   545:                                                                "futureusers",
1.87      bisitz    546:                                                                "future",
                    547:                                                                \%defaultUsers,
1.95      raeburn   548:                                                                1, "selectedusers",0,'email')
1.87      bisitz    549:        ) {
1.95      raeburn   550:        $result .= '<fieldset id="LC_futureusers"><legend><b>'.&mt('Bcc: course members with future access').'</b></legend><form name="previoususers">';
                    551:        $result .= $tmptext.'</form></fieldset>';
                    552:        if (ref($statushash) eq 'HASH') {
                    553:            $statushash->{'future'} = 1;
                    554:        }
                    555: 
1.87      bisitz    556:     }
1.25      foxr      557:     return $result;
                    558: }
                    559: 
1.38      raeburn   560: sub disgroup {
1.105     raeburn   561:     my ($r,$cdom,$cnum,$group,$access_status) = @_;
                    562:     my $hasfloat;
1.38      raeburn   563:     #  Needs to be in a course
                    564:     if (!($env{'request.course.fn'})) {
1.105     raeburn   565:         $r->print('<span class="LC_error">'.&mt('Error: you must have a course role selected to be able to send a broadcast message to a group in the course.').'</span>');
                    566:         return;
1.38      raeburn   567:     }
                    568:     if ($cdom eq '' || $cnum eq '') {
1.105     raeburn   569:         $r->print('<span class="LC_error">'.&mt('Error: could not determine domain or number of course').'</span>');
                    570:         return;
1.38      raeburn   571:     }
                    572:     my ($memberinfo,$numitems) =
                    573:                  &Apache::longroup::group_memberlist($cdom,$cnum,$group,{},[]);
                    574:     my @statustypes = ('active');
1.95      raeburn   575:     my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.
                    576:                    ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
                    577:     my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'}.
                    578:                    ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
1.38      raeburn   579:     if ($viewgrps || $editgrps) {
                    580:         push(@statustypes,('future','previous'));
                    581:     }
                    582:     if (keys(%{$memberinfo}) == 0) {
1.105     raeburn   583:         $r->print('<span class="LC_warning">'.
                    584:                   &mt('As this group has no members, there are no recipients to select').
                    585:                   '</span>');
                    586:         return;
1.38      raeburn   587:     } else {
1.105     raeburn   588:         $hasfloat = 1;
1.110     raeburn   589:         unless($env{'environment.wysiwygeditor'} eq 'on') {
                    590:             $r->print('<div class="LC_left_float">');
                    591:         }
1.38      raeburn   592:         my %Sortby = (
                    593:                          active   => {},
                    594:                          previous => {},
                    595:                          future   => {},
                    596:                      );
                    597:         my %lt = &Apache::lonlocal::texthash(
                    598:                                      'name'     => 'Name',
                    599:                                      'usnm'     => 'Username',
                    600:                                      'doma'     => 'Domain',
1.95      raeburn   601:                                      'active'   => 'Broadcast to Active Members',
                    602:                                      'previous' => 'Broadcast (Bcc) to Former Members',
                    603:                                      'future'   => 'Broadcast (Bcc) to Future Members',
1.38      raeburn   604:                                     );
                    605:         foreach my $user (sort(keys(%{$memberinfo}))) {
                    606:             my $status = $$memberinfo{$user}{status};
                    607:             if ($env{'form.'.$status.'.sortby'} eq 'fullname') {
                    608:                 push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
                    609:             } elsif ($env{'form.'.$status.'.sortby'} eq 'username') {
                    610:                 push(@{$Sortby{$status}{$$memberinfo{$user}{uname}}},$user);
                    611:             } elsif ($env{'form.'.$status.'.sortby'} eq 'domain') {
                    612:                 push(@{$Sortby{$status}{$$memberinfo{$user}{udom}}},$user);
                    613:             } else {
                    614:                 push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
                    615:             }
                    616:         }
1.105     raeburn   617:         $r->print(&group_check_uncheck());
1.38      raeburn   618:         foreach my $status (@statustypes)  {
                    619:             if (ref($numitems) eq 'HASH') {
                    620:                 if ((defined($$numitems{$status})) && ($$numitems{$status})) {
1.95      raeburn   621:                     my $formname = $status.'users';
                    622:                     if (ref($access_status) eq 'HASH') {
                    623:                         $access_status->{$status} = $$numitems{$status};
                    624:                     }
1.105     raeburn   625:                     $r->print('<fieldset><legend><b>'.$lt{$status}.
                    626:                               '</b></legend><form name="'.$formname.'">'.
                    627:                               '<span class="LC_nobreak">'.
                    628:                               '<input type="button" value="'.&mt('Check All').'" '.
                    629:                               'onclick="javascript:toggleAll('."this.form,'check'".')" />'.
                    630:                               '&nbsp;&nbsp;'.
                    631:                               '<input type="button" value="'.&mt('Uncheck All').'" '.
                    632:                               'onclick="javascript:toggleAll('."this.form,'uncheck'".')" />'.
                    633:                               '</span>');
1.95      raeburn   634:                     if ($status eq 'active') {
1.105     raeburn   635:                         $r->print(('&nbsp;'x3).'<select name="groupmail">'.
                    636:                                  '<option value="bcc" selected="selected">'.&mt('Bcc').'</option>'.
                    637:                                  '<option value="cc">'.&mt('Cc').'</option>'.
                    638:                                '</select>');
1.95      raeburn   639:                     }
1.105     raeburn   640:                     $r->print('<br />'.&Apache::loncommon::start_data_table().
1.95      raeburn   641:                                &Apache::loncommon::start_data_table_header_row().
1.105     raeburn   642:                                "<th>$lt{'name'}</th>".
                    643:                                "<th>$lt{'usnm'}</th>".
                    644:                                "<th>$lt{'doma'}</th>".
                    645:                                &Apache::loncommon::end_data_table_header_row());
1.38      raeburn   646:                     foreach my $key (sort(keys(%{$Sortby{$status}}))) {
                    647:                         foreach my $user (@{$Sortby{$status}{$key}}) {
1.105     raeburn   648:                             $r->print(&Apache::loncommon::start_data_table_row().
                    649:                                 '<td><span class="LC_nobreak"><input type="checkbox" '.
1.38      raeburn   650:                                 'name="selectedusers_forminput" value="'.
                    651:                                 $user.':'.$status.'" />'.
1.105     raeburn   652:                                 $$memberinfo{$user}{'fullname'}.'</span></td>'.
1.38      raeburn   653:                                 '<td>'.$$memberinfo{$user}{'uname'}.'</td>'.
                    654:                                 '<td>'.$$memberinfo{$user}{'udom'}.'</td>'.
1.105     raeburn   655:                                 &Apache::loncommon::end_data_table_row());
1.38      raeburn   656:                         }
                    657:                     }
1.105     raeburn   658:                     $r->print(&Apache::loncommon::end_data_table().'</form>'.
1.110     raeburn   659:                               '</fieldset><br />');
1.38      raeburn   660:                 }
                    661:             }
                    662:         }
1.110     raeburn   663:         unless($env{'environment.wysiwygeditor'} eq 'on') {
                    664:             $r->print('</div>');
                    665:         }
1.38      raeburn   666:     }
1.105     raeburn   667:     return $hasfloat;
1.38      raeburn   668: }
                    669: 
                    670: sub group_check_uncheck {
                    671:     my $output = qq|
                    672: <script type="text/javascript">
1.95      raeburn   673: function toggleAll(form,action) {
                    674:     if (typeof(form.selectedusers_forminput.length)=="undefined") {
                    675:          if (action == 'check') {
                    676:             form.selectedusers_forminput.checked = true;
                    677:          } else {
                    678:             form.selectedusers_forminput.checked = false;
                    679:         }
                    680:     } else {
                    681:         for (var i=0; i<form.selectedusers_forminput.length; i++) {
1.38      raeburn   682:             if (action == 'check') {
1.95      raeburn   683:                 form.selectedusers_forminput[i].checked = true;
1.38      raeburn   684:             } else {
1.95      raeburn   685:                 form.selectedusers_forminput[i].checked = false;
1.38      raeburn   686:             }
                    687:         }
                    688:     }
                    689: }
                    690: </script>
                    691:     |;
                    692: }
                    693: 
                    694: sub groupmail_header {
                    695:     my ($action,$group,$cdom,$cnum) = @_;
                    696:     my ($description,$refarg);
                    697:     if (!$cdom || !$cnum) {
                    698:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    699:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    700:     }
                    701:     if (exists($env{'form.ref'})) {
                    702:         $refarg = 'ref='.$env{'form.ref'};
                    703:     }
                    704:     if (!$group) {
                    705:         $group = $env{'form.group'};
                    706:     }
                    707:     if ($group eq '') {
                    708:         return  '';
                    709:     } else {
                    710:         my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$group);
                    711:         if (defined($curr_groups{$group})) {
                    712:             my %groupinfo =
                    713:                     &Apache::longroup::get_group_settings($curr_groups{$group});
                    714:             $description = &unescape($groupinfo{'description'});
                    715:         }
                    716:     }
                    717:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                    718:     if ($refarg) {
                    719:         &Apache::lonhtmlcommon::add_breadcrumb
                    720:             ({href=>"/adm/coursegroups",
                    721:               text=>"Groups",
                    722:               title=>"View course groups"});
                    723:     }
                    724:     &Apache::lonhtmlcommon::add_breadcrumb
                    725:         ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
                    726:           text=>"Group: $description",
                    727:           title=>"Go to group's home page"},
                    728:          {href=>"/adm/email?compose=group&amp;group=".
                    729:                 "$env{'form.group'}&amp;$refarg",
                    730:           text=>"Send a Message in a Group",
1.99      schafran  731:           title=>"Compose Group Message"},);
1.38      raeburn   732:     if ($action eq 'sending') {
                    733:             &Apache::lonhtmlcommon::add_breadcrumb
1.99      schafran  734:                          ({text=>"Messages being sent.",
1.96      schafran  735:                            title=>"E-mails sent"},);
1.38      raeburn   736:     }
1.99      schafran  737:     my $groupheader = &Apache::loncommon::start_page('Group Message');
1.38      raeburn   738:     $groupheader .= &Apache::lonhtmlcommon::breadcrumbs
                    739:                 ('Group - '.$env{'form.group'}.' Email');
                    740:     return $groupheader;
                    741: }
                    742: 
                    743: sub groupmail_sent {
                    744:     my ($group,$cdom,$cnum) = @_;
                    745:     my $refarg;
                    746:     if (exists($env{'form.ref'})) {
                    747:         $refarg = 'ref='.$env{'form.ref'};
                    748:     }
                    749:     my $output .= '<br /><br /><a href="/adm/email?compose=group&amp;group='.
                    750:                   $group.'&amp;'.$refarg.'">'.
1.99      schafran  751:                   &mt('Send another group message').'</a>'.'&nbsp;&nbsp;&nbsp;'.
1.38      raeburn   752:                   '<a href="/adm/'.$cdom.'/'.$cnum.'/'.$group.'/smppg?'.
                    753:                   $refarg.'">'. &mt('Return to group page').'</a>';
                    754:     return $output;
                    755: }
                    756: 
1.1       albertel  757: # ==================================================== Display Critical Message
                    758: 
                    759: sub discrit {
                    760:     my $r=shift;
1.89      bisitz    761:     my $header = '<h1>'.&mt('Critical Messages').'</h1>'
                    762:                 .'<div class="LC_warning">'
                    763:                 .&mt('Access to other pages will be prevented until you have moved all critical messages to your inbox.')
                    764:                 .'</div><br />'
                    765:                 .'<form action="/adm/email" method="POST">'
                    766:                 .'<input type="hidden" name="confirm" value="true" />';
1.1       albertel  767:     my %what=&Apache::lonnet::dump('critical');
                    768:     my $result = '';
1.42      raeburn   769:     foreach my $key (sort(keys(%what))) {
                    770:         my %content=&Apache::lonmsg::unpackagemsg($what{$key});
1.1       albertel  771:         next if ($content{'senderdomain'} eq '');
1.88      bisitz    772:         $result .= &Apache::lonhtmlcommon::start_pick_box()
                    773:                   .&Apache::lonhtmlcommon::row_title(&mt('From'),undef,'LC_oddrow_value')
                    774:                   .'<b>'.&Apache::loncommon::aboutmewrapper(
                    775:                    &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b>'
                    776:                   .' ('.$content{'sendername'}.':'.$content{'senderdomain'}.')'
                    777:                   .&Apache::lonhtmlcommon::row_closure(1)
                    778:                   .&Apache::lonhtmlcommon::row_title(&mt('Date'),undef,'LC_evenrow_value')
                    779:                   .$content{'time'}
                    780:                   .&Apache::lonhtmlcommon::row_closure(1)
                    781:                   .&Apache::lonhtmlcommon::row_title(&mt('Subject'),undef,'LC_oddrow_value')
                    782:                   .$content{'subject'}
                    783:                   .&Apache::lonhtmlcommon::row_closure(1)
                    784:                   .&Apache::lonhtmlcommon::row_title(&mt('Message'),undef,'LC_evenrow_value')
                    785:                   .'<pre>'.&Apache::lontexconvert::msgtexconverted($content{'message'}).'</pre>'
                    786:                   .&Apache::lonhtmlcommon::row_closure()
                    787:                   .&Apache::lonhtmlcommon::row_title('',undef,'LC_oddrow_value')
                    788:                   .'<div class="LC_warning">';
1.78      raeburn   789:         my ($rec_button,$reprec_button);
                    790:         $rec_button = &mt('Move to Inbox');
                    791:         if (!$content{'noreplies'}) {
                    792:             $reprec_button = &mt('Move to Inbox/Compose reply');
                    793:         }
1.75      raeburn   794:         if ($content{'sendback'}) {
                    795:             $rec_button = &mt('Confirm Receipt');
1.78      raeburn   796:             if (!$content{'noreplies'}) {
                    797:                 $reprec_button = &mt('Confirm Receipt and Reply');
                    798:             }
1.75      raeburn   799:             $result .= &mt('You have to confirm that you have received this message before you can view other pages. After confirmation, this message will be moved to your regular inbox');
                    800:         } else {
1.78      raeburn   801:             $result .= &mt('Access to other pages will be prevented until you have moved the message to your inbox.'); 
1.75      raeburn   802:         }
1.88      bisitz    803:         $result .= '</div>'
                    804:                   .&Apache::lonhtmlcommon::row_closure(1)
                    805:                   .&Apache::lonhtmlcommon::row_title('',undef,'LC_evenrow_value')
                    806:                   .'<input type="submit" name="rec_'.$key.'" value="'.$rec_button.'" />';
1.78      raeburn   807:         if (!$content{'noreplies'}) {
1.88      bisitz    808:             $result .= '<input type="submit" name="reprec_'.$key.'" '
                    809:                       .'value="'.$reprec_button.'" />'
1.78      raeburn   810:         }
1.88      bisitz    811:         $result .= &Apache::lonhtmlcommon::row_closure(1)
                    812:                   .&Apache::lonhtmlcommon::end_pick_box()
                    813:                   .'<br />';
1.1       albertel  814:     }
                    815:     # Check to see if there were any messages.
                    816:     if ($result eq '') {
                    817:         $result = "<h2>".&mt('You have no critical messages.')."</h2>".
1.38      raeburn   818: 	    '<a href="/adm/roles">'.&mt('Select a course').'</a><br />'.
1.1       albertel  819:             '<a href="/adm/email">'.&mt('Communicate').'</a>';
                    820:     } else {
                    821:         $r->print($header);
                    822:     }
                    823:     $r->print($result);
                    824:     $r->print('<input type="hidden" name="displayedcrit" value="true" /></form>');
                    825: }
                    826: 
                    827: sub sortedmessages {
1.53      raeburn   828:     my ($blocked,$startblock,$endblock,$numblocked,$folder,$msgstatus) = @_;
1.1       albertel  829:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
                    830:     my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
                    831:     #unpack the varibles and repack into temp for sorting
                    832:     my @temp;
                    833:     my %descriptions;
                    834:     my %status_cache = 
                    835: 	&Apache::lonnet::get('email_status'.&Apache::lonmsg::foldersuffix($folder),\@messages);
1.11      albertel  836: 
                    837:     my $get_received;
                    838:     if ($folder eq 'sent' 
                    839: 	&& ($env{'form.sortedby'} =~ m/^(rev)?(user|domain)$/)) {
                    840: 	$get_received = 1;
                    841:     }
                    842: 
                    843:     foreach my $msgid (@messages) {
1.114     raeburn   844:         next if ($msgid eq '');
1.29      www       845: 	my $esc_msgid=&escape($msgid);
1.59      raeburn   846: 	my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,$processid,$symb,$error) =
1.11      albertel  847: 	    &Apache::lonmsg::unpackmsgid($esc_msgid,$folder,undef,
1.1       albertel  848: 					 \%status_cache);
1.53      raeburn   849:         next if ($msgstatus ne '' && $msgstatus ne $status);
1.1       albertel  850:         my $description = &get_course_desc($fromcid,\%descriptions);
                    851: 	my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
1.11      albertel  852: 		     $esc_msgid,$description);
                    853: 	if ($get_received) {
                    854: 	    my %message = &Apache::lonnet::get('nohist_email'.$suffix,
                    855: 					       [$msgid]);
                    856: 	    my %content = &Apache::lonmsg::unpackagemsg($message{$msgid});
                    857: 	    push(@temp1,$content{'recuser'},$content{'recdomain'});
                    858: 	}
1.1       albertel  859:         # Check whether message was sent during blocking period.
                    860:         if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {
1.11      albertel  861:             $$blocked{$msgid} = 'ON';
1.1       albertel  862:             $$numblocked ++;
                    863:         } else { 
                    864:             push @temp ,\@temp1;
                    865:         }
                    866:     }
                    867:     #default sort
                    868:     @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
                    869:     if ($env{'form.sortedby'} eq "date"){
                    870:         @temp = sort  {$a->[0] <=> $b->[0]} @temp;    
                    871:     }
                    872:     if ($env{'form.sortedby'} eq "revdate"){
                    873:     	@temp = sort  {$b->[0] <=> $a->[0]} @temp; 
                    874:     }
                    875:     if ($env{'form.sortedby'} eq "user"){
1.11      albertel  876: 	if ($get_received) {
                    877: 	    @temp = sort  {lc($a->[7][0]) cmp lc($b->[7][0])} @temp;
                    878: 	} else {
                    879: 	    @temp = sort  {lc($a->[2])    cmp lc($b->[2])}    @temp;
                    880: 	}
1.1       albertel  881:     }
                    882:     if ($env{'form.sortedby'} eq "revuser"){
1.11      albertel  883: 	if ($get_received) {
                    884: 	    @temp = sort  {lc($b->[7][0]) cmp lc($a->[7][0])} @temp;
                    885: 	} else {
                    886: 	    @temp = sort  {lc($b->[2])    cmp lc($a->[2])}    @temp;
                    887: 	}
1.1       albertel  888:     }
                    889:     if ($env{'form.sortedby'} eq "domain"){
1.11      albertel  890: 	if ($get_received) {
                    891: 	    @temp = sort  {$a->[8][0] cmp $b->[8][0]} @temp;
                    892: 	} else {
                    893: 	    @temp = sort  {$a->[3]    cmp $b->[3]}    @temp;
                    894: 	}
1.1       albertel  895:     }
                    896:     if ($env{'form.sortedby'} eq "revdomain"){
1.11      albertel  897: 	if ($get_received) {
                    898: 	    @temp = sort  {$b->[8][0] cmp $a->[8][0]} @temp;
                    899: 	} else {
                    900: 	    @temp = sort  {$b->[3]    cmp $a->[3]}    @temp;
                    901: 	}
1.1       albertel  902:     }
                    903:     if ($env{'form.sortedby'} eq "subject"){
                    904:         @temp = sort  {lc($a->[1]) cmp lc($b->[1])} @temp;
                    905:     }
                    906:     if ($env{'form.sortedby'} eq "revsubject"){
                    907:         @temp = sort  {lc($b->[1]) cmp lc($a->[1])} @temp;
                    908:     }
                    909:     if ($env{'form.sortedby'} eq "course"){
                    910:         @temp = sort  {lc($a->[6]) cmp lc($b->[6])} @temp;
                    911:     }
                    912:     if ($env{'form.sortedby'} eq "revcourse"){
                    913:         @temp = sort  {lc($b->[6]) cmp lc($a->[6])} @temp;
                    914:     }
                    915:     if ($env{'form.sortedby'} eq "status"){
                    916:         @temp = sort  {$a->[4] cmp $b->[4]} @temp;
                    917:     }
                    918:     if ($env{'form.sortedby'} eq "revstatus"){
                    919:         @temp = sort  {$b->[4] cmp $a->[4]} @temp;
                    920:     }
                    921:     return @temp;
                    922: }
                    923: 
                    924: sub get_course_desc {
                    925:     my ($fromcid,$descriptions) = @_;
                    926:     my $description;
                    927:     if (!$fromcid) {
                    928:         return $description;
                    929:     } else {
                    930:         if (defined($$descriptions{$fromcid})) {
                    931:             $description = $$descriptions{$fromcid};
                    932:         } else {
                    933:             if (defined($env{'course.'.$fromcid.'.description'})) {
                    934:                 $description = $env{'course.'.$fromcid.'.description'};
                    935:             } else {
1.48      albertel  936:                 my %courseinfo=&Apache::lonnet::coursedescription($fromcid);
1.1       albertel  937:                 $description = $courseinfo{'description'};
                    938:             }
                    939:             $$descriptions{$fromcid} = $description;
                    940:         }
                    941:         return $description;
                    942:     }
                    943: }
                    944: 
                    945: # ======================================================== Display all messages
                    946: 
                    947: sub disall {
1.53      raeburn   948:     my ($r,$folder,$msgstatus)=@_;
1.81      albertel  949:     my %saveable = ('msgstatus' => 'scalar',
1.57      albertel  950: 		    'sortedby'  => 'scalar',
                    951: 		    'interdis'  => 'scalar',
                    952: 		    );
                    953:     &Apache::loncommon::store_settings('user','mail',\%saveable);
                    954:     &Apache::loncommon::restore_settings('user','mail',\%saveable);
                    955:     $folder    ||= $env{'form.folder'};
                    956:     $msgstatus ||= $env{'form.msgstatus'};
                    957:     $env{'form.interdis'} ||= 20;
                    958: 
1.53      raeburn   959:     $r->print(&folderlist($folder,$msgstatus));
                    960:     if ($folder eq 'critical') {
1.1       albertel  961: 	&discrit($r);
                    962:     } else {
1.53      raeburn   963: 	&disfolder($r,$folder,$msgstatus);
1.1       albertel  964:     }
                    965: }
                    966: 
                    967: # ============================================================ Display a folder
                    968: 
                    969: sub disfolder {
1.53      raeburn   970:     my ($r,$folder,$msgstatus)=@_;
                    971:     my %statushash = &get_msgstatus_types();
1.1       albertel  972:     my %blocked = ();
                    973:     my %setters = ();
                    974:     my $numblocked = 0;
1.44      raeburn   975:     my ($startblock,$endblock) = &Apache::loncommon::blockcheck(\%setters,'com');
1.53      raeburn   976:     my %lt = &Apache::lonlocal::texthash(
                    977:                       sede => 'Select a destination folder to which the messages will be moved.',
                    978:                       nome => 'No messages have been selected to apply ths action to.',
                    979:                       chec => 'Check the checkbox for at least one message.',  
                    980:     );
1.64      raeburn   981:     my $jscript = &Apache::loncommon::check_uncheck_jscript();
1.1       albertel  982:     $r->print(<<ENDDISHEADER);
1.16      albertel  983: <script type="text/javascript">
1.64      raeburn   984:     $jscript
1.1       albertel  985: 
1.53      raeburn   986:     function validate_checkedaction() {
                    987:         document.disall.markedaction.value = document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value;
                    988:         if (document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value == 'markedmove') {
                    989:             if (document.disall.movetofolder.options[document.disall.movetofolder.selectedIndex].value == "") {
                    990:                 alert("$lt{'sede'}");
                    991:                 return;
                    992:             } 
                    993:         }
                    994:         var checktotal = 0;
1.64      raeburn   995:         if (document.forms.disall.delmark.length > 0) {
                    996:             for (var i=0; i<document.forms.disall.delmark.length; i++) {
                    997:                 if (document.forms.disall.delmark[i].checked) {
                    998:                     checktotal ++;
                    999:                 }
                   1000:             }
                   1001:         } else {
                   1002:             if (document.forms.disall.delmark.checked) {
1.53      raeburn  1003:                 checktotal ++;
                   1004:             }
1.64      raeburn  1005:         }   
1.53      raeburn  1006:         if (checktotal == 0) {
                   1007:             alert("$lt{'nome'}\\n$lt{'chec'}");
                   1008:             return;
                   1009:         }
                   1010:         document.disall.submit();
                   1011:     }
                   1012: 
1.1       albertel 1013: </script>
                   1014: ENDDISHEADER
1.54      albertel 1015: 
1.1       albertel 1016:     my $fsqs='&folder='.$folder;
1.53      raeburn  1017:     my @temp=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder,$msgstatus);
1.1       albertel 1018:     my $totalnumber=$#temp+1;
1.53      raeburn  1019:     if ($totalnumber < 1) {
                   1020:         if ($msgstatus eq '') {
                   1021: 	    $r->print('<h2>'.&mt('Empty Folder').'</h2>');
                   1022:         } elsif ($msgstatus eq 'replied') {
                   1023:             $r->print('<h2>'.&mt('You have not replied to any messages in this folder.').'</h2>');
                   1024:         } else { 
1.55      albertel 1025:             $r->print('<h2>'.&mt('There are no '.lc($statushash{$msgstatus}).' messages in this folder.').'</h2>');
1.53      raeburn  1026:         }
1.65      raeburn  1027:         if ($numblocked > 0) {
                   1028:             $r->print(&blocked_in_folder($numblocked,$startblock,$endblock,
                   1029:                                          \%setters));
                   1030:         }
1.1       albertel 1031: 	return;
                   1032:     }
1.57      albertel 1033:     my $interdis = $env{'form.interdis'};
1.1       albertel 1034:     my $number=int($totalnumber/$interdis);
1.57      albertel 1035:     if ($totalnumber%$interdis == 0) {
                   1036: 	$number--; 
1.53      raeburn  1037:     }
                   1038: 
1.1       albertel 1039:     if (($startdis<0) || ($startdis>$number)) { $startdis=$number; }
                   1040:     my $firstdis=$interdis*$startdis;
                   1041:     if ($firstdis>$#temp) { $firstdis=$#temp-$interdis+1; }
                   1042:     my $lastdis=$firstdis+$interdis-1;
                   1043:     if ($lastdis>$#temp) { $lastdis=$#temp; }
1.53      raeburn  1044:     $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber,$msgstatus));
1.1       albertel 1045:     $r->print('<form method="post" name="disall" action="/adm/email">'.
1.53      raeburn  1046: 	      '<table class="LC_mail_list"><tr><th colspan="1">&nbsp;</th><th>');
1.1       albertel 1047:     if ($env{'form.sortedby'} eq "revdate") {
                   1048: 	$r->print('<a href = "?sortedby=date'.$fsqs.'">'.&mt('Date').'</a></th>');
                   1049:     } else {
                   1050: 	$r->print('<a href = "?sortedby=revdate'.$fsqs.'">'.&mt('Date').'</a></th>');
                   1051:     }
                   1052:     $r->print('<th>');
                   1053:     if ($env{'form.sortedby'} eq "revuser") {
                   1054: 	$r->print('<a href = "?sortedby=user'.$fsqs.'">'.&mt('Username').'</a>');
                   1055:     } else {
                   1056: 	$r->print('<a href = "?sortedby=revuser'.$fsqs.'">'.&mt('Username').'</a>');
                   1057:     }
                   1058:     $r->print('</th><th>');
                   1059:     if ($env{'form.sortedby'} eq "revdomain") {
                   1060: 	$r->print('<a href = "?sortedby=domain'.$fsqs.'">'.&mt('Domain').'</a>');
                   1061:     } else {
                   1062: 	$r->print('<a href = "?sortedby=revdomain'.$fsqs.'">'.&mt('Domain').'</a>');
                   1063:     }
                   1064:     $r->print('</th><th>');
                   1065:     if ($env{'form.sortedby'} eq "revsubject") {
                   1066: 	$r->print('<a href = "?sortedby=subject'.$fsqs.'">'.&mt('Subject').'</a>');
                   1067:     } else {
                   1068:     	$r->print('<a href = "?sortedby=revsubject'.$fsqs.'">'.&mt('Subject').'</a>');
                   1069:     }
                   1070:     $r->print('</th><th>');
                   1071:     if ($env{'form.sortedby'} eq "revcourse") {
1.46      raeburn  1072:         $r->print('<a href = "?sortedby=course'.$fsqs.'">'.&mt('Course').'</a>');
1.1       albertel 1073:     } else {
1.46      raeburn  1074:         $r->print('<a href = "?sortedby=revcourse'.$fsqs.'">'.&mt('Course').'</a>');
1.1       albertel 1075:     }
                   1076:     $r->print('</th><th>');
                   1077:     if ($env{'form.sortedby'} eq "revstatus") {
                   1078: 	$r->print('<a href = "?sortedby=status'.$fsqs.'">'.&mt('Status').'</a></th>');
                   1079:     } else {
                   1080:      	$r->print('<a href = "?sortedby=revstatus'.$fsqs.'">'.&mt('Status').'</a></th>');
                   1081:     }
                   1082:     $r->print("</tr>\n");
1.6       albertel 1083: 
                   1084:     my $suffix = &Apache::lonmsg::foldersuffix($folder);
1.114     raeburn  1085:     my $count = 0;
1.1       albertel 1086:     for (my $n=$firstdis;$n<=$lastdis;$n++) {
1.11      albertel 1087: 	my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID,
                   1088: 	    $description,$recv_name,$recv_domain)= 
                   1089: 		@{$temp[$n]};
1.1       albertel 1090: 	if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) {
1.114     raeburn  1091:             $count ++;
1.1       albertel 1092: 	    if ($status eq 'new') {
1.4       albertel 1093: 		$r->print('<tr class="LC_mail_new">');
1.1       albertel 1094: 	    } elsif ($status eq 'read') {
1.4       albertel 1095: 		$r->print('<tr class="LC_mail_read">');
1.1       albertel 1096: 	    } elsif ($status eq 'replied') {
1.4       albertel 1097: 		$r->print('<tr class="LC_mail_replied">'); 
1.1       albertel 1098: 	    } else {
1.4       albertel 1099: 		$r->print('<tr class="LC_mail_other">');
1.1       albertel 1100: 	    }
1.6       albertel 1101: 	    my ($dis_name,$dis_domain) = ($fromname,$fromdomain);
                   1102: 	    if ($folder eq 'sent') {
1.69      raeburn  1103:                 if (defined($recv_name) && defined($recv_domain)) {
                   1104: 		    if (ref($recv_name) eq 'ARRAY' && 
                   1105:                         ref($recv_domain) eq 'ARRAY') {
                   1106: 		        $dis_name   = join('<br />',@{$recv_name});
                   1107: 		        $dis_domain = join('<br />',@{$recv_domain});
                   1108:                     }
1.11      albertel 1109: 		} else {
1.29      www      1110: 		    my $msg_id  = &unescape($origID);
1.11      albertel 1111: 		    my %message = &Apache::lonnet::get('nohist_email'.$suffix,
                   1112: 						       [$msg_id]);
                   1113: 		    my %content = &Apache::lonmsg::unpackagemsg($message{$msg_id});
1.69      raeburn  1114:                     if (ref($content{'recuser'}) eq 'ARRAY') {
                   1115: 		        $dis_name   = join('<br />',@{$content{'recuser'}});
                   1116:                     }
                   1117:                     if (ref($content{'recdomain'}) eq 'ARRAY') {
                   1118: 		        $dis_domain = join('<br />',@{$content{'recdomain'}});
                   1119:                     }
1.11      albertel 1120: 		}
1.6       albertel 1121: 	    }
1.53      raeburn  1122:             my $localsenttime = &Apache::lonlocal::locallocaltime($sendtime);
1.102     bisitz   1123: 	    $r->print('<td align="right"><span class="LC_nobreak">'.(($status eq 'new')?'<b>':'').
1.53      raeburn  1124:                       $count.'.'.(($status eq 'new')?'</b>':'').'&nbsp;'.
                   1125:                       '<input type="checkbox" name="delmark"'. 
1.102     bisitz   1126:                       ' value="'.$origID.'" /></span></td>');
1.53      raeburn  1127:             foreach my $item ($localsenttime,$dis_name,$dis_domain,$shortsubj) {
                   1128:                 $r->print('<td>'.(($status eq 'new')?'<b>':'').
1.61      raeburn  1129:                           '<a href="/adm/email?display='.$origID.$sqs.'">'.
1.53      raeburn  1130:                           $item.(($status eq 'new')?'</b>':'').'</td>');
                   1131:             }
                   1132:             my $showstatus;
                   1133:             my %statushash = &get_msgstatus_types();
                   1134:             if ($status eq '') {
                   1135:                 $showstatus = '';
                   1136:             } else {
                   1137:                 $showstatus = $statushash{$status};
                   1138:             }
                   1139: 	    $r->print('<td>'.(($status eq 'new')?'<b>':'').$description.
                   1140:                       (($status eq 'new')?'</b>':'').'</td><td>'.
                   1141:                       (($status eq 'new')?'<b>':'').$showstatus.
                   1142:                       (($status eq 'new')?'</b>':'').'</td></tr>'."\n");
1.1       albertel 1143: 	} elsif ($status eq 'deleted') {
                   1144: # purge
1.9       albertel 1145: 	    my ($result,$msg) = 
1.29      www      1146: 		&movemsg(&unescape($origID),$folder,'trash');
1.9       albertel 1147: 	    
1.1       albertel 1148: 	}
                   1149:     }   
1.53      raeburn  1150:     $r->print("</table>\n");
                   1151:     $r->print('<table border="0" cellspacing="2" cellpadding="2">
                   1152:  <tr>
                   1153:   <td>'.
1.64      raeburn  1154:   '<input type="button" onclick="javascript:checkAll(document.disall.delmark)" value="'.&mt('Check All').'" /><br />'."\n".
                   1155:   '<input type="button" onclick="javascript:uncheckAll(document.disall.delmark)" value="'.&mt('Uncheck All').'" />'."\n".
1.53      raeburn  1156:   '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" /></td><td>&nbsp;</td>'."\n".
                   1157:   '<td align="center"><b>'.&mt('Action').'</b><br />'."\n".
1.83      raeburn  1158:   '  <select name="checkedaction">'."\n");
1.53      raeburn  1159: 
1.1       albertel 1160:     if ($folder ne 'trash') {
1.53      raeburn  1161:         $r->print('    <option value="markeddel">'.&mt('Delete').'</option>'."\n");
                   1162:     }
                   1163:     if ($msgstatus ne 'read') {
                   1164:         $r->print('    <option value="markedread">'.&mt('Mark Read').'</option>."\n"');
                   1165:     }
                   1166:     if ($msgstatus ne 'unread') {
                   1167:         $r->print('    <option value="markedunread">'.&mt('Mark Unread').'</option>'."\n");
1.1       albertel 1168:     }
1.53      raeburn  1169:     $r->print('   <option value="markedforward">'.&mt('Forward').'</option>'."\n");
1.54      albertel 1170: 
                   1171:     my %gotfolders = &Apache::lonmsg::get_user_folders();
1.53      raeburn  1172:     if (keys(%gotfolders) > 0) {
                   1173:         $r->print('   <option value="markedmove">'.&mt('Move to Folder ->').
                   1174:                   '</option>');
                   1175:     }
                   1176:     $r->print("\n".'</select></td>'."\n");
1.54      albertel 1177: 
1.53      raeburn  1178:     if (keys(%gotfolders) > 0) {
                   1179:         $r->print('<td align="center"><b>'.&mt('Destination folder').'<b><br />');
1.54      albertel 1180: 	my %userfolders;
1.53      raeburn  1181:         foreach my $key (keys(%gotfolders)) {
                   1182:             $userfolders{$key} = $key;
                   1183:         }
                   1184:         $userfolders{''} = "";
                   1185:         $r->print(&Apache::loncommon::select_form('','movetofolder',%userfolders).
                   1186:                   '</td>');
                   1187:     }
                   1188:     $r->print('<td>&nbsp;</td><td>&nbsp;&nbsp;'.
                   1189:               '<input type="button" name="go" value="'.&mt('Go').
                   1190:               '" onclick="javascript:validate_checkedaction()"/></td>'."\n".
                   1191:               '</tr></table>');
1.1       albertel 1192:     my $postedstartdis=$startdis+1;
1.53      raeburn  1193:     $r->print('<input type="hidden" name="folder" value="'.$folder.'" /><input type="hidden" name="startdis" value="'.$postedstartdis.'" /><input type="hidden" name="interdis" value="'.$env{'form.interdis'}.'" /><input type="hidden" name="msgstatus" value="'.$msgstatus.'" ><input type="hidden" name="markedaction" value="" /></form>');
1.1       albertel 1194:     if ($numblocked > 0) {
1.65      raeburn  1195:         $r->print(&blocked_in_folder($numblocked,$startblock,$endblock,
                   1196:                                      \%setters));
1.1       albertel 1197:     }
                   1198: }
                   1199: 
1.65      raeburn  1200: sub blocked_in_folder {
                   1201:     my ($numblocked,$startblock,$endblock,$setters) = @_;
                   1202:     my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
                   1203:     my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
                   1204:     my $output = '<br /><br />'.
                   1205:                   &mt('[quant,_1,message is, messages are] not viewable because display of LON-CAPA messages sent to you by other students between [_2] and [_3] is currently being blocked because of online exams.',$numblocked,$beginblock,$finishblock);
                   1206:     $output .= &Apache::loncommon::build_block_table($startblock,$endblock,
                   1207:                                                      $setters);
                   1208:     return $output;
                   1209: }
                   1210: 
1.1       albertel 1211: # ============================================================== Compose output
                   1212: 
                   1213: sub compout {
1.53      raeburn  1214:     my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode,
                   1215:         $multiforward)=@_;
1.1       albertel 1216:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
1.38      raeburn  1217:     my ($cdom,$cnum,$group,$refarg);
                   1218:     if (exists($env{'form.group'})) {
                   1219:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1220:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   1221:         $group = $env{'form.group'};
                   1222:         my $action = 'composing';
                   1223:         $r->print(&groupmail_header($action,$group,$cdom,$cnum));
                   1224:     } elsif ($broadcast eq 'individual') {
1.1       albertel 1225: 	&printheader($r,'/adm/email?compose=individual',
                   1226: 	     'Send a Message');
                   1227:     } elsif ($broadcast) {
                   1228: 	&printheader($r,'/adm/email?compose=group',
                   1229: 	     'Broadcast Message');
                   1230:     } elsif ($forwarding) {
                   1231: 	&Apache::lonhtmlcommon::add_breadcrumb
1.29      www      1232:         ({href=>"/adm/email?display=".&escape($forwarding),
1.1       albertel 1233:           text=>"Display Message"});
1.29      www      1234: 	&printheader($r,'/adm/email?forward='.&escape($forwarding),
1.1       albertel 1235: 	     'Forwarding a Message');
                   1236:     } elsif ($replying) {
                   1237: 	&Apache::lonhtmlcommon::add_breadcrumb
1.29      www      1238:         ({href=>"/adm/email?display=".&escape($replying),
1.1       albertel 1239:           text=>"Display Message"});
1.29      www      1240: 	&printheader($r,'/adm/email?replyto='.&escape($replying),
1.1       albertel 1241: 	     'Replying to a Message');
                   1242:     } elsif ($replycrit) {
                   1243: 	$r->print('<h3>'.&mt('Replying to a Critical Message').'</h3>');
                   1244: 	$replying=$replycrit;
1.53      raeburn  1245:     } elsif ($multiforward) {
                   1246:         &Apache::lonhtmlcommon::add_breadcrumb
                   1247:         ({href=>"/adm/email?folder=".&escape($folder),
1.112     weissno  1248:           text=>"Display All Messages"});
1.53      raeburn  1249:         &printheader($r,'/adm/email?compose=multiforward',
                   1250:              'Forwarding Multiple Messages');
1.70      raeburn  1251:         if ($multiforward > 1) {
1.85      bisitz   1252:             $r->print(&mt('Each of the <b>[quant,_1,message]</b> you checked'
                   1253:                          .' will be forwarded to the recipient(s) you select below.',$multiforward)
                   1254:                     .'<br />');
1.70      raeburn  1255:         } else {
                   1256:             $r->print(&mt('The message you checked will be forwarded to the recipient(s) you select below.').'<br />');
                   1257:         }
                   1258: 
1.1       albertel 1259:     } else {
                   1260: 	&printheader($r,'/adm/email?compose=upload',
                   1261: 	     'Distribute from Uploaded File');
                   1262:     }
                   1263: 
                   1264:     my $dispcrit='';
                   1265:     my $dissub='';
                   1266:     my $dismsg='';
                   1267:     my $disbase='';
1.86      raeburn  1268:     my $attachrow;
1.94      bisitz   1269:     my $func1='Send'; # do not translate here!
                   1270:     my %func2=( # do not translate here!
                   1271:                'ma'  => 'Message',
                   1272:                'msg' => 'Messages',
                   1273:               );
1.50      raeburn  1274:     my %lt=&Apache::lonlocal::texthash('us'  => 'Username',
                   1275: 				       'do'  => 'Domain',
                   1276: 				       'ad'  => 'Additional Recipients',
1.78      raeburn  1277:                                        'rt'  => 'Reply to',
                   1278:                                        'ar'  => 'Allow replies',
1.50      raeburn  1279: 				       'sb'  => 'Subject',
                   1280: 				       'ca'  => 'Cancel',
                   1281:                                        'gen' => 'Generate messages from a file',
                   1282:                                        'gmt' => 'General message text',
                   1283:                                        'tff' => 'The file format for the uploaded portion of the message is',
                   1284:                                        'uas' => 'Upload and Send',
1.86      raeburn  1285:                                        'atta' => 'Attachment',
1.95      raeburn  1286:                                        'to'   => 'To:',
1.50      raeburn  1287:                                       );
1.86      raeburn  1288:     my %attachmax = (
1.93      bisitz   1289:                      text => &mt('(128 KB max size)'),
1.86      raeburn  1290:                      num  => 131072,
                   1291:                     );
                   1292:     if (!$forwarding && !$multiforward) {
1.95      raeburn  1293:         $attachrow = '<tr><td colspan="3"><b>'.$lt{'atta'}.'</b> '.$attachmax{'text'}.': <input type="file" name="attachment" /></td></tr>';
1.86      raeburn  1294:     }
1.1       albertel 1295:     if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
                   1296: 	|| &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
                   1297: 				    '/'.$env{'request.course.sec'})) {
                   1298: 	 my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
                   1299:          $dispcrit=
1.95      raeburn  1300:  '<span class="LC_nobreak"><label><input type="checkbox" name="critmsg" /> '.&mt('Send as critical message').'.</label>'.$crithelp.'&nbsp;&nbsp;'.&mt('Require return receipt?').'<label><input type="radio" name="sendbck" value="1" />'.&mt('Yes').'</label>&nbsp;&nbsp;<label><input type="radio" name="sendbck" value="" checked="checked" />'.&mt('No').'</label></span><br />'.
                   1301:  '<label><input type="checkbox" name="permanent" /> '.
1.100     schafran 1302: &mt('Send copy to permanent e-mail address (if known)').'</label><br />'.
1.95      raeburn  1303: '<label><input type="checkbox" name="rsspost" /> '.
                   1304: 		  &mt('Include in course RSS newsfeed').'</label><br />';
1.70      raeburn  1305:     }
1.71      raeburn  1306:     if ($broadcast ne 'group') {
                   1307:         if (&Apache::lonnet::allowed('dff',$env{'request.course.id'}) ||
                   1308:             &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
                   1309:                                      '/'.$env{'request.course.sec'})) {
                   1310: 
1.95      raeburn  1311:             $dispcrit.='<label>'.
1.71      raeburn  1312:                        '<input type="checkbox" name="courserecord" value="1" /> '.
                   1313:                        &mt("Include in course's 'User records' for recipient(s)").
1.95      raeburn  1314:                        '</label><br />';
1.71      raeburn  1315:         }
1.70      raeburn  1316:     }
                   1317: 
1.1       albertel 1318:     my %message;
                   1319:     my %content;
1.95      raeburn  1320:     my ($hasfloat,$broadcast_js,$sendmode,$can_grp_broadcast);
1.1       albertel 1321:     my $defdom=$env{'user.domain'};
1.95      raeburn  1322:     if ($broadcast eq 'group') {
                   1323:         my %access_status = (
                   1324:                            active => 0,
                   1325:                            previous => 0,
                   1326:                            future => 0,
                   1327:                       );
                   1328:  
                   1329:         if ($group eq '') {
                   1330:             my $studentsel = &discourse(\%access_status);
                   1331:             if ($studentsel) {
1.110     raeburn  1332:                 if ($env{'environment.wysiwygeditor'} eq 'on') {
                   1333:                     $r->print($studentsel);
                   1334:                 } else {
                   1335:                     $r->print('<div class="LC_left_float">'.$studentsel.'</div>');
                   1336:                 }
1.95      raeburn  1337:                 $hasfloat = 1;
                   1338:             }
                   1339:         } else {
                   1340:             $can_grp_broadcast = &check_group_priv($group);
                   1341:             if ($can_grp_broadcast) {
1.105     raeburn  1342:                 $hasfloat = &disgroup($r,$cdom,$cnum,$group,\%access_status);
1.95      raeburn  1343:             }
                   1344:         }
                   1345:         if ($hasfloat) {
                   1346:             $sendmode = '<input type="hidden" name="sendmode" value="group" />'."\n";
                   1347:             $broadcast_js = qq|
                   1348: <script type="text/javascript">
                   1349: function courseRecipients() {
                   1350: |;
                   1351:         foreach my $type (keys(%access_status)) {
                   1352:             if ($access_status{$type}) {
                   1353:                 my $formname = $type.'users';
                   1354:                 if ($type eq 'active' && $group ne '') {
                   1355:                     $broadcast_js .= qq|
                   1356:                     document.compemail.groupmail.value = document.$formname.groupmail[document.$formname.groupmail.selectedIndex].value;
                   1357: |;
                   1358:                 }
                   1359:                 $broadcast_js .= qq|
                   1360:     if (typeof(document.$formname.selectedusers_forminput.length)=="undefined") {
                   1361:         document.compemail.courserecips.value += '_&&&_'+document.$formname.selectedusers_forminput.value;
                   1362:     } else {
                   1363:         for (var i=0; i<document.$formname.selectedusers_forminput.length; i++) {
                   1364:             if (document.$formname.selectedusers_forminput[i].checked) {
                   1365:                 document.compemail.courserecips.value += '_&&&_'+document.$formname.selectedusers_forminput[i].value;  
                   1366:             }
                   1367:         }
                   1368:     }
                   1369:                 |;
                   1370:             }
                   1371:         }
                   1372:         $broadcast_js .= qq|
                   1373:     return;
                   1374: }
                   1375: </script>
                   1376: 
                   1377: |;
                   1378:         }
                   1379:     }
1.1       albertel 1380:     if ($forwarding) {
                   1381: 	%message=&Apache::lonnet::get('nohist_email'.$suffix,[$forwarding]);
                   1382: 	%content=&Apache::lonmsg::unpackagemsg($message{$forwarding},$folder);
                   1383: 	$dispcrit.='<input type="hidden" name="forwid" value="'.
                   1384: 	    $forwarding.'" />';
1.94      bisitz   1385: 	$func1='Forward'; # do not translate here!
1.1       albertel 1386: 	
                   1387: 	$dissub=&mt('Forwarding').': '.$content{'subject'};
                   1388: 	$dismsg=&mt('Forwarded message from').' '.
                   1389: 	    $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'};
                   1390: 	if ($content{'baseurl'}) {
1.29      www      1391: 	    $disbase='<input type="hidden" name="baseurl" value="'.&escape($content{'baseurl'}).'" />';
1.1       albertel 1392: 	}
                   1393:     }
                   1394:     if ($replying) {
                   1395: 	%message=&Apache::lonnet::get('nohist_email'.$suffix,[$replying]);
                   1396: 	%content=&Apache::lonmsg::unpackagemsg($message{$replying},$folder);
                   1397: 	$dispcrit.='<input type="hidden" name="replyid" value="'.
                   1398: 	    $replying.'" />';
1.94      bisitz   1399: 	$func1='Send Reply to'; # do not translate here!
1.1       albertel 1400: 	
                   1401: 	$dissub=&mt('Reply').': '.$content{'subject'};       
                   1402: 	$dismsg='> '.$content{'message'};
                   1403: 	$dismsg=~s/\r/\n/g;
                   1404: 	$dismsg=~s/\f/\n/g;
                   1405: 	$dismsg=~s/\n+/\n\> /g;
                   1406: 	if ($content{'baseurl'}) {
1.29      www      1407: 	    $disbase='<input type="hidden" name="baseurl" value="'.&escape($content{'baseurl'}).'" />';
1.1       albertel 1408: 	    if ($env{'user.adv'}) {
1.72      albertel 1409: 		$disbase.='<label><input type="checkbox" name="storebasecomment" />'.&mt('Save message for re-use').
1.1       albertel 1410: 		    '</label> <a href="/adm/email?showcommentbaseurl='.
1.29      www      1411: 		    &escape($content{'baseurl'}).'" target="comments">'.
1.1       albertel 1412: 		    &mt('Show re-usable messages').'</a><br />';
                   1413: 	    }
                   1414: 	}
1.73      raeburn  1415:         my $jscript = &Apache::loncommon::check_uncheck_jscript();
                   1416:         $r->print(<<"ENDREPSCRIPT");
                   1417: <script type="text/javascript">
                   1418: $jscript
                   1419: </script>
                   1420: ENDREPSCRIPT
1.1       albertel 1421:     }
                   1422:     my $citation=&displayresource(%content);
1.95      raeburn  1423:     my $onsubmit;
1.1       albertel 1424:     if ($env{'form.recdom'}) { $defdom=$env{'form.recdom'}; }
1.23      www      1425:     if ($env{'form.text'}) { $dismsg=$env{'form.text'}; }
                   1426:     if ($env{'form.subject'}) { $dissub=$env{'form.subject'}; }
1.95      raeburn  1427:     if ($hasfloat) {
1.110     raeburn  1428:         if ($env{'environment.wysiwygeditor'} eq 'on') {
                   1429:             $r->print($broadcast_js);
                   1430:         } else {
                   1431:             $r->print($broadcast_js.'<div class="LC_left_float">');
                   1432:         }
1.95      raeburn  1433:         $onsubmit = ' onsubmit="javascript:courseRecipients();" ';
                   1434:     }
1.23      www      1435:     $r->print(
1.1       albertel 1436:                 '<form action="/adm/email"  name="compemail" method="post"'.
1.95      raeburn  1437:                 ' enctype="multipart/form-data"'.$onsubmit.'>'."\n".
                   1438:                 '<input type="hidden" name="sendmail" value="on" />'."\n".
                   1439:                 '<table>');
                   1440:     if (($broadcast eq 'group') && ($group ne '') && (!$can_grp_broadcast)) {
1.38      raeburn  1441:         $r->print(&recipient_input_row($cdom,%lt));
1.95      raeburn  1442:     }
1.38      raeburn  1443:     if (($broadcast ne 'group') && ($broadcast ne 'upload')) {
1.1       albertel 1444: 	if ($replying) {
1.78      raeburn  1445:             if ($content{'noreplies'}) {
                   1446:                 $r->print('<tr><td>'.&mt('This message was designated by the sender not to allow replies.').'</td></tr></table></form>');
                   1447:                 return;
                   1448:             }
1.95      raeburn  1449:             $r->print('<tr><td colspan="3"><b>'.&mt('Replying to').'</b> ');
1.78      raeburn  1450:             if ($content{'replytoaddr'}) {
                   1451:                 my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
                   1452:                 if ($replytoname ne '' && $replytodom ne '') {
                   1453:                     $r->print(&Apache::loncommon::plainname($replytoname,
                   1454:                                  $replytodom).' ('.$replytoname.':'.
                   1455:                                  $replytodom.')');
                   1456:                     $r->print('<input type="hidden" name="recuname" value="'.
                   1457:                           $replytoname.'" />'.
                   1458:                           '<input type="hidden" name="recdomain" value="'.
                   1459:                           $replytodom.'" /></td></tr>');
                   1460: 
                   1461:                 } else {
                   1462:                     $r->print(&mt('The sender did not designate a reply to address for this message.').'</td></tr></table>');
                   1463:                     return;
                   1464:                 }
                   1465:             } else {
                   1466: 	        $r->print(&Apache::loncommon::aboutmewrapper(
1.1       albertel 1467: 							 &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('.
1.14      albertel 1468: 		      $content{'sendername'}.':'.
1.78      raeburn  1469: 		      $content{'senderdomain'}.')');
                   1470:                 $r->print('<input type="hidden" name="recuname" value="'.
                   1471: 		          $content{'sendername'}.'" />'.
                   1472: 		          '<input type="hidden" name="recdomain" value="'.
                   1473:                           $content{'senderdomain'}.'" /></td></tr>');
                   1474:             }
1.73      raeburn  1475:             if ($content{'recipid'}) {
1.95      raeburn  1476:                 my %recips;
                   1477:                 &retrieve_recips('replying',\%content,\%recips);
                   1478:                 if (ref($recips{'to'}) eq 'ARRAY') {
                   1479:                     if (@{$recips{'to'}} > 0) {
                   1480:                         my $replyall;
                   1481:                         if (@{$recips{'to'}} > 1) {
                   1482:                             $replyall = qq|
                   1483:  <span class="LC_nobreak">
                   1484:       <input type="button" value="check all"
                   1485:         onclick="javascript:checkAll(document.compemail.replying_to)" />
                   1486:         &nbsp;&nbsp;
                   1487:       <input type="button" value="uncheck all"
                   1488:         onclick="javascript:uncheckAll(document.compemail.replying_to)" />
                   1489:  </span>
                   1490: |;
                   1491:                         }
                   1492:                         my $tolist = join(' ',@{$recips{'to'}});
                   1493:                         $r->print('<tr><td colspan="3"><table><tr><td>'.&mt('[_1]Send reply[_2] to other recipients','<b>','</b>').':<br />'.$replyall.'</td><td>'.$tolist.'</td></tr></table></td></tr>');
                   1494:                     }
                   1495:                 }
                   1496:                 if (ref($recips{'cc'}) eq 'ARRAY') {
                   1497:                     if (@{$recips{'cc'}} > 0) {
                   1498:                         my $replyall;
                   1499:                         if (@{$recips{'cc'}} > 1) {
                   1500:                             $replyall = qq|
1.73      raeburn  1501:  <span class="LC_nobreak">
                   1502:       <input type="button" value="check all"
                   1503:         onclick="javascript:checkAll(document.compemail.replying_cc)" />
                   1504:         &nbsp;&nbsp;
                   1505:       <input type="button" value="uncheck all"
                   1506:         onclick="javascript:uncheckAll(document.compemail.replying_cc)" />
                   1507:  </span>
                   1508: |;
1.95      raeburn  1509:                         }
                   1510:                         my $cclist = join(' ',@{$recips{'cc'}});
                   1511:                         $r->print('<tr><td colspan="3"><table><tr><td>'.&mt('[_1]Cc[_2] to other copied recipients','<b>','</b>').':<br />'.$replyall.'</td><td>'.$cclist.'</td></tr></table></td></tr>');
                   1512:                     }
                   1513:                 }
                   1514:                 if ($content{'group'} ne '') {
                   1515:                     if (&check_group_priv($content{'group'})) {
                   1516:                         if (ref($recips{'group_cc_broadcast'}) eq 'ARRAY') {
                   1517:                             if (@{$recips{'group_cc_broadcast'}} > 0) {
                   1518:                                 my $replyall;
                   1519:                                 if (@{$recips{'group_cc_broadcast'}} > 1) {
                   1520:                                     $replyall = qq|
                   1521:  <span class="LC_nobreak">
                   1522:       <input type="button" value="check all"
                   1523:         onclick="javascript:checkAll(document.compemail.replying_groupcc)" />
                   1524:         &nbsp;&nbsp;
                   1525:       <input type="button" value="uncheck all"
                   1526:         onclick="javascript:uncheckAll(document.compemail.replying_groupcc)" />
                   1527:  </span>
                   1528: |;
                   1529:                                 }
                   1530:                                 my $groupcclist = join(' ',@{$recips{'group_cc_broadcast'}});
                   1531:                                 $r->print('<tr><td colspan="3"><table><tr><td>'.&mt('[_1]Cc[_2] to other copied group members','<b>','</b>').':<br />'.$replyall.'</td><td>'.$groupcclist.'<input type="hidden" name="group" value="'.$content{'group'}.'" /><input type="hidden" name="sendmode" value="group" /><input type="hidden" name="groupmail" value="cc" /></td></tr></table></td></tr>');
                   1532:                             }
                   1533:                         }
                   1534:                     }
1.73      raeburn  1535:                 }
                   1536:             }
1.1       albertel 1537: 	} else {
1.38      raeburn  1538:             $r->print(&recipient_input_row($defdom,%lt));
1.1       albertel 1539:         }
                   1540:     }
1.109     raeburn  1541:     my $latexHelp = &Apache::loncommon::helpLatexCheatsheet(undef,undef,1);
1.95      raeburn  1542:     my $wysiwyglink=&Apache::lonhtmlcommon::htmlareaselectactive('message').'<br />';
1.53      raeburn  1543:     my $subj_size;
                   1544:     if ($multiforward) {
                   1545:         $r->print(&additional_rec_row(\%lt));
                   1546:         $r->print('<tr><td colspan="2">'.
                   1547:                   &mt('Unless you choose otherwise:').'<ul><li>'.
                   1548:         &mt("The subject in each forwarded message will be <i>'Forwarding:'</i> followed by the original subject.").'</li><li>'.
                   1549:         &mt("The message itself will begin with a first line: <i>'Forwarded message from'</i> followed by the original sender's name.").'</li></ul></td></tr>');
1.94      bisitz   1550:         $func1='Forward'; # do not translate here!
1.53      raeburn  1551:         $dissub = &mt('Forwarding').': ';
                   1552:         $subj_size = '10';
                   1553:         my $extra = '&lt;'.&mt('original subject').'&gt;&nbsp;&nbsp;&nbsp;'.
                   1554:                     '<input type="radio" name="showorigsubj" value="1" checked="checked" />'.&mt('Yes').'&nbsp;<input type="radio" name="showorigsubj" value="0" />'.&mt('No');
                   1555:         $dismsg = &mt('Forwarded message from ').' ';
                   1556:         my $sender = &mt("sender's name");
                   1557:         $r->print(&msg_subject_row($dissub,\%lt,$subj_size,$extra));
                   1558:         $r->print('<tr><td>'.&mt('Message begins with:').'</td><td><input type="text" name="msgheader" value="'.$dismsg.'" />&nbsp;'.$sender.'&nbsp;&nbsp;&nbsp;<input type="radio" name="showorigsender" value="1" checked="checked" />'.&mt('Yes').'&nbsp;<input type="radio" name="showorigsender" value="0" />'.&mt('No').'<input type="hidden" name="multiforward" value="'.$multiforward.'" /></td></tr>
                   1559: </table>
1.95      raeburn  1560: <br /><table>
                   1561: <tr><td align="left">'."\n".
                   1562: $latexHelp."<br />\n".
                   1563: &mt("Any new text to display before the text of the original messages:").'<br />'."\n".
                   1564: '<textarea name="message" id="message" cols="80" rows="5" wrap="hard"></textarea>'.
                   1565: $wysiwyglink);
1.53      raeburn  1566:         my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark');
                   1567:         foreach my $msg (@to_forward) {
                   1568:             $r->print('<input type="hidden" name="delmark" value="'.$msg.'" />');
                   1569:         }
1.94      bisitz   1570:         $r->print(&submit_button_row($folder,$dismode,&mt($func1.' '.$func2{'msg'}),
1.53      raeburn  1571:                                      \%lt));
                   1572:     } elsif ($broadcast ne 'upload') {
                   1573:         $subj_size = '50';
                   1574:         $r->print(&additional_rec_row(\%lt));
1.78      raeburn  1575:         if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
                   1576:             || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
                   1577:                                         '/'.$env{'request.course.sec'})) {
                   1578:             $r->print(&reply_to_row(\%lt));
                   1579:         }
1.53      raeburn  1580:         $r->print(&msg_subject_row($dissub,\%lt,$subj_size));
                   1581:         $r->print(<<"ENDCOMP");
1.95      raeburn  1582: $attachrow
                   1583: </table><br />
1.117     bisitz   1584: $latexHelp<br />
1.1       albertel 1585: <textarea name="message" id="message" cols="80" rows="15" wrap="hard">$dismsg
1.95      raeburn  1586: </textarea>$wysiwyglink
                   1587: $sendmode
1.1       albertel 1588: $dispcrit
                   1589: $disbase
                   1590: ENDCOMP
1.97      schafran 1591:         $r->print(&submit_button_row($folder,$dismode,&mt($func1.' '.$func2{'ma'}),
1.95      raeburn  1592:                                      \%lt,$hasfloat,$group));
1.53      raeburn  1593:         $r->print($citation);
1.38      raeburn  1594:         if (exists($env{'form.ref'})) {
                   1595:             $r->print('<input type="hidden" name="ref" value="'.
                   1596:                       $env{'form.ref'}.'" />');
                   1597:         }
                   1598:         if (exists($env{'form.group'})) {
                   1599:             $r->print('<input type="hidden" name="group" value="'.
                   1600:                       $env{'form.group'}.'" />');
                   1601:         }
1.1       albertel 1602:     } else { # $broadcast is 'upload'
1.50      raeburn  1603: 	$r->print(<<ENDBLOCK);
1.1       albertel 1604: <input type="hidden" name="sendmode" value="upload" />
                   1605: <input type="hidden" name="send" value="on" />
1.50      raeburn  1606: <h3>$lt{'gen'}</h3>
1.1       albertel 1607: <p>
                   1608: Subject: <input type="text" size="50" name="subject" />
                   1609: </p>
1.50      raeburn  1610: <p>$lt{'gmt'}:<br />
1.1       albertel 1611: <textarea name="message" id="message" cols="60" rows="10" wrap="hard">$dismsg
1.95      raeburn  1612: </textarea>$wysiwyglink</p>
1.1       albertel 1613: <p>
1.50      raeburn  1614: $lt{'tff'}:
                   1615: ENDBLOCK
                   1616:        $r->print('
                   1617: <pre>'."\n".
                   1618: &mt('username1:domain1: text')."\n".
                   1619: &mt('username2:domain2: text')."\n".
                   1620: &mt('username3:domain1: text')."\n".
                   1621: '</pre>
1.1       albertel 1622: </p>
                   1623: <p>
1.50      raeburn  1624: '.&mt('The messages will be assembled from all lines with the respective'."\n".'<tt>username:domain</tt>, and appended to the general message text.'));
                   1625:         $r->print(<<ENDUPLOAD);
                   1626: </p>
1.1       albertel 1627: <p>
                   1628: <input type="file" name="upfile" size="40" /></p><p>
                   1629: $dispcrit
1.50      raeburn  1630: <input type="submit" value="$lt{'uas'}" /></p>
1.1       albertel 1631: ENDUPLOAD
                   1632:     }
1.36      albertel 1633:     if ($env{'form.displayedcrit'}) {
                   1634: 	$r->print('<input type="hidden" name="displayedcrit" value="true" />');
                   1635:     }
1.95      raeburn  1636:     $r->print('</form>');
                   1637:     if ($hasfloat) {
1.110     raeburn  1638:         unless($env{'environment.wysiwygeditor'} eq 'on') {
                   1639:             $r->print('</div><div class="LC_clear_float_footer"></div>');
                   1640:         }
1.95      raeburn  1641:     }
                   1642:     $r->print(&generate_preview_form);
                   1643: }
                   1644: 
                   1645: sub check_group_priv {
                   1646:     my ($group) = @_;
                   1647:     my $cid = $env{'request.course.id'};
                   1648:     my $sec = $env{'request.course.sec'};
                   1649:     return if !$cid;
                   1650:     my $can_broadcast = &Apache::lonnet::allowed('sgb',$cid.'/'.$group);
                   1651:     my $viewgrps = &Apache::lonnet::allowed('vcg',$cid.($sec?'/'.$sec:''));
                   1652:     my $editgrps = &Apache::lonnet::allowed('mdg',$cid.($sec?'/'.$sec:''));
                   1653:     if ($viewgrps || $editgrps || $can_broadcast) {
                   1654:         return 1;
                   1655:     }
                   1656:     return;
1.1       albertel 1657: }
                   1658: 
1.38      raeburn  1659: sub recipient_input_row {
                   1660:     my ($dom,%lt) = @_;
                   1661:     my $domform = &Apache::loncommon::select_dom_form($dom,'recdomain');
                   1662:     my $selectlink=
                   1663:       &Apache::loncommon::selectstudent_link('compemail','recuname',
                   1664:                                              'recdomain');
                   1665:     my $output = <<"ENDREC";
1.95      raeburn  1666: <tr><td colspan="3"><span class="LC_nobreak"><b>$lt{'to'}</b> $lt{'us'}:&nbsp;<input type="text" size="12" name="recuname" value="$env{'form.recname'}" />&nbsp;$lt{'do'}:&nbsp;$domform&nbsp;&nbsp;$selectlink</span></td></tr>
1.38      raeburn  1667: ENDREC
                   1668:     return $output;
                   1669: }
                   1670: 
1.78      raeburn  1671: sub reply_to_row {
                   1672:     my ($lt) = @_;
                   1673:     my $radioyes = &mt('Yes');
                   1674:     my $radiono = &mt('No');
                   1675:     my $output = <<"ENDREP";
1.95      raeburn  1676: <tr><td colspan="3"><span class="LC_nobreak"><b>$lt->{'ar'}</b>:<label><input type="radio" name="can_reply" value="Y" checked="checked" />$radioyes</label>&nbsp;&nbsp;<label><input type="radio" name="can_reply" value="N" />$radiono</label></span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="LC_nobreak">$lt->{'rt'}:&nbsp;<input type="text" size="25" name="reply_to_addr" value="$env{'user.name'}:$env{'user.domain'}" /></span></td></tr>
1.78      raeburn  1677: ENDREP
                   1678:     return $output;
                   1679: }
                   1680: 
1.53      raeburn  1681: sub additional_rec_row {
                   1682:     my ($lt) = @_;
1.73      raeburn  1683:     my $cc = &mt('Cc:');
1.85      bisitz   1684:     my $bcc = &mt('Bcc:');
                   1685:     my $exmpl = &mt('username:domain,username:domain,...'); 
1.53      raeburn  1686:     my $output = <<"ENDADD";
1.95      raeburn  1687: <tr><td colspan="3"><fieldset id="LC_additionalrecips"><legend><b>$lt->{'ad'}</b> <tt>($exmpl)</tt>:</legend><table>
                   1688: <tr><td>&nbsp;</td><td>$lt->{'to'}</td><td><input type="text" size="50" name="additionalrec_to" /></td></tr>
                   1689: <tr><td>&nbsp;</td><td>$cc</td><td><input type="text" size="50" name="additionalrec_cc" /></td></tr> 
1.110     raeburn  1690: <tr><td>&nbsp;</td><td>$bcc</td><td><input type="text" size="50" name="additionalrec_bcc" /></td></tr></table></fieldset></td></tr>
1.53      raeburn  1691: ENDADD
                   1692:     return $output;
                   1693: }
                   1694: 
                   1695: sub submit_button_row {
1.95      raeburn  1696:     my ($folder,$dismode,$sendtext,$lt,$is_crsform,$group) = @_;
                   1697:     my $pre=&mt("Show Preview and Check Spelling");
1.98      schafran 1698:     my $value=&mt('Send');
1.95      raeburn  1699:     my $prevbutton = '<input type="button" name="preview" value="'.$pre.'" onclick="if (typeof(document.compemail.onsubmit)=='."'function'".') {document.compemail.onsubmit();};document.preview.comment.value=document.compemail.message.value;document.preview.subject.value=document.compemail.subject.value;document.preview.submit();" />';
                   1700:     my $output = qq|
1.53      raeburn  1701: <input type="hidden" name="folder" value="$folder" />
1.95      raeburn  1702: <input type="hidden" name="dismode" value="$dismode" />|;
                   1703:     if ($is_crsform) {
                   1704:         $output .= '<input type="hidden" name="courserecips" value="" />'."\n";
                   1705:         if ($group ne '') {
                   1706:             $output .= '<input type="hidden" name="groupmail" value="" />'."\n";
                   1707:         }
                   1708:     }
                   1709:     $output .= qq|
                   1710: <table><tr><td align="left">
1.98      schafran 1711: <input type="submit" name="send" value="$value" title="$sendtext" />
1.95      raeburn  1712: <input type="submit" name="cancel" value="$lt->{'ca'}" />
                   1713: </td><td width="60">&nbsp;</td><td align="right">$prevbutton</td></tr></table>
1.53      raeburn  1714: |;
                   1715:     return $output;
                   1716: }
                   1717: 
                   1718: sub msg_subject_row {
                   1719:     my ($dissub,$lt,$subj_size,$extra) = @_;
1.95      raeburn  1720:     my $output = '<tr><td colspan="3"><b>'.$lt->{'sb'}.'</b>:&nbsp;<input type="text" size="'.
1.53      raeburn  1721:                  $subj_size.'" name="subject" value="'.$dissub.'" />'.$extra.
                   1722:                  '</td></tr>';
                   1723:     return $output;
                   1724: }
                   1725: 
1.95      raeburn  1726: sub generate_preview_form {
                   1727:     my $prevbutton = (<<ENDPREVIEW);
                   1728: <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
                   1729: <input type="hidden" name="subject" />
                   1730: <input type="hidden" name="comment" />
                   1731: </form>
                   1732: ENDPREVIEW
                   1733: }
                   1734: 
                   1735: # ---------------------------------------------------- Display all face to face
                   1736: 
1.1       albertel 1737: sub retrieve_instructor_comments {
                   1738:     my ($user,$domain)=@_;
                   1739:     my $target=$env{'form.grade_target'};
                   1740:     if (! $env{'request.course.id'}) { return; }
1.49      albertel 1741:     if (! &Apache::lonnet::allowed('dff',$env{'request.course.id'})
                   1742: 	&& ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
1.1       albertel 1743: 				      '/'.$env{'request.course.sec'})) {
                   1744: 	return;
                   1745:     }
                   1746:     my %records=&Apache::lonnet::dump('nohist_email',
                   1747: 			 $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1748: 			 $env{'course.'.$env{'request.course.id'}.'.num'},
                   1749:                          '%255b'.$user.'%253a'.$domain.'%255d');
                   1750:     my $result='';
1.42      raeburn  1751:     foreach my $key (sort(keys(%records))) {
                   1752:         my %content=&Apache::lonmsg::unpackagemsg($records{$key});
1.1       albertel 1753:         next if ($content{'senderdomain'} eq '');
                   1754:         next if ($content{'subject'} !~ /^Record/);
                   1755: 	# &Apache::lonfeedback::newline_to_br(\$content{'message'});
                   1756: 	$result.='Recorded by '.
1.14      albertel 1757:             $content{'sendername'}.':'.$content{'senderdomain'}."\n";
1.1       albertel 1758:         $result.=
                   1759:             &Apache::lontexconvert::msgtexconverted($content{'message'})."\n";
                   1760:      }
                   1761:     return $result;
                   1762: }
                   1763: 
                   1764: sub disfacetoface {
                   1765:     my ($r,$user,$domain)=@_;
                   1766:     my $target=$env{'form.grade_target'};
                   1767:     unless ($env{'request.course.id'}) { return; }
1.49      albertel 1768:     if  (!&Apache::lonnet::allowed('dff',$env{'request.course.id'})
                   1769: 	 && ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
1.1       albertel 1770: 				       '/'.$env{'request.course.sec'})) {
1.50      raeburn  1771: 	$r->print(&mt('Not allowed'));
1.1       albertel 1772: 	return;
                   1773:     }
                   1774:     my %records=&Apache::lonnet::dump('nohist_email',
                   1775: 			 $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1776: 			 $env{'course.'.$env{'request.course.id'}.'.num'},
                   1777:                          '%255b'.$user.'%253a'.$domain.'%255d');
                   1778:     my $result='';
1.42      raeburn  1779:     foreach my $key (sort(keys(%records))) {
                   1780:         my %content=&Apache::lonmsg::unpackagemsg($records{$key});
1.1       albertel 1781:         next if ($content{'senderdomain'} eq '');
                   1782: 	&Apache::lonfeedback::newline_to_br(\$content{'message'});
                   1783:         if ($content{'subject'}=~/^Record/) {
                   1784: 	    $result.='<h3>'.&mt('Record').'</h3>';
                   1785:         } elsif ($content{'subject'}=~/^Broadcast/) {
                   1786:             $result .='<h3>'.&mt('Broadcast Message').'</h3>';
                   1787:             if ($content{'subject'}=~/^Broadcast\./) {
                   1788:                 if (defined($content{'coursemsgid'})) {
1.29      www      1789:                     my $crsmsgid = &escape($content{'coursemsgid'});
1.1       albertel 1790:                     my $broadcast_message = &general_message($crsmsgid);
                   1791:                     $content{'message'} = '<b>'.&mt('Subject').': '.$content{'message'}.'</b><br />'.$broadcast_message;
                   1792:                 } else {
                   1793:                     %content=&Apache::lonmsg::unpackagemsg($content{'message'});
                   1794:                     $content{'message'} =
                   1795:                     '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'.
                   1796:                     $content{'message'};
                   1797:                 }
1.70      raeburn  1798:             }
                   1799:         } elsif ($content{'subject'}=~/^Archive/) {
                   1800:             $result.='<h3>'.&mt('Archived Message').'</h3>';
                   1801:             if (defined($content{'coursemsgid'})) {
                   1802:                 my $crsmsgid = &escape($content{'coursemsgid'});
                   1803:                 my $archive_message = &general_message($crsmsgid);
                   1804:                 $content{'message'} = '<b>'.&mt('Subject').': '.$content{'message'}.'</b><br />'.$archive_message;
                   1805:             } else {
                   1806:                 %content=&Apache::lonmsg::unpackagemsg($content{'message'});
                   1807:                 $content{'message'} =
                   1808:                 '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br
                   1809: '.
                   1810:                 $content{'message'};
                   1811:             }
1.1       albertel 1812:         } else {
                   1813:             $result.='<h3>'.&mt('Critical Message').'</h3>';
                   1814:             if (defined($content{'coursemsgid'})) {
1.29      www      1815:                 my $crsmsgid=&escape($content{'coursemsgid'});
1.1       albertel 1816:                 my $critical_message = &general_message($crsmsgid);
                   1817:                 $content{'message'} = '<b>'.&mt('Subject').': '.$content{'message'}.'</b><br />'.$critical_message;
                   1818:             } else {
                   1819:                 %content=&Apache::lonmsg::unpackagemsg($content{'message'});
                   1820:                 $content{'message'}=
                   1821:                 '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'.
                   1822: 		$content{'message'};
                   1823:             }
                   1824:         }
                   1825:         $result.=&mt('By').': <b>'.
                   1826: &Apache::loncommon::aboutmewrapper(
                   1827:  &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
1.14      albertel 1828: $content{'sendername'}.':'.
1.1       albertel 1829:             $content{'senderdomain'}.') '.$content{'time'}.
                   1830:             '<br /><pre>'.
                   1831:               &Apache::lontexconvert::msgtexconverted($content{'message'}).
                   1832: 	      '</pre>';
                   1833:      }
                   1834:     # Check to see if there were any messages.
                   1835:     if ($result eq '') {
1.106     riegler  1836:         my $lctype = &mt(lc(&Apache::loncommon::course_type()));
1.1       albertel 1837: 	if ($target ne 'tex') { 
1.30      raeburn  1838: 	    $r->print("<p><b>".&mt('No notes, face-to-face discussion records, critical messages, or broadcast messages in this [_1].',$lctype)."</b></p>");
1.1       albertel 1839: 	} else {
1.30      raeburn  1840: 	    $r->print('\textbf{'.&mt('No notes, face-to-face discussion records, critical messages or broadcast messages in this [_1].',$lctype).'}\\\\');
1.1       albertel 1841: 	}
                   1842:     } else {
                   1843:        $r->print($result);
                   1844:     }
                   1845: }
                   1846: 
                   1847: sub general_message {
                   1848:     my ($crsmsgid) = @_;
                   1849:     my %general_content;
                   1850:     if ($crsmsgid) { 
                   1851:         my %course_content = &Apache::lonnet::get('nohist_email',[$crsmsgid],
                   1852:                            $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1853:                            $env{'course.'.$env{'request.course.id'}.'.num'});
                   1854:         %general_content = &Apache::lonmsg::unpackagemsg($course_content{$crsmsgid});
                   1855:     }
                   1856:     return $general_content{'message'};
                   1857: }
                   1858: 
                   1859: # ---------------------------------------------------------------- Face to face
                   1860: 
                   1861: sub facetoface {
                   1862:     my ($r,$stage)=@_;
1.49      albertel 1863:     if (!&Apache::lonnet::allowed('dff',$env{'request.course.id'})
                   1864: 	&& ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
1.1       albertel 1865: 				      '/'.$env{'request.course.sec'})) {
1.50      raeburn  1866: 	$r->print(&mt('Not allowed'));
1.1       albertel 1867: 	return;
                   1868:     }
1.33      albertel 1869:     my $crstype = &Apache::loncommon::course_type();
                   1870:     my $leaders = ($crstype eq 'Group') ? 'coordinators and leaders'
                   1871:                                         : 'faculty and staff';
1.1       albertel 1872:     &printheader($r,
                   1873: 		 '/adm/email?recordftf=query',
1.70      raeburn  1874: 		 "User Notes, Face-to-Face, Critical Messages, Broadcast Messages, Archived Messages");
1.1       albertel 1875: # from query string
                   1876: 
                   1877:     if ($env{'form.recname'}) { $env{'form.recuname'}=$env{'form.recname'}; }
                   1878:     if ($env{'form.recdom'}) { $env{'form.recdomain'}=$env{'form.recdom'}; }
                   1879: 
                   1880:     my $defdom=$env{'user.domain'};
                   1881: # already filled in
                   1882:     if ($env{'form.recdomain'}) { $defdom=$env{'form.recdomain'}; }
                   1883: # generate output
                   1884:     my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain');
                   1885:     my $stdbrws = &Apache::loncommon::selectstudent_link
                   1886: 	('stdselect','recuname','recdomain');
                   1887:     my %lt=&Apache::lonlocal::texthash('user' => 'Username',
                   1888: 				       'dom' => 'Domain',
1.70      raeburn  1889: 				       'head' => "User Notes, Records of Face-To-Face Discussions, Critical Messages, Broadcast Messages and Archived Messages in $crstype",
1.1       albertel 1890: 				       'subm' => 'Retrieve discussion and message records',
1.30      raeburn  1891: 				       'newr' => 'New Record (record is visible to '.lc($crstype).' '.$leaders.')',
1.1       albertel 1892: 				       'post' => 'Post this Record');
                   1893:     $r->print(<<"ENDTREC");
                   1894: <h3>$lt{'head'}</h3>
                   1895: <form method="post" action="/adm/email" name="stdselect">
                   1896: <input type="hidden" name="recordftf" value="retrieve" />
                   1897: <table>
                   1898: <tr><td>$lt{'user'}:</td><td><input type="text" size="12" name="recuname" value="$env{'form.recuname'}" /></td>
                   1899: <td rowspan="2">
                   1900: $stdbrws
                   1901: <input type="submit" value="$lt{'subm'}" /></td>
                   1902: </tr>
                   1903: <tr><td>$lt{'dom'}:</td>
                   1904: <td>$domform</td></tr>
                   1905: </table>
                   1906: </form>
                   1907: ENDTREC
                   1908:     if (($stage ne 'query') &&
                   1909:         ($env{'form.recdomain'}) && ($env{'form.recuname'})) {
                   1910:         chomp($env{'form.newrecord'});
                   1911:         if ($env{'form.newrecord'}) {
1.31      albertel 1912: 	    &Apache::lonmsg::store_instructor_comment($env{'form.newrecord'},
                   1913: 						      $env{'form.recuname'},
                   1914: 						      $env{'form.recdomain'});
1.1       albertel 1915:         }
                   1916:         $r->print('<h3>'.&Apache::loncommon::plainname($env{'form.recuname'},
                   1917: 				     $env{'form.recdomain'}).'</h3>');
                   1918:         &disfacetoface($r,$env{'form.recuname'},$env{'form.recdomain'});
                   1919: 	$r->print(<<ENDRHEAD);
                   1920: <form method="post" action="/adm/email">
                   1921: <input name="recdomain" value="$env{'form.recdomain'}" type="hidden" />
                   1922: <input name="recuname" value="$env{'form.recuname'}" type="hidden" />
                   1923: ENDRHEAD
                   1924:         $r->print(<<ENDBFORM);
                   1925: <hr />$lt{'newr'}<br />
                   1926: <textarea name="newrecord" cols="80" rows="10" wrap="hard"></textarea>
                   1927: <br />
                   1928: <input type="hidden" name="recordftf" value="post" />
                   1929: <input type="submit" value="$lt{'post'}" />
                   1930: </form>
                   1931: ENDBFORM
                   1932:     }
                   1933: }
                   1934: 
                   1935: # ----------------------------------------------------------- Blocking during exams
                   1936: 
                   1937: sub examblock {
                   1938:     my ($r,$action) = @_;
                   1939:     unless ($env{'request.course.id'}) { return;}
1.44      raeburn  1940:     if (!&Apache::lonnet::allowed('dcm',$env{'request.course.id'})
                   1941: 	&& ! &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
1.1       albertel 1942: 				      '/'.$env{'request.course.sec'})) {
                   1943: 	$r->print('Not allowed');
                   1944: 	return;
                   1945:     }
1.34      albertel 1946:     my $usertype = (&Apache::loncommon::course_type() eq 'Group') ? 'members'
1.33      albertel 1947: 	                                                          : 'students';
1.1       albertel 1948:     my %lt=&Apache::lonlocal::texthash(
                   1949:             'comb' => 'Communication Blocking',
                   1950:             'cbds' => 'Communication blocking during scheduled exams',
1.30      raeburn  1951:             'desc' => "You can use communication blocking to prevent $usertype enrolled in this course from displaying LON-CAPA messages sent by other $usertype during an online exam. As blocking of communication could potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA course, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.",
1.1       albertel 1952:              'mecb' => 'Modify existing communication blocking periods',
1.72      albertel 1953:              'ncbc' => 'No communication blocks currently saved',
                   1954:              'stor' => 'Save',
1.1       albertel 1955:     );
                   1956: 
                   1957:     my %ltext = &Apache::lonlocal::texthash(
                   1958:             'dura' => 'Duration',
                   1959:             'setb' => 'Set by',
                   1960:             'even' => 'Event',
1.44      raeburn  1961:             'blck' => 'Blocked?',
1.1       albertel 1962:             'actn' => 'Action',
                   1963:             'star' => 'Start',
                   1964:             'endd' => 'End'
                   1965:     );
                   1966: 
                   1967:     &printheader($r,'/adm/email?block=display',$lt{'comb'});
                   1968:     $r->print('<h3>'.$lt{'cbds'}.'</h3>');
                   1969: 
                   1970:     if ($action eq 'store') {
                   1971:         &blockstore($r);
                   1972:     }
                   1973: 
                   1974:     $r->print($lt{'desc'}.'<br /><br />
                   1975:                <form name="blockform" method="post" action="/adm/email?block=store">
                   1976:              ');
                   1977: 
                   1978:     $r->print('<h4>'.$lt{'mecb'}.'</h4>');
                   1979:     my %records = ();
                   1980:     my $blockcount = 0;
                   1981:     my $parmcount = 0;
                   1982:     &get_blockdates(\%records,\$blockcount);
                   1983:     if ($blockcount > 0) {
                   1984:         $parmcount = &display_blocker_status($r,\%records,\%ltext);
                   1985:     } else {
                   1986:         $r->print($lt{'ncbc'}.'<br /><br />');
                   1987:     }
                   1988:     &display_addblocker_table($r,$parmcount,\%ltext);
                   1989:     my $end_page=&Apache::loncommon::end_page();
                   1990:     $r->print(<<"END");
                   1991: <br />
                   1992: <input type="hidden" name="blocktotal" value="$blockcount" />
1.50      raeburn  1993: <input type ="submit" value="$lt{'stor'}" />
1.1       albertel 1994: </form>
                   1995: $end_page
                   1996: END
                   1997:     return;
                   1998: }
                   1999: 
                   2000: sub blockstore {
                   2001:     my $r = shift;
                   2002:     my %lt=&Apache::lonlocal::texthash(
                   2003:             'tfcm' => 'The following changes were made',
                   2004:             'ncwm' => 'No changes were made.' 
                   2005:     );
                   2006:     my %adds = ();
                   2007:     my %removals = ();
                   2008:     my %cancels = ();
                   2009:     my $modtotal = 0;
                   2010:     my $canceltotal = 0;
                   2011:     my $addtotal = 0;
                   2012:     my %blocking = ();
                   2013:     $r->print('<h3>'.$lt{'head'}.'</h3>');
1.42      raeburn  2014:     foreach my $envkey (keys(%env)) {
1.44      raeburn  2015:         if ($envkey =~ m/^form\.modify_(\d+)$/) {
1.1       albertel 2016:             $adds{$1} = $1;
                   2017:             $removals{$1} = $1;
                   2018:             $modtotal ++;
1.42      raeburn  2019:         } elsif ($envkey =~ m/^form\.cancel_(\d+)$/) {
1.1       albertel 2020:             $cancels{$1} = $1;
                   2021:             unless ( defined($removals{$1}) ) {
                   2022:                 $removals{$1} = $1;
                   2023:                 $canceltotal ++;
                   2024:             }
1.42      raeburn  2025:         } elsif ($envkey =~ m/^form\.add_(\d+)$/) {
1.1       albertel 2026:             $adds{$1} = $1;
                   2027:             $addtotal ++;
1.44      raeburn  2028:         } 
1.1       albertel 2029:     }
                   2030: 
1.42      raeburn  2031:     foreach my $key (keys(%removals)) {
                   2032:         my $hashkey = $env{'form.key_'.$key};
1.1       albertel 2033:         &Apache::lonnet::del('comm_block',["$hashkey"],
                   2034:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2035:                          $env{'course.'.$env{'request.course.id'}.'.num'}
                   2036:                          );
                   2037:     }
1.42      raeburn  2038:     foreach my $key (keys(%adds)) {
                   2039:         unless ( defined($cancels{$key}) ) {
                   2040:             my ($newstart,$newend) = &get_dates_from_form($key);
1.1       albertel 2041:             my $newkey = $newstart.'____'.$newend;
1.44      raeburn  2042:             my $blocktypes = &get_block_choices($key);
                   2043:             $blocking{$newkey} = {
                   2044:                           setter => $env{'user.name'}.':'.$env{'user.domain'},
                   2045:                           event  => &escape($env{'form.title_'.$key}),
                   2046:                           blocks => $blocktypes,
                   2047:                         };
1.1       albertel 2048:         }
                   2049:     }
                   2050:     if ($addtotal + $modtotal > 0) {
                   2051:         &Apache::lonnet::put('comm_block',\%blocking,
                   2052:                      $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2053:                      $env{'course.'.$env{'request.course.id'}.'.num'}
                   2054:                      );
                   2055:     }
                   2056:     my $chgestotal = $canceltotal + $modtotal + $addtotal;
                   2057:     if ($chgestotal > 0) {
                   2058:         $r->print($lt{'tfcm'}.'<ul>');
                   2059:         if ($canceltotal > 0) {
1.50      raeburn  2060:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] removed.',$canceltotal).'</li>');
1.1       albertel 2061:         }
                   2062:         if ($modtotal > 0) {
1.50      raeburn  2063:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] modified.',$modtotal).'</li>');
1.1       albertel 2064:         }
                   2065:         if ($addtotal > 0) {
1.50      raeburn  2066:             $r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] added.',$addtotal).'</li>');
1.1       albertel 2067:         }
                   2068:         $r->print('</ul>');
                   2069:     } else {
                   2070:         $r->print($lt{'ncwm'});
                   2071:     }
                   2072:     $r->print('<br />');
                   2073:     return;
                   2074: }
                   2075: 
                   2076: sub get_dates_from_form {
                   2077:     my $item = shift;
                   2078:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$item);
                   2079:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$item);
                   2080:     return ($startdate,$enddate);
                   2081: }
                   2082: 
                   2083: sub get_blockdates {
                   2084:     my ($records,$blockcount) = @_;
                   2085:     $$blockcount = 0;
                   2086:     %{$records} = &Apache::lonnet::dump('comm_block',
                   2087:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2088:                          $env{'course.'.$env{'request.course.id'}.'.num'}
                   2089:                          );
1.15      albertel 2090:     $$blockcount = keys(%{$records});
                   2091: 
                   2092:     if ((keys(%{$records}))[0] =~ /^error: 2 /) {
                   2093: 	$records = {};
                   2094: 	$$blockcount = 0;
1.1       albertel 2095:     }
                   2096: }
                   2097: 
1.44      raeburn  2098: sub get_block_choices {
                   2099:     my $item = shift;
                   2100:     my $blocklist;
                   2101:     my ($typeorder,$types) = &blocktype_text();
                   2102:     foreach my $type (@{$typeorder}) {
                   2103:         if ($env{'form.'.$type.'_'.$item}) {
                   2104:             $blocklist->{$type} = 'on'; 
                   2105:         } else {
                   2106:             $blocklist->{$type} = 'off';
                   2107:         }
                   2108:     }
                   2109:     return $blocklist;
                   2110: }
                   2111: 
1.1       albertel 2112: sub display_blocker_status {
                   2113:     my ($r,$records,$ltext) = @_;
                   2114:     my $parmcount = 0;
1.16      albertel 2115:   
1.1       albertel 2116:     my %lt = &Apache::lonlocal::texthash(
                   2117:         'modi' => 'Modify',
                   2118:         'canc' => 'Cancel',
                   2119:     );
1.44      raeburn  2120:     my ($typeorder,$types) = &blocktype_text();
1.18      albertel 2121:     $r->print(&Apache::loncommon::start_data_table());
1.1       albertel 2122:     $r->print(<<"END");
1.16      albertel 2123:   <tr>
1.44      raeburn  2124:     <th>$ltext->{'dura'}</th>
                   2125:     <th>$ltext->{'setb'}</th>
                   2126:     <th>$ltext->{'even'}</th>
                   2127:     <th>$ltext->{'blck'}</th>
                   2128:     <th>$ltext->{'actn'}?</th>
1.16      albertel 2129:   </tr>
1.1       albertel 2130: END
1.18      albertel 2131:     foreach my $record (sort(keys(%{$records}))) {
1.1       albertel 2132:         my $onchange = 'onFocus="javascript:window.document.forms['.
                   2133:                        "'blockform'].elements['modify_".$parmcount."'].".
                   2134:                        'checked=true;"';
1.18      albertel 2135:         my ($start,$end) = split(/____/,$record);
1.1       albertel 2136:         my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
                   2137:         my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
1.15      albertel 2138: 	
1.44      raeburn  2139: 	my ($setuname,$setudom,$title,$blocks) = 
                   2140: 	    &Apache::loncommon::parse_block_record($$records{$record});
1.21      albertel 2141: 	$title = &HTML::Entities::encode($title,'"<>&');
1.44      raeburn  2142:         my $settername = 
                   2143:            &Apache::loncommon::aboutmewrapper(
                   2144:                            &Apache::loncommon::plainname($setuname,$setudom),
                   2145:                            $setuname,$setudom);
1.18      albertel 2146:         $r->print(&Apache::loncommon::start_data_table_row());
1.1       albertel 2147:         $r->print(<<"END");
1.44      raeburn  2148:         <td>$ltext->{'star'}:&nbsp;$startform<br/>$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
1.1       albertel 2149:         <td>$settername</td>
1.18      albertel 2150:         <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$record" /></td>
1.44      raeburn  2151:         <td>
                   2152: END
                   2153:         foreach my $block (@{$typeorder}) {
                   2154:             my $blockstatus = '';
                   2155:             if ($blocks->{$block} eq 'on') {
1.118     bisitz   2156:                 $blockstatus = 'checked="checked"';
1.44      raeburn  2157:             }
                   2158:             $r->print('<label><input type="checkbox" name="'.$block.'_'.$parmcount.'" '.$blockstatus.' value="1" />'.$types->{$block}.'</label><br />');
                   2159:         }
                   2160:         $r->print(<<"END");
                   2161:         </td>      
1.1       albertel 2162:         <td><label>$lt{'modi'}?&nbsp;<input type="checkbox" name="modify_$parmcount" /></label><br /><label>$lt{'canc'}?&nbsp;&nbsp;<input type="checkbox" name="cancel_$parmcount" /></label>
                   2163: END
1.18      albertel 2164:         $r->print(&Apache::loncommon::end_data_table_row());
                   2165:         $parmcount++;
1.1       albertel 2166:     }
                   2167:     $r->print(<<"END");
                   2168: </table>
                   2169: <br />
                   2170: <br />
                   2171: END
                   2172:     return $parmcount;
                   2173: }
                   2174: 
                   2175: sub display_addblocker_table {
                   2176:     my ($r,$parmcount,$ltext) = @_;
                   2177:     my $start = time;
                   2178:     my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration.
                   2179:     my $onchange = 'onFocus="javascript:window.document.forms['.
                   2180:                    "'blockform'].elements['add_".$parmcount."'].".
                   2181:                    'checked=true;"';
                   2182:     my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange);
                   2183:     my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange);
                   2184:     my %lt = &Apache::lonlocal::texthash(
                   2185:         'addb' => 'Add block',
                   2186:         'exam' => 'e.g., Exam 1',
                   2187:         'addn' => 'Add new communication blocking periods'
                   2188:     );
1.44      raeburn  2189:     my ($typeorder,$types) = &blocktype_text();
1.1       albertel 2190:     $r->print(<<"END");
                   2191: <h4>$lt{'addn'}</h4> 
1.18      albertel 2192: END
                   2193:     $r->print(&Apache::loncommon::start_data_table());
                   2194:     $r->print(<<"END");
1.16      albertel 2195:    <tr>
1.44      raeburn  2196:      <th>$ltext->{'dura'}</th>
                   2197:      <th>$ltext->{'even'} $lt{'exam'}</th>
                   2198:      <th>$ltext->{'blck'}</th>
                   2199:      <th>$ltext->{'actn'}?</th>
1.16      albertel 2200:    </tr>
1.18      albertel 2201: END
1.44      raeburn  2202:     $r->print(&Apache::loncommon::start_data_table_row());
1.18      albertel 2203:     $r->print(<<"END");
1.44      raeburn  2204:      <td>$ltext->{'star'}:&nbsp;$startform<br />$ltext->{'endd'}:&nbsp;&nbsp;$endform</td>
1.16      albertel 2205:      <td><input type="text" name="title_$parmcount" size="15" value="" /></td>
1.44      raeburn  2206:      <td>
                   2207: END
                   2208:     foreach my $block (@{$typeorder}) {
                   2209:         $r->print('<label><input type="checkbox" name="'.$block.'_'.$parmcount.'" value="1" />'.$types->{$block}.'</label><br />');
                   2210:      }
                   2211:      $r->print(<<"END");
                   2212:      </td> 
1.16      albertel 2213:      <td><label>$lt{'addb'}?&nbsp;<input type="checkbox" name="add_$parmcount" value="1" /></label></td>
1.1       albertel 2214: END
1.18      albertel 2215:     $r->print(&Apache::loncommon::end_data_table_row());
                   2216:     $r->print(&Apache::loncommon::end_data_table());
1.1       albertel 2217:     return;
                   2218: }
                   2219: 
1.44      raeburn  2220: sub blocktype_text {
                   2221:     my %types = &Apache::lonlocal::texthash(
                   2222:         'com' => 'Messaging',
1.115     hauer    2223:         'chat' => 'Chat Room',
1.44      raeburn  2224:         'boards' => 'Discussion',
                   2225:         'port' => 'Portfolio',
1.45      raeburn  2226:         'groups' => 'Groups',
                   2227:         'blogs' => 'Blogs',
1.18      albertel 2228:     );
1.45      raeburn  2229:     my $typeorder = ['com','chat','boards','port','groups','blogs'];
1.44      raeburn  2230:     return ($typeorder,\%types);
1.1       albertel 2231: }
                   2232: 
                   2233: # ----------------------------------------------------------- Display a message
                   2234: 
                   2235: sub displaymessage {
1.53      raeburn  2236:     my ($r,$msgid,$folder,$msgstatus)=@_;
1.1       albertel 2237:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
                   2238:     my %blocked = ();
                   2239:     my %setters = ();
                   2240:     my $numblocked = 0;
1.33      albertel 2241:     my $crstype = &Apache::loncommon::course_type();
1.30      raeburn  2242: 
1.1       albertel 2243: # info to generate "next" and "previous" buttons and check if message is blocked
1.44      raeburn  2244:     my ($startblock,$endblock) = &Apache::loncommon::blockcheck(\%setters,'com');
1.53      raeburn  2245:     my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder,$msgstatus);
1.1       albertel 2246:     if ( $blocked{$msgid} eq 'ON' ) {
                   2247:         &printheader($r,'/adm/email',&mt('Display a Message'));
                   2248:         $r->print(&mt('You attempted to display a message that is currently blocked because you are enrolled in one or more courses for which there is an ongoing online exam.'));
                   2249:         &build_block_table($r,$startblock,$endblock,\%setters);
                   2250:         return;
                   2251:     }
1.59      raeburn  2252:     if ($msgstatus eq '') {
                   2253:         &statuschange($msgid,'read',$folder);
                   2254:     }
1.1       albertel 2255:     my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
                   2256:     my %content=&Apache::lonmsg::unpackagemsg($message{$msgid});
                   2257:     my $counter=0;
1.29      www      2258:     my $escmsgid=&escape($msgid);
1.1       albertel 2259:     foreach (@messages) {
                   2260: 	if ($_->[5] eq $escmsgid){
                   2261: 	    last;
                   2262: 	}
                   2263: 	$counter++;
                   2264:     }
1.82      albertel 2265: 
                   2266:     my $see_anonymous;
                   2267:     my $from_student = 0;
                   2268:     if ($env{'request.course.id'} eq $content{'courseid'}) {
                   2269: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2270: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2271: 	my $username = $content{'sendername'}.':'.$content{'senderdomain'};
                   2272: 	my %classlist_entry =
                   2273: 	    &Apache::lonnet::get('classlist',[$username],$cdom,$cnum);
                   2274: 	if (exists($classlist_entry{$username})) {
                   2275: 	    $from_student = 1;
                   2276: 	    $see_anonymous = &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
                   2277: 	}
                   2278:     }
                   2279: 
                   2280: 
1.1       albertel 2281:     my $number_of_messages = scalar(@messages); #subtract 1 for last index
                   2282: # start output
1.29      www      2283:     &printheader($r,'/adm/email?display='.&escape($msgid),'Display a Message','',$content{'baseurl'});
1.1       albertel 2284:     my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'});
1.101     bisitz   2285: 
                   2286: # Prepare available functions
1.119     bisitz   2287:     my @functionlist;
1.78      raeburn  2288:     if (!$content{'noreplies'}) {
1.119     bisitz   2289:         push(@functionlist,'<a href="/adm/email?replyto='.&escape($msgid).$sqs.'">'
1.101     bisitz   2290:                      .&mt('Reply')
1.119     bisitz   2291:                      .'</a>');
1.101     bisitz   2292:     }
1.119     bisitz   2293:     push(@functionlist,'<a href="/adm/email?forward='.&escape($msgid).$sqs.'">'
1.101     bisitz   2294:                   .&mt('Forward')
1.119     bisitz   2295:                   .'</a>');
                   2296:     push(@functionlist,'<a href="/adm/email?markunread='.&escape($msgid).$sqs.'">'
1.101     bisitz   2297:                   .&mt('Mark Unread')
1.119     bisitz   2298:                   .'</a>');
                   2299:     push(@functionlist,'<a href="/adm/email?markdel='.&escape($msgid).$sqs.'">'
1.101     bisitz   2300:                   .&mt('Delete')
1.119     bisitz   2301:                   .'</a>');
                   2302:     push(@functionlist,'<a href="/adm/email?'.$sqs.'">'
1.101     bisitz   2303:                   .&mt('Back to Folder Display')
1.119     bisitz   2304:                   .'</a>');
1.1       albertel 2305:     if ($counter > 0){
1.119     bisitz   2306:         push(@functionlist,'<a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.'">'
                   2307:                           .&mt('Previous')
                   2308:                           .'</a>');
1.1       albertel 2309:     }
                   2310:     if ($counter < $number_of_messages - 1){
1.119     bisitz   2311:         push(@functionlist,'<a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.'">'
                   2312:                           .&mt('Next')
                   2313:                           .'</a>');
1.101     bisitz   2314:     }
                   2315: # Print functions
1.119     bisitz   2316:     my $legendtext='<span class="LC_mail_functions">'
                   2317:                    .&mt('Functions')
                   2318:                    .'</span>';
1.104     raeburn  2319:     $r->print('<div class="LC_left_float">'
1.119     bisitz   2320:                      .&Apache::lontemplate::start_functionslist($legendtext)
                   2321:     );
                   2322:     foreach my $item (@functionlist) {
                   2323:         $r->print(&Apache::lontemplate::item_functionslist($item));
                   2324:     }
                   2325:     $r->print(&Apache::lontemplate::end_functionslist()
1.101     bisitz   2326:              .'</div>'
                   2327:     );
                   2328: 
                   2329: # Prepare available actions
1.59      raeburn  2330:     my $symb;
                   2331:     if (defined($content{'symb'})) {
                   2332:         $symb = $content{'symb'};
                   2333:     } elsif (defined($content{'baseurl'})) {
                   2334:         $symb=&Apache::lonnet::symbread($content{'baseurl'});
                   2335:     }
1.1       albertel 2336:     if ($env{'user.adv'}) {
1.119     bisitz   2337:         my @actionlist;
1.101     bisitz   2338: 
1.1       albertel 2339: 	if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
1.119     bisitz   2340: 		push(@actionlist,&Apache::loncommon::track_student_link(
                   2341:                                       &mt('View recent activity')
                   2342:                                      ,$content{'sendername'}
                   2343:                                      ,$content{'senderdomain'}
                   2344:                                      ,'check'));
1.90      bisitz   2345: 	}
1.1       albertel 2346: 	if (&Apache::lonnet::allowed('opa',$env{'request.course.id'}) && $symb) {
1.119     bisitz   2347: 	    push(@actionlist,&Apache::loncommon::pprmlink(
                   2348:                                   &mt('Set/Change parameters')
                   2349:                                      ,$content{'sendername'}
                   2350:                                      ,$content{'senderdomain'}
                   2351:                                      ,$symb
                   2352:                                      ,'check'));
1.1       albertel 2353: 	}
                   2354: 	if (&Apache::lonnet::allowed('mgr',$env{'request.course.id'}) && $symb) {
1.119     bisitz   2355: 	    push(@actionlist,&Apache::loncommon::pgrdlink(
                   2356:                                  &mt('Set/Change grades')
                   2357:                                      ,$content{'sendername'}
                   2358:                                      ,$content{'senderdomain'}
                   2359:                                      ,$symb
                   2360:                                      ,'check'));
1.90      bisitz   2361: 	}
1.101     bisitz   2362: 
                   2363: # Print actions
1.119     bisitz   2364:         if (@actionlist) {
                   2365:             $legendtext=&mt('[_1]Currently available actions[_2] (will open extra window):'
                   2366:                            ,'<span class="LC_mail_functions">','</span>');
1.104     raeburn  2367:             $r->print('<div class="LC_left_float">'
1.119     bisitz   2368:                      .&Apache::lontemplate::start_functionslist($legendtext)
                   2369:             );
                   2370:             foreach my $item (@actionlist) {
                   2371:                 $r->print(&Apache::lontemplate::item_functionslist($item));
                   2372:             }
                   2373:             $r->print(&Apache::lontemplate::end_functionslist()
1.101     bisitz   2374:                      .'</div>'
                   2375:             );
1.90      bisitz   2376:         }
1.1       albertel 2377:     }
1.101     bisitz   2378: 
1.95      raeburn  2379:     my ($tonum,$tolist,$cclist,$bcclist,$groupcclist,%recipients);
                   2380:     if ($content{'recipid'}) {
                   2381:         $tonum = &retrieve_recips('display',\%content,\%recipients);
                   2382:         if (ref($recipients{'cc'}) eq 'ARRAY') {
                   2383:             $cclist = join(', ',@{$recipients{'cc'}});
                   2384:         }
                   2385:         if (ref($recipients{'to'}) eq 'ARRAY') {
                   2386:             $tolist = join(', ',@{$recipients{'to'}});
                   2387:         }
                   2388:         if (ref($recipients{'bcc'}) eq 'ARRAY') {
                   2389:             $bcclist = join(', ',@{$recipients{'bcc'}});
                   2390:         }
                   2391:     }
1.107     raeburn  2392: 
                   2393:     my $broadcast_link;
                   2394:     if (($content{'courseid'}) && ($content{'recipid'} &&
                   2395:         (ref($recipients{'course_broadcast'}) eq 'ARRAY') ||
                   2396:         (ref($recipients{'group_cc_broadcast'}) eq 'ARRAY') ||
                   2397:         (ref($recipients{'group_bcc_broadcast'}) eq 'ARRAY'))) {
                   2398:         $broadcast_link = &recipients_link($r,\%content,\%recipients);
                   2399:     }
                   2400: 
                   2401:     if (((!$tolist) && (!$broadcast_link)) && ref($content{'recuser'}) eq 'ARRAY') {
1.95      raeburn  2402:         my @recipients;
1.73      raeburn  2403:         for (my $i=0; $i<@{$content{'recuser'}}; $i++) {
                   2404:             $recipients[$i] =  &Apache::loncommon::aboutmewrapper(
                   2405:                &Apache::loncommon::plainname($content{'recuser'}[$i],
1.1       albertel 2406:                                       $content{'recdomain'}[$i]),
1.73      raeburn  2407:                   $content{'recuser'}[$i],$content{'recdomain'}[$i]).
1.95      raeburn  2408:            ' ('.$content{'recuser'}[$i].':'.$content{'recdomain'}[$i].') ';
1.73      raeburn  2409:         }
1.95      raeburn  2410:         $tolist = join(', ',@recipients);
1.73      raeburn  2411:     }
1.59      raeburn  2412:     my ($restitle,$baseurl,$refers_to);
                   2413:     if (defined($content{'resource_title'})) {
                   2414:         $restitle = $content{'resource_title'};
                   2415:     } else {
                   2416:         if (defined($content{'baseurl'})) {
                   2417:             $restitle = &Apache::lonnet::gettitle($content{'baseurl'});
                   2418:         }
                   2419:     }
                   2420:     if (defined($content{'baseurl'})) {
                   2421:         $baseurl = &Apache::lonenc::check_encrypt($content{'baseurl'});
                   2422:     }
1.104     raeburn  2423:     $r->print('<div class="LC_clear_float_footer">');
1.82      albertel 2424:     if ($from_student && $see_anonymous ) {
1.104     raeburn  2425: 	$r->print(&Apache::loncommon::student_image_tag($content{'senderdomain'},$content{'sendername'}).'</br>');
1.82      albertel 2426:     }
                   2427: 
1.91      bisitz   2428:     # Display LON-CAPA Message (Start)
                   2429:     # Subject
1.104     raeburn  2430:     $r->print('</div>'
1.91      bisitz   2431:              .&Apache::lonhtmlcommon::start_pick_box()
                   2432:              .&Apache::lonhtmlcommon::row_title(&mt('Subject'))
                   2433:              .$content{'subject'}
                   2434:              .&Apache::lonhtmlcommon::row_closure()
                   2435:     );
1.73      raeburn  2436:     if ($folder eq 'sent') {
1.91      bisitz   2437:         # To
1.107     raeburn  2438:         if ($tolist) {
                   2439:             $r->print(&Apache::lonhtmlcommon::row_title(&mt('To'))
                   2440:                      .$tolist
                   2441:                      .&Apache::lonhtmlcommon::row_closure()
                   2442:             );
                   2443:         }
1.95      raeburn  2444:         if ($cclist) {
                   2445:             $r->print(&Apache::lonhtmlcommon::row_title(&mt('Cc'))
                   2446:                      .$cclist
                   2447:                      .&Apache::lonhtmlcommon::row_closure()
                   2448:             );
                   2449:         }
                   2450:         if ($bcclist) {
                   2451:             $r->print(&Apache::lonhtmlcommon::row_title(&mt('Bcc'))
                   2452:                      .$bcclist
                   2453:                      .&Apache::lonhtmlcommon::row_closure()
                   2454:             );
                   2455:         }
                   2456:         if (($content{'courseid'}) && ($content{'recipid'})) {
                   2457:             my %broadcast_types = 
                   2458:                 &Apache::lonlocal::texthash (
                   2459:                     course_broadcast    => 'Broadcast to', 
                   2460:                     group_cc_broadcast  => 'Cc to group',
                   2461:                     group_bcc_broadcast => 'Bcc to group',
                   2462:                 );                   
                   2463:             foreach my $type (sort(keys(%broadcast_types))) {
                   2464:                 if (ref($recipients{$type}) eq 'ARRAY') {
                   2465:                     my $num = @{$recipients{$type}};
                   2466:                     my $broadcastlist = join(', ',@{$recipients{$type}});
                   2467:                     if ($broadcastlist && $broadcast_link) {
                   2468:                         if ($type eq 'group_cc_broadcast') {
                   2469:                             $groupcclist = $broadcastlist;
                   2470:                         }
                   2471:                         $r->print(&Apache::lonhtmlcommon::row_title(
                   2472:                                             $broadcast_types{$type})
                   2473:                                   .&mt('[quant,_1,recipient]',$num)
                   2474:                                   .' <a href="javascript:showBroadcastList();">['
                   2475:                                   .&mt('Show').']</a>' 
                   2476:                                   .&Apache::lonhtmlcommon::row_closure());
                   2477:                     }
                   2478:                 }
                   2479:             }
                   2480:         }
1.78      raeburn  2481:         if ($content{'replytoaddr'}) {
                   2482:             my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
                   2483:             if ($replytoname ne '' && $replytodom ne '') {
1.91      bisitz   2484:                 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
1.95      raeburn  2485:                          .$replytoname.':'.$replytodom
1.91      bisitz   2486:                          .&Apache::lonhtmlcommon::row_closure()
                   2487:                 );
1.78      raeburn  2488:             }
                   2489:         }
1.73      raeburn  2490:     } else {
1.91      bisitz   2491:         # From, Reply
                   2492:         $r->print(&Apache::lonhtmlcommon::row_title(&mt('From'))
                   2493:                  .&Apache::loncommon::aboutmewrapper(
                   2494:                      &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
                   2495:                                                  $content{'sendername'},$content{'senderdomain'})
                   2496:         );
1.78      raeburn  2497:         if ($content{'noreplies'}) {
1.91      bisitz   2498:             $r->print(' ('.&mt('No replies to sender').')'
                   2499:                      .&Apache::lonhtmlcommon::row_closure()
1.95      raeburn  2500:             );
1.78      raeburn  2501:         } else {
                   2502:             if ($content{'replytoaddr'}) {
                   2503:                 my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
                   2504:                 if ($replytoname ne '' && $replytodom ne '') {
1.91      bisitz   2505:                     $r->print(&Apache::lonhtmlcommon::row_closure()
                   2506:                              .&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
1.95      raeburn  2507:                              .$replytoname.':'.$replytodom
1.91      bisitz   2508:                              .&Apache::lonhtmlcommon::row_closure()
                   2509:                     );
                   2510:                 } else {
                   2511:                     $r->print(&Apache::lonhtmlcommon::row_closure());
1.78      raeburn  2512:                 }
                   2513:             } else {
1.95      raeburn  2514:                 $r->print(' ('.$content{'sendername'}.':'.$content{'senderdomain'}.') '
1.91      bisitz   2515:                          .&Apache::lonhtmlcommon::row_closure()
                   2516:                 );
1.78      raeburn  2517:             }
1.95      raeburn  2518:             if ($tonum && $tolist) {
                   2519:                 $r->print(&Apache::lonhtmlcommon::row_title(&mt('To'))
                   2520:                          .$tolist
                   2521:                          .&Apache::lonhtmlcommon::row_closure()
                   2522:                     );
                   2523:             }
                   2524:             if ($cclist) { 
1.91      bisitz   2525:                 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Cc'))
                   2526:                          .$cclist
                   2527:                          .&Apache::lonhtmlcommon::row_closure()
                   2528:                     );
1.95      raeburn  2529:             }
                   2530:             if ($content{'group'} ne '') {
                   2531:                 if (&check_group_priv($content{'group'})) {
                   2532:                     $groupcclist = join(', ',@{$recipients{'group_cc_broadcast'}});
                   2533:                     if ($groupcclist) {
                   2534:                         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group Cc'))
                   2535:                                  .$groupcclist
                   2536:                                  .&Apache::lonhtmlcommon::row_closure()
                   2537:                         );
                   2538:                     }
                   2539:                 }
1.78      raeburn  2540:             }
1.91      bisitz   2541:         }
1.73      raeburn  2542:     }
1.91      bisitz   2543: 
                   2544:     # Course
1.73      raeburn  2545:     if ($content{'courseid'}) {
1.91      bisitz   2546:         $r->print(&Apache::lonhtmlcommon::row_title(&mt($crstype))
                   2547:                  .$courseinfo{'description'}
                   2548:         );
1.73      raeburn  2549:         if ($content{'coursesec'}) {
                   2550:             $r->print(' ('.&mt('Section').': '.$content{'coursesec'}.')');
                   2551:         }
1.91      bisitz   2552:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.73      raeburn  2553:     }
1.91      bisitz   2554:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Time'))
                   2555:              .$content{'time'}
                   2556:              .&Apache::lonhtmlcommon::row_closure()
                   2557:     );
                   2558: 
                   2559:     # Refers to
1.59      raeburn  2560:     if ($baseurl) {
                   2561:         if (defined($content{'courseid'}) && defined($env{'request.course.id'})) {
                   2562:             if ($content{'courseid'} eq $env{'request.course.id'}) {
                   2563:                 my $symblink;
1.62      raeburn  2564:                 my $showsymb = &Apache::lonenc::check_decrypt($symb);
                   2565:                 my $showurl = &Apache::lonenc::check_decrypt($baseurl);
                   2566:                 my $encrypturl = &Apache::lonnet::EXT('resource.0.encrypturl',
                   2567:                               $showsymb,$env{'user.domain'},$env{'user.name'});
1.59      raeburn  2568:                 if ($symb) {
1.62      raeburn  2569:                     if ($encrypturl =~ /^yes$/i && !$env{'request.role.adv'}) {
                   2570:                         $showsymb = &Apache::lonenc::check_encrypt($symb);
                   2571:                     }
                   2572:                     $symblink = '?symb='.$showsymb;
                   2573:                 }
                   2574:                 if ($encrypturl =~ /^yes$/i && !$env{'request.role.adv'}) {
                   2575:                     $showurl = $baseurl;
1.59      raeburn  2576:                 }
1.91      bisitz   2577:                 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
                   2578:                          .'<a href="'.$showurl.$symblink.'">'.$restitle.'</a>'
                   2579:                          .&Apache::lonhtmlcommon::row_closure()
                   2580:                 );
1.59      raeburn  2581:                 $refers_to = 1;
                   2582:             }
                   2583:         }
                   2584:         if (!$refers_to) {
                   2585:             if ($baseurl =~ m-^/enc/-) {
                   2586:                 if (defined($content{'courseid'})) {
1.62      raeburn  2587:                     if (!$env{'request.course.id'}) {
                   2588:                         my $unencurl =
                   2589:                            &Apache::lonenc::unencrypted($baseurl,
                   2590:                                                         $content{'courseid'});
                   2591:                         if ($unencurl ne '') {
                   2592:                             if (&Apache::lonnet::allowed('bre',$unencurl)) {
1.91      bisitz   2593:                                 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
                   2594:                                          .'<a href="'.$unencurl.'">'.$restitle.'</a>'
                   2595:                                          .&Apache::lonhtmlcommon::row_closure()
                   2596:                                 );
1.62      raeburn  2597:                             }
1.59      raeburn  2598:                         }
                   2599:                     }
                   2600:                 }
                   2601:             } else {
                   2602:                 if (&Apache::lonnet::allowed('bre',$baseurl)) {
1.91      bisitz   2603:                     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
                   2604:                              .'<a href="'.$baseurl.'">'.$restitle.'</a>'
                   2605:                              .&Apache::lonhtmlcommon::row_closure()
                   2606:                     );
                   2607: 
1.59      raeburn  2608:                 }
                   2609:             }
                   2610:         }
                   2611:     }
1.91      bisitz   2612: 
                   2613:     # Message
                   2614:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Message'))
                   2615:              .'<pre>'
                   2616: 	     .&Apache::lontexconvert::msgtexconverted($content{'message'},1)
                   2617: 	     .'</pre>'
                   2618:     );
                   2619:     if (&displayresource(%content)) {
                   2620:         $r->print(&Apache::lonhtmlcommon::row_closure()
                   2621:                  .&Apache::lonhtmlcommon::row_title(&mt('Resource Details'))
                   2622:                  .&displayresource(%content)
                   2623:         );
                   2624:     } 
1.92      raeburn  2625:     $r->print(&Apache::lonhtmlcommon::row_closure(1).
                   2626:               &Apache::lonhtmlcommon::end_pick_box());
1.91      bisitz   2627:     # Display LON-CAPA Message (End)
1.59      raeburn  2628:     return;
1.1       albertel 2629: }
                   2630: 
1.95      raeburn  2631: sub retrieve_recips {
                   2632:     my ($context,$content,$recips)= @_;
                   2633:     my $tonum = 0;
                   2634:     if (ref($content) eq 'HASH') {
                   2635:         my %reciphash =
                   2636:             &Apache::lonnet::get('nohist_emailrecip',[$content->{'recipid'}],
                   2637:                                  $content->{'senderdomain'},$content->{'sendername'});
                   2638:         my $recipinfo = $reciphash{$content->{'recipid'}};
                   2639:         if (ref($recipinfo) eq 'HASH') {
                   2640:             foreach my $type ('to','cc','course_broadcast','group_cc_broadcast','group_bcc_broadcast') {
                   2641:                 if (ref($recipinfo->{$type}) eq 'HASH') {
                   2642:                     if ($type eq 'to') {
                   2643:                         $tonum = keys(%{$recipinfo->{$type}});
                   2644:                     }
                   2645:                     foreach my $user (sort(keys(%{$recipinfo->{$type}}))) {
                   2646:                         my ($uname,$udom) = split(/:/,$user);
                   2647:                         next if (($context eq 'replying') && ($uname eq $env{'user.name'})
                   2648:                                  && ($udom eq $env{'user.domain'}));
                   2649:                         my $showuser ='<span class="LC_nobreak">';
                   2650:                         if ($context eq 'replying') {
                   2651:                             if (($type eq 'to') || ($type eq 'cc')) { 
                   2652:                                 $showuser = '<label><input type="checkbox" name="replying_'.$type.'" value="'.$user.'" />';
                   2653:                             } elsif ($type eq 'group_cc_broadcast') {
                   2654:                                 $showuser = '<label><input type="checkbox" name="replying_groupcc" value="'.$user.'" />';
                   2655:                             }
                   2656:                         }
                   2657:                         $showuser .= &Apache::loncommon::aboutmewrapper(
                   2658:                                            &Apache::loncommon::plainname($uname,
                   2659:                                            $udom),$uname,$udom);
                   2660: 		        if ($context eq 'replying') {
                   2661: 		            $showuser .='</label>';
                   2662: 		        }
                   2663: 		        $showuser .= '</span>';
                   2664:                         if (ref($recips) eq 'HASH') {
                   2665: 		            push(@{$recips->{$type}},$showuser);
                   2666:                         }
                   2667:                     }
1.73      raeburn  2668:                 }
                   2669:             }
                   2670:         }
                   2671:     }
1.95      raeburn  2672:     return $tonum;
                   2673: }
                   2674: 
                   2675: sub recipients_link {
                   2676:     my ($r,$content,$recipients) = @_;
                   2677:     my ($broadcast_link,$show);
                   2678:     if ((ref($content) eq 'HASH') && (ref($recipients) eq 'HASH')) {
                   2679:         if (ref($recipients->{'course_broadcast'}) eq 'ARRAY') {
                   2680:             if (@{$recipients->{'course_broadcast'}} > 0) {
                   2681:                 $show = 'course';
                   2682:             }
                   2683:         } elsif (ref($recipients->{'group_cc_broadcast'}) eq 'ARRAY') {
                   2684:             if (@{$recipients->{'group_cc_broadcast'}} > 0) {
                   2685:                 $show = 'group_cc';
                   2686:             }
                   2687:         } elsif (ref($recipients->{'group_bcc_broadcast'}) eq 'ARRAY') {
                   2688:             if (@{$recipients->{'group_bcc_broadcast'}} > 0) {
                   2689:                 $show = 'group_bcc';
                   2690:             }
                   2691:         }
                   2692:         if ($show) {
                   2693:             my ($nothing,$height,$width,$start_page,$end_page,$body);
                   2694:             $nothing=&Apache::lonhtmlcommon::javascript_nothing();
                   2695:             $height = 400;
                   2696:             $width = 600;
1.108     raeburn  2697:             $start_page =
                   2698:                 &Apache::loncommon::start_page('Broadcast List', undef,
                   2699:                                                {only_body => 1,
                   2700:                                                 js_ready  => 1,});
                   2701:             $end_page = &Apache::loncommon::end_page({js_ready => 1,});
                   2702:             $body = '<h3>'.&mt("Recipients of broadcast message").'</h3>'.
                   2703:                     &Apache::loncommon::start_data_table();
1.95      raeburn  2704:             my $cell = 0;
                   2705:             $body .= &Apache::loncommon::start_data_table_row();
                   2706:             foreach my $item (@{$recipients->{$show.'_broadcast'}}) {
                   2707:                 $item =~ s/'/\\'/g;
                   2708:                 if (!($cell%2) && $cell > 0) {
                   2709:                     $body .= &Apache::loncommon::end_data_table_row().
                   2710:                              &Apache::loncommon::start_data_table_row();
                   2711:                 }
                   2712:                 $cell ++;
                   2713:                 $body .= '<td>'.$cell.'&nbsp;'.$item.'&nbsp;&nbsp;</td>';
                   2714:             }
                   2715:             if ($cell%2) {
                   2716:                 $body .= '<td>&nbsp;</td>';
                   2717:             }
                   2718:             $body .= &Apache::loncommon::end_data_table_row().
                   2719:                      &Apache::loncommon::end_data_table();
                   2720:             $body =~ s{</}{<\\/}g;
                   2721:             $body =~ s{\n}{}g;
                   2722:             $r->print(<<ENDJS);
                   2723: <script type="text/javascript">
                   2724: function showBroadcastList() {
                   2725:     var caller = this;
                   2726:     var newWindow = null;
                   2727:     try {
                   2728:         newWindow =  window.open($nothing,"broadcast","HEIGHT=$height,WIDTH=$width,resizable=yes,scrollbars=yes" );
                   2729:     }
                   2730:     catch(error) {
                   2731:         writeWin(caller);
                   2732:         return;
                   2733:     }
                   2734:     if (newWindow) {
                   2735:         caller = newWindow;
                   2736:     }
                   2737:     writeWin(caller);
                   2738:     return;
                   2739: }
                   2740: 
                   2741: function writeWin(caller) {
                   2742:     caller.document.writeln('$start_page $body $end_page');
                   2743:     caller.document.close();
                   2744:     caller.focus();
                   2745: }
                   2746: 
                   2747: </script>
                   2748: 
                   2749: ENDJS
                   2750:             $broadcast_link = 1;
                   2751:         }
                   2752:     }
                   2753:     return $broadcast_link;
1.73      raeburn  2754: }
                   2755: 
1.1       albertel 2756: # =========================================================== Show the citation
                   2757: 
                   2758: sub displayresource {
                   2759:     my %content=@_;
                   2760: #
                   2761: # If the recipient is in the same course that the message was sent from and
                   2762: # has sufficient privileges, show "all details," else show citation
                   2763: #
                   2764:     if (($env{'request.course.id'} eq $content{'courseid'})
                   2765:      && (&Apache::lonnet::allowed('vgr',$content{'courseid'}))) {
1.59      raeburn  2766:         my $symb;
                   2767:         if (defined($content{'symb'})) {
                   2768:             $symb = $content{'symb'};
                   2769:         } else { 
                   2770: 	    $symb=&Apache::lonnet::symbread($content{'baseurl'});
                   2771:         }
1.1       albertel 2772: # Could not get a symb, give up
                   2773: 	unless ($symb) { return $content{'citation'}; }
                   2774: # Have a symb, can render
                   2775: 	return '<h2>'.&mt('Current attempts of student (if applicable)').'</h2>'.
                   2776: 	    &Apache::loncommon::get_previous_attempt($symb,
                   2777: 						     $content{'sendername'},
                   2778: 						     $content{'senderdomain'},
                   2779: 						     $content{'courseid'}).
                   2780: 	    '<hr /><h2>'.&mt('Current screen output (if applicable)').'</h2>'.
                   2781: 	    &Apache::loncommon::get_student_view($symb,
                   2782: 						 $content{'sendername'},
                   2783: 						 $content{'senderdomain'},
                   2784: 						 $content{'courseid'}).
                   2785: 	    '<h2>'.&mt('Correct Answer(s) (if applicable)').'</h2>'.
                   2786: 	    &Apache::loncommon::get_student_answers($symb,
                   2787: 						    $content{'sendername'},
                   2788: 						    $content{'senderdomain'},
                   2789: 						    $content{'courseid'});
                   2790:     } elsif ($env{'user.adv'}) {
                   2791: 	return $content{'citation'};
                   2792:     }
                   2793:     return '';
                   2794: }
                   2795: 
                   2796: # ================================================================== The Header
                   2797: 
                   2798: sub header {
                   2799:     my ($r,$title,$baseurl)=@_;
                   2800:     my $extra = &Apache::loncommon::studentbrowser_javascript();
                   2801:     if ($baseurl) {
1.41      albertel 2802: 	$extra .= "<base href=\"".&Apache::lonnet::absolute_url()."/$baseurl\" />";
1.1       albertel 2803:     }
1.116     schafran 2804:     $r->print(&Apache::loncommon::start_page('Communication',
1.38      raeburn  2805:  					$extra));
1.1       albertel 2806:     $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.116     schafran 2807:      		(($title?$title:'Send and Receive Messages')));
1.1       albertel 2808: }
                   2809: 
                   2810: # ---------------------------------------------------------------- Print header
                   2811: 
                   2812: sub printheader {
                   2813:     my ($r,$url,$desc,$title,$baseurl)=@_;
                   2814:     &Apache::lonhtmlcommon::add_breadcrumb
                   2815: 	({href=>$url,
                   2816: 	  text=>$desc});
                   2817:     &header($r,$title,$baseurl);
                   2818: }
                   2819: 
                   2820: # ------------------------------------------------------------ Store the comment
                   2821: 
                   2822: sub storecomment {
                   2823:     my ($r)=@_;
                   2824:     my $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'});
                   2825:     my $cleanmsgtxt='';
1.42      raeburn  2826:     foreach my $line (split(/[\n\r]/,$msgtxt)) {
                   2827: 	unless ($line=~/^\s*(\>|\&gt\;)/) {
                   2828: 	    $cleanmsgtxt.=$line."\n";
1.1       albertel 2829: 	}
                   2830:     }
1.29      www      2831:     my $key=&escape($env{'form.baseurl'}).'___'.time;
1.1       albertel 2832:     &Apache::lonnet::put('nohist_stored_comments',{ $key => $cleanmsgtxt });
                   2833: }
                   2834: 
                   2835: sub storedcommentlisting {
                   2836:     my ($r)=@_;
                   2837:     my %msgs=&Apache::lonnet::dump('nohist_stored_comments',undef,undef,
1.29      www      2838:        '^'.&escape(&escape($env{'form.showcommentbaseurl'})));
1.72      albertel 2839:     $r->print(&Apache::loncommon::start_page('Saved Comment Listing',undef,
1.1       albertel 2840: 					     {'onlybody' => 1}));
                   2841:     if ((keys %msgs)[0]=~/^error\:/) {
1.72      albertel 2842: 	$r->print(&mt('No saved comments yet.'));
1.1       albertel 2843:     } else {
                   2844: 	my $found=0;
1.42      raeburn  2845: 	foreach my $key (sort(keys(%msgs))) {
                   2846: 	    $r->print("\n".$msgs{$key}."<hr />");
1.1       albertel 2847: 	    $found=1;
                   2848: 	}
                   2849: 	unless ($found) {
1.72      albertel 2850: 	    $r->print(&mt('No saved comments yet for this resource.'));
1.1       albertel 2851: 	}
                   2852:     }
                   2853: }
                   2854: 
                   2855: # ---------------------------------------------------------------- Send an email
                   2856: 
                   2857: sub sendoffmail {
                   2858:     my ($r,$folder)=@_;
                   2859:     my $suffix=&Apache::lonmsg::foldersuffix($folder);
                   2860:     my $sendstatus='';
1.71      raeburn  2861:     my %msg_status;
                   2862:     my $numsent = 0;
                   2863:     my $nosentstore = 1;
1.86      raeburn  2864:     my $attachmenturl;
                   2865:     my $now = time;
1.38      raeburn  2866:     my ($cdom,$cnum,$group);
                   2867:     if (exists($env{'form.group'})) {
                   2868:         $group = $env{'form.group'};
                   2869:     }
                   2870:     if (exists($env{'request.course.id'})) {
                   2871:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2872:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2873:     }
1.1       albertel 2874:     if ($env{'form.send'}) {
1.53      raeburn  2875:         if (!$env{'form.multiforward'}) { 
                   2876:             if ($group eq '') {
                   2877: 	        &printheader($r,'','Messages being sent.');
                   2878:             } else {
                   2879:                 $r->print(&groupmail_header('sending',$group));
                   2880:             }
1.38      raeburn  2881:         }
1.1       albertel 2882: 	$r->rflush();
                   2883: 	my %content=();
                   2884: 	undef %content;
                   2885: 	if ($env{'form.forwid'}) {
                   2886: 	    my $msgid=$env{'form.forwid'};
                   2887: 	    my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
1.86      raeburn  2888: 	    %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1,1);
1.1       albertel 2889: 	    &statuschange($msgid,'forwarded',$folder);
1.86      raeburn  2890:             if ($content{'attachmenturl'} ne '') {
                   2891:                 $attachmenturl = $content{'attachmenturl'};
                   2892:             }
                   2893: 	    $env{'form.message'} .= "\n\n-- Forwarded message --\n\n".
                   2894: 		                    $content{'message'};
1.1       albertel 2895: 	}
                   2896: 	if ($env{'form.replyid'}) {
                   2897: 	    my $msgid=$env{'form.replyid'};
                   2898: 	    my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
                   2899: 	    %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1);
                   2900: 	    &statuschange($msgid,'replied',$folder);
                   2901: 	}
1.13      albertel 2902: 
1.25      foxr     2903: 	my $mode = $env{'form.sendmode'};
1.95      raeburn  2904: 	my (%toaddr,$tos,$cc,$bcc,$broadcast);
1.25      foxr     2905: 
1.95      raeburn  2906: 	if ($mode eq 'group') {
                   2907:             if (defined($env{'form.courserecips'})) {
                   2908:                 my $courseusers = $env{'form.courserecips'};
                   2909:                 $courseusers =~ s/^_\&\&\&_//;
                   2910:                 my @to = split('_&&&_',$courseusers);
                   2911:                 foreach my $dest (@to) {
                   2912:                     my ($user,$domain) = split(/:/, $dest);
                   2913:                     if (($user ne '') && ($domain ne '')) {
                   2914:                         my $rec = $user.":".$domain;
                   2915:                         $toaddr{$rec} = '';
                   2916:                         $broadcast->{$rec} = '';
                   2917:                     }
                   2918:                 }
                   2919:             }
                   2920: 	} elsif ($mode eq 'upload') {
1.71      raeburn  2921:             $nosentstore = 0;
1.13      albertel 2922: 	    foreach my $line (split(/[\n\r\f]+/,$env{'form.upfile'})) {
1.43      raeburn  2923:                 my ($rec,$txt) = ($line =~ /^([^:]+:[^:]+):(.*)$/);
1.1       albertel 2924: 		if ($txt) {
1.43      raeburn  2925:                     $rec =~ s/^\s+//;
1.44      raeburn  2926:                     $rec =~ s/\s+$//;
1.1       albertel 2927: 		    $toaddr{$rec}.=$txt."\n";
1.95      raeburn  2928:                     $broadcast->{$rec} = '';
1.1       albertel 2929: 		}
                   2930: 	    }
                   2931: 	} else {
1.25      foxr     2932: 	    if (($env{'form.recuname'} ne '') && ($env{'form.recdomain'} ne '')) {
                   2933: 		$toaddr{$env{'form.recuname'}.':'.$env{'form.recdomain'}}='';
1.95      raeburn  2934:                 $tos->{$env{'form.recuname'}.':'.$env{'form.recdomain'}}='';
1.25      foxr     2935: 	    }
1.1       albertel 2936: 	}
1.95      raeburn  2937:         if ($env{'form.additionalrec_to'}) {
                   2938:             foreach my $rec (split(/\s*,\s*/,$env{'form.additionalrec_to'})) {
                   2939:                 my ($auname,$audom)=split(/:/,$rec);
                   2940:                 if (($auname ne "") && ($audom ne "")) {
                   2941:                     $toaddr{$auname.':'.$audom}='';
                   2942:                     $tos->{$auname.':'.$audom}='';
                   2943:                 }
                   2944:             }
                   2945:         }
                   2946:         if ($env{'form.replying_to'}) {
                   2947:             my @toreplies =
                   2948:                 &Apache::loncommon::get_env_multiple('form.replying_to');
                   2949:             foreach my $rec (@toreplies) {
                   2950:                 my ($auname,$audom)=split(/:/,$rec);
                   2951:                 if (($auname ne "") && ($audom ne "")) {
                   2952:                     $toaddr{$auname.':'.$audom}='';
                   2953:                     $tos->{$auname.':'.$audom}='';
                   2954:                 }
                   2955:             }
                   2956:         }
1.73      raeburn  2957: 	if ($env{'form.additionalrec_cc'}) {
                   2958: 	    foreach my $rec (split(/\s*,\s*/,$env{'form.additionalrec_cc'})) {
1.43      raeburn  2959: 		my ($auname,$audom)=split(/:/,$rec);
1.25      foxr     2960: 		if (($auname ne "") && ($audom ne "")) {
1.73      raeburn  2961:                     $toaddr{$auname.':'.$audom}='';
1.95      raeburn  2962:                     if (!defined($tos->{$auname.':'.$audom})) {
                   2963: 		        $cc->{$auname.':'.$audom}='';
                   2964:                     }
1.25      foxr     2965: 		}
1.1       albertel 2966: 	    }
                   2967: 	}
1.95      raeburn  2968:         if ($env{'form.replying_cc'}) {
                   2969:             my @ccreplies =
                   2970:                 &Apache::loncommon::get_env_multiple('form.replying_cc');
                   2971:             foreach my $rec (@ccreplies) {
                   2972:                 my ($auname,$audom)=split(/:/,$rec);
                   2973:                 if (($auname ne "") && ($audom ne "")) {
                   2974:                     $toaddr{$auname.':'.$audom}='';
                   2975:                     if (!defined($tos->{$auname.':'.$audom})) {
                   2976:                         $cc->{$auname.':'.$audom}='';
                   2977:                     }
                   2978:                 }
                   2979:             }
                   2980:         }
                   2981:         if ($env{'form.replying_groupcc'}) {
                   2982:             my @groupreplies =
                   2983:                 &Apache::loncommon::get_env_multiple('form.replying_groupcc');
                   2984:             foreach my $rec (@groupreplies) {
1.73      raeburn  2985:                 my ($auname,$audom)=split(/:/,$rec);
                   2986:                 if (($auname ne "") && ($audom ne "")) {
                   2987:                     $toaddr{$auname.':'.$audom}='';
1.95      raeburn  2988:                     if (!defined($tos->{$auname.':'.$audom})) {
                   2989:                         $broadcast->{$auname.':'.$audom}='';
                   2990:                     }
1.73      raeburn  2991:                 }
                   2992:             }
                   2993:         }
1.95      raeburn  2994:         if ($env{'form.additionalrec_bcc'}) {
                   2995:             foreach my $rec (split(/\s*,\s*/,$env{'form.additionalrec_bcc'})) {
1.73      raeburn  2996:                 my ($auname,$audom)=split(/:/,$rec);
                   2997:                 if (($auname ne "") && ($audom ne "")) {
                   2998:                     $toaddr{$auname.':'.$audom}='';
1.95      raeburn  2999:                     if ((!defined($tos->{$auname.':'.$audom})) && 
                   3000:                         (!defined($cc->{$auname.':'.$audom}))) {
                   3001:                         $bcc->{$auname.':'.$audom}='';
                   3002:                     }
1.73      raeburn  3003:                 }
                   3004:             }
                   3005:         }
1.1       albertel 3006:         my $savemsg;
                   3007:         my $msgtype;
                   3008:         my %sentmessage;
1.7       albertel 3009:         my $msgsubj=&Apache::lonfeedback::clear_out_html($env{'form.subject'},
                   3010: 							 undef,1);
1.1       albertel 3011:         if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
                   3012:             (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
                   3013: 	     || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
                   3014: 					 '/'.$env{'request.course.sec'})
                   3015: 	     )) {
                   3016:             $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'},1);
                   3017:             $msgtype = 'critical';
                   3018:         } else {
                   3019:             $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'});
                   3020:         }
1.73      raeburn  3021:         my %reciphash = (
1.95      raeburn  3022:                            to => $tos,
1.73      raeburn  3023:                            cc => $cc,
                   3024:                            bcc => $bcc,
1.95      raeburn  3025:                         );
                   3026:         if ($mode eq 'group') {
                   3027:             if ($group eq '') {
                   3028:                 $reciphash{'course_broadcast'} = $broadcast;
                   3029:             } else {
                   3030:                 if ($env{'form.groupmail'} eq 'cc') {
                   3031:                     $reciphash{'group_cc_broadcast'} = $broadcast;
                   3032:                 } else {
                   3033:                     $reciphash{'group_bcc_broadcast'} = $broadcast;
                   3034:                 }
                   3035:             }
                   3036:         }
1.73      raeburn  3037:         my ($recipid,$recipstatus) = 
                   3038:             &Apache::lonmsg::store_recipients($msgsubj,$env{'user.name'},
                   3039:                                        $env{'user.domain'},\%reciphash);
                   3040:         if ($recipstatus ne 'ok') {
1.95      raeburn  3041:             &Apache::lonnet::logthis('Failed to store To, Bcc and Cc recipients for '.$env{'user.name'}.':'.$env{'user.domain'});
1.86      raeburn  3042:         }
                   3043:         if ($env{'form.attachment'}) {
                   3044:             if (length($env{'form.attachment'})<131072) {
                   3045:                 $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback/'.$now);
                   3046:             } else {
                   3047:                 $r->print('<p><span class="LC_warning">'.&mt('Attachment not included - exceeded permitted length').'</span><br /></p>');
                   3048:             }
                   3049:         } elsif ($env{'form.multiforward'}) {
                   3050:             if ($env{'form.attachmenturl'} ne '') {
                   3051:                 $attachmenturl = $env{'form.attachmenturl'};
                   3052:             }
                   3053:         }
1.71      raeburn  3054:         my @recusers;
                   3055:         my @recudoms;
1.13      albertel 3056: 	foreach my $address (sort(keys(%toaddr))) {
                   3057: 	    my ($recuname,$recdomain)=split(/\:/,$address);
1.1       albertel 3058:             my $msgtxt = $savemsg;
1.73      raeburn  3059:             if ($toaddr{$address}) {
                   3060: 	        $msgtxt.='<hr />'.$toaddr{$address};
                   3061:             }
1.12      albertel 3062: 	    my @thismsg;
1.60      raeburn  3063: 	    if ($msgtype eq 'critical') {
                   3064: 		$r->print(&mt('Sending critical message').' '.
                   3065:                               $recuname.':'.$recdomain.': ');
1.13      albertel 3066: 		@thismsg=
                   3067: 		    &Apache::lonmsg::user_crit_msg($recuname,$recdomain,
                   3068: 						   $msgsubj,$msgtxt,
                   3069: 						   $env{'form.sendbck'},
                   3070: 						   $env{'form.permanent'},
1.71      raeburn  3071: 						   \$sentmessage{$address},
1.73      raeburn  3072:                                                    $nosentstore,$recipid);
1.1       albertel 3073: 	    } else {
1.14      albertel 3074: 		$r->print(&mt('Sending').' '.$recuname.':'.$recdomain.': ');
1.13      albertel 3075: 		@thismsg=
                   3076: 		    &Apache::lonmsg::user_normal_msg($recuname,$recdomain,
                   3077: 						     $msgsubj,$msgtxt,
                   3078: 						     $content{'citation'},
1.86      raeburn  3079: 						     undef,$attachmenturl,
1.13      albertel 3080: 						     $env{'form.permanent'},
1.71      raeburn  3081: 						     \$sentmessage{$address},
                   3082:                                                      undef,undef,undef,
1.73      raeburn  3083:                                                      $nosentstore,$recipid);
1.71      raeburn  3084:             }
                   3085: 	    $msg_status{$recuname.':'.$recdomain}=join(' ',@thismsg);
                   3086: 	    if ($msg_status{$recuname.':'.$recdomain} =~ /(ok|con_delayed)/) {  
                   3087: 	        $numsent++;
                   3088:                 push(@recusers,$recuname);
                   3089:                 push(@recudoms,$recdomain);
1.1       albertel 3090: 	    }
1.12      albertel 3091: 	    $sendstatus.=' '.join(' ',@thismsg);
1.1       albertel 3092: 	}
1.71      raeburn  3093:         my $subj_prefix;
                   3094:         if ($numsent > 0) {
                   3095:             if (($env{'request.course.id'}) && 
1.95      raeburn  3096:                 (($mode eq 'group') ||
1.71      raeburn  3097:                  ($env{'form.courserecord'}) ||
1.95      raeburn  3098:                  ($msgtype eq 'critical')) ||
                   3099:                 ($env{'form.replyid'} && 
                   3100:                  (($content{'courseid'} ne '') && 
                   3101:                   ($mode eq 'group')))) {
1.71      raeburn  3102:                 if ($msgtype eq 'critical') {
                   3103:                     $subj_prefix = 'Critical.';
1.95      raeburn  3104:                 } elsif ($mode eq 'group') {
1.71      raeburn  3105:                     $subj_prefix = 'Broadcast.';
                   3106:                 } else {
                   3107:                     $subj_prefix = 'Archive';
                   3108:                 }
                   3109:                 my ($specialmsgid,$specialresult);
1.95      raeburn  3110:                 my $course_str;
                   3111:                 if ($env{'form.replyid'}) {
                   3112:                     if ($content{'courseid'} ne '') {
                   3113:                         my %crsdesc = 
                   3114:                             &Apache::lonnet::coursedescription($content{'courseid'},
                   3115:                                                                {'one_time' => 1});
                   3116:                         $course_str = &escape('['.$crsdesc{'num'}.':'.$crsdesc{'domain'}.']');
                   3117:                     }
                   3118:                 } elsif ($env{'request.course.id'}) {
                   3119:                     $course_str = &escape('['.$cnum.':'.$cdom.']');
                   3120:                 }
1.71      raeburn  3121:                 $specialresult = 
                   3122:                     &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,
                   3123:                         $subj_prefix.' '.$course_str,$savemsg,undef,undef,
1.86      raeburn  3124:                         $attachmenturl,undef,undef,\$specialmsgid,undef,undef,undef,
1.71      raeburn  3125:                         undef,undef,1);
1.29      www      3126:                 $specialmsgid = &unescape($specialmsgid);
1.71      raeburn  3127:                 if ($specialresult eq 'ok') {
                   3128:                     my ($stamp,$crssubj,$msgname,$msgdom,$msgcount,$context,$pid) =
                   3129: 		        split(/\:/,&unescape($specialmsgid));
                   3130: 
                   3131:                     foreach my $recipient (sort(keys(%toaddr))) {
                   3132:                         if ($msg_status{$recipient} =~ /\s*(ok|con_delayed)\s*/) {
                   3133:                             my $usersubj = $subj_prefix.'['.$recipient.']';
                   3134:                             my $usermsgid = 
                   3135: 			        &Apache::lonmsg::buildmsgid($stamp,$usersubj,
                   3136: 							    $msgname,$msgdom,
                   3137: 							    $msgcount,$context,
                   3138: 							    $pid);
                   3139:                             &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,
                   3140:                                 $subj_prefix.' ['.$recipient.']',$msgsubj,
1.86      raeburn  3141:                                 undef,undef,$attachmenturl,undef,$usermsgid,undef,
1.71      raeburn  3142:                                 undef,$specialmsgid,undef,undef,undef,1);
                   3143:                         }
                   3144:                     }
1.95      raeburn  3145:                     if (($mode ne 'upload') && (@recusers > 0)) {
1.71      raeburn  3146:                         &Apache::lonmsg::process_sent_mail($msgsubj,
                   3147:                            $subj_prefix,$numsent,$stamp,$msgname,$msgdom,
                   3148:                            $msgcount,$context,$pid,$savemsg,\@recusers,
1.95      raeburn  3149:                            \@recudoms,undef,$attachmenturl,'','','','',$recipid);
1.1       albertel 3150:                     }
1.71      raeburn  3151:                 } else {
1.78      raeburn  3152:                     &Apache::lonnet::logthis('Failed to create record of critical, broadcast or archived message in '.$env{'course.'.$env{'request.course.id'}.'.num'}.' '&mt('at').' '.$env{'course.'.$env{'request.course.id'}.'.domain'}.' - no msgid generated');
1.1       albertel 3153:                 }
                   3154:             } else {
1.71      raeburn  3155:                 my $stamp = time;
                   3156:                 my $msgcount = &Apache::lonmsg::get_uniq();
                   3157:                 my $context = &Apache::lonmsg::get_course_context();
                   3158:                 &Apache::lonmsg::process_sent_mail($msgsubj,$subj_prefix,
                   3159:                        $numsent,$stamp,$env{'user.name'},
                   3160:                        $env{'user.domain'},$msgcount,$context,
1.95      raeburn  3161:                        $$,$savemsg,\@recusers,\@recudoms,undef,$attachmenturl,
                   3162:                        '','','','',$recipid);
1.1       albertel 3163:             }
                   3164:         }
1.71      raeburn  3165:         if (!$env{'form.multiforward'}) { 
                   3166:             if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) {
                   3167: 	        $r->print('<br /><span class="LC_success">'.&mt('Completed.').
                   3168:                           '</span>');
                   3169: 	        if ($env{'form.displayedcrit'}) {
                   3170: 	            &discrit($r);
                   3171:                 }
                   3172:                 if ($group ne '') {
                   3173:                     $r->print(&groupmail_sent($group,$cdom,$cnum)); 
                   3174: 	        } else {
                   3175: 	            &Apache::loncommunicate::menu($r);
                   3176: 	        }
                   3177:             } else {
                   3178: 	        $r->print('<p><span class="LC_error">'.&mt('Could not deliver message').'</span> '.
1.85      bisitz   3179: 		          &mt('Please use the browser "Back" button and correct the recipient addresses ([_1]).',$sendstatus).'</p>');
1.53      raeburn  3180:             }
1.38      raeburn  3181:         }
1.1       albertel 3182:     }
1.53      raeburn  3183:     return $sendstatus;
1.1       albertel 3184: }
                   3185: 
                   3186: # ===================================================================== Handler
                   3187: 
                   3188: sub handler {
                   3189:     my $r=shift;
                   3190: 
                   3191: # ----------------------------------------------------------- Set document type
                   3192:     
                   3193:     &Apache::loncommon::content_type($r,'text/html');
                   3194:     $r->send_http_header;
                   3195:     
                   3196:     return OK if $r->header_only;
                   3197:     
                   3198: # --------------------------- Get query string for limited number of parameters
                   3199:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   3200:         ['display','replyto','forward','markread','markdel','markunread',
                   3201:          'sendreply','compose','sendmail','critical','recname','recdom',
                   3202:          'recordftf','sortedby','block','folder','startdis','interdis',
1.53      raeburn  3203: 	 'showcommentbaseurl','dismode','group','subject','text','ref',
                   3204:          'msgstatus']);
1.1       albertel 3205:     $sqs='&sortedby='.$env{'form.sortedby'};
                   3206: 
                   3207: # ------------------------------------------------------ They checked for email
                   3208:     unless ($env{'form.block'}) {
                   3209:         &Apache::lonnet::put('email_status',{'recnewemail'=>0});
                   3210:     }
                   3211: 
                   3212: # ----------------------------------------------------------------- Breadcrumbs
                   3213: 
                   3214:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   3215:     &Apache::lonhtmlcommon::add_breadcrumb
                   3216:         ({href=>"/adm/communicate",
                   3217:           text=>"Communication/Messages",
                   3218:           faq=>12,bug=>'Communication Tools',});
                   3219: 
                   3220: # ------------------------------------------------------------------ Get Folder
                   3221: 
                   3222:     my $folder=$env{'form.folder'};
                   3223:     unless ($folder) { 
                   3224: 	$folder=''; 
                   3225:     } else {
1.29      www      3226: 	$sqs.='&folder='.&escape($folder);
1.1       albertel 3227:     }
                   3228: # ------------------------------------------------------------ Get Display Mode
                   3229: 
                   3230:     my $dismode=$env{'form.dismode'};
                   3231:     unless ($dismode) { 
                   3232: 	$dismode=''; 
                   3233:     } else {
1.48      albertel 3234: 	$sqs.='&amp;dismode='.&escape($dismode);
1.1       albertel 3235:     }
                   3236: 
                   3237: # --------------------------------------------------------------------- Display
1.53      raeburn  3238:     my $msgstatus = $env{'form.msgstatus'};
1.1       albertel 3239:     $startdis=$env{'form.startdis'};
1.53      raeburn  3240:     if ($startdis ne '') {
                   3241:         $startdis--;
                   3242:     }
1.1       albertel 3243:     unless ($startdis) { $startdis=0; }
                   3244: 
                   3245:     if ($env{'form.firstview'}) {
                   3246: 	$startdis=0;
                   3247:     }
                   3248:     if ($env{'form.lastview'}) {
                   3249: 	$startdis=-1;
                   3250:     }
                   3251:     if ($env{'form.prevview'}) {
                   3252: 	$startdis--;
                   3253:     }
                   3254:     if ($env{'form.nextview'}) {
                   3255: 	$startdis++;
                   3256:     }
                   3257:     my $postedstartdis=$startdis+1;
                   3258:     $sqs.='&startdis='.$postedstartdis;
                   3259: 
                   3260: # --------------------------------------------------------------- Render Output
                   3261: 
                   3262:     if ($env{'form.display'}) {
1.53      raeburn  3263: 	&displaymessage($r,$env{'form.display'},$folder,$msgstatus);
1.1       albertel 3264:     } elsif ($env{'form.replyto'}) {
                   3265: 	&compout($r,'',$env{'form.replyto'},undef,undef,$folder,$dismode);
                   3266:     } elsif ($env{'form.confirm'}) {
                   3267: 	&printheader($r,'','Confirmed Receipt');
1.36      albertel 3268: 	my $replying = 0;
1.42      raeburn  3269: 	foreach my $envkey (keys(%env)) {
1.75      raeburn  3270: 	    if ($envkey=~/^form\.(rep)?rec\_(.*)$/) {
1.77      raeburn  3271:                 my $repchk = $1;
1.75      raeburn  3272:        		my $msgid = $2;
                   3273: 		$r->print('<b>'.&mt('Confirming Receipt').':</b> ');
                   3274: 		my $result = &Apache::lonmsg::user_crit_received($msgid);
                   3275:                 if ($result =~ /trans:\s+ok/) {
                   3276:                     &statuschange($msgid,'read');
                   3277:                 }
1.76      albertel 3278:                 $r->print($result.'<br />');
1.77      raeburn  3279:                 if ($repchk eq 'rep') {
1.75      raeburn  3280: 		    &compout($r,'','','',$msgid);
                   3281: 		    $replying = 1;
                   3282:                 }
1.1       albertel 3283: 	    }
                   3284: 	}
1.36      albertel 3285: 	if (!$replying) {
                   3286: 	    &discrit($r);
                   3287: 	}
1.1       albertel 3288:     } elsif ($env{'form.critical'}) {
                   3289: 	&printheader($r,'','Displaying Critical Messages');
                   3290: 	&discrit($r);
                   3291:     } elsif ($env{'form.forward'}) {
                   3292: 	&compout($r,$env{'form.forward'},undef,undef,undef,$folder);
                   3293:     } elsif ($env{'form.markdel'}) {
                   3294: 	&printheader($r,'','Deleted Message');
1.9       albertel 3295: 	my ($result,$msg) = 
                   3296: 	    &statuschange($env{'form.markdel'},'deleted',$folder);
                   3297: 	if (!$result) {
1.10      albertel 3298: 	    $r->print('<p class="LC_error">'.
                   3299: 		      &mt('Failed to delete the message.').'</p>'.
1.9       albertel 3300: 		      '<p class="LC_error">'.$msg."</p>\n");
                   3301: 	}
1.1       albertel 3302: 	&Apache::loncommunicate::menu($r);
1.53      raeburn  3303: 	&disall($r,($folder?$folder:$dismode),$msgstatus);
                   3304:     } elsif ($env{'form.markedaction'} eq 'markedforward') {
                   3305:         my $total = 0;
                   3306:         my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark');
                   3307:         foreach my $msgid (@to_forward) {
                   3308:             &statuschange(&unescape($msgid),'forwarded',$folder);
                   3309:             $total ++;
                   3310:         }
                   3311:         if ($total > 0) {
                   3312:             &compout($r,undef,undef,undef,undef,$folder,$dismode,$total);
                   3313:         }
                   3314:     } elsif ($env{'form.markedaction'} eq 'markedread') {
                   3315:         my $total = 0;
                   3316:         my @to_markread = &Apache::loncommon::get_env_multiple('form.delmark');
                   3317:         foreach my $msgid (@to_markread) {
                   3318:             &statuschange(&unescape($msgid),'read',$folder);
                   3319:             $total ++;
                   3320:         }
                   3321:         &printheader($r,'','Marked Messages Read');
                   3322:         $r->print(&mt('Marked [_1] message(s) read',$total).'<p>');
                   3323:         &Apache::loncommunicate::menu($r);
                   3324:         &disall($r,($folder?$folder:$dismode),$msgstatus);
                   3325:     } elsif ($env{'form.markedaction'} eq 'markedunread') {
                   3326:         my $total = 0;
                   3327:         my @to_markunread = &Apache::loncommon::get_env_multiple('form.delmark');
                   3328:         foreach my $msgid (@to_markunread) {
                   3329:             &statuschange(&unescape($msgid),'new',$folder);
                   3330:             $total ++;
                   3331:         }
                   3332:         &printheader($r,'','Marked Messages Unread');
                   3333:         $r->print(&mt('Marked [_1] message(s) unread',$total).'<p>');
                   3334:         &Apache::loncommunicate::menu($r);
                   3335:         &disall($r,($folder?$folder:$dismode),$msgstatus);
                   3336:     } elsif ($env{'form.markedaction'} eq 'markedmove') {
                   3337:         my $destfolder = $env{'form.movetofolder'};
                   3338:         my %gotfolders = &Apache::lonmsg::get_user_folders();
                   3339:         &printheader($r,'','Moved Messages');
                   3340:         if (!defined($gotfolders{$destfolder})) {
                   3341:             $r->print(&mt('Destination folder [_1] is not a valid folder',
                   3342:                       $destfolder));
                   3343:         } else {
                   3344: 	    my ($total,$failed,@failed_msg)=(0,0);
                   3345:             my @to_move = &Apache::loncommon::get_env_multiple('form.delmark');
                   3346:             foreach my $msgid (@to_move) {
                   3347: 	        my ($result,$msg) = &movemsg(&unescape($msgid),$folder,
                   3348: 			                     $env{'form.movetofolder'});
                   3349: 	        if ($result) {
1.9       albertel 3350: 		    $total++;
1.53      raeburn  3351: 	        } else {
1.9       albertel 3352: 		    $failed++;
                   3353: 		    push(@failed_msg,$msg);
1.53      raeburn  3354: 	        }
1.1       albertel 3355: 	    }
1.53      raeburn  3356: 	    if ($failed) {
                   3357: 	        $r->print('<p class="LC_error">
1.10      albertel 3358:                           '.&mt('Failed to move [_1] message(s)',$failed).
                   3359: 		      '</p>');
1.53      raeburn  3360: 	        $r->print('<p class="LC_error">'.
                   3361: 	   	          join("</p>\n<p class=\"LC_error\">",@failed_msg).
                   3362: 		          "</p>\n");
                   3363: 	    }
                   3364: 	    $r->print(&mt('Moved [_1] message(s)',$total).'<p>');
                   3365:         }
1.1       albertel 3366: 	&Apache::loncommunicate::menu($r);
1.53      raeburn  3367: 	&disall($r,($folder?$folder:$dismode),$msgstatus);
                   3368:     } elsif ($env{'form.markedaction'} eq 'markeddel') {
1.9       albertel 3369: 	my ($total,$failed,@failed_msg)=(0,0);
1.53      raeburn  3370:         my @to_delete = &Apache::loncommon::get_env_multiple('form.delmark');
                   3371:         foreach my $msgid (@to_delete) {
                   3372: 	    my ($result,$msg) = &statuschange(&unescape($msgid),'deleted', 
                   3373: 				              $folder);
                   3374: 	    if ($result) {
                   3375: 	        $total++;
                   3376: 	    } else {
                   3377: 	        $failed++;
                   3378: 		push(@failed_msg,$msg);
1.1       albertel 3379: 	    }
                   3380: 	}
                   3381: 	&printheader($r,'','Deleted Messages');
1.9       albertel 3382: 	if ($failed) {
                   3383: 	    $r->print('<p class="LC_error">
1.10      albertel 3384:                           '.&mt('Failed to delete [_1] message(s)',$failed).
                   3385: 		      '</p>');
1.9       albertel 3386: 	    $r->print('<p class="LC_error">'.
                   3387: 		      join("</p>\n<p class=\"LC_error\">",@failed_msg).
                   3388: 		      "</p>\n");
                   3389: 	}
1.10      albertel 3390: 	$r->print(&mt('Deleted [_1] message(s)',$total).'<p>');
1.1       albertel 3391: 	&Apache::loncommunicate::menu($r);
1.53      raeburn  3392: 	&disall($r,($folder?$folder:$dismode),$msgstatus);
1.1       albertel 3393:     } elsif ($env{'form.markunread'}) {
                   3394: 	&printheader($r,'','Marked Message as Unread');
                   3395: 	&statuschange($env{'form.markunread'},'new');
                   3396: 	&Apache::loncommunicate::menu($r);
1.53      raeburn  3397: 	&disall($r,($folder?$folder:$dismode),$msgstatus);
1.1       albertel 3398:     } elsif ($env{'form.compose'}) {
                   3399: 	&compout($r,'','',$env{'form.compose'});
                   3400:     } elsif ($env{'form.recordftf'}) {
                   3401: 	&facetoface($r,$env{'form.recordftf'});
                   3402:     } elsif ($env{'form.block'}) {
                   3403:         &examblock($r,$env{'form.block'});
                   3404:     } elsif ($env{'form.sendmail'}) {
1.53      raeburn  3405:         if ($env{'form.multiforward'}) {
                   3406:             &printheader($r,'','Messages being sent.');
                   3407:             my $fixed_subj = $env{'form.subject'};
                   3408:             my $suffix=&Apache::lonmsg::foldersuffix($folder);
                   3409:             my (%sendresult,%forwardok,%forwardfail,$fwdcount);
                   3410:             my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark');
                   3411:             foreach my $item (@to_forward) {
                   3412:                 my $msgid=&unescape($item);
                   3413:                 my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
1.86      raeburn  3414:                 my %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1,1);
1.53      raeburn  3415:                 if ($env{'form.showorigsubj'}) {
                   3416:                     $env{'form.subject'} = $fixed_subj.$content{'subject'};
                   3417:                 } else {
                   3418:                     $env{'form.subject'} = '';
                   3419:                 }
                   3420:                 my $uname = $content{'sendername'};
                   3421:                 my $udom = $content{'senderdomain'};
                   3422:                 &statuschange($msgid,'forwarded',$folder);
                   3423:                 if ($env{'form.showorigsender'}) {
                   3424:                     $env{'form.message'} = $env{'form.msgheader'}.' '.
                   3425:                         &Apache::loncommon::plainname($uname,$udom).' ('.
                   3426:                                            $uname.':'.$udom.')';
                   3427:                 }
1.86      raeburn  3428:                 $env{'form.message'}.="\n\n-- Forwarded message --\n\n".
                   3429:                                       $content{'message'};
                   3430:                 $env{'form.attachmenturl'} = $content{'attachmenturl'};
                   3431:                 $env{'form.multiforwid'} = $item;
1.53      raeburn  3432:                 $fwdcount ++;
                   3433:                 $r->print($fwdcount.': '); 
                   3434:                 $sendresult{$msgid} = &sendoffmail($r,$folder);
                   3435:                 $r->print('<br />');
                   3436:             }
                   3437:             foreach my $key (keys(%sendresult)) {
                   3438:                 if ($sendresult{$key} =~/^(\s*(?:ok|con_delayed)\s*)*$/) {
                   3439:                     $forwardok{$key} = $sendresult{$key};
                   3440:                 } else {
                   3441:                     $forwardfail{$key} = $sendresult{$key}; 
                   3442:                 }
                   3443:             }
                   3444:             if (keys(%forwardok) > 0) {
                   3445:                 my $count = keys(%forwardok);
                   3446:                 $r->print('<br /><span class="LC_success">'.
                   3447:                           &mt('[quant,_1,message] forwarded.',$count).
                   3448:                           '</span>');
                   3449:             }
                   3450:             if (keys(%forwardfail) > 0) {
                   3451:                 my $count = keys(%forwardfail);
                   3452:                 $r->print('<p><span class="LC_error">'.
                   3453:                           &mt('Could not forward [quant,_1,message].',$count).
                   3454:                           '</span> ');
                   3455:                 foreach my $key (keys(%forwardfail)) {
                   3456:                     $r->print(&mt('Could not deliver forwarded message.').'</span> '.
                   3457:                               &mt('The recipient addresses may need to be corrected').' ('.$forwardfail{$key}.').<br /><br />');
                   3458:                 }
                   3459:             }
                   3460:             &Apache::loncommunicate::menu($r);
                   3461:         } else {
                   3462: 	    &sendoffmail($r,$folder);
                   3463:         }
1.1       albertel 3464: 	if ($env{'form.storebasecomment'}) {
                   3465: 	    &storecomment($r);
1.38      raeburn  3466:         }
1.1       albertel 3467: 	if (($env{'form.rsspost'}) && ($env{'request.course.id'})) {
1.38      raeburn  3468: 	        &Apache::lonrss::addentry($env{'course.'.$env{'request.course.id'}.'.num'},
1.1       albertel 3469: 				      $env{'course.'.$env{'request.course.id'}.'.domain'},
                   3470: 				      'Course_Announcements',
                   3471: 				      $env{'form.subject'},
                   3472: 				      $env{'form.message'},'/adm/communicate','public');
                   3473: 	}
1.38      raeburn  3474: 	if ((!exists($env{'form.group'})) && (!$env{'form.displayedcrit'})) {
1.53      raeburn  3475: 	    &disall($r,($folder?$folder:$dismode),$msgstatus);
1.36      albertel 3476: 	}
1.1       albertel 3477:     } elsif ($env{'form.newfolder'}) {
                   3478: 	&printheader($r,'','New Folder');
1.46      raeburn  3479:         my $showfolder = $env{'form.newfolder'};
                   3480: 	my ($makeresult,$warning) = &makefolder($env{'form.newfolder'});
                   3481:         if ($makeresult eq 'ok') {
1.113     schafran 3482:             $r->print(&mt('Folder "[_1]" created.',$showfolder).'<br />');
1.46      raeburn  3483:         } else {
                   3484:             $r->print(&mt('Creation failed.').' '.$makeresult.'<br />'.
                   3485:                       $warning);
                   3486:             $showfolder = $folder;
                   3487:         }
                   3488:         &Apache::loncommunicate::menu($r);
1.53      raeburn  3489: 	&disall($r,$showfolder,$msgstatus);
1.1       albertel 3490:     } elsif ($env{'form.showcommentbaseurl'}) {
                   3491: 	&storedcommentlisting($r);
1.46      raeburn  3492:     } elsif ($env{'form.folderaction'} eq 'delete') {
                   3493:         &printheader($r,'','Deleted Folder');
                   3494:         my $showfolder = '';
                   3495:         my $delresult = &deletefolder($folder);
                   3496:         if ($delresult eq 'ok') {
1.113     schafran 3497:             $r->print(&mt('Folder "[_1]" deleted.',$folder).'<br />');
1.65      raeburn  3498:             $env{'form.folder'} = '';
1.46      raeburn  3499:         } else {
                   3500:             $r->print(&mt('Deletion failed.').' '.$delresult.'<br />');
                   3501:             $showfolder = $folder;
                   3502:         }
                   3503:         &Apache::loncommunicate::menu($r);
1.53      raeburn  3504:         &disall($r,$showfolder,$msgstatus);
1.46      raeburn  3505:     } elsif ($env{'form.folderaction'} eq 'rename') {
                   3506:         &printheader($r,'','Renamed Folder');
                   3507:         my $showfolder = $env{'form.renamed'};
                   3508:         my $renresult = &renamefolder($folder);
                   3509:         if ($renresult eq 'ok') {
1.113     schafran 3510:             $r->print(&mt('Folder "[_1]" renamed to "[_2]".',$folder,$showfolder).'<br />');
1.46      raeburn  3511:         } else {
                   3512:             $r->print(&mt('Renaming failed.').' '.$renresult.'<br />');
                   3513:             $showfolder = $folder;
                   3514:         }
                   3515:         &Apache::loncommunicate::menu($r);
1.53      raeburn  3516:         &disall($r,$showfolder,$msgstatus);
1.1       albertel 3517:     } else {
1.112     weissno  3518: 	&printheader($r,'','Display All Messages');
1.44      raeburn  3519: 	&Apache::loncommunicate::menu($r);
1.53      raeburn  3520: 	&disall($r,($folder?$folder:$dismode),$msgstatus);
1.1       albertel 3521:     }
                   3522:     $r->print(&Apache::loncommon::end_page());
                   3523:     return OK;
                   3524: }
                   3525: # ================================================= Main program, reset counter
                   3526: 
                   3527: =pod
                   3528: 
                   3529: =cut
                   3530: 
                   3531: 1; 
                   3532: 
                   3533: __END__
                   3534: 

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

Internal Server Error

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

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

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