--- loncom/interface/lonfeedback.pm 2004/07/27 23:35:34 1.107 +++ loncom/interface/lonfeedback.pm 2004/07/28 18:50:26 1.108 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.107 2004/07/27 23:35:34 www Exp $ +# $Id: lonfeedback.pm,v 1.108 2004/07/28 18:50:26 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -125,7 +125,7 @@ sub list_discussion { } } -# Get information about students and non-stundents in course for filtering display of posts +# Get information about students and non-students in course for filtering display of posts my %roleshash = (); my %roleinfo = (); if ($rolefilter) { @@ -258,22 +258,36 @@ sub list_discussion { $numoldver = 1; } } - my $message=$contrib{$idx.':message'}; + my ($message,$subject); + if ($idx > 0) { + if ($contrib{$idx.':message'} =~ /.*::::\Q$numoldver\E::::(.+?)$/si) { + $message = $1; + } else { + $message = $contrib{$idx.':message'}; + } + } else { + $message=$contrib{$idx.':message'}; + } + my $attachmenturls = $contrib{$idx.':attachmenturl'}; $message=~s/\n/\
/g; - $message=&Apache::lontexconvert::msgtexconverted($message,undef,$numoldver); - my $subject=$contrib{$idx.':subject'}; + $message=&Apache::lontexconvert::msgtexconverted($message); + if ($idx > 0) { + if ($contrib{$idx.':subject'} =~ /.*::::\Q$numoldver\E::::(.+?)$/si) { + $subject = $1; + } else { + $subject = $contrib{$idx.':subject'}; + } + } else { + $subject=$contrib{$idx.':subject'}; + } if (defined($subject)) { $subject=~s/\n/\
/g; - $subject=&Apache::lontexconvert::msgtexconverted($subject,undef,$numoldver); + $subject=&Apache::lontexconvert::msgtexconverted($subject); } - if ($contrib{$idx.':attachmenturl'}) { - my ($fname) - =($contrib{$idx.':attachmenturl'}=~m|/([^/]+)$|); - &Apache::lonnet::allowuploaded('/adm/feedback', - $contrib{$idx.':attachmenturl'}); - $message.='

'.&mt('Attachment'). - ': '. - $fname.'

'; + if ($attachmenturls) { + my @attachments = (); + my %currattach = (); + &extract_attachments($attachmenturls,$idx,$numoldver,\$message,\@attachments,\%currattach); } if ($message) { if ($hidden) { @@ -432,6 +446,7 @@ sub list_discussion { if ($showonlyunread && $prevread > $posttime) { $notshown{$idx} = 1; } else { +# apply filters my $uname = $contrib{$idx.':sendername'}; my $udom = $contrib{$idx.':senderdomain'}; my $poster = $uname.':'.$udom; @@ -741,23 +756,60 @@ END } } if ($discussiononly) { + my $now = time; + my $attachnum = 0; + my $newattachmsg = ''; + my @currnewattach = (); + my @currdelold = (); + my $comment = ''; + my $subject = ''; + if ($ENV{'form.origpage'}) { + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['addnewattach','deloldattach','delnewattach','timestamp','idx','subject','comment']); + $subject = &HTML::Entities::encode($ENV{'form.subject'},'<>&"'); + $comment = &HTML::Entities::encode($ENV{'form.comment'},'<>&"'); + my @keepold = (); + &process_attachments(\@currnewattach,\@currdelold,\@keepold); + if (@currnewattach > 0) { + $attachnum += @currnewattach; + } + } $discussion.=(< -
-Note: in anonymous discussion, your name is visible only to -course faculty
-Title: 

- -

-Attachment (128 KB max size): -

- + +
+Note: in anonymous discussion, your name is visible only +to course faculty
+Title: 

+ ENDDISCUSS + if ($ENV{'form.origpage'}) { + $discussion.=''."\n"; + foreach (@currnewattach) { + $discussion.=''."\n"; + } + } + $discussion.="\n"; if ($outputtarget ne 'tex') { + $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode); + if (@currnewattach > 0) { + $newattachmsg .= 'New attachments
'; + if (@currnewattach > 1) { + $newattachmsg .= '
    '; + foreach my $item (@currnewattach) { + $item =~ m#.*/([^/]+)$#; + $newattachmsg .= '
  1. '.$1.'
  2. '."\n"; + } + $newattachmsg .= '
'."\n"; + } else { + $currnewattach[0] =~ m#.*/([^/]+)$#; + $newattachmsg .= ''.$1.'
'."\n"; + } + } + $discussion.=$newattachmsg; $discussion.=&generate_preview_button(); } } else { @@ -778,22 +830,62 @@ ENDDISCUSS sub mail_screen { my ($r,$feedurl,$options) = @_; + if (exists($ENV{'form.origpage'})) { + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss']); + } my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion', '','onLoad="window.focus();setposttype();"'); my $title=&Apache::lonnet::gettitle($feedurl); if (!$title) { $title = $feedurl; } my $quote=''; my $subject = ''; - my $oldmessage = ''; + my $comment = ''; my $prevtag = ''; my $parentmsg = ''; - my $anonscript = (< 0) { + if ($contrib{$idx.':message'} =~ /::::\Q$numoldver\E::::(.+?)$/si) { + $message = $1; + } else { + $message = $contrib{$idx.':message'}; + } + } else { + $message=$contrib{$idx.':message'}; + } $message=~s/\n/\
/g; - $quote='
'.&Apache::lontexconvert::msgtexconverted($message,undef,$numoldver).'
'; + $quote='
'.&Apache::lontexconvert::msgtexconverted($message).'
'; if ($idx > 0) { - if ($contrib{'subject'} =~ /::::\d+::::(.+)$/si) { + if ($contrib{$idx.':subject'} =~ /::::\Q$numoldver\E::::(.+?)$/si) { $subject = $1; } else { $subject = $contrib{$idx.':subject'}; } $subject = 'Re: '.$subject; } + $subject = &HTML::Entities::encode($subject,'<>&"'); } else { - if ($contrib{$idx.':message'} =~ /::::\d+::::(.+)$/si) { - $oldmessage = $1; + $attachmenturls = $contrib{$idx.':attachmenturl'}; + if ($contrib{$idx.':message'} =~ /.*::::(\d+)::::(.*?)$/si) { + $numoldver = $1; + $comment = $2; } else { - $oldmessage = $contrib{$idx.':message'}; + $comment = $contrib{$idx.':message'}; } - $oldmessage=&HTML::Entities::encode($oldmessage,'<>&"'); - if ($contrib{$idx.':subject'} =~ /::::\d+::::(.+)$/si) { + $comment = &HTML::Entities::encode($comment,'<>&"'); + if ($contrib{$idx.':subject'} =~ /.*::::\d+::::(.+?)$/si) { $subject = $1; } else { $subject = $contrib{$idx.':subject'}; } + $subject = &HTML::Entities::encode($subject,'<>&"'); if (defined($contrib{$idx.':replyto'})) { $parentmsg = $contrib{$idx.':replyto'}; } - my $anonflag = 0; - if ($contrib{$idx.':anonymous'}) { - $anonflag = 1; - } - $anonscript = (<'; } } + + if ($ENV{'form.origpage'}) { + $subject = $ENV{'form.subject'}; + $comment = $ENV{'form.comment'}; + &process_attachments(\@currnewattach,\@currdelold,\@keepold); + } my $latexHelp=&Apache::loncommon::helpLatexCheatsheet(); my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders(); my $send=&mt('Send'); @@ -916,6 +1028,7 @@ $htmlheader alert('Please check a feedback type.'); } } + $anonchk $anonscript //--> @@ -937,7 +1050,7 @@ END END } - $r->print(<print(< $quote @@ -946,20 +1059,78 @@ $quote $latexHelp Title:

