--- loncom/interface/lonfeedback.pm	2005/04/07 06:56:23	1.157
+++ loncom/interface/lonfeedback.pm	2006/03/19 21:43:21	1.186
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Feedback
 #
-# $Id: lonfeedback.pm,v 1.157 2005/04/07 06:56:23 albertel Exp $
+# $Id: lonfeedback.pm,v 1.186 2006/03/19 21:43:21 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -39,12 +39,14 @@ use Apache::lonnet;
 use Apache::lonhtmlcommon();
 use Apache::lonnavmaps;
 use Apache::lonenc();
+use Apache::lonrss();
 use HTML::LCParser();
 use Apache::lonspeller();
 use Cwd;
 
 sub discussion_open {
     my ($status,$symb)=@_;
+    if ($env{'request.role.adv'}) { return 1; }
     if (defined($status) &&
 	!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
 	  || $status eq 'OPEN')) {
@@ -97,7 +99,7 @@ sub list_discussion {
     $ressymb=&wrap_symb($ressymb);
     my $encsymb=&Apache::lonenc::check_encrypt($ressymb);
     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
-		  && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form)$/));
+		  && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form|task)$/));
     
     my %usernamesort = ();
     my %namesort =();
@@ -113,7 +115,7 @@ sub list_discussion {
     my $toggkey = $ressymb.'_readtoggle';
     my $readkey = $ressymb.'_read';
     $ressymb=$encsymb;
-    my %dischash = &Apache::lonnet::get('nohist_'.$env{'request.course.id'}.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$env{'user.domain'},$env{'user.name'});
+    my %dischash = &Apache::lonnet::get('nohist_'.$cid.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$env{'user.domain'},$env{'user.name'});
     my %discinfo = ();
     my $showonlyunread = 0;
     my $showunmark = 0; 
@@ -154,7 +156,9 @@ sub list_discussion {
     my %roleshash = ();
     my %roleinfo = ();
     if ($env{'form.rolefilter'}) {
-        %roleshash = &Apache::lonnet::dump('nohist_userroles',$env{'course.'.$env{'request.course.id'}.'.domain'},$env{'course.'.$env{'request.course.id'}.'.num'});
+        %roleshash = &Apache::lonnet::dump('nohist_userroles',
+					   $env{'course.'.$cid.'.domain'},
+					   $env{'course.'.$cid.'.num'});
         foreach (keys %roleshash) {
             my ($role,$uname,$udom,$sec) = split/:/,$_;
             if ($role =~ /^cr/) {
@@ -171,9 +175,8 @@ sub list_discussion {
             }
         }
         my ($classlist) = &Apache::loncoursedata::get_classlist(
-                              $env{'request.course.id'},
-                              $env{'course.'.$env{'request.course.id'}.'.domain'},
-                              $env{'course.'.$env{'request.course.id'}.'.num'});
+                              $env{'course.'.$cid.'.domain'},
+                              $env{'course.'.$cid.'.num'});
         my $sec_index = &Apache::loncoursedata::CL_SECTION();
         my $status_index = &Apache::loncoursedata::CL_STATUS();
         while (my ($student,$data) = each %$classlist) {
@@ -235,7 +238,8 @@ sub list_discussion {
     my %notshown = ();
     my %newitem = ();
     my $maxdepth=0;
-
+    my %anonhash=();
+    my $anoncnt=0;
     my $target='';
     unless ($env{'browser.interface'} eq 'textual' ||
 	    $env{'environment.remote'} eq 'off' ) {
@@ -245,8 +249,8 @@ sub list_discussion {
     my $now = time;
     $discinfo{$visitkey} = $visit;
 
-    &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});
-    &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget);
+    &Apache::lonnet::put('nohist_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});
+    &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt);
 
     my $discussion='';
     my $manifestfile;
@@ -390,19 +394,20 @@ imscp_v1p1.xsd http://www.imsglobal.org/
 	    $discussion.='<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$ressymb.'" ><table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
 	    $discussion .='<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.
 		'<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';
+	    my $escsymb=&Apache::lonnet::escape($ressymb);
 	    if ($visible>2) {
 		$discussion.='<td align="left">'.
-		    '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$ressymb;
+		    '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$escsymb;
 		if ($newpostsflag) {
 		    $discussion .= '&previous='.$prevread;
 		}
 		$discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
-		    '<a href="/adm/feedback?cmd=threadedoff&amp;symb='.$ressymb;
+		    '<a href="/adm/feedback?cmd=threadedoff&amp;symb='.$escsymb;
 		if ($newpostsflag) {
 		    $discussion .= '&previous='.$prevread;
 		}
 		$discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;
-                              <a href= "/adm/feedback?cmd=sortfilter&amp;symb='.$ressymb;
+                              <a href= "/adm/feedback?cmd=sortfilter&amp;symb='.$escsymb;
                 if ($newpostsflag) {
                     $discussion .= '&previous='.$prevread;
                 }
@@ -410,14 +415,16 @@ imscp_v1p1.xsd http://www.imsglobal.org/
             } else {
                 $discussion .= '<td align="left">';
             }
-            $discussion .='<a href= "/adm/feedback?export='.$ressymb;
+            $discussion .='<a href= "/adm/feedback?export='.$escsymb;
             if ($newpostsflag) {
                 $discussion .= '&previous='.$prevread;
             }
             $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';
 	    if ($newpostsflag) {
 		if (!$markondisp) {
-		    $discussion .='<td align="right"><a href="/adm/feedback?markread=1&amp;symb='.$ressymb.'">'.&mt('Mark NEW posts no longer new').'</a>&nbsp;&nbsp;';
+		    $discussion .='<td align="right"><a href="/adm/preferences?action=changediscussions">'.
+			&mt('Preferences on what is marked as NEW').
+			'</a><br /><a href="/adm/feedback?markread=1&amp;symb='.$escsymb.'">'.&mt('Mark NEW posts no longer new').'</a>';
 		} else {
 		    $discussion .= '<td>&nbsp;</td>';
 		}
@@ -430,7 +437,7 @@ imscp_v1p1.xsd http://www.imsglobal.org/
             if ($numhidden > 0) {
                 my $colspan = $maxdepth+1;
                 $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
-                         '<a href="/adm/feedback?allposts=1&amp;symb='.$ressymb;
+                         '<a href="/adm/feedback?allposts=1&amp;symb='.$escsymb;
                 if ($newpostsflag) {
                     $discussion .= '&previous='.$prevread;
                 }
@@ -743,7 +750,7 @@ ENDDISCUSS
 	        ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
 	    if ($outputtarget ne 'tex') {
 		$discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.
-		    $ressymb.':::" '.$target.'>'.
+		    &Apache::lonnet::escape($ressymb).':::" '.$target.'>'.
 		    '<img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').'" border="0" />'.
 		    &mt('Post Discussion').'</a></td></tr></table>';
 	    }
@@ -753,10 +760,11 @@ ENDDISCUSS
 }
 
 sub build_posting_display {
-    my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$statusfilter,$toggkey,$outputtarget) = @_;
+    my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt) = @_;
     my @original=();
     my @index=();
     my $symb=&Apache::lonenc::check_decrypt($ressymb);
+    my $escsymb=&Apache::lonnet::escape($ressymb);
     my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
 			  $env{'course.'.$env{'request.course.id'}.'.num'});
@@ -820,6 +828,13 @@ sub build_posting_display {
                 my %allattachments = ();
                 my ($screenname,$plainname);
                 my $sender = &mt('Anonymous');
+# Anonymous users getting number within a discussion
+# Since idx is in static order, this should give the same sequence every time. 
+		my $key=$contrib{$idx.':sendername'}.'@'.$contrib{$idx.':senderdomain'};
+		unless ($$anonhash{$key}) {
+                    $anoncnt++;
+		    $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;
+		}
                 my ($message,$subject,$vgrlink,$ctlink);
                 &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver);
 
@@ -858,7 +873,7 @@ sub build_posting_display {
 					 $contrib{$idx.':sendername'}.' at '.
 					 $contrib{$idx.':senderdomain'}.')';
 			    if ($contrib{$idx.':anonymous'}) {
-			        $sender.=' ['.&mt('anonymous').'] '.
+			        $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.
 				    $screenname;
 			    }
 
@@ -891,16 +906,16 @@ sub build_posting_display {
                             } else {
                                 @{$$namesort{$lastname}{$firstname}} = ("$idx");
                             }
-                            if ($env{'course.'.$env{'request.course.id'}.'.allow_discussion_post_editing'} =~ m/yes/i) {
+                            if (&editing_allowed()) {
                                 if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {
                                     $sender.=' <a href="/adm/feedback?editdisc='.
-                                         $ressymb.':::'.$idx;
-                                    if ($newpostsflag) {
+                                         $escsymb.':::'.$idx;
+                                    if ($$newpostsflag) {
                                         $sender .= '&previous='.$prevread;
                                     }
                                     $sender .= '" '.$target.'>'.&mt('Edit').'</a>';                                             
                                     unless ($seeid) {
-                                        $sender.=" <a href=\"javascript:studentdelete('$ressymb','$idx','$newpostsflag','$prevread')";
+                                        $sender.=" <a href=\"javascript:studentdelete('$escsymb','$idx','$$newpostsflag','$prevread')";
                                         $sender .= '">'.&mt('Delete').'</a>';
                                     }
                                 }
@@ -909,23 +924,23 @@ sub build_posting_display {
 			        if ($hidden) {
                                     unless ($studenthidden) {
 			                $sender.=' <a href="/adm/feedback?unhide='.
-				                $ressymb.':::'.$idx;
-                                        if ($newpostsflag) {
-                                             $sender .= '&previous='.$prevread;
+				                $escsymb.':::'.$idx;
+                                        if ($$newpostsflag) {
+                                            $sender .= '&previous='.$prevread;
                                         }
                                         $sender .= '">'.&mt('Make Visible').'</a>';
                                     }
 			        } else {
 				    $sender.=' <a href="/adm/feedback?hide='.
-				        $ressymb.':::'.$idx;
-                                    if ($newpostsflag) {
+				        $escsymb.':::'.$idx;
+                                    if ($$newpostsflag) {
                                         $sender .= '&previous='.$prevread;
                                     }
                                     $sender .= '">'.&mt('Hide').'</a>';
 			        }                     
 			        $sender.=' <a href="/adm/feedback?deldisc='.
-				        $ressymb.':::'.$idx;
-                                if ($newpostsflag) {
+				        $escsymb.':::'.$idx;
+                                if ($$newpostsflag) {
                                     $sender .= '&previous='.$prevread;
                                 }
                                 $sender .= '">'.&mt('Delete').'</a>';
@@ -933,6 +948,8 @@ sub build_posting_display {
 		        } else {
 			    if ($screenname) {
 			        $sender='<i>'.$screenname.'</i>';
+			    } else {
+				$sender='<i>'.$$anonhash{$key}.'</i>';
 			    }
 # Set up for sorting by domain, then username for anonymous
                             unless (defined($$usernamesort{'__anon'})) {
@@ -958,9 +975,9 @@ sub build_posting_display {
 						 $env{'request.course.id'}.
 						 ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
 			    $sender.=' <a href="/adm/feedback?replydisc='.
-			            $ressymb.':::'.$idx;
-                            if ($newpostsflag) {
-                                    $sender .= '&previous='.$prevread;
+			            $escsymb.':::'.$idx;
+                            if ($$newpostsflag) {
+                                $sender .= '&previous='.$prevread;
                             }
                             $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
                         }
@@ -1074,7 +1091,7 @@ sub build_posting_display {
                                 my @postversions = ();
                                 $$discussionitems[$idx] .= &mt('This post has been edited by the author.');
                                 if ($seeid) {
-                                    $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$ressymb.':::'.$idx.'">'.&mt('Display all versions').'</a>';
+                                    $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$escsymb.':::'.$idx.'">'.&mt('Display all versions').'</a>';
                                 }
                                 $$discussionitems[$idx].='<br/>'.&mt('Earlier version(s) were posted on: ');
                                 if ($contrib{$idx.':history'} =~ m/:/) {
@@ -1164,11 +1181,11 @@ sub get_post_contents {
 #    $$screenname=&Apache::loncommon::screenname(
 #                                        $$contrib{$idx.':sendername'},
 #                                        $$contrib{$idx.':senderdomain'});
-#    $$plainname=&Apache::loncommon::nickname(
-#                                        $$contrib{$idx.':sendername'},
-#                                        $$contrib{$idx.':senderdomain'});
-    ($$screenname,$$plainname)=($$contrib{$idx.':screenname'},
-				$$contrib{$idx.':plainname'});
+    $$plainname=&Apache::loncommon::nickname(
+                                        $$contrib{$idx.':sendername'},
+                                        $$contrib{$idx.':senderdomain'});
+    $$screenname=$$contrib{$idx.':screenname'};
+
     my $sender=&Apache::loncommon::aboutmewrapper(
                                  $$plainname,
                                  $$contrib{$idx.':sendername'},
@@ -1180,11 +1197,7 @@ sub get_post_contents {
     if ($type eq 'allversions' || $type eq 'export') {
         $start = 0;
         if ($$contrib{$idx.':history'}) {
-            if ($$contrib{$idx.':history'} =~ m/:/) {
-                @postversions = split/:/,$$contrib{$idx.':history'};
-            } else {
-                @postversions = ("$$contrib{$idx.':history'}");
-            }
+	    @postversions = split(/:/,$$contrib{$idx.':history'});
         }
         &get_post_versions($messages,$$contrib{$idx.':message'},1);
         &get_post_versions($subjects,$$contrib{$idx.':subject'},1);
@@ -1205,7 +1218,7 @@ sub get_post_contents {
         my ($timesent,$attachmsg);
         my %currattach = ();
         $timesent = &Apache::lonlocal::locallocaltime($postversions[$i]);
-        $$messages{$i}=~s/\n/\<br \/\>/g;
+	&newline_to_br(\$messages->{$i});
         $$messages{$i}=&Apache::lontexconvert::msgtexconverted($$messages{$i});
         $$subjects{$i}=~s/\n/\<br \/\>/g;
         $$subjects{$i}=&Apache::lontexconvert::msgtexconverted($$subjects{$i});
@@ -1288,10 +1301,9 @@ sub replicate_attachments {
 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']);
+      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss','blog']);
   }
-  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='';
@@ -1375,7 +1387,7 @@ END
                   &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
                   $message = $msgversions{$numoldver};
               }
-	      $message=~s/\n/\<br \/\>/g;
+	      &newline_to_br(\$message);
 	      $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';
               if ($idx > 0) {
                   my %subversions = ();
@@ -1429,15 +1441,8 @@ END
       &process_attachments(\@currnewattach,\@currdelold,\@keepold);
   }
   my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
-  my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();
   my $send=&mt('Send');
-  my $html=&Apache::lonxml::xmlbegin();
-  $r->print(<<END);
-$html
-<head>
-<title>The LearningOnline Network with CAPA</title>
-<meta http-equiv="pragma" content="no-cache"></meta>
-$htmlheader
+  my $js= <<END;
 <script type="text/javascript">
 //<!--
     function gosubmit() {
@@ -1472,6 +1477,11 @@ $htmlheader
              rec=1;
           } 
         }
+        if (typeof(document.mailform.elements.blog)!="undefined") {
+          if (document.mailform.elements.blog.checked) {
+             rec=1;
+          } 
+        }
 
         if (rec) {
             if (typeof(document.mailform.onsubmit)=='function') {
@@ -1486,8 +1496,15 @@ $htmlheader
     $anonscript
 //-->
 </script>
-</head>
-$bodytag
+END
+
+  my $onload = 'onLoad="window.focus();setposttype();"';
+  my $start_page=
+      &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,
+				     {'add_entries' => $onload});
+
+  $r->print(<<END);
+$start_page
 <h2><tt>$title</tt></h2>
 <form action="/adm/feedback" method="post" name="mailform"
 enctype="multipart/form-data">
@@ -1584,7 +1601,8 @@ END
     }
     $r->print(&generate_preview_button().
               &Apache::lonhtmlcommon::htmlareaselectactive('comment').
-              '</body></html>');
+	      &Apache::loncommon::end_page());
+
 }
 
 sub print_display_options {
@@ -1960,11 +1978,7 @@ sub print_showposters {
                           $env{'course.'.$env{'request.course.id'}.'.num'});
     my %namesort = ();
     my %postcounts = ();
-    my %lt=&Apache::lonlocal::texthash(
-                     'diso' => 'Discussion filtering options',
-    );
-    my $bodytag=&Apache::loncommon::bodytag('Discussion options',
-                                          '','');
+
     if ($contrib{'version'}) {
         for (my $idx=1;$idx<=$contrib{'version'};$idx++) {
             my $hidden=($contrib{'hidden'}=~/\.$idx\./);
@@ -1996,14 +2010,11 @@ sub print_showposters {
             }
         }
     }
-    my $html=&Apache::lonxml::xmlbegin();
+
+    my $start_page = &Apache::loncommon::start_page('Discussion options');
+
     $r->print(<<END);
-$html
-<head>
-<title>$lt{'diso'}</title>
-<meta http-equiv="pragma" content="no-cache" />
-</head>
-$bodytag
+$start_page
  <form name="pickpostersform" method="post">
   <table border="0">
    <tr>
@@ -2030,6 +2041,8 @@ END
             }
         }
     }
+
+    my $end_page   = &Apache::loncommon::end_page();
     $r->print(<<END);
      </table>
     </td>
@@ -2040,8 +2053,7 @@ END
 <input type="hidden" name="userpick" value="$symb" />
 <input type="button" name="store" value="Display posts" onClick="javascript:document.pickpostersform.submit()" />
 </form>
-</body>
-</html>
+$end_page
 END
 }
 
@@ -2049,7 +2061,8 @@ sub get_post_versions {
     my ($versions,$incoming,$htmldecode,$numver) = @_;
     if ($incoming =~ /^<version num="0">/) {
         my $p = HTML::LCParser->new(\$incoming);
-        my $done = 0;                                                                       
+        my $done = 0; 
+
         while ( (my $token = $p->get_tag("version")) && (!$done)) {
             my $num = $token->[1]{num};
             my $text = $p->get_text("/version");
@@ -2110,25 +2123,19 @@ sub fail_redirect {
   my ($r,$feedurl) = @_;
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
-  my $html=&Apache::lonxml::xmlbegin();
-  $r->print (<<ENDFAILREDIR);
-$html
-<head>
-<title>Feedback not sent</title>
-<meta http-equiv="pragma" content="no-cache" />
-<meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
-</head>
-<body bgcolor="#FFFFFF">
+  $r->print(&Apache::loncommon::start_page('Feedback not sent',undef,
+					   {'redirect'  => [2,$feedurl],
+					    'only_body' => 1,}));
+  $r->print(<<ENDFAILREDIR);
 <img align="right" src="$logo" />
 <b>Sorry, no recipients  ...</b>
 <br /><a href="$feedurl">Continue</a>
-</body>
-</html>
 ENDFAILREDIR
+  $r->print(&Apache::loncommon::end_page());
 }
 
 sub redirect_back {
-  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$numpicks) = @_;
+  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$blog,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$numpicks) = @_;
   my $sorttag = '';
   my $roletag = '';
   my $statustag = '';
@@ -2198,18 +2205,20 @@ sub redirect_back {
   }
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
-  my $html=&Apache::lonxml::xmlbegin();
-  $r->print (<<ENDREDIR);
-$html
-<head>
-<title>Feedback sent</title>
-<meta http-equiv="pragma" content="no-cache" />
-<meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
-</head>
-<body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
+  my $onload = 'onLoad=\'if (window.name!="loncapaclient") { this.document.reldt.submit(); self.window.close(); }\'';
+  my $start_page=
+      &Apache::loncommon::start_page('New posts marked as read',undef,
+				     {'redirect'    => [2,$feedurl],
+				      'only_body'   => 1,
+				      'add_entries' => $onload});
+  my $end_page = &Apache::loncommon::end_page();
+
+  $r->print(<<ENDREDIR);
+$start_page
 <img align="right" src="$logo" />
 $typestyle
 <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
+$blog
 <font color="red">$status</font>
 <form name="reldt" action="$feedurl" target="loncapaclient">
 $prevtag
@@ -2220,8 +2229,7 @@ $sectag
 $userpicktag
 </form>
 <br /><a href="$feedurl">Continue</a>
-</body>
-</html>
+$end_page
 ENDREDIR
 }
 
@@ -2245,7 +2253,7 @@ ENDNOREDIR
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   $r->print (<<ENDNOREDIRTWO);
 </head>
-<body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>
+<body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.window.close(); }'>
 <img align="right" src="$logo" />
 <b>$nofeed</b>
 <br /><a href="$feedurl">$continue</a>
@@ -2259,7 +2267,7 @@ sub screen_header {
     my $msgoptions='';
     my $discussoptions='';
     unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {
-	if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {
+	if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/) && ($env{'user.adv'})) {
 	    $msgoptions= 
 		'<p><label><input type="checkbox" name="author" /> '.
 		&mt('Feedback to resource author').'</label></p>';
@@ -2292,8 +2300,11 @@ sub screen_header {
 		&mt('Contribution to course discussion of resource');
 	    $discussoptions.='</label><br /><label><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.
 		&mt('Anonymous contribution to course discussion of resource').
-		' <i>('.&mt('name only visible to course faculty').')</i></label>';
+		' <i>('.&mt('name only visible to course faculty').')</i></label> '.
+		'<a href="/adm/preferences?action=changescreenname">'.&mt('Change Screenname').'</a>';
         }
+        $discussoptions.='<br /><label><input type="checkbox" name="blog" /> '.
+	    &mt('Add to my public course blog').'</label>';
     }
     if ($msgoptions) { $msgoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/feedback.gif').'" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }
     if ($discussoptions) { 
@@ -2375,17 +2386,48 @@ sub secapply {
     return '';
 }
 
+=pod 
+
+=over 4
+
+=item *
+
+decide_receiver($feedurl,$author,$question,$course,$policy,$defaultflag);
+
+Arguments
+  $feedurl - /res/ url of resource (only need if $author is true)
+  $author,$question,$course,$policy - all true/false parameters
+    if true will attempt to find the addresses of user that should receive
+    this type of feedback (author - feedback to author of resource $feedurl,
+    $question 'Resource Content Questions', $course 'Course Content Question',
+    $policy 'Course Policy')
+    (Additionally it also checks $env for whether the corresponding form.<name>
+    element exists, for ease of use in a html response context)
+   
+  $defaultflag - (internal should be left blank) if true gather addresses 
+                 that aren't for a section even if I have a section
+                 (used for reccursion internally, first we look for
+                 addresses for our specific section then we recurse
+                 and look for non section addresses)
+
+Returns
+  $typestyle - string of html text, describing what addresses were found
+  %to - a hash, which keys are addresses of users to send messages to
+        the keys will look like   name:domain
+
+=cut
+
 sub decide_receiver {
   my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
   my $typestyle='';
   my %to=();
   if ($env{'form.author'}||$author) {
-    $typestyle.='Submitting as Author Feedback<br>';
+    $typestyle.='Submitting as Author Feedback<br />';
     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
     $to{$2.':'.$1}=1;
   }
   if ($env{'form.question'}||$question) {
-    $typestyle.='Submitting as Question<br>';
+    $typestyle.='Submitting as Question<br />';
     foreach (split(/\,/,
 		   $env{'course.'.$env{'request.course.id'}.'.question.email'})
 	     ) {
@@ -2425,14 +2467,16 @@ sub feedback_available {
 }
 
 sub send_msg {
-  my ($feedurl,$email,$citations,$attachmenturl,%to)=@_;
+  my ($title,$feedurl,$email,$citations,$attachmenturl,%to)=@_;
   my $status='';
   my $sendsomething=0;
+  if ($title=~/^Error/) { $title=&mt('Feedback').': '.$title; }
+  unless ($title=~/\w/) { $title=&mt('Feedback'); }
   foreach (keys %to) {
     if ($_) {
       my $declutter=&Apache::lonnet::declutter($feedurl);
       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),
-               'Feedback ['.$declutter.']',$email,$citations,$feedurl,
+               $title.' ['.$declutter.']',$email,$citations,$feedurl,
                 $attachmenturl)=~/ok/) {
 	$status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';
       } else {
@@ -2486,7 +2530,6 @@ sub adddiscuss {
     }
     if (($symb) && ($email)) {
         if ($env{'form.editdisc'}) {
-            my %newcontrib = ();
             $contrib{'ip'}=$ENV{'REMOTE_ADDR'};
             $contrib{'host'}=$Apache::lonnet::perlvar{'lonHostID'};
             $contrib{'timestamp'} = time;
@@ -2529,12 +2572,8 @@ sub adddiscuss {
                 }
             }
             $contrib{'history'} .= $oldcontrib{$oldidx.':timestamp'};
-            foreach (keys %contrib) {
-                my $key = $oldidx.':'.&Apache::lonnet::escape($oldsymb).':'.$_;                                                                               
-                $newcontrib{$key} = $contrib{$_};
-            }
             my $put_reply = &Apache::lonnet::putstore($env{'request.course.id'},
-                  \%newcontrib,
+                  $oldsymb,$oldidx,\%contrib,
                   $env{'course.'.$env{'request.course.id'}.'.domain'},
                   $env{'course.'.$env{'request.course.id'}.'.num'});
             $status='Editing class discussion'.($anon?' (anonymous)':'');
@@ -2572,7 +2611,7 @@ sub show_preview {
     &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;
     my $message=&clear_out_html($env{'form.comment'});
-    $message=~s/\n/\<br \/\>/g;
+    &newline_to_br(\$message);
     $message=&Apache::lonspeller::markeduptext($message);
     $message=&Apache::lontexconvert::msgtexconverted($message);
     my $subject=&clear_out_html($env{'form.subject'});
@@ -2585,14 +2624,39 @@ sub show_preview {
 	      $message.'</td></tr></table></body></html>');
 }
 
+
+sub newline_to_br {
+    my ($message)=@_;
+    my $newmessage;
+    my $parser=HTML::LCParser->new($message);
+    while (my $token=$parser->get_token()) {
+	if ($token->[0] eq 'T') {
+	    my $text=$token->[1];
+	    $text=~s/\n/\<br \/\>/g;
+	    $newmessage.=$text;
+	} elsif ($token->[0] eq 'D' || $token->[0] eq 'C') {
+	    $newmessage.=$token->[1];
+	} elsif ($token->[0] eq 'PI' || $token->[0] eq 'E') {
+	    $newmessage.=$token->[2];
+	} elsif ($token->[0] eq 'S') {
+	    $newmessage.=$token->[4];
+	}
+	    
+    }
+    $$message=$newmessage;
+}
+
 sub generate_preview_button {
+    my ($formname,$fieldname)=@_;
+    unless ($formname) { $formname='mailform'; }
+    unless ($fieldname) { $fieldname='comment'; }
     my $pre=&mt("Show Preview and Check Spelling");
     return(<<ENDPREVIEW);
 <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
 <input type="hidden" name="subject">
 <input type="hidden" name="comment" />
 <input type="button" value="$pre"
-onClick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=document.mailform.comment.value;this.form.subject.value=document.mailform.subject.value;this.form.submit();" />
+onClick="if (typeof(document.$formname.onsubmit)=='function') {document.$formname.onsubmit();};this.form.comment.value=document.$formname.$fieldname.value;this.form.subject.value=document.$formname.subject.value;this.form.submit();" />
 </form>
 ENDPREVIEW
 }
@@ -2667,6 +2731,7 @@ END
 <input type="hidden" name="numoldver" value="$env{'form.numoldver'}" />
 <input type="hidden" name="origpage" value="$env{'form.origpage'}" />
 <input type="hidden" name="anondiscuss" value="$env{'form.anondiscuss'}" />
+<input type="hidden" name="blog" value="$env{'form.blog'}" />
 <input type="hidden" name="discuss" value="$env{'form.discuss'}" />
 END
     foreach (@{$currnewattach}) {
@@ -2686,28 +2751,15 @@ END
 
 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'};
-        }
-    }
+
+    @{$currnewattach}=
+	&Apache::loncommon::get_env_multiple('form.currnewattach');
+    @{$currdelold}=
+	&Apache::loncommon::get_env_multiple('form.deloldattach');
     if (exists($env{'form.delnewattach'})) {
-        my @currdelnew = ();
+        my @currdelnew =
+	    &Apache::loncommon::get_env_multiple('form.delnewattach');
         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) {
@@ -2722,13 +2774,7 @@ sub process_attachments {
         }
         @{$currnewattach} = @currnew;
     }
-    if (exists($env{'form.keepold'})) {
-        if (ref($env{'form.keepold'}) eq 'ARRAY') {
-            @{$keepold} = @{$env{'form.keepold'}};
-        } else {
-            $$keepold[0] = $env{'form.keepold'};
-        }
-    }
+    @{$keepold} = &Apache::loncommon::get_env_multiple('form.keepold');
 }
 
 sub generate_attachments_button {
@@ -2750,8 +2796,9 @@ this.form.submit();" />
 <input type="hidden" name="timestamp" value="$now" />
 <input type="hidden" name="subject" />
 <input type="hidden" name="comment" />
-<input type="hidden" name="anondiscuss" value = "0";
-<input type="hidden" name="discuss" value = "0";
+<input type="hidden" name="blog" value = "0" />
+<input type="hidden" name="anondiscuss" value = "0" />
+<input type="hidden" name="discuss" value = "0" />
 <input type="hidden" name="numoldver" value="$numoldver" />
 ENDATTACH
     if (defined($deloldattach)) {
@@ -2885,12 +2932,7 @@ sub has_discussion {
     my @allres=$navmap->retrieveResources();
     foreach my $resource (@allres) {
         if ($resource->hasDiscussion()) {
-            my $ressymb;
-            if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) {
-                $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';
-            } else {
-                $ressymb = $resource->symb();
-            }
+            my $ressymb = $resource->wrap_symb();
             push @{$resourcesref}, $ressymb;
         }
     }
@@ -2936,7 +2978,15 @@ sub handler {
 
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
          ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']);
-
+  if ($env{'form.editdisc'}) {
+      if (!(&editing_allowed())) {
+          my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
+          my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
+          my $feedurl=&Apache::lonnet::clutter($url);
+          &redirect_back($r,$feedurl,&mt('Editing not permitted').'<br />',                     '0','0','','',$env{'form.previous'},'','','',);
+          return OK;
+      }
+  } 
   if ($env{'form.discsymb'}) {
       my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.discsymb'});
       my $readkey = $symb.'_read';
@@ -2960,7 +3010,7 @@ sub handler {
 			  \%readinghash,$env{'user.domain'},$env{'user.name'});
       }
       &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'<br />',
-		     '0','0','',$env{'form.previous'},'','','',);
+		     '0','0','','',$env{'form.previous'},'','','',);
       return OK;
   }
   if ($env{'form.allversions'}) {
@@ -3012,14 +3062,14 @@ END
       $discinfo{$symb.'_userpick'} = join('&',@posters);
       &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',
 			   \%discinfo,$env{'user.domain'},$env{'user.name'});
-      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',
+      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',
 		     '',$env{'form.previous'},$env{'form.sortposts'},'','','',
 		     $numpicks);
       return OK;
   }
   if ($env{'form.applysort'}) {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.applysort'});
-      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',
+      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',
 		     '',$env{'form.previous'},$env{'form.sortposts'},
 		     $env{'form.rolefilter'},$env{'form.statusfilter'},
 		     $env{'form.sectionpick'});
@@ -3049,14 +3099,8 @@ END
           'twnp' => 'There are currently no resources or bulletin boards with unread discussion postings.'
       );       
       foreach (@resources) {
-# backward compatibility (bulletin boards used to be 'wrapped')
           my $ressymb=$_;
 	  &Apache::lonenc::check_decrypt(\$ressymb);
-          if ($ressymb =~ m/bulletin___\d+___/) {
-              unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
-                  $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper/|;
-              }
-          }
           my $lastkey = $ressymb.'_lastread';
           $discinfo{$lastkey} = $env{'form.navtime'};
       }
@@ -3070,22 +3114,21 @@ END
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
       my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
-      my $html=&Apache::lonxml::xmlbegin();
+      my $onload = 'onLoad=\'if (window.name!="loncapaclient") { this.document.reldt.submit(); self.window.close(); }\'';
+      my $start_page=
+	  &Apache::loncommon::start_page('New posts marked as read',undef,
+					 {'redirect'    => [2,$feedurl],
+					  'only_body'   => 1,
+					  'add_entries' => $onload});
+      my $end_page = &Apache::loncommon::end_page();
       $r->print (<<ENDREDIR);
-$html
-<head>
-<title>New posts marked as read</title>
-<meta http-equiv="pragma" content="no-cache" />
-<meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
-</head>
-<body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
+$start_page
 <img align="right" src="$logo" />
 $textline
 <form name="reldt" action="$feedurl" target="loncapaclient">
 </form>
 <br /><a href="$feedurl">Continue</a>
-</body>
-</html>
+$end_page
 ENDREDIR
       return OK;
   } elsif ($env{'form.modifydisp'}) {
@@ -3129,7 +3172,7 @@ ENDREDIR
       my $previous=$env{'form.previous'};
       if ($env{'form.markondisp'}) { $previous=undef; }
       &redirect_back($r,$feedurl,&mt('Changed display status').'<br />',
-		     '0','0','',$previous);
+		     '0','0','','',$previous);
       return OK;
   } elsif (($env{'form.hide'}) || ($env{'form.unhide'})) {
 # ----------------------------------------------------------------- Hide/unhide
@@ -3137,6 +3180,18 @@ ENDREDIR
       my ($symb,$idx)=split(/\:\:\:/,$entry);
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
 
+      my $crs='/'.$env{'request.course.id'};
+      if ($env{'request.course.sec'}) {
+          $crs.='_'.$env{'request.course.sec'};
+      }
+      $crs=~s/\_/\//g;
+      my $seeid=&Apache::lonnet::allowed('rin',$crs);
+
+      if ($env{'form.hide'} && !$seeid && !(&editing_allowed())) {
+          &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',                 '0','0','','',$env{'form.previous'},'','','',);
+          return OK;
+      }
+
       my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                           $env{'course.'.$env{'request.course.id'}.'.domain'},
 		          $env{'course.'.$env{'request.course.id'}.'.num'});
@@ -3144,13 +3199,6 @@ ENDREDIR
       my $currenthidden=$contrib{'hidden'};
       my $currentstudenthidden=$contrib{'studenthidden'};
 
-      my $crs='/'.$env{'request.course.id'};
-      if ($env{'request.course.sec'}) {
-	  $crs.='_'.$env{'request.course.sec'};
-      }
-      $crs=~s/\_/\//g;
-      my $seeid=&Apache::lonnet::allowed('rin',$crs);
-
       if ($env{'form.hide'}) {
 	  $currenthidden.='.'.$idx.'.';
 	  unless ($seeid) {
@@ -3169,7 +3217,7 @@ ENDREDIR
 			   $env{'course.'.$env{'request.course.id'}.'.num'});
 
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
-		     '0','0','',$env{'form.previous'});
+		     '0','0','','',$env{'form.previous'});
       return OK;
   } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
@@ -3181,7 +3229,7 @@ ENDREDIR
 	  &Apache::lonnet::delenv('environment\.threadeddiscussion');
       }
       &redirect_back($r,$feedurl,&mt('Changed discussion view mode').'<br />',
-		     '0','0','',$env{'form.previous'});
+		     '0','0','','',$env{'form.previous'});
       return OK;
   } elsif ($env{'form.deldisc'}) {
 # --------------------------------------------------------------- Hide for good
@@ -3195,7 +3243,7 @@ ENDREDIR
 			   $env{'course.'.$env{'request.course.id'}.'.domain'},
 			   $env{'course.'.$env{'request.course.id'}.'.num'});
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
-		     '0','0','',$env{'form.previous'});
+		     '0','0','','',$env{'form.previous'});
       return OK;
   } elsif ($env{'form.preview'}) {
 # -------------------------------------------------------- User wants a preview
@@ -3205,7 +3253,7 @@ ENDREDIR
 # -------------------------------------------------------- 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']);
+      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','addnewattach','delnewattach','timestamp','numoldver','idx','anondiscuss','discuss','blog']);
       my (@currnewattach,@currdelold,@keepold);
       &process_attachments(\@currnewattach,\@currdelold,\@keepold);
       if (exists($env{'form.addnewattach.filename'})) {
@@ -3234,7 +3282,7 @@ ENDREDIR
       my $mode='board';
       my $status='OPEN';
       my $previous=$env{'form.previous'};
-      if ($feedurl =~ /\.(problem|exam|quiz|assess|survey|form|library)$/) {
+      if ($feedurl =~ /\.(problem|exam|quiz|assess|survey|form|library|task)$/) {
           $mode='problem';
           $status=$Apache::inputtags::status[-1];
       }
@@ -3273,13 +3321,11 @@ ENDREDIR
       }
       &Apache::lonenc::check_decrypt(\$symb);
       my $goahead=1;
-      if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {
+      if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {
 	  unless ($symb) { $goahead=0; }
       }
       # backward compatibility (bulletin boards used to be 'wrapped')
-      if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
-	  $feedurl=~s|^/adm/wrapper||;
-      }
+      &dewrapper(\$feedurl);
       if (!$goahead) {
           # Ambiguous Problem Resource
 	  $r->internal_redirect('/adm/ambiguous');
@@ -3299,6 +3345,7 @@ ENDREDIR
 	  $r->send_http_header;
 # Unable to give feedback
 	  &no_redirect_back($r,$feedurl);
+	  return OK;
       }
 # --------------------------------------------------- Print login screen header
       unless ($env{'form.sendit'}) {
@@ -3362,7 +3409,7 @@ ENDREDIR
       my ($typestyle,%to) = &decide_receiver($feedurl);
 
 # Actually send mail
-      my ($status,$numsent)=&send_msg($feedurl,$email,$citations,
+      my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'}),$feedurl,$email,$citations,
 				      $attachmenturl,%to);
 
 # Discussion? Store that.
@@ -3375,9 +3422,21 @@ ENDREDIR
 				  $subject);
 	  $numpost++;
       }
+
+# Add to blog?
+
+      my $blog='';
+      if ($env{'form.blog'}) {
+	  my $subject = &clear_out_html($env{'form.subject'});
+	  $status.=&Apache::lonrss::addentry($env{'user.name'},
+				    $env{'user.domain'},
+				    'CourseBlog_'.$env{'request.course.id'},
+				    $subject,$message,$feedurl,'public');
+	  $blog='<br />'.&mt('Added to my course blog').'<br />';
+      }
 	  
 # Receipt screen and redirect back to where came from
-      &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$env{'form.previous'});
+      &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$blog,$status,$env{'form.previous'});
   }
   return OK;
 } 
@@ -3416,5 +3475,34 @@ sub get_feedurl_and_clean_symb {
     my $feedurl = &get_feedurl($symb);
     return ($symb,$feedurl);
 }
+
+sub editing_allowed {
+    my $can_edit = 0;
+    my $cid = $env{'request.course.id'};
+    my $role = (split(/\./,$env{'request.role'}))[0];
+    my $section = $env{'request.course.sec'};
+    my $allow_editing_config = 
+	$env{'course.'.$cid.'.allow_discussion_post_editing'};
+    if ($allow_editing_config =~ m/^\s*yes\s*$/i) {
+        $can_edit = 1;
+    } else {
+	foreach my $editor (split(/,/,$allow_editing_config)) {
+	    my ($editor_role,$editor_sec) = split(/:/,$editor);
+	    if ($editor_role eq $role
+		&& defined($editor_sec)
+		&& defined($section)
+		&& $editor_sec eq $section) {
+		$can_edit = 1;
+		last;
+	    }
+	    if ($editor_role eq $role
+		&& !defined($editor_sec)) {
+		$can_edit = 1;
+	    }
+	}
+    }
+    return $can_edit;
+}
+
 1;
 __END__