--- loncom/interface/lonmsgdisplay.pm 2006/06/30 02:06:15 1.35.2.2
+++ loncom/interface/lonmsgdisplay.pm 2014/01/16 16:34:01 1.172
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines for messaging display
#
-# $Id: lonmsgdisplay.pm,v 1.35.2.2 2006/06/30 02:06:15 albertel Exp $
+# $Id: lonmsgdisplay.pm,v 1.172 2014/01/16 16:34:01 bisitz Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -33,12 +33,13 @@ package Apache::lonmsgdisplay;
=head1 NAME
-Apache::lonmsg: supports internal messaging
+Apache::lonmsgdisplay: supports internal messaging
=head1 SYNOPSIS
-lonmsg provides routines for sending messages, receiving messages, and
-a handler to allow users to read, send, and delete messages.
+lonmsgdisplay provides a handler to allow users to read, send,
+and delete messages, and to create and delete message folders,
+and to move messages between folders.
=head1 OVERVIEW
@@ -74,8 +75,8 @@ email program, so they have full access
interface, or other features they may wish to use in response to the
student's query.
-=item * B: LON-CAPA can block display of e-mails that are
-sent to a student during an online exam. A course coordinator or
+=item * B: LON-CAPA can block selected communication
+features for students during an online exam. A course coordinator or
instructor can set an open and close date/time for scheduled online
exams in a course. If a user uses the LON-CAPA internal messaging
system to display e-mails during the scheduled blocking event,
@@ -93,25 +94,6 @@ addresses on their B screen, but g
are much more useful than traditional email can be made to be, even
with HTML support.
-Right now, this document will cover just how to send a message, since
-it is likely you will not need to programmatically read messages,
-since lonmsg already implements that functionality.
-
-The routines used to package messages and unpackage messages are not
-only used by lonmsg when creating/extracting messages for LON-CAPA's
-internal messaging system, but also by lonnotify.pm which is available
-for use by Domain Coordinators to broadcast standard e-mail to specified
-users in their domain. The XML packaging used in the two cases is very
-similar. The differences are the use of $uname and
-$udom in stored internal messages, compared
-with $email in stored
-Domain Coordinator e-mail for the storage of information about
-recipients of the message/e-mail.
-
-=head1 FUNCTIONS
-
-=over 4
-
=cut
use strict;
@@ -119,6 +101,7 @@ use Apache::lonnet;
use HTML::TokeParser();
use Apache::Constants qw(:common);
use Apache::loncommon();
+use Apache::lonhtmlcommon();
use Apache::lontexconvert();
use HTML::Entities();
use Apache::lonlocal;
@@ -127,49 +110,210 @@ use Apache::lonfeedback;
use Apache::lonrss();
use Apache::lonselstudent();
use lib '/home/httpd/lib/perl/';
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
# Querystring component with sorting type
-my $sqs;
-my $startdis;
-my $interdis;
+my $sqs='';
+my $startdis='';
# ============================================================ List all folders
sub folderlist {
- my $folder=shift;
- my @allfolders=&Apache::lonnet::getkeys('email_folders');
- if ($allfolders[0]=~/^error:/) { @allfolders=(); }
- return '':'');
+ ''.
+ ($folder=~/^critical/?'':'');
+ return $output;
+}
+
+sub get_permanent_folders {
+ my %permfolders =
+ &Apache::lonlocal::texthash('' => 'INBOX',
+ 'trash' => 'TRASH',
+ 'critical' => 'Critical',
+ 'sent' => 'Sent Messages',
+ );
+ return %permfolders;
+}
+
+sub get_msgstatus_types {
+ # Don't translate here!
+ my %statushash = (
+ '' => 'Any',
+ 'new' => 'Unread',
+ 'read' => 'Read',
+ 'replied' => 'Replied to',
+ 'forwarded' => 'Forwarded',
+ );
+ return %statushash;
}
sub scrollbuttons {
- my ($start,$maxdis,$first,$finish,$total)=@_;
+ my ($start,$maxdis,$first,$finish,$total,$msgstatus)=@_;
unless ($total>0) { return ''; }
$start++; $maxdis++;$first++;$finish++;
- return
- &mt('Page').': '.
- ''.
- ''.
- ' of '.$maxdis.
- ''.
- ' '.
- &mt('Showing messages [_1] through [_2] of [_3]',$first,$finish,$total).'';
+
+ my %statushash = &get_msgstatus_types();
+ my $status;
+ if ($msgstatus eq '') {
+ $status = 'All'; # Don't translate here!
+ } else {
+ $status = $statushash{$msgstatus};
+ }
+ my $output = ''.&mt('Page:').' ';
+ if ($maxdis == 1) {
+ # No buttons if only one page is displayed
+ $output .= '1/1';
+ } else {
+ $output .=
+ ''.
+ ''.
+ ' / '.$maxdis.' '.
+ ''.
+ '';
+ }
+ $output .=
+ '
'
+ .''.&mt($status.' messages:').' '
+ .&mt('showing messages [_1] through [_2] of [_3].',
+ $first,$finish,$total)
+ .'
'
+ .'';
+
+ return $output;
}
# =============================================================== Status Change
@@ -195,14 +339,126 @@ sub statuschange {
# ============================================================= Make new folder
sub makefolder {
- my ($newfolder)=@_;
- if (($newfolder eq 'sent')
- || ($newfolder eq 'critical')
- || ($newfolder eq 'trash')
- || ($newfolder eq 'new')) { return; }
- &Apache::lonnet::put('email_folders',{$newfolder => time});
+ my ($newfolder) = @_;
+ my %permfolders = &get_permanent_folders();
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ my ($outcome,$warning);
+ if (defined($userfolders{$newfolder})) {
+ return &mt('The folder name: "[_1]" is already in use for an existing folder.',$newfolder);
+ }
+ foreach my $perm (keys(%permfolders)) {
+ if ($permfolders{$perm} eq $newfolder) {
+ return &mt('The folder name: "[_1]" is already used for one of the folders automatically generated by the system.',$newfolder);
+ }
+ }
+ if (&get_msgfolder_lock() eq 'ok') {
+ my %counter_hash = &Apache::lonnet::get('email_folders',["\0".'idcount']);
+ my $lastcount = $counter_hash{"\0".'idcount'};
+ my $folder_id = $lastcount + 1;
+ while (defined($userfolders{$folder_id})) {
+ $folder_id ++;
+ }
+ my %folderinfo = ( id => $folder_id,
+ created => time, );
+ $outcome =
+ &Apache::lonnet::put('email_folders',{$newfolder => \%folderinfo,
+ "\0".'idcount' => $folder_id});
+ my $releaseresult = &release_msgfolder_lock();
+ if ($releaseresult ne 'ok') {
+ $warning = $releaseresult;
+ }
+ } else {
+ $outcome =
+ &mt('Error - could not obtain lock on message folders record.');
+ }
+ return ($outcome,$warning);
}
+# ============================================================= Delete folder
+
+sub deletefolder {
+ my ($folder)=@_;
+ my %permfolders = &get_permanent_folders();
+ if (defined($permfolders{$folder})) {
+ return &mt('The folder "[_1]" may not be deleted.',$permfolders{$folder});
+ }
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ if (!defined($userfolders{$folder})) {
+ return &mt('The folder "[_1]" does not exist so deletion is not required.',
+ $folder);
+ }
+ # check folder is empty;
+ my $suffix=&Apache::lonmsg::foldersuffix($folder);
+ my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
+ if (@messages > 0) {
+ return &mt('The folder "[_1]" contains messages so it may not be deleted.',$folder).
+ ' '.
+ &mt('Delete or move the messages to a different folder first.');
+ }
+ my $delresult = &Apache::lonnet::del('email_folders',[$folder]);
+ return $delresult;
+}
+
+sub renamefolder {
+ my ($folder) = @_;
+ my $newname = $env{'form.renamed'};
+ my %permfolders = &get_permanent_folders();
+ if ($env{'form.renamed'} eq '') {
+ return &mt('The folder "[_1]" may not be renamed to "[_2]" as the new name you requested is an invalid name.',$folder,$newname);
+ }
+ if (defined($permfolders{$folder})) {
+ return &mt('The folder "[_1]" may not be renamed as it is a folder provided by the system.',$folder);
+ }
+ if (defined($permfolders{$newname})) {
+ 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);
+ }
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ if (defined($userfolders{$newname})) {
+ 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);
+ }
+ if (!defined($userfolders{$folder})) {
+ return &mt('The folder "[_1]" could not be renamed to "[_2]" because the folder does not exist.',$folder,$newname);
+ }
+ my %folderinfo;
+ if (ref($userfolders{$folder}) eq 'HASH') {
+ %folderinfo = %{$userfolders{$folder}};
+ } else {
+ %folderinfo = ( id => $folder,
+ created => $userfolders{$folder},);
+ }
+ my $outcome =
+ &Apache::lonnet::put('email_folders',{$newname => \%folderinfo});
+ if ($outcome eq 'ok') {
+ $outcome = &Apache::lonnet::del('email_folders',[$folder]);
+ }
+ return $outcome;
+}
+
+sub get_msgfolder_lock {
+ # get lock for mail folder counter.
+ my $lockhash = { "\0".'lock_counter' => time, };
+ my $tries = 0;
+ my $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
+ while (($gotlock ne 'ok') && $tries <3) {
+ $tries ++;
+ sleep(1);
+ $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
+ }
+ return $gotlock;
+}
+
+sub release_msgfolder_lock {
+ # remove lock
+ my @del_lock = ("\0".'lock_counter');
+ my $dellockoutcome=&Apache::lonnet::del('email_folders',\@del_lock);
+ if ($dellockoutcome ne 'ok') {
+ return (' '.&mt('Warning: failed to release lock for counter').' ');
+ } else {
+ return 'ok';
+ }
+}
+
+
# ======================================================== Move between folders
sub movemsg {
@@ -262,7 +518,9 @@ sub movemsg {
# ======================================================= Display a course list
sub discourse {
- my $result;
+ my ($statushash) = @_;
+ my ($result,$active,$previous,$future);
+ my $crstype = &Apache::loncommon::course_type();
my ($course_personnel,
$current_members,
$expired_members,
@@ -270,58 +528,360 @@ sub discourse {
&Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
unshift @$current_members, (@$course_personnel);
my %defaultUsers;
+
+ my $tmptext;
+ if ($tmptext = &Apache::lonselstudent::render_student_list($current_members,
+ "activeusers",
+ "current",
+ \%defaultUsers,
+ 1,"selectedusers",1,'email')
+ ) {
+ my $bcc_curr_hdr;
+ if ($crstype eq 'Community') {
+ $bcc_curr_hdr = &mt('Bcc: community participants with current access');
+ } else {
+ $bcc_curr_hdr = &mt('Bcc: course members with current access');
+ }
+ $result .= ' ';
+ if (ref($statushash) eq 'HASH') {
+ $statushash->{'active'} = 1;
+ }
+ }
+ if ($tmptext = &Apache::lonselstudent::render_student_list($expired_members,
+ "previoususers",
+ "expired",
+ \%defaultUsers,
+ 1, "selectedusers",0,'email')
+ ) {
+ my $bcc_prev_hdr;
+ if ($crstype eq 'Community') {
+ $bcc_prev_hdr = &mt('Bcc: community participants with expired access');
+ } else {
+ $bcc_prev_hdr = &mt('Bcc: course members with expired access');
+ }
+ $result .= ' ';
+ if (ref($statushash) eq 'HASH') {
+ $statushash->{'previous'} = 1;
+ }
+
+ }
+ if ($tmptext = &Apache::lonselstudent::render_student_list($future_members,
+ "futureusers",
+ "future",
+ \%defaultUsers,
+ 1, "selectedusers",0,'email')
+ ) {
+ my $bcc_future_hdr;
+ if ($crstype eq 'Community') {
+ $bcc_future_hdr = &mt('Bcc: community participants with future access');
+ } else {
+ $bcc_future_hdr = &mt('Bcc: course members with future access');
+ }
+
+ $result .= '';
+ if (ref($statushash) eq 'HASH') {
+ $statushash->{'future'} = 1;
+ }
- $result = &Apache::lonselstudent::render_student_list($current_members,
- "compemail",
- "current",
- \%defaultUsers,
- 1,"selectedusers",1);
-
- $result .= &Apache::lonselstudent::render_student_list($expired_members,
- "compemail",
- "expired",
- \%defaultUsers,
- 1, "selectedusers",0);
- $result .= &Apache::lonselstudent::render_student_list($future_members,
- "compemail",
- "future",
- \%defaultUsers,
- 1, "selectedusers", 0);
+ }
return $result;
}
+sub disgroup {
+ my ($r,$cdom,$cnum,$group,$access_status) = @_;
+ my $hasfloat;
+ # Needs to be in a course
+ if (!($env{'request.course.fn'})) {
+ $r->print(''.&mt('Error: you must have a course role selected to be able to send a broadcast message to a group in the course.').'');
+ return;
+ }
+ if ($cdom eq '' || $cnum eq '') {
+ $r->print(''.&mt('Error: could not determine domain or number of course').'');
+ return;
+ }
+ my ($memberinfo,$numitems) =
+ &Apache::longroup::group_memberlist($cdom,$cnum,$group,{},[]);
+ my @statustypes = ('active');
+ my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.
+ ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
+ my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'}.
+ ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
+ if ($viewgrps || $editgrps) {
+ push(@statustypes,('future','previous'));
+ }
+ if (keys(%{$memberinfo}) == 0) {
+ $r->print(''.
+ &mt('As this group has no members, there are no recipients to select').
+ '');
+ return;
+ } else {
+ $hasfloat = 1;
+ $r->print('
');
+ my %Sortby = (
+ active => {},
+ previous => {},
+ future => {},
+ );
+ my %lt = &Apache::lonlocal::texthash(
+ 'name' => 'Name',
+ 'usnm' => 'Username',
+ 'doma' => 'Domain',
+ 'active' => 'Broadcast to Active Members',
+ 'previous' => 'Broadcast (Bcc) to Former Members',
+ 'future' => 'Broadcast (Bcc) to Future Members',
+ );
+ foreach my $user (sort(keys(%{$memberinfo}))) {
+ my $status = $$memberinfo{$user}{status};
+ if ($env{'form.'.$status.'.sortby'} eq 'fullname') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
+ } elsif ($env{'form.'.$status.'.sortby'} eq 'username') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{uname}}},$user);
+ } elsif ($env{'form.'.$status.'.sortby'} eq 'domain') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{udom}}},$user);
+ } else {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
+ }
+ }
+ $r->print(&group_check_uncheck());
+ foreach my $status (@statustypes) {
+ if (ref($numitems) eq 'HASH') {
+ if ((defined($$numitems{$status})) && ($$numitems{$status})) {
+ my $formname = $status.'users';
+ if (ref($access_status) eq 'HASH') {
+ $access_status->{$status} = $$numitems{$status};
+ }
+ $r->print(' ');
+ }
+ }
+ }
+ $r->print('
');
+ }
+ return $hasfloat;
+}
+
+sub group_check_uncheck {
+ my $output = qq|
+
+ |;
+}
+
+sub groupmail_header {
+ my ($action,$group,$cdom,$cnum) = @_;
+ my ($description,$refarg);
+ if (!$cdom || !$cnum) {
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ }
+ if (exists($env{'form.ref'})) {
+ $refarg = 'ref='.$env{'form.ref'};
+ }
+ if (!$group) {
+ $group = $env{'form.group'};
+ }
+ if ($group eq '') {
+ return '';
+ } else {
+ my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$group);
+ if (defined($curr_groups{$group})) {
+ my %groupinfo =
+ &Apache::longroup::get_group_settings($curr_groups{$group});
+ $description = &unescape($groupinfo{'description'});
+ }
+ }
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ if ($refarg) {
+ my $brtitle;
+ if (&Apache::loncommon::course_type() eq 'Community') {
+ $brtitle = 'View community groups';
+ } else {
+ $brtitle = 'View course groups';
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/coursegroups",
+ text=>"Groups",
+ title=>$brtitle});
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
+ text=>"Group: $description",
+ title=>"Go to group's home page"},
+ {href=>"/adm/email?compose=group&group=".
+ "$env{'form.group'}&$refarg",
+ text=>"Send a Message in a Group",
+ title=>"Compose Group Message"},);
+ if ($action eq 'sending') {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({text=>"Messages being sent.",
+ title=>"E-mails sent"},);
+ }
+ my $groupheader = &Apache::loncommon::start_page('Group Message');
+ $groupheader .= &Apache::lonhtmlcommon::breadcrumbs
+ ('Group - '.$env{'form.group'}.' Email');
+ return $groupheader;
+}
+
+sub groupmail_sent {
+ my ($group,$cdom,$cnum) = @_;
+ my $refarg;
+ if (exists($env{'form.ref'})) {
+ $refarg = 'ref='.$env{'form.ref'};
+ }
+ my $output .= '
'.
- '');
if ($numblocked > 0) {
- my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
- my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
- $r->print('
'.
- $numblocked.' '.&mt('message(s) is/are not viewable because display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams.'));
- &build_block_table($r,$startblock,$endblock,\%setters);
+ $r->print(&blocked_in_folder($numblocked,$startblock,$endblock,
+ \%setters));
}
}
+sub blocked_in_folder {
+ my ($numblocked,$startblock,$endblock,$setters) = @_;
+ my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
+ my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
+ my $output = '
'.
+ &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);
+ #$output .= &Apache::loncommon::build_block_table($startblock,$endblock,
+ # $setters);
+
+ my ($blocked, $blocktext) = &Apache::loncommon::blocking_status("com");
+ $output .="
".$blocktext;
+
+ return $output;
+}
+
# ============================================================== Compose output
sub compout {
- my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_;
+ my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode,
+ $multiforward)=@_;
my $suffix=&Apache::lonmsg::foldersuffix($folder);
-
- if ($broadcast eq 'individual') {
+ my ($cdom,$cnum,$group,$refarg);
+ if (exists($env{'form.group'})) {
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ $group = $env{'form.group'};
+ my $action = 'composing';
+ $r->print(&groupmail_header($action,$group,$cdom,$cnum));
+ } elsif ($broadcast eq 'individual') {
&printheader($r,'/adm/email?compose=individual',
'Send a Message');
} elsif ($broadcast) {
@@ -731,6 +1341,21 @@ sub compout {
} elsif ($replycrit) {
$r->print('
'.&mt('Replying to a Critical Message').'
');
$replying=$replycrit;
+ } elsif ($multiforward) {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/email?folder=".&escape($folder),
+ text=>"Display All Messages"});
+ &printheader($r,'/adm/email?compose=multiforward',
+ 'Forwarding Multiple Messages');
+ if ($multiforward > 1) {
+ $r->print(&mt('Each of the[_1] [quant,_2,message] [_3]you checked'
+ .' will be forwarded to the recipient(s) you select below.'
+ ,'',$multiforward,'')
+ .' ');
+ } else {
+ $r->print(&mt('The message you checked will be forwarded to the recipient(s) you select below.').' ');
+ }
+
} else {
&printheader($r,'/adm/email?compose=upload',
'Distribute from Uploaded File');
@@ -740,37 +1365,139 @@ sub compout {
my $dissub='';
my $dismsg='';
my $disbase='';
- my $func=&mt('Send New');
- my %lt=&Apache::lonlocal::texthash('us' => 'Username',
- 'do' => 'Domain',
- 'ad' => 'Additional Recipients',
- 'sb' => 'Subject',
- 'ca' => 'Cancel',
- 'ma' => 'Mail');
-
+ my $attachrow;
+ my $func1='Send'; # do not translate here!
+ my %func2=( # do not translate here!
+ 'ma' => 'Message',
+ 'msg' => 'Messages',
+ );
+ my %lt=&Apache::lonlocal::texthash('us' => 'Username',
+ 'do' => 'Domain',
+ 'ad' => 'Additional Recipients',
+ 'rt' => 'Reply to',
+ 'ar' => 'Allow replies',
+ 'sb' => 'Subject',
+ 'ca' => 'Cancel',
+ 'gen' => 'Generate messages from a file',
+ 'gmt' => 'General message text',
+ 'tff' => 'The file format for the uploaded portion of the message is',
+ 'uas' => 'Upload and Send',
+ 'atta' => 'Attachment',
+ 'to' => 'To:',
+ );
+ my %attachmax = (
+ text => &mt('(128 KB max size)'),
+ num => 131072,
+ );
+ if (!$forwarding && !$multiforward) {
+ $attachrow = '
'.$lt{'atta'}.' '.$attachmax{'text'}.':
';
+ }
if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
|| &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
+ my $crstype = &Apache::loncommon::course_type();
my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
+ my $rsstxt;
+ if (&Apache::loncommon::course_type() eq 'Community') {
+ $rsstxt = &mt('Include in community RSS newsfeed');
+ } else {
+ $rsstxt = &mt('Include in course RSS newsfeed');
+ }
$dispcrit=
- '
' . $crithelp .
- '
'.
- '' . $crithelp .
- '
'.
-'';
- }
+ ''.$crithelp.' '.&mt('Require return receipt?').' '.
+ ' '.
+' ';
+ }
+ if ($broadcast ne 'group') {
+ if (&Apache::lonnet::allowed('dff',$env{'request.course.id'}) ||
+ &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
+
+ my $rectxt;
+ if (&Apache::loncommon::course_type() eq 'Community') {
+ $rectxt = &mt("Include in community's 'User records' for recipient(s)");
+ } else {
+ $rectxt = &mt("Include in course's 'User records' for recipient(s)");
+ }
+
+ $dispcrit.=' ';
+ }
+ }
+
my %message;
my %content;
+ my ($hasfloat,$broadcast_js,$sendmode,$can_grp_broadcast);
my $defdom=$env{'user.domain'};
+ if ($broadcast eq 'group') {
+ my %access_status = (
+ active => 0,
+ previous => 0,
+ future => 0,
+ );
+
+ if ($group eq '') {
+ my $studentsel = &discourse(\%access_status);
+ if ($studentsel) {
+ $r->print('
'.$studentsel.'
');
+ $hasfloat = 1;
+ }
+ } else {
+ $can_grp_broadcast = &check_group_priv($group);
+ if ($can_grp_broadcast) {
+ $hasfloat = &disgroup($r,$cdom,$cnum,$group,\%access_status);
+ }
+ }
+ if ($hasfloat) {
+ $sendmode = ''."\n";
+ $broadcast_js = qq|
+
+
+|;
+ }
+ }
if ($forwarding) {
%message=&Apache::lonnet::get('nohist_email'.$suffix,[$forwarding]);
%content=&Apache::lonmsg::unpackagemsg($message{$forwarding},$folder);
$dispcrit.='';
- $func=&mt('Forward');
+ $func1='Forward'; # do not translate here!
$dissub=&mt('Forwarding').': '.$content{'subject'};
$dismsg=&mt('Forwarded message from').' '.
@@ -784,7 +1511,7 @@ sub compout {
%content=&Apache::lonmsg::unpackagemsg($message{$replying},$folder);
$dispcrit.='';
- $func=&mt('Send Reply to');
+ $func1='Send Reply to'; # do not translate here!
$dissub=&mt('Reply').': '.$content{'subject'};
$dismsg='> '.$content{'message'};
@@ -794,101 +1521,330 @@ sub compout {
if ($content{'baseurl'}) {
$disbase='';
if ($env{'user.adv'}) {
- $disbase.='
');
- return;
+ $r->print(''
+ .&Apache::lonhtmlcommon::start_pick_box()
+ .&Apache::lonhtmlcommon::row_title(&mt('Subject'))
+ .$content{'subject'}
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ if ($folder eq 'sent') {
+ # To
+ if ($tolist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('To'))
+ .$tolist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if ($cclist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Cc'))
+ .$cclist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if ($bcclist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Bcc'))
+ .$bcclist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if (($content{'courseid'}) && ($content{'recipid'})) {
+ my %broadcast_types =
+ &Apache::lonlocal::texthash (
+ course_broadcast => 'Broadcast to',
+ group_cc_broadcast => 'Cc to group',
+ group_bcc_broadcast => 'Bcc to group',
+ );
+ foreach my $type (sort(keys(%broadcast_types))) {
+ if (ref($recipients{$type}) eq 'ARRAY') {
+ my $num = @{$recipients{$type}};
+ my $broadcastlist = join(', ',@{$recipients{$type}});
+ if ($broadcastlist && $broadcast_link) {
+ if ($type eq 'group_cc_broadcast') {
+ $groupcclist = $broadcastlist;
+ }
+ $r->print(&Apache::lonhtmlcommon::row_title(
+ $broadcast_types{$type})
+ .&mt('[quant,_1,recipient]',$num)
+ .' ['
+ .&mt('Show').']'
+ .&Apache::lonhtmlcommon::row_closure());
+ }
+ }
+ }
+ }
+ if ($content{'replytoaddr'}) {
+ my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
+ if ($replytoname ne '' && $replytodom ne '') {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
+ .$replytoname.':'.$replytodom
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ }
+ } else {
+ # From, Reply
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('From'))
+ .&Apache::loncommon::aboutmewrapper(
+ &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
+ $content{'sendername'},$content{'senderdomain'})
+ );
+ if ($content{'noreplies'}) {
+ $r->print(' ('.&mt('No replies to sender').')'
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ } else {
+ if ($content{'replytoaddr'}) {
+ my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
+ if ($replytoname ne '' && $replytodom ne '') {
+ $r->print(&Apache::lonhtmlcommon::row_closure()
+ .&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
+ .$replytoname.':'.$replytodom
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ } else {
+ $r->print(&Apache::lonhtmlcommon::row_closure());
+ }
+ } else {
+ $r->print(' ('.$content{'sendername'}.':'.$content{'senderdomain'}.') '
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if ($tonum && $tolist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('To'))
+ .$tolist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if ($cclist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Cc'))
+ .$cclist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ if ($content{'group'} ne '') {
+ if (&check_group_priv($content{'group'})) {
+ if (ref($recipients{'group_cc_broadcast'}) eq 'ARRAY') {
+ $groupcclist = join(', ',@{$recipients{'group_cc_broadcast'}});
+ if ($groupcclist) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group Cc'))
+ .$groupcclist
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Course
+ if ($content{'courseid'} ne '') {
+ if ($content{'courseid'} =~ m{^$match_domain\_$match_courseid$}) {
+ my %courseinfo;
+ %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'},
+ {'one_time' => 1});
+ my $description = $courseinfo{'description'};
+ if ($description ne '') {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt($crstype))
+ .$description
+ );
+ if ($content{'coursesec'}) {
+ $r->print(' ('.&mt('Section').': '.$content{'coursesec'}.')');
+ }
+ $r->print(&Apache::lonhtmlcommon::row_closure());
+ }
+ }
+ }
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Time'))
+ .$content{'time'}
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+
+ # Refers to
+ if ($baseurl) {
+ if (defined($content{'courseid'}) && defined($env{'request.course.id'})) {
+ if ($content{'courseid'} eq $env{'request.course.id'}) {
+ my $symblink;
+ my $showsymb = &Apache::lonenc::check_decrypt($symb);
+ my $showurl = &Apache::lonenc::check_decrypt($baseurl);
+ my $encrypturl = &Apache::lonnet::EXT('resource.0.encrypturl',
+ $showsymb,$env{'user.domain'},$env{'user.name'});
+ if ($symb) {
+ if ($encrypturl =~ /^yes$/i && !$env{'request.role.adv'}) {
+ $showsymb = &Apache::lonenc::check_encrypt($symb);
+ }
+ $symblink = '?symb='.$showsymb;
+ }
+ if ($encrypturl =~ /^yes$/i && !$env{'request.role.adv'}) {
+ $showurl = $baseurl;
+ }
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+ .''.$restitle.''
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ $refers_to = 1;
+ }
+ }
+ if (!$refers_to) {
+ if ($baseurl =~ m-^/enc/-) {
+ if (defined($content{'courseid'})) {
+ if (!$env{'request.course.id'}) {
+ my $unencurl =
+ &Apache::lonenc::unencrypted($baseurl,
+ $content{'courseid'});
+ if ($unencurl ne '') {
+ if (&Apache::lonnet::allowed('bre',$unencurl)) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+ .''.$restitle.''
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+ }
+ }
+ }
+ }
+ } else {
+ if (&Apache::lonnet::allowed('bre',$baseurl)) {
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+ .''.$restitle.''
+ .&Apache::lonhtmlcommon::row_closure()
+ );
+
+ }
+ }
+ }
+ }
+
+ # Message
+ $r->print(&Apache::lonhtmlcommon::row_title(&mt('Message'))
+ .'