-

+END + if ( ($ENV{'form.editdisc'}) || ($ENV{'form.replydisc'}) ) { + if ($ENV{'form.origpage'}) { + foreach (@currnewattach) { + $r->print(''."\n"); + } + foreach (@currdelold) { + $r->print(''."\n"); + } + } + if ($ENV{'form.editdisc'}) { + if ($attachmenturls) { + &extract_attachments($attachmenturls,$idx,$numoldver,\$attachmsg,\@attachments,\%currattach,\@currdelold); + $attachnum = scalar(keys %currattach); + foreach (keys %currattach) { + $r->print(''."\n"); + } + } + } + } else { + $r->print(<

+END + } + $r->print(<

-ENDDOCUMENT -$r->print(&generate_preview_button(). -&Apache::lonhtmlcommon::htmlareaselectactive('comment'). -''); +END + if ($ENV{'form.editdisc'} || $ENV{'form.replydisc'}) { + my $now = time; + my $ressymb = $symb; + my $postidx = ''; + if ($ENV{'form.editdisc'}) { + $postidx = $idx; + } + if (@currnewattach > 0) { + $attachnum += @currnewattach; + } + $r->print(&generate_attachments_button($postidx,$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,$numoldver)); + if ($attachnum > 0) { + if (@currnewattach > 0) { + $newattachmsg .= 'New attachments
'; + if (@currnewattach > 1) { + $newattachmsg .= '
    '; + foreach my $item (@currnewattach) { + $item =~ m#.*/([^/]+)$#; + $newattachmsg .= '
  1. '.$1.'
  2. '."\n"; + } + $newattachmsg .= '
'."\n"; + } else { + $currnewattach[0] =~ m#.*/([^/]+)$#; + $newattachmsg .= ''.$1.'
'."\n"; + } + } + if ($attachmsg) { + $r->print("Retained attachments:$attachmsg
\n"); + } + if ($newattachmsg) { + $r->print("$newattachmsg
"); + } + } + } + $r->print(&generate_preview_button(). + &Apache::lonhtmlcommon::htmlareaselectactive('comment'). + ''); } sub print_display_options { @@ -1698,11 +1869,20 @@ sub adddiscuss { } $contrib{'history'} = $oldcontrib{$oldidx.':history'}.':'; } + my $numnewver = $numoldver + 1; if (defined($oldcontrib{$oldidx.':subject'})) { - $contrib{'subject'} = $oldcontrib{$oldidx.':subject'}.'::::'.$numoldver.'::::'.$contrib{'subject'}; + if ($oldcontrib{$oldidx.':subject'} =~ /::::\d+::::/) { + $contrib{'subject'} = $oldcontrib{$oldidx.':subject'}.'::::'.$numnewver.'::::'.$contrib{'subject'}; + } else { + $contrib{'subject'} = '::::0::::'.$oldcontrib{$oldidx.':subject'}.'::::1::::'.$contrib{'subject'}; + } } if (defined($oldcontrib{$oldidx.':message'})) { - $contrib{'message'} = $oldcontrib{$oldidx.':message'}.'::::'.$numoldver.'::::'.$contrib{'message'}; + if ($oldcontrib{$oldidx.':message'} =~ /::::\d+::::/) { + $contrib{'message'} = $oldcontrib{$oldidx.':message'}.'::::'.$numnewver.'::::'.$contrib{'message'}; + } else { + $contrib{'message'} = '::::0::::'.$oldcontrib{$oldidx.':message'}.'::::1::::'.$contrib{'message'}; + } } $contrib{'history'} .= $oldcontrib{$oldidx.':timestamp'}; foreach (keys %contrib) { @@ -1769,6 +1949,300 @@ onClick="if (typeof(document.mailform.on ENDPREVIEW } +sub modify_attachments { + my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_; + my $subject=&clear_out_html($ENV{'form.subject'}); + $subject=~s/\n/\
/g; + $subject=&Apache::lontexconvert::msgtexconverted($subject); + my $timestamp=$ENV{'form.timestamp'}; + my $numoldver=$ENV{'form.numoldver'}; + my $bodytag=&Apache::loncommon::bodytag('Discussion Post Attachments', + '',''); + my $msg = ''; + my @attachments = (); + my %currattach = (); + if ($idx) { + &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\@attachments,\%currattach,$currdelold); + } + $r->print(< + +Managing Attachments + + +$bodytag +
+ + + + +
+ Subject:$subject

+END + if ($idx) { + if ($attachmenturls) { + my @currold = keys %currattach; + if (@currold > 0) { + $r->print("The following attachments were part of the most recent saved version of this posting.
Check the checkboxes for any you wish to remove
\n"); + foreach (@currold) { + my $id = $_; + $attachments[$id] =~ m#/([^/]+)$#; + $r->print(' '.$1.'
'."\n"); + } + $r->print("
"); + } + } + } + if (@{$currnewattach} > 0) { + $r->print("The following attachments have been uploaded for inclusion with this posting.
Check the checkboxes for any you wish to remove
\n"); + foreach (@{$currnewattach}) { + $_ =~ m#/([^/]+)$#; + $r->print(' '.$1.'
'."\n"); + } + $r->print("
"); + } + $r->print(< +
+ + + + + + + + +END + foreach (@{$currnewattach}) { + $r->print(''."\n"); + } + foreach (@{$currdelold}) { + $r->print(''."\n"); + } + $r->print(< + + + +END + return; +} + +sub process_attachments { + my ($currnewattach,$currdelold,$keepold) = @_; + if (exists($ENV{'form.currnewattach'})) { + if (ref($ENV{'form.currnewattach'}) eq 'ARRAY') { + @{$currnewattach} = @{$ENV{'form.currnewattach'}}; + } else { + $$currnewattach[0] = $ENV{'form.currnewattach'}; + } + } + if (exists($ENV{'form.deloldattach'})) { + if (ref($ENV{'form.deloldattach'}) eq 'ARRAY') { + @{$currdelold} = @{$ENV{'form.deloldattach'}}; + } else { + $$currdelold[0] = $ENV{'form.deloldattach'}; + } + } + if (exists($ENV{'form.delnewattach'})) { + my @currdelnew = (); + my @currnew = (); + if (ref($ENV{'form.delnewattach'}) eq 'ARRAY') { + @currdelnew = @{$ENV{'form.delnewattach'}}; + } else { + $currdelnew[0] = $ENV{'form.delnewattach'}; + } + foreach my $newone (@{$currnewattach}) { + my $delflag = 0; + foreach (@currdelnew) { + if ($newone eq $_) { + $delflag = 1; + last; + } + } + unless ($delflag) { + push @currnew, $newone; + } + } + @{$currnewattach} = @currnew; + } + if (exists($ENV{'form.keepold'})) { + if (ref($ENV{'form.keepold'}) eq 'ARRAY') { + @{$keepold} = @{$ENV{'form.keepold'}}; + } else { + $$keepold[0] = $ENV{'form.keepold'}; + } + } +} + +sub generate_attachments_button { + my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach,$numoldver,$mode) = @_; + my $origpage = $ENV{'REQUEST_URI'}; + my $att=$attachnum.' '.&mt("attachments"); + my $response = (< +Click to add/remove attachments:  + + + + + + +ENDATTACH + if (defined($deloldattach)) { + if (@{$deloldattach} > 0) { + foreach (@{$deloldattach}) { + $response .= ''."\n"; + } + } + } + if (defined($currnewattach)) { + if (@{$currnewattach} > 0) { + foreach (@{$currnewattach}) { + $response .= ''."\n"; + } + } + } + $response .= ''; + return $response; +} + +sub extract_attachments { + my ($attachmenturls,$idx,$numoldver,$message,$attachments,$currattach,$currdelold) = @_; + if ($attachmenturls =~ m/::::\d+:[\.yn\d]+::::/) { + @{$attachments} = split/::::\d+:[\.yn\d]+::::/,$attachmenturls; + shift @{$attachments}; + my $searchstr = '::::'; + for (my $i=0; $i<@{$attachments}; $i++) { + if ($attachmenturls =~ m#^\Q$searchstr\E(\d+)(:[\.yn\d]+)::::#) { + my $info = $1.$2; + my $attachid = $1-1; + $searchstr .= $info.'::::'.$$attachments[$i].'::::'; + if ($info =~ /\.$numoldver([yn])\./) { + if (defined($currdelold)) { + if (@{$currdelold} > 0) { + unless (grep/^$attachid$/,@{$currdelold}) { + my $id = $i; + $$currattach{$id} = $1; + } + } else { + my $id = $i; + $$currattach{$id} = $1; + } + } else { + my $id = $i; + $$currattach{$id} = $1; + } + } + } + } + my @attached = (sort { $a <=> $b } keys %{$currattach}); + if (@attached == 1) { + my $id = $attached[0]; + $$attachments[$attached[0]]=~m|/([^/]+)$|; + $$message.='
'. + $1.'
'; + &Apache::lonnet::allowuploaded('/adm/feedback', + $$attachments[$id]); + } elsif (@attached > 1) { + $$message.='
    '; + foreach (@attached) { + my $id = $_; + my ($fname) + =($$attachments[$id]=~m|/([^/]+)$|); + $$message .= '
  1. '. + $fname.'
  2. '; + &Apache::lonnet::allowuploaded('/adm/feedback', + $$attachments[$id]); + } + $$message .= '

'; + } + } else { + my ($fname) + =($attachmenturls=~m|/([^/]+)$|); + $$message .='

'.&mt('Attachment'). + ': '. + $fname.'

'; + $$attachments[0] = $attachmenturls; + $$currattach{'0'} = 'n'; + &Apache::lonnet::allowuploaded('/adm/feedback', + $attachmenturls); + } +} + +sub construct_attachmenturl { + my ($currnewattach,$keepold,$symb,$idx)=@_; + my $oldattachmenturl; + my $newattachmenturl; + my $startnum = 1; + my $currver = 0; + if (($ENV{'form.editdisc'}) && ($idx)) { + my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + $oldattachmenturl = $contrib{$idx.':attachmenturl'}; + if ($contrib{$idx.':history'}) { + if ($contrib{$idx.':history'} =~ /:/) { + my @oldversions = split/:/,$contrib{$idx.':history'}; + $currver = 1 + scalar(@oldversions); + } else { + $currver = 2; + } + } else { + $currver = 1; + } + if ($oldattachmenturl) { + if ($oldattachmenturl =~ m/::::\d+:[\.yn\d]+::::/) { + my @attachments = split/::::\d+:[\.yn\d]+::::/,$oldattachmenturl; + shift @attachments; + $startnum += @attachments; + my $searchstr = '::::'; + $newattachmenturl = '::::'; + for (my $i=0; $i<@attachments; $i++) { + if ($oldattachmenturl =~ m#^\Q$searchstr\E(\d+)(:[\.yn\d]+)::::#) { + my $attachid = $1 - 1; + $searchstr .= $1.$2.'::::'.$attachments[$i].'::::'; + $newattachmenturl .= $1.$2; + if (grep/^$attachid$/,@{$keepold}) { + $newattachmenturl .= '.'.$currver.'n.'; + } + $newattachmenturl .= '::::'.$attachments[$i].'::::'; + } + } + $newattachmenturl =~ s/::::$//; + } else { + $newattachmenturl = '::::1:.0n.'; + unless (grep/^0$/,@{$keepold}) { + $newattachmenturl .= '.1n.'; + } + $newattachmenturl .= '::::'.$oldattachmenturl; + $startnum ++; + } + } + } + for (my $i=0; $i<@{$currnewattach}; $i++) { + my $attachnum = $startnum + $i; + $newattachmenturl .= '::::'.$attachnum.':.'.$currver.'n.::::'.$$currnewattach[$i]; + } + return $newattachmenturl; +} + sub handler { my $r = shift; if ($r->header_only) { @@ -1780,7 +2254,7 @@ sub handler { # --------------------------- Get query string for limited number of parameters &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp','modifydisp','changes','navmaps','navurl','sortfilter','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick']); + ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp','modifydisp','changes','navmaps','navurl','sortfilter','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold']); if ($ENV{'form.posterlist'}) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; @@ -2074,6 +2548,32 @@ ENDREDIR $r->content_type('text/html'); $r->send_http_header; &show_preview($r); + } elsif ($ENV{'form.attach'}) { +# -------------------------------------------------------- Work on attachments + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','addnewattach','delnewattach','timestamp','numoldver','idx','anondiscuss','discuss']); + my @currnewattach = (); + my @currdelold = (); + my @keepold = (); + &process_attachments(\@currnewattach,\@currdelold,\@keepold); + if (exists($ENV{'form.addnewattach.filename'})) { + unless (length($ENV{'form.addnewattach'})>131072) { + my $subdir = 'feedback/'.$ENV{'form.timestamp'}; + my $newattachment=&Apache::lonnet::userfileupload('addnewattach',undef,$subdir); + push @currnewattach, $newattachment; + } + } + my $attachmenturls = ''; + my $idx = $ENV{'form.idx'}; + my $symb = $ENV{'form.attach'}; + if ($idx) { + my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + $attachmenturls = $contrib{$idx.':attachmenturl'}; + } + &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,$attachmenturls); } else { # ------------------------------------------------------------- Normal feedback my $feedurl=$ENV{'form.postdata'}; @@ -2091,6 +2591,8 @@ ENDREDIR $symb=(split(/\:\:\:/,$ENV{'form.editdisc'}))[0]; my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); $feedurl=&Apache::lonnet::clutter($url); + } elsif ($ENV{'form.origpage'}) { + $symb=""; } else { $symb=&Apache::lonnet::symbread($feedurl); } @@ -2127,7 +2629,7 @@ ENDREDIR unless ($ENV{'form.sendit'}) { my $options=&screen_header($feedurl); if ($options) { - &mail_screen($r,$feedurl,$options); + &mail_screen($r,$feedurl,$options); } else { &fail_redirect($r,$feedurl); } @@ -2149,7 +2651,21 @@ ENDREDIR &Apache::lonnet::delenv('allowed.vgr'); # Get attachments, if any, and not too large my $attachmenturl=''; - if ($ENV{'form.attachment.filename'}) { + if (($ENV{'form.origpage'}) || ($ENV{'form.editdisc'}) || ($ENV{'form.replydisc'})) { + my ($symb,$idx); + if ($ENV{'form.replydisc'}) { + ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'}); + } elsif ($ENV{'form.editdisc'}) { + ($symb,$idx)=split(/\:\:\:/,$ENV{'form.editdisc'}); + } elsif ($ENV{'form.origpage'}) { + $symb = $ENV{'form.symb'}; + } + my @currnewattach = (); + my @deloldattach = (); + my @keepold = (); + &process_attachments(\@currnewattach,\@deloldattach,\@keepold); + $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx); + } elsif ($ENV{'form.attachment.filename'}) { unless (length($ENV{'form.attachment'})>131072) { $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback'); }