Diff for /loncom/interface/lonfeedback.pm between versions 1.290.2.7.2.6 and 1.291

version 1.290.2.7.2.6, 2012/06/17 15:35:15 version 1.291, 2010/03/10 21:25:50
Line 49  use LONCAPA; Line 49  use LONCAPA;
   
 sub discussion_open {  sub discussion_open {
     my ($status,$symb)=@_;      my ($status,$symb)=@_;
 # Advanced roles can always discuss  
     if ($env{'request.role.adv'}) { return 1; }      if ($env{'request.role.adv'}) { return 1; }
 # Get discussion closing date  
     my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb);  
 # If it is defined and in the future, the instructor wants this discussion to be open  
     if (defined($close) && $close ne '' && $close > time) {  
         return 1;  
     }  
 # It was not explicitly open, check if the problem is available.  
 # If the problem is not available, close the discussion  
     if (defined($status) &&      if (defined($status) &&
         !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'   !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
           || $status eq 'OPEN')) {    || $status eq 'OPEN')) {
         return 0;   return 0;
     }      }
 # The problem is available, but check if the instructor explictly closed discussion      my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb);
     if (defined($close) && $close ne '' && $close < time) {      if (defined($close) && $close ne '' && $close < time) {
         return 0;   return 0;
     }      }
     return 1;      return 1;
 }  }
Line 82  sub discussion_visible { Line 73  sub discussion_visible {
     return 1;      return 1;
 }  }
   
 sub discussion_vote_available {  
     my ($status,$symb)=@_;  
     my $canvote=&Apache::lonnet::EXT('resource.0.discussvote',$symb);  
     if ((lc($canvote) eq 'yes') ||  
         ((lc($canvote) eq 'notended') && (&discussion_open($status,$symb)))) {  
         return 1;  
     }  
 }  
   
 sub get_realsymb {  
     my ($symb) = @_;  
     my $realsymb = $symb;  
     if ($symb=~/^bulletin___/) {  
         my $filename=(&Apache::lonnet::decode_symb($symb))[2];  
         $filename=~s{^adm/wrapper/}{};  
         $realsymb=&Apache::lonnet::symbread($filename);  
     }  
     return $realsymb;  
 }  
   
 sub list_discussion {  sub list_discussion {
     my ($mode,$status,$ressymb,$imsextras,$group)=@_;      my ($mode,$status,$ressymb,$imsextras,$group)=@_;
     unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }      unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }
Line 277  sub list_discussion { Line 248  sub list_discussion {
     $visit ++;      $visit ++;
   
     my $seeid;      my $seeid;
     if (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {      if (($group ne '') && ($mode eq 'board') && 
         $seeid = 1;          ($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {
           if (&check_group_priv($group,'dgp') eq 'ok') {
               $seeid = 1;
           }
       } else {
           $seeid=&Apache::lonnet::allowed('rin',$crs);
     }      }
     my $seehidden = &can_see_hidden($mode,$ressymb,undef,$group,$cdom,$cnum,$crs);  
 # Is voting on discussions available  
     my $realsymb = &get_realsymb($ressymb);  
     my $canvote = &discussion_vote_available($status,$realsymb);  
   
     my @discussionitems=();      my @discussionitems=();
     my %shown = ();      my %shown = ();
     my @posteridentity=();      my @posteridentity=();
Line 302  sub list_discussion { Line 273  sub list_discussion {
     my %anonhash=();      my %anonhash=();
     my $anoncnt=0;      my $anoncnt=0;
     my $target='';      my $target='';
     unless ($env{'browser.interface'} eq 'textual' ||  
     $env{'environment.remote'} eq 'off' ) {  
  $target='target="LONcom"';  
     }  
   
     my $now = time;      my $now = time;
     $discinfo{$visitkey} = $visit;      $discinfo{$visitkey} = $visit;
   
     &Apache::lonnet::put('nohist_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});      &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,$seehidden,$canvote,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);      &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,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);
   
     my $discussion='';      my $discussion='';
     my $manifestfile;      my $manifestfile;
Line 346  sub list_discussion { Line 313  sub list_discussion {
         'dpwn' => 'Deleted posts will no longer be visible to you and other students',          'dpwn' => 'Deleted posts will no longer be visible to you and other students',
         'bwco' => 'but will continue to be visible to your instructor',          'bwco' => 'but will continue to be visible to your instructor',
         'depo' => 'Deleted posts will no longer be visible to you or anyone else.',          'depo' => 'Deleted posts will no longer be visible to you or anyone else.',
         'discussions' => 'DISCUSSIONS'  
     );      );
   
     my $currdisp = $lt{'allposts'};      my $currdisp = $lt{'allposts'};
Line 398  sub list_discussion { Line 364  sub list_discussion {
 # Print the discusssion  # Print the discusssion
         if ($outputtarget eq 'tex') {          if ($outputtarget eq 'tex') {
             $discussion.='<tex>{\tiny \vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.              $discussion.='<tex>{\tiny \vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.
                          '\textbf{'.$lt{'discussions'}.'}\makebox[2 cm][b]{\hrulefill}\vskip 0 mm'.                           '\textbf{DISCUSSIONS}\makebox[2 cm][b]{\hrulefill}'.
                            '\vskip 0 mm\noindent\textbf{'.$lt{'cuse'}.'}:\vskip 0 mm'.
                          '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'.                           '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'.
                          '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}}</tex>';                           '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}}</tex>';
         } elsif ($outputtarget eq 'export') {          } elsif ($outputtarget eq 'export') {
Line 470  imscp_v1p1.xsd http://www.imsglobal.org/ Line 437  imscp_v1p1.xsd http://www.imsglobal.org/
                          "\n".'<table class="LC_discussion">';                           "\n".'<table class="LC_discussion">';
             $discussion .= &action_links_bar($colspan,$ressymb,$visible,              $discussion .= &action_links_bar($colspan,$ressymb,$visible,
                                              $newpostsflag,$group,                                               $newpostsflag,$group,
                                              $prevread,$markondisp,$seehidden);                                               $prevread,$markondisp);
             my $escsymb=&escape($ressymb);              my $escsymb=&escape($ressymb);
             my $numhidden = keys(%notshown);              my $numhidden = keys(%notshown);
             if ($numhidden > 0) {              if ($numhidden > 0) {
Line 543  imscp_v1p1.xsd http://www.imsglobal.org/ Line 510  imscp_v1p1.xsd http://www.imsglobal.org/
  $threadinsert='<br /><strong>Reply: '.$thisdepth.'</strong>';   $threadinsert='<br /><strong>Reply: '.$thisdepth.'</strong>';
     }      }
     $discussionitems[$alldiscussion{$post}]=~s/<\/td><td([^>]*)>/$threadinsert<\/td><td TeXwidth="65 mm" align="left">/;      $discussionitems[$alldiscussion{$post}]=~s/<\/td><td([^>]*)>/$threadinsert<\/td><td TeXwidth="65 mm" align="left">/;
       $discussionitems[$alldiscussion{$post}]=~s/<a([^>]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g;
                     $discussionitems[$alldiscussion{$post}]=~s/(<b>|<\/b>|<\/a>|<a([^>]+)>)//g;                      $discussionitems[$alldiscussion{$post}]=~s/(<b>|<\/b>|<\/a>|<a([^>]+)>)//g;
   
     $discussionitems[$alldiscussion{$post}]='<tex>\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}</tex>'.$discussionitems[$alldiscussion{$post}];      $discussionitems[$alldiscussion{$post}]='<tex>\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}</tex>'.$discussionitems[$alldiscussion{$post}];
Line 684  END Line 652  END
 END  END
             $discussion .= &action_links_bar($colspan,$ressymb,$visible,              $discussion .= &action_links_bar($colspan,$ressymb,$visible,
                                              $newpostsflag,$group,                                               $newpostsflag,$group,
                                              $prevread,$markondisp,$seehidden);                                               $prevread,$markondisp);
             $discussion .= "              $discussion .= "
            </table>             </table>
            <br /><br /></form>\n";             <br /><br /></form>\n";
Line 747  END Line 715  END
                 $attachnum += @{$currnewattach};                  $attachnum += @{$currnewattach};
             }              }
         }          }
  if ((&discussion_open($status)) && ($outputtarget ne 'tex')) {   if (&discussion_open($status)) {
             if (($group ne '') && ($mode eq 'board')) {              if (($group ne '') && ($mode eq 'board')) {  
                 if ((&check_group_priv($group,'pgd') eq 'ok') &&                  if (&check_group_priv($group,'pgd') eq 'ok') {
                    ($ressymb =~ m{^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$})) {  
                     $discussion .=                      $discussion .=
  &postingform_display($mode,$ressymb,$now,$subject,   &postingform_display($mode,$ressymb,$now,$subject,
      $comment,$outputtarget,$attachnum,       $comment,$outputtarget,$attachnum,
Line 758  END Line 725  END
      $group,$crstype);       $group,$crstype);
                 }                  }
             } else {              } else {
                 if (&Apache::lonnet::allowed('pch',$env{'request.course.id'}.          $discussion.= 
                     ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {      &postingform_display($mode,$ressymb,$now,$subject,
    $comment,$outputtarget,$attachnum,
                     $discussion.=   $currnewattach,$currdelold,'',$crstype);
                         &postingform_display($mode,$ressymb,$now,$subject,  
                                              $comment,$outputtarget,$attachnum,  
                                              $currnewattach,$currdelold,'',$crstype);  
                 } else {  
                     $discussion.= '<span class="LC_feedback_link">'.  
                                   &mt('This discussion is closed.').'</span>';  
                 }  
             }              }
  }   }
         if (!(&discussion_open($status)) && ($outputtarget ne 'tex')) {      } else {
             $discussion.= '<span class="LC_feedback_link">'.  
                           &mt('This discussion is closed.').'</span>';  
         }  
     } elsif ($outputtarget ne 'tex') {  
         $discussion.='<div class="LC_feedback_link">';          $discussion.='<div class="LC_feedback_link">';
         if (&discussion_open($status) &&          if (&discussion_open($status) &&
             &Apache::lonnet::allowed('pch',              &Apache::lonnet::allowed('pch',
            $env{'request.course.id'}.             $env{'request.course.id'}.
         ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {          ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
     $discussion.= &send_feedback_link($ressymb,$target);      if ($outputtarget ne 'tex') {
             if ($env{'request.role.adv'}) {   $discussion.= &send_feedback_link($ressymb,$target);
                 my $close = &Apache::lonnet::EXT('resource.0.discussend',$ressymb);  
                 my $canvote = &Apache::lonnet::EXT('resource.0.discussvote',$ressymb);  
                 if (defined($close) && $close ne '' && $close < time) {  
                     if ($canvote eq 'notended') {  
                         $discussion .= '&nbsp;'.&mt('(Posting and voting closed for [_1] roles)',  
                                                     &Apache::lonnet::plaintext('st',$crstype));   
                     } else {  
                         $discussion .= '&nbsp;'.&mt('(Closed for [_1] roles)',  
                                                     &Apache::lonnet::plaintext('st',$crstype));  
                     }  
                 }  
             }              }
         } else {   }
             $discussion.= '<span class="LC_feedback_link">'.&mt('This discussion is closed.').'</span>';          if ($outputtarget ne 'tex') {
       $discussion.= &send_message_link($ressymb);
         }          }
  $discussion.= &send_message_link($ressymb).'</div>';          $discussion.='</div>';
     }      }
     return $discussion;      return $discussion;
 }  }
   
 sub can_see_hidden {  
     my ($mode,$ressymb,$feedurl,$group,$cdom,$cnum,$crs) = @_;  
     my $seehidden;  
     if ($env{'request.course.id'}) {  
         unless ($cdom ne '' && $cnum ne '') {  
             $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
             $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
         }  
         if ($crs eq '') {  
             $crs = '/'.$env{'request.course.id'};  
             if ($env{'request.course.sec'}) {  
                 $crs.='_'.$env{'request.course.sec'};  
             }  
             $crs=~s{_}{/}g;  
         }  
         if ($mode eq '') {  
             $mode='board';  
             if ($feedurl =~ /$LONCAPA::assess_re/) {  
                 $mode='problem';  
             }  
         }  
         if (($group ne '') && ($mode eq 'board') &&  
             ($ressymb =~ m{^bulletin___\d+\Q___adm/wrapper/adm/$cdom/$cnum/\E\d+/bulletinboard$})) {  
             if (&check_group_priv($group,'dgp') eq 'ok') {  
                 $seehidden = 1;  
             }  
         } else {  
             $seehidden=&Apache::lonnet::allowed('rin',$crs);  
         }  
     }  
     return $seehidden;  
 }  
   
 sub discussion_link {  
     my ($ressymb,$linktext,$cmd,$item,$flag,$prev,$adds,$title) = @_;  
     my $link = '<a href="/adm/feedback?'.$cmd.'='.&escape($ressymb).':::'.$item;  
     if ($flag) { $link .= '&amp;previous='.$prev; }  
     if ($adds) { $link .= $adds; }  
     $link .= '"';  
     if ($title) { $link .= ' title="'.$title.'"'; }  
     $link .= '>'.$linktext.'</a>';  
     return $link;  
 }  
   
 sub send_feedback_link {  sub send_feedback_link {
     my ($ressymb,$target) = @_;      my ($ressymb,$target) = @_;
     my $output = '<span class="LC_feedback_link">'.      my $output = '<span class="LC_feedback_link">'.
Line 863  sub send_message_link { Line 765  sub send_message_link {
     my $output = '<span class="LC_message_link">'.      my $output = '<span class="LC_message_link">'.
                  '  <a href="/adm/feedback?sendmessageonly=1&amp;symb='.                   '  <a href="/adm/feedback?sendmessageonly=1&amp;symb='.
                  &escape($ressymb).'"><img alt="" class="LC_noBorder" src="'.                   &escape($ressymb).'"><img alt="" class="LC_noBorder" src="'.
                  &Apache::loncommon::lonhttpdurl('/res/adm/pages/feedback.png').                   &Apache::loncommon::lonhttpdurl('/res/adm/pages/com.png').
                  '" border="0" /><span class="LC_menubuttons_inline_text">'.&mt('Send Feedback').'</span></a></span>';                   '" border="0" /><span class="LC_menubuttons_inline_text">'.&mt('Send Feedback').'</span></a></span>';
     return $output;      return $output;
 }  }
   
 sub action_links_bar {  sub action_links_bar {
     my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp,      my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp) = @_;
         $seehidden) = @_;  
     my $discussion = '<tr><td class="LC_disc_action_links_bar" colspan="'.$colspan.'">'.      my $discussion = '<tr><td class="LC_disc_action_links_bar" colspan="'.$colspan.'">'.
                      '<table width="100%" class="LC_disc_action_table"><tr>'.                       '<table width="100%" class="LC_disc_action_table"><tr>'.
                      '<td class="LC_disc_action_left">';                       '<td class="LC_disc_action_left">';
     my $escsymb=&escape($ressymb);      my $escsymb=&escape($ressymb);
     if ($visible) {      if ($visible>2) {
         $discussion .= '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$escsymb;          $discussion .= '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$escsymb;
         if ($newpostsflag) {          if ($newpostsflag) {
             $discussion .= '&amp;previous='.$prevread;              $discussion .= '&amp;previous='.$prevread;
Line 900  sub action_links_bar { Line 801  sub action_links_bar {
         $discussion .= '&amp;previous='.$prevread;          $discussion .= '&amp;previous='.$prevread;
     }      }
     $discussion .= &group_args($group);      $discussion .= &group_args($group);
     $discussion .= '">'.&mt('Export').'</a>';      $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';
     if ($seehidden) {  
         $discussion .= '&nbsp;&nbsp;';  
         $discussion .='<a href="/adm/feedback?undeleteall='.$escsymb;  
         if ($newpostsflag) {  
             $discussion .= '&amp;previous='.$prevread;  
         }  
         $discussion .= &group_args($group);  
         $discussion .= '">'.&mt('Undelete all deleted entries').'</a>';  
     }  
     $discussion.='</td>';  
     if ($newpostsflag) {      if ($newpostsflag) {
         if (!$markondisp) {          if (!$markondisp) {
             $discussion .='<td class="LC_disc_action_right"><a href="/adm/preferences?action=changediscussions';              $discussion .='<td class="LC_disc_action_right"><a href="/adm/preferences?action=changediscussions';
Line 944  sub postingform_display { Line 835  sub postingform_display {
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $lt{'note'} = &mt('Note: in anonymous discussion, your name is visible only to community facilitators');          $lt{'note'} = &mt('Note: in anonymous discussion, your name is visible only to community facilitators');
     }      }
     my ($postingform,$textareaclass);      my $postingform = (<<ENDDISCUSS);
     if (&Apache::lonhtmlcommon::htmlareabrowser()) {  
         $postingform = &Apache::lonhtmlcommon::htmlareaselectactive();  
         $textareaclass = 'class="LC_richDefaultOff"';  
         if ($env{'request.course.id'}) {  
             unless (($env{'course.'.$env{'request.course.id'}.'.allow_limited_html_in_feedback'} =~ /^\s*yes\s*$/i) || ($env{'form.sendmessageonly'})) {  
                 undef($textareaclass);  
             }  
         }  
     }  
     $postingform .= (<<ENDDISCUSS);  
 <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data"> <input type="submit" name="discuss" value="$lt{'podi'}" />  <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data"> <input type="submit" name="discuss" value="$lt{'podi'}" />
 <input type="submit" name="anondiscuss" value="$lt{'poan'}" /> <input type="hidden" name="symb" value="$ressymb" />  <input type="submit" name="anondiscuss" value="$lt{'poan'}" /> <input type="hidden" name="symb" value="$ressymb" />
 <input type="hidden" name="sendit" value="true" />  <input type="hidden" name="sendit" value="true" />
Line 962  sub postingform_display { Line 843  sub postingform_display {
 <br /><a name="newpost"></a>  <br /><a name="newpost"></a>
 <font size="1">$lt{'note'}</font><br />  <font size="1">$lt{'note'}</font><br />
 <b>$lt{'title'}:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />  <b>$lt{'title'}:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />
 <textarea name="comment" cols="80" rows="14" id="comment" $textareaclass>$comment</textarea>  <textarea name="comment" cols="80" rows="14" >$comment</textarea>
 ENDDISCUSS  ENDDISCUSS
     if ($env{'form.origpage'}) {      if ($env{'form.origpage'}) {
         $postingform .= '<input type="hidden" name="origpage" value="'.          $postingform .= '<input type="hidden" name="origpage" value="'.
Line 984  ENDDISCUSS Line 865  ENDDISCUSS
         $postingform .= &add_blog_checkbox($crstype);          $postingform .= &add_blog_checkbox($crstype);
     }      }
     $postingform .= "</form>\n";      $postingform .= "</form>\n";
     $postingform .= &generate_attachments_button('',$attachnum,$ressymb,      if ($outputtarget ne 'tex') {
                                                  $now,$currnewattach,          $postingform .= &generate_attachments_button('',$attachnum,$ressymb,
                                                  $currdelold,'',$mode,                                                       $now,$currnewattach,
                                                  $blockblog);                                                       $currdelold,'',$mode,
     if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {                                                       $blockblog);
         $newattachmsg = '<br /><b>'.$lt{'newa'}.'</b><br />';          if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
         if (@{$currnewattach} > 1) {              $newattachmsg = '<br /><b>'.$lt{'newa'}.'</b><br />';
             $newattachmsg .= '<ol>';              if (@{$currnewattach} > 1) {
             foreach my $item (@{$currnewattach}) {                  $newattachmsg .= '<ol>';
                 $item =~ m#.*/([^/]+)$#;                  foreach my $item (@{$currnewattach}) {
                 $newattachmsg .= '<li><a href="'.$item.'">'.$1.'</a></li>'."\n";                      $item =~ m#.*/([^/]+)$#;
                       $newattachmsg .= '<li><a href="'.$item.'">'.$1.'</a></li>'."\n";
                   }
                   $newattachmsg .= '</ol>'."\n";
               } else {
                   $$currnewattach[0] =~ m#.*/([^/]+)$#;
                   $newattachmsg .= '<a href="'.$$currnewattach[0].'">'.$1.'</a><br />'."\n";
             }              }
             $newattachmsg .= '</ol>'."\n";  
         } else {  
             $$currnewattach[0] =~ m#.*/([^/]+)$#;  
             $newattachmsg .= '<a href="'.$$currnewattach[0].'">'.$1.'</a><br />'."\n";  
         }          }
           $postingform .= $newattachmsg;
           $postingform .= &generate_preview_button();
     }      }
     $postingform .= $newattachmsg;  
     $postingform .= &generate_preview_button();  
     return $postingform;      return $postingform;
 }  }
   
 sub build_posting_display {  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,$seehidden,$canvote,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;      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,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;
     my @original=();      my @original=();
     my @index=();      my @index=();
     my $skip_group_check = 0;      my $skip_group_check = 0;
     my $symb=&Apache::lonenc::check_decrypt($ressymb);      my $symb=&Apache::lonenc::check_decrypt($ressymb);
     my $escsymb=&escape($ressymb);      my $escsymb=&escape($ressymb);
 # These are the discussion contributions  
     my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},      my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
   $env{'course.'.$env{'request.course.id'}.'.domain'},    $env{'course.'.$env{'request.course.id'}.'.domain'},
   $env{'course.'.$env{'request.course.id'}.'.num'});    $env{'course.'.$env{'request.course.id'}.'.num'});
     my (%likes,%userlikes,%userunlikes,@theselikes,$oneplus,$twoplus,$oneminus,$twominus);  
 # And these are the likes/unlikes  
     my $thisuser=$env{'user.name'}.':'.$env{'user.domain'};  
     if ($seeid || $canvote) {  
         %likes=&Apache::lonnet::dump('disclikes',  
                           $env{'course.'.$env{'request.course.id'}.'.domain'},  
                           $env{'course.'.$env{'request.course.id'}.'.num'},  
                           '^'.$symb.':');  
 # Array with likes to figure out averages, etc.  
         @theselikes=();  
 # Hashes containing likes and unlikes for this user.  
         %userlikes=();  
         %userunlikes=();  
     }  
 # Is the user allowed to see the real name behind anonymous postings?  
     my $see_anonymous =       my $see_anonymous = 
  &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));   &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
   
     if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {      if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {
         $skip_group_check = 1;          $skip_group_check = 1;
     }      }
     my (%deletions,%hiddens);  
     if ($contrib{'deleted'}) {  
        my $deleted = $contrib{'deleted'};  
        $deleted =~ s/^\.//;  
        $deleted =~ s/\.$//;  
        %deletions = map { $_ => 1 } (split(/\.\./,$deleted));  
     }  
     if ($contrib{'hidden'}) {  
        my $hidden = $contrib{'hidden'};  
        $hidden =~ s/^\.//;  
        $hidden =~ s/\.$//;  
        %hiddens = map { $_ => 1 } (split(/\.\./,$hidden));  
     }  
     if ($contrib{'version'}) {      if ($contrib{'version'}) {
         my $oldest = $contrib{'1:timestamp'};          my $oldest = $contrib{'1:timestamp'};
         if ($prevread eq '0') {          if ($prevread eq '0') {
Line 1062  sub build_posting_display { Line 917  sub build_posting_display {
             ($skiptest,$roleregexp,$secregexp,$statusregexp) =               ($skiptest,$roleregexp,$secregexp,$statusregexp) = 
                      &filter_regexp($rolefilter,$sectionpick,$statusfilter);                       &filter_regexp($rolefilter,$sectionpick,$statusfilter);
             $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;              $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;
         }          } 
         if ($seeid || $canvote) {  
 # We need to go through this twice, first to get the likes/dislikes, then to actually build the display  
             for (my $id=1;$id<=$contrib{'version'};$id++) {  
                 my $idx=$id;  
                 next if ($contrib{$idx.':deleted'});  
                 next if ($contrib{$idx.':hidden'});  
                 unless ((($hiddens{$idx}) && (!$seehidden)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) {  
                     push(@theselikes,$likes{$symb.':'.$idx.':likes'});  
                     if ($likes{$symb.':'.$idx.':likes'} ne '') {  
                         if (ref($likes{$symb.':'.$idx.':likers'}) eq 'HASH') {  
                             if (exists($likes{$symb.':'.$idx.':likers'}{$thisuser})) {  
                                 $userlikes{$idx} = 1;  
                             }  
                         }  
                         if (ref($likes{$symb.':'.$idx.':unlikers'}) eq 'HASH') {  
                             if (exists($likes{$symb.':'.$idx.':unlikers'}{$thisuser})) {  
                                 $userunlikes{$idx} = 1;  
                             }  
                         }  
                     }  
                 }  
             }  
 # Figure out average likes and standard deviation if there are enough   
 # discussions to warrant that  
             my $ave=0;  
             my $stddev=10000;  
             if ($#theselikes>1) {  
                 my $sum=0;  
                 my $num=$#theselikes+1;  
                 foreach my $thislike (@theselikes) {  
                     $sum+=$thislike;  
                 }  
                 $ave=$sum/$num;  
                 my $sumsq=0;  
                 foreach my $thislike (@theselikes) {  
                    $sumsq+=($thislike-$ave)*($thislike-$ave);  
                 }  
                 $stddev=sqrt($sumsq/$num);  
             }  
 # Now we know the average likes $ave and the standard deviation $stddev  
 # Get the boundaries for markup  
             $oneplus=$ave+$stddev;  
             $twoplus=$ave+2.*$stddev;  
             $oneminus=$ave-$stddev;  
             $twominus=$ave-2.*$stddev;  
         }  
 #  
 # This is now the real loop. Go through all entries, pick up what we need  
 #  
  for (my $id=1;$id<=$contrib{'version'};$id++) {   for (my $id=1;$id<=$contrib{'version'};$id++) {
     my $idx=$id;      my $idx=$id;
             next if ($contrib{$idx.':deleted'});  
             next if ($contrib{$idx.':hidden'});  
             my $posttime = $contrib{$idx.':timestamp'};              my $posttime = $contrib{$idx.':timestamp'};
             if ($prevread <= $posttime) {              if ($prevread <= $posttime) {
                 $$newpostsflag = 1;                  $$newpostsflag = 1;
             }              }
       my $hidden=($contrib{'hidden'}=~/\.$idx\./);
             my $studenthidden=($contrib{'studenthidden'}=~/\.$idx\./);              my $studenthidden=($contrib{'studenthidden'}=~/\.$idx\./);
       my $deleted=($contrib{'deleted'}=~/\.$idx\./);
     my $origindex='0.';      my $origindex='0.';
             my $numoldver=0;              my $numoldver=0;
     if ($contrib{$idx.':replyto'}) {      if ($contrib{$idx.':replyto'}) {
Line 1144  sub build_posting_display { Line 950  sub build_posting_display {
     } else {      } else {
  $$replies[$$depth[$idx]]=1;   $$replies[$$depth[$idx]]=1;
     }      }
             unless ((($hiddens{$idx}) && (!$seehidden)) || ($deletions{$idx})) {      unless ((($hidden) && (!$seeid)) || ($deleted)) {
  $$visible++;   $$visible++;
                 if ($contrib{$idx.':history'}) {                  if ($contrib{$idx.':history'}) {
                     if ($contrib{$idx.':history'} =~ /:/) {                      if ($contrib{$idx.':history'} =~ /:/) {
Line 1159  sub build_posting_display { Line 965  sub build_posting_display {
                 my %subjects = ();                  my %subjects = ();
                 my %attachtxt = ();                  my %attachtxt = ();
                 my %allattachments = ();                  my %allattachments = ();
                 my ($screenname,$plainname,$showaboutme);                  my ($screenname,$plainname);
                 my $sender = &mt('Anonymous');                  my $sender = &mt('Anonymous');
 # Anonymous users getting number within a discussion  # Anonymous users getting number within a discussion
 # Since idx is in static order, this should give the same sequence every time.   # Since idx is in static order, this should give the same sequence every time. 
Line 1169  sub build_posting_display { Line 975  sub build_posting_display {
     $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;      $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;
  }   }
                 my ($message,$subject,$vgrlink,$ctlink);                  my ($message,$subject,$vgrlink,$ctlink);
                 &get_post_contents(\%contrib,$idx,$seeid,$seehidden,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,\$showaboutme,$numoldver);                  &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver);
   
   
 # Set up for sorting by subject  # Set up for sorting by subject
Line 1178  sub build_posting_display { Line 984  sub build_posting_display {
                     $message.=$attachtxt{$numoldver};                      $message.=$attachtxt{$numoldver};
                     $subject=$subjects{$numoldver};                      $subject=$subjects{$numoldver};
                     if ($message) {                      if ($message) {
           if ($hiddens{$idx}) {            if ($hidden) {
     $message='<font color="#888888">'.$message.'</font>';      $message='<font color="#888888">'.$message.'</font>';
                             if ($studenthidden) {                              if ($studenthidden) {
                                 $message .='<br /><br />Deleted by poster (student).';                                  $message .='<br /><br />Deleted by poster (student).';
Line 1199  sub build_posting_display { Line 1005  sub build_posting_display {
                             }                              }
                         }                          }
         if (!$contrib{$idx.':anonymous'} || $see_anonymous) {          if (!$contrib{$idx.':anonymous'} || $see_anonymous) {
                             if ($showaboutme) {      $sender=&Apache::loncommon::aboutmewrapper(
                                 $sender = &Apache::loncommon::aboutmewrapper(   $plainname,
                                               $plainname,   $contrib{$idx.':sendername'},
                                               $contrib{$idx.':sendername'},   $contrib{$idx.':senderdomain'}).' ('.
                                               $contrib{$idx.':senderdomain'});   $contrib{$idx.':sendername'}.':'.
                             } else {   $contrib{$idx.':senderdomain'}.')';
                                 $sender = $plainname;  
                             }  
                             if ($see_anonymous) {  
                                 $sender .= ' ('.$contrib{$idx.':sendername'}.':'.  
                                            $contrib{$idx.':senderdomain'}.')';  
                             }  
                             $sender = '<b>'.$sender.'</b>';                              $sender = '<b>'.$sender.'</b>';
     if ($contrib{$idx.':anonymous'}) {      if ($contrib{$idx.':anonymous'}) {
         $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.          $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.
Line 1248  sub build_posting_display { Line 1048  sub build_posting_display {
                             } else {                              } else {
                                 @{$$namesort{$lastname}{$firstname}} = ("$idx");                                  @{$$namesort{$lastname}{$firstname}} = ("$idx");
                             }                              }
                             if ($outputtarget ne 'tex') {                              if (&editing_allowed($escsymb.':::'.$idx,$group)) {
                                 if (&editing_allowed($escsymb.':::'.$idx,$group)) {                                  if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {
                                     if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {                                      $sender.=' <a href="/adm/feedback?editdisc='.
                                         $sender.=' <a href="/adm/feedback?editdisc='.                                           $escsymb.':::'.$idx;
                                              $escsymb.':::'.$idx;                                      if ($$newpostsflag) {
                                         if ($$newpostsflag) {                                          $sender .= '&amp;previous='.$prevread;
                                             $sender .= '&amp;previous='.$prevread;                                      }
                                         }      $sender .= &group_args($group);
         $sender .= &group_args($group);                                      $sender .= '" '.$target.'>'.&mt('Edit').'</a>';
                                         $sender .= '" '.$target.'>'.&mt('Edit').'</a>';  
                                                                           
                                         unless ($seehidden) {                                      unless ($seeid) {
                                             my $grpargs = &group_args($group);                                          my $grpargs = &group_args($group);
                                             $sender.=" <a href=\"javascript:verifydelete('studentdelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')";                                          $sender.=" <a href=\"javascript:verifydelete('studentdelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')";
                                             $sender .= '">'.&mt('Delete').'</a>';                                          $sender .= '">'.&mt('Delete').'</a>';
                                         }  
                                     }                                      }
                                 }                                  }
                                 if ($seehidden) {                              } 
             if ($hiddens{$idx}) {      if ($seeid) {
                                         unless ($studenthidden) {          if ($hidden) {
                     $sender.=' <a href="/adm/feedback?unhide='.                                      unless ($studenthidden) {
                     $escsymb.':::'.$idx;                  $sender.=' <a href="/adm/feedback?unhide='.
                                             if ($$newpostsflag) {                  $escsymb.':::'.$idx;
                                                 $sender .= '&amp;previous='.$prevread;  
                                             }  
                                             $sender .= '">'.&mt('Make Visible').'</a>';  
                                         }  
             } else {  
         $sender.=' <a href="/adm/feedback?hide='.  
             $escsymb.':::'.$idx;  
                                         if ($$newpostsflag) {                                          if ($$newpostsflag) {
                                             $sender .= '&amp;previous='.$prevread;                                              $sender .= '&amp;previous='.$prevread;
                                         }                                          }
         $sender .= &group_args($group);                                          $sender .= '">'.&mt('Make Visible').'</a>';
                                         $sender .= '">'.&mt('Hide').'</a>';                                      }
             }          } else {
                                     my $grpargs = &group_args($group);      $sender.=' <a href="/adm/feedback?hide='.
             $sender.=           $escsymb.':::'.$idx;
                                         " <a href=\"javascript:verifydelete('seeiddelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')\">";                                      if ($$newpostsflag) {
                                     $sender .= &mt('Delete').'</a>';                                          $sender .= '&amp;previous='.$prevread;
                                 }                                      }
       $sender .= &group_args($group);
                                       $sender .= '">'.&mt('Hide').'</a>';
           }
                                   my $grpargs = &group_args($group);
           $sender.= 
                                       " <a href=\"javascript:verifydelete('seeiddelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')\">";
                                   $sender .= &mt('Delete').'</a>';
                             }                              }
         } else {          } else {
     if ($screenname) {      if ($screenname) {
Line 1317  sub build_posting_display { Line 1115  sub build_posting_display {
                                 @{$$namesort{'__anon'}{'__anon'}} = ("$idx");                                  @{$$namesort{'__anon'}{'__anon'}} = ("$idx");
                             }                              }
         }          }
                         if ($outputtarget ne 'tex') {          if (&discussion_open($status)) {
                             if (&discussion_open($status)) {                              if (($group ne '') && 
                                 if (($group ne '') &&                                   (&check_group_priv($group,'pgd') eq 'ok')) {
                                     (&check_group_priv($group,'pgd') eq 'ok')) {                                   $sender.=' <a href="/adm/feedback?replydisc='.
                                      $sender.=' <a href="/adm/feedback?replydisc='.                                            $escsymb.':::'.$idx;
                                               $escsymb.':::'.$idx;                                  if ($$newpostsflag) {
                                     if ($$newpostsflag) {                                      $sender .= '&amp;previous='.$prevread;
                                         $sender .= '&amp;previous='.$prevread;                                  }
                                     }                                  $sender .= &group_args($group);
                                     $sender .= &group_args($group);                                  $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
                                     $sender .= '" '.$target.'>'.&mt('Reply').'</a>';                              } elsif (&Apache::lonnet::allowed('pch', 
                                 } elsif (&Apache::lonnet::allowed('pch',    $env{'request.course.id'}.
      $env{'request.course.id'}.   ($env{'request.course.sec'}?'/'.
      ($env{'request.course.sec'}?'/'.                                    $env{'request.course.sec'}:''))) {
                                       $env{'request.course.sec'}:''))) {           $sender.=' <a href="/adm/feedback?replydisc='.
              $sender.=' <a href="/adm/feedback?replydisc='.                    $escsymb.':::'.$idx;
                       $escsymb.':::'.$idx;                                  if ($$newpostsflag) {
                                     if ($$newpostsflag) {                                      $sender .= '&amp;previous='.$prevread;
                                         $sender .= '&amp;previous='.$prevread;  
                                     }  
                                     $sender .= '" '.$target.'>'.&mt('Reply').'</a>';  
                                 }                                  }
                                   $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
                             }                              }
                             if ($viewgrades) {                          }
           if ($viewgrades) {
         $vgrlink=&Apache::loncommon::submlink(&mt('Submissions'),          $vgrlink=&Apache::loncommon::submlink(&mt('Submissions'),
                                 $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb);                              $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb);
             }          }
                             if ($$dischash{$readkey}=~/\.$idx\./) {                          if ($$dischash{$readkey}=~/\.$idx\./) { 
                                 $ctlink = '<label><b>'.&mt('Mark unread').'?</b>&nbsp;<input type="checkbox" name="postunread_'.$idx.'" /></label>';                              $ctlink = '<label><b>'.&mt('Mark unread').'?</b>&nbsp;<input type="checkbox" name="postunread_'.$idx.'" /></label>';
                             } else {                          } else {
                                 $ctlink = '<label><b>'.&mt('Mark read').'?</b>&nbsp;<input type="checkbox" name="postread_'.$idx.'" /></label>';                              $ctlink = '<label><b>'.&mt('Mark read').'?</b>&nbsp;<input type="checkbox" name="postread_'.$idx.'" /></label>';
                             }  
                         }                          }
                     }                      }
 #figure out at what position this needs to print  #figure out at what position this needs to print
Line 1365  sub build_posting_display { Line 1161  sub build_posting_display {
                 if ($outputtarget eq 'export') {                  if ($outputtarget eq 'export') {
                     %{$$imsitems{$idx}} = ();                      %{$$imsitems{$idx}} = ();
                     $$imsitems{$idx}{'isvisible'}='true';                      $$imsitems{$idx}{'isvisible'}='true';
                     if ($hiddens{$idx}) {                      if ($hidden) {
                         $$imsitems{$idx}{'isvisible'}='false';                          $$imsitems{$idx}{'isvisible'}='false';
                     }                      }
                     $$imsitems{$idx}{'title'}=$subjects{$numoldver};                      $$imsitems{$idx}{'title'}=$subjects{$numoldver};
Line 1387  sub build_posting_display { Line 1183  sub build_posting_display {
                 } else {                  } else {
                     if ($message) {                      if ($message) {
                         my $spansize = 2;                          my $spansize = 2;
                         my ($uname,$udom);  
                         if ($showonlyunread && $prevread > $posttime) {                          if ($showonlyunread && $prevread > $posttime) {
                             $$notshown{$idx} = 1;                              $$notshown{$idx} = 1;
                         } elsif ($showunmark && $$dischash{$readkey}=~/\.$idx\./) {                          } elsif ($showunmark && $$dischash{$readkey}=~/\.$idx\./) {
                             $$notshown{$idx} = 1;                              $$notshown{$idx} = 1;
                         } else {                          } else {
 # apply filters  # apply filters
                             $uname = $contrib{$idx.':sendername'};                              my $uname = $contrib{$idx.':sendername'};
                             $udom = $contrib{$idx.':senderdomain'};                              my $udom = $contrib{$idx.':senderdomain'};
                             my $poster = $uname.':'.$udom;                              my $poster = $uname.':'.$udom;
                             if ($env{'form.totposters'} ne '') {                              if ($env{'form.totposters'} ne '') {
                                 if ($totposters == 0) {                                  if ($totposters == 0) {
Line 1448  sub build_posting_display { Line 1243  sub build_posting_display {
                                 $$newitem{$idx} = 1;                                  $$newitem{$idx} = 1;
                                 $$discussionitems[$idx] .= '                                  $$discussionitems[$idx] .= '
                                   <table border="0" width="100%">                                    <table border="0" width="100%">
                                   <tr><td align="left"><font color="#FF0000"><b>'.&mt('NEW').'&nbsp;</b></font></td>';                                    <tr><td align="left"><font color="#FF0000"><b>'.&mt('NEW').'</b></font></td>';
                             } else {                              } else {
                                 $$newitem{$idx} = 0;                                  $$newitem{$idx} = 0;
                                 $$discussionitems[$idx] .= '                                  $$discussionitems[$idx] .= '
Line 1463  sub build_posting_display { Line 1258  sub build_posting_display {
                                 $$discussionitems[$idx].='<td align="right">&nbsp;&nbsp;'.                                  $$discussionitems[$idx].='<td align="right">&nbsp;&nbsp;'.
                                   $ctlink.'</td>';                                    $ctlink.'</td>';
                             }                              }
                             my $likesize="100";  
                             if ($seeid || $canvote) {  
 # Figure out size based on likes  
                                 my $thislikes=$likes{$symb.':'.$idx.':likes'};  
                                 if ($thislikes>$twoplus) {  
                                     $likesize="200";  
                                 } elsif ($thislikes>$oneplus) {  
                                     $likesize="150";  
                                 }  
                                 if ($thislikes<$twominus) {  
                                     $likesize="50";  
                                 } elsif ($thislikes<$oneminus) {  
                                     $likesize="75";  
                                 }  
                             }  
 # Actually glue in the message itself  
                             $$discussionitems[$idx].= '</tr></table><blockquote>'.                              $$discussionitems[$idx].= '</tr></table><blockquote>'.
                                     "<div style='font-size:$likesize%'>".                                      $message.'</blockquote>';
                                     $message.  
                                     '</div></blockquote>';  
                             if ($canvote) {  
                                 my $ownpost;  
                                 if (($uname eq $env{'user.name'}) &&  
                                     ($udom eq $env{'user.domain'})) {  
                                     $ownpost = 1;  
                                 }  
 # Put in the like and unlike buttons  
                                 if ($ownpost || (($hiddens{$idx}) && ($seehidden))) {  
                                     my $novote;  
                                     if ($ownpost) {  
                                         $novote = &mt('No voting for your own posts.');  
                                     } else {  
                                         $novote = &mt('No voting for hidden posts.');  
                                     }  
                                     $$discussionitems[$idx].=  
                                         '<a href="javascript:alert('."'$novote'".');" style="text-decoration: none;">'.  
                                         '<img border="0" src="/res/adm/pages/thumbsup_novote.png" alt="'.$novote.'" />&nbsp;'.  
                                         '<img border="0" src="/res/adm/pages/thumbsdown_novote.png" alt="'.$novote.'" /></a>';  
                                 } else {  
                                     if ($userlikes{$idx}) {  
                                         $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsup_gray.png" alt="'.&mt('You like this posting').'" />';  
                                     } else {  
                                         $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsup.png" alt="'.&mt('Like').'" />','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting"));   
                                     }  
                                     if ($userunlikes{$idx}) {  
                                         $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsdown_gray.png" alt="'.&mt('You unlike this posting').'" />';  
                                     } else {  
                                         $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsdown.png" alt="'.&mt('Unlike').'" />','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting"));  
                                     }  
                                 }  
                             }  
                             if ($seeid || $canvote) {  
                                 my $thislikes=$likes{$symb.':'.$idx.':likes'};  
                                 if ($thislikes>0) {  
                                     $$discussionitems[$idx].='&nbsp;('.&mt("[_1] likes",$thislikes).')';  
                                 } elsif ($thislikes<0) {  
                                     $$discussionitems[$idx].='&nbsp;('.&mt("[_1] unlikes",abs($thislikes)).')';  
                                 }  
                             }  
 # If there is any history to this post, inform the reader  
                             if ($contrib{$idx.':history'}) {                              if ($contrib{$idx.':history'}) {
                                 my @postversions = ();                                  my @postversions = ();
                                 $$discussionitems[$idx] .= &mt('This post has been edited by the author.');                                  $$discussionitems[$idx] .= &mt('This post has been edited by the author.');
                                 if ($seehidden) {                                  if ($seeid) {
                                     $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$escsymb.':::'.$idx;                                      $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$escsymb.':::'.$idx;
     $$discussionitems[$idx] .= &group_args($group);      $$discussionitems[$idx] .= &group_args($group);
                                     $$discussionitems[$idx] .= '">'.&mt('Display all versions').'</a>';                                      $$discussionitems[$idx] .= '">'.&mt('Display all versions').'</a>';
Line 1606  sub filter_regexp { Line 1343  sub filter_regexp {
   
   
 sub get_post_contents {  sub get_post_contents {
     my ($contrib,$idx,$seeid,$seehidden,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$showaboutme,$numver) = @_;      my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_;
     my $discussion = '';      my $discussion = '';
     my $start=$numver;      my $start=$numver;
     my $end=$numver + 1;      my $end=$numver + 1;
     %{$$imsfiles{$idx}}=();      %{$$imsfiles{$idx}}=();
     if ($type eq 'allversions') {      if ($type eq 'allversions') {
        unless($seehidden) {         unless($seeid) {
            $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');             $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');
            return $discussion;             return $discussion;
        }          } 
Line 1624  sub get_post_contents { Line 1361  sub get_post_contents {
                                         $$contrib{$idx.':sendername'},                                          $$contrib{$idx.':sendername'},
                                         $$contrib{$idx.':senderdomain'});                                          $$contrib{$idx.':senderdomain'});
     $$screenname=$$contrib{$idx.':screenname'};      $$screenname=$$contrib{$idx.':screenname'};
     $$showaboutme = &Apache::lonnet::usertools_access($$contrib{$idx.':sendername'},  
                                                       $$contrib{$idx.':senderdomain'},      my $sender=&Apache::loncommon::aboutmewrapper(
                                                       'aboutme');  
     my $sender = $$plainname;  
     if ($$showaboutme) {  
         $sender = &Apache::loncommon::aboutmewrapper(  
                                  $$plainname,                                   $$plainname,
                                  $$contrib{$idx.':sendername'},                                   $$contrib{$idx.':sendername'},
                                  $$contrib{$idx.':senderdomain'});                                   $$contrib{$idx.':senderdomain'}).' ('.
     }                                   $$contrib{$idx.':sendername'}.':'.
     if ($seeid) {                                   $$contrib{$idx.':senderdomain'}.')';
         $sender .= ' ('.$$contrib{$idx.':sendername'}.':'.  
                    $$contrib{$idx.':senderdomain'}.')';  
     }  
     my $attachmenturls = $$contrib{$idx.':attachmenturl'};      my $attachmenturls = $$contrib{$idx.':attachmenturl'};
     my @postversions = ();      my @postversions = ();
     if ($type eq 'allversions' || $type eq 'export') {      if ($type eq 'allversions' || $type eq 'export') {
Line 1822  END Line 1552  END
    $env{'course.'.$env{'request.course.id'}.'.domain'},     $env{'course.'.$env{'request.course.id'}.'.domain'},
    $env{'course.'.$env{'request.course.id'}.'.num'});     $env{'course.'.$env{'request.course.id'}.'.num'});
       unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {        unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
           my $numoldver = 0;  
           if ($contrib{$idx.':history'}) {            if ($contrib{$idx.':history'}) {
               if ($contrib{$idx.':history'} =~ /:/) {                if ($contrib{$idx.':history'} =~ /:/) {
                   my @oldversions = split(/:/,$contrib{$idx.':history'});                    my @oldversions = split(/:/,$contrib{$idx.':history'});
Line 1831  END Line 1560  END
                   $numoldver = 1;                    $numoldver = 1;
               }                }
           }            }
           if ($idx > 0) {            if ($env{'form.replydisc'}) {
               my (%msgversions,%subversions,$htmldecode);                if ($contrib{$idx.':history'}) {
               $htmldecode = 0;                    if ($contrib{$idx.':history'} =~ /:/) {
               if ($env{'form.replydisc'}) {                        my @oldversions = split(/:/,$contrib{$idx.':history'});
                   $htmldecode = 1;                        $numoldver = @oldversions;
                     } else {
                         $numoldver = 1;
                     }
               }                }
               &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);                if ($idx > 0) {
               &get_post_versions(\%subversions,$contrib{$idx.':subject'},$htmldecode,                    my %msgversions = ();
                                  $numoldver);                    &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
               $subject = $subversions{$numoldver};  
               if ($env{'form.replydisc'}) {  
                   $quote = $msgversions{$numoldver};                    $quote = $msgversions{$numoldver};
                   $subject = &HTML::Entities::encode(&mt('Re: ').$subject,'<>&"');  
               } else {  
                   $comment = $msgversions{$numoldver};  
               }                }
           }                if ($idx > 0) {
           if ($env{'form.editdisc'}) {                    my %subversions = ();
                     &get_post_versions(\%subversions,$contrib{$idx.':subject'},1,$numoldver);
                     $subject = &mt('Re: ').$subversions{$numoldver};
                 }
                 $subject = &HTML::Entities::encode($subject,'<>&"');
             } else {
               $attachmenturls = $contrib{$idx.':attachmenturl'};                $attachmenturls = $contrib{$idx.':attachmenturl'};
                 if ($idx > 0) {
                     my %msgversions = ();
                     &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
                     $comment = $msgversions{$numoldver};
                     my %subversions = ();
                     &get_post_versions(\%subversions,$contrib{$idx.':subject'},0,$numoldver);
                     $subject = $subversions{$numoldver}; 
                 }
               if (defined($contrib{$idx.':replyto'})) {                if (defined($contrib{$idx.':replyto'})) {
                   $parentmsg = $contrib{$idx.':replyto'};                    $parentmsg = $contrib{$idx.':replyto'};
               }                }
Line 1924  END Line 1664  END
 </script>  </script>
 END  END
   
   my ($textareaheader,$textareaclass);  
   if (&Apache::lonhtmlcommon::htmlareabrowser()) {  
       $textareaheader = &Apache::lonhtmlcommon::htmlareaselectactive();  
       $textareaclass = 'class="LC_richDefaultOff"';  
       if ($env{'request.course.id'}) {  
           unless (($env{'course.'.$env{'request.course.id'}.'.allow_limited_html_in_feedback'} =~ /^\s*yes\s*$/i) || ($env{'form.sendmessageonly'})) {  
               undef($textareaclass);  
           }  
       }  
   }  
   
   # Breadcrumbs    # Breadcrumbs
   my $brcrum = [{'href' => '',    my $brcrum = [{'href' => '',
                  'text' => 'Resource Feedback and Discussion'}];                   'text' => 'Resource Feedback and Discussion'}];
Line 1974  END Line 1703  END
   $r->print(<<END);    $r->print(<<END);
 $options<hr />  $options<hr />
 $quote  $quote
 <p>$lt{'myqu'}  <p>$lt{'myqu'}</p>
 $textareaheader  
 </p>  
 <p>  <p>
 $latexHelp  $latexHelp
 </p>  </p>
 <p>  <p>
 $lt{'title'}: <input type="text" name="subject" size="30" value="$subject" /></p>  $lt{'title'}: <input type="text" name="subject" size="30" value="$subject" /></p>
 <p>  <p>
 <textarea name="comment" id="comment" cols="60" rows="10"  $textareaclass>$comment  <textarea name="comment" id="comment" cols="60" rows="10">$comment
 </textarea></p>  </textarea></p>
 END  END
     if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) {      if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) {
Line 2061  END Line 1788  END
         }          }
     }      }
     $r->print(&generate_preview_button().      $r->print(&generate_preview_button().
                 &Apache::lonhtmlcommon::htmlareaselectactive('comment').
       &Apache::loncommon::end_page());        &Apache::loncommon::end_page());
   
 }  }
Line 2498  sub print_showposters { Line 2226  sub print_showposters {
     $r->send_http_header;      $r->send_http_header;
   
     &Apache::lonenc::check_encrypt(\$symb);      &Apache::lonenc::check_encrypt(\$symb);
       my $crs='/'.$env{'request.course.id'};
       if ($env{'request.course.sec'}) {
           $crs.='_'.$env{'request.course.sec'};
       }
       $crs=~s/\_/\//g;
       my $seeid;
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $group = $env{'form.group'};      my $group = $env{'form.group'};
     my $ressymb = &wrap_symb($symb);      my $ressymb = &wrap_symb($symb);
     my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);      if (($group ne '') &&
           ($ressymb =~ m|^bulletin___ \d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {
           if (&check_group_priv($group,'dgp') eq 'ok') {
               $seeid = 1;
           }
       } else {
           $seeid=&Apache::lonnet::allowed('rin',$crs);
       }
     my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},      my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                          $cdom,$cnum);                                           $cdom,$cnum);
     my %namesort = ();      my %namesort = ();
Line 2518  sub print_showposters { Line 2259  sub print_showposters {
         for (my $idx=1;$idx<=$contrib{'version'};$idx++) {          for (my $idx=1;$idx<=$contrib{'version'};$idx++) {
             my $hidden=($contrib{'hidden'}=~/\.$idx\./);              my $hidden=($contrib{'hidden'}=~/\.$idx\./);
             my $deleted=($contrib{'deleted'}=~/\.$idx\./);              my $deleted=($contrib{'deleted'}=~/\.$idx\./);
             unless ((($hidden) && (!$seehidden)) || ($deleted)) {              unless ((($hidden) && (!$seeid)) || ($deleted)) {
                 if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {                  if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {
                     my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});                      my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
                     my $lastname = $names{'lastname'};                      my $lastname = $names{'lastname'};
Line 2770  sub redirect_back { Line 2511  sub redirect_back {
   &Apache::lonenc::check_encrypt(\$feedurl);    &Apache::lonenc::check_encrypt(\$feedurl);
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');    my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   my %onload;    my %onload;
   if ($env{'environment.remote'} ne 'off') {  
       $onload{'onload'} =  
   "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }";  
   }  
   my $start_page=    my $start_page=
       &Apache::loncommon::start_page('Feedback sent',undef,        &Apache::loncommon::start_page('Feedback sent',undef,
      {'redirect'    => [0,$feedurl],       {'redirect'    => [0,$feedurl],
Line 2807  sub no_redirect_back { Line 2544  sub no_redirect_back {
   my $nofeed=&mt('Sorry, no feedback possible on this resource ...');    my $nofeed=&mt('Sorry, no feedback possible on this resource ...');
     
   my %onload;    my %onload;
   if ($env{'environment.remote'} ne 'off') {  
       $onload{'onload'} =   
   "if (window.name!='loncapaclient') { self.window.close(); }";  
   }  
   
   my %body_options = ('only_body'   => 1,    my %body_options = ('only_body'   => 1,
       'bgcolor'     => '#FFFFFF',        'bgcolor'     => '#FFFFFF',
       'add_entries' => \%onload,);        'add_entries' => \%onload,);
   
   if ($feedurl !~ m{^/adm/feedback}) {     if ($feedurl !~ m{^/adm/feedback}) { 
       $body_options{'redirect'} = [2,$feedurl];        $body_options{'rediect'} = [2,$feedurl];
   }    }
   my $start_page=    my $start_page=
       &Apache::loncommon::start_page('Feedback not sent',undef,        &Apache::loncommon::start_page('Feedback not sent',undef,
Line 2837  ENDNOREDIRTWO Line 2570  ENDNOREDIRTWO
 }  }
   
 sub screen_header {  sub screen_header {
     my ($feedurl,$symb,$group) = @_;      my ($feedurl,$symb) = @_;
     my $crscontent = &mt('Question/Comment/Feedback about course content');      my $crscontent = &mt('Question/Comment/Feedback about course content');
     my $crspolicy = &mt('Question/Comment/Feedback about course policy');      my $crspolicy = &mt('Question/Comment/Feedback about course policy');
     my $contribdisc = &mt('Contribution to course discussion of resource');      my $contribdisc = &mt('Contribution to course discussion of resource');
Line 2886  sub screen_header { Line 2619  sub screen_header {
     }      }
     if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) {      if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) {
         my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards');          my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards');
         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};          if (!$blocked && &discussion_open(undef,$symb) && 
         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      &Apache::lonnet::allowed('pch',
         my $realsymb = &get_realsymb($symb);  
         if (!$blocked && &discussion_open(undef,$realsymb) &&   
     (&Apache::lonnet::allowed('pch',  
      $env{'request.course.id'}.       $env{'request.course.id'}.
      ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')) ||       ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
             (($group ne '') && ($symb =~ m{^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$}) && (&check_group_priv($group,'pgd') eq 'ok')))) {  
     $discussoptions='<label><input type="radio" name="discuss" value="nonanon" checked="checked" /> '.      $discussoptions='<label><input type="radio" name="discuss" value="nonanon" checked="checked" /> '.
  $contribdisc.   $contribdisc.
         '</label><br /><label><input type="radio" name="discuss" value="anon" /> '.          '</label><br /><label><input type="radio" name="discuss" value="anon" /> '.
Line 2907  sub screen_header { Line 2636  sub screen_header {
         }          }
     }      }
     if ($msgoptions) {      if ($msgoptions) {
         $msgoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/feedback.png').'" />'          $msgoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/com.png').'" />'
                    .' '.&mt('Send Feedback').'</h2><p>'.&Apache::lonhtmlcommon::coursepreflink(&mt('Feedback Settings'),'feedback').'</p>'                     .' '.&mt('Send Feedback').'</h2><p>'.&Apache::lonhtmlcommon::coursepreflink(&mt('Feedback Settings'),'feedback').'</p>'
                    .$msgoptions;                     .$msgoptions;
     }      }
Line 2933  sub resource_output { Line 2662  sub resource_output {
 }  }
   
 sub clear_out_html {  sub clear_out_html {
   my ($message,$override)=@_;    my ($message,$override,$ignore_htmlarea)=@_;
     if (!$ignore_htmlarea
         && !&Apache::lonhtmlcommon::htmlareablocked()) { return $message; }
 # Always allow the <m>-tag  # Always allow the <m>-tag
   my %html=(M=>1);    my %html=(M=>1);
 # Check if more is allowed  # Check if more is allowed
Line 2944  sub clear_out_html { Line 2675  sub clear_out_html {
       # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>        # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>
       # <SUP> <TABLE> <TR> <TD> <TH> <TBODY>        # <SUP> <TABLE> <TR> <TD> <TH> <TBODY>
       %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,        %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
              BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, PRE=>1, DIV=>1, IMG=>1,       BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
              M=>1, CHEM=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1,       M=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1, 
      H1=>1, H2=>1, H3=>1, H4=>1, H5=>1, H6=>1,        H1=>1, H2=>1, H3=>1, H4=>1, H5=>1, H6=>1, 
      TABLE=>1, TR=>1, TD=>1, TH=>1, TBODY=>1);       TABLE=>1, TR=>1, TD=>1, TH=>1, TBODY=>1);
   }    }
Line 3031  sub send_msg { Line 2762  sub send_msg {
     return ($status,$sendsomething);      return ($status,$sendsomething);
 }  }
   
 # Store feedback "likes"  
   
 sub storefeedbacklikes {  
     my ($likes,$uname,$udom,$course)=@_;  
     unless ($likes) { $likes=0; }  
     if ($likes>0) { $likes=1; }  
     if ($likes<0) { $likes=-1; }  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my %record=&getfeedbackrecords($uname,$udom,$course);  
     my $totallikes=$record{'totallikes'};  
     $totallikes+=$likes;  
     my %newrecord=('likes_user'   => $env{'user.name'},  
                    'likes_domain' => $env{'user.domain'},  
                    'likes' => $likes,  
                    'totallikes' => $totallikes);  
     return &Apache::lonnet::cstore(\%newrecord,'_feedback',$course,$udom,$uname);  
 }  
   
 sub adddiscuss {  sub adddiscuss {
     my ($symb,$email,$anon,$attachmenturl,$subject,$group)=@_;      my ($symb,$email,$anon,$attachmenturl,$subject)=@_;
     my $status='';      my $status='';
     my $realsymb = &get_realsymb($symb);  
     my ($cnum,$cdom);  
     if ($env{'request.course.id'}) {  
         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
     }  
     my $realsymb;      my $realsymb;
       if ($symb=~/^bulletin___/) {
    my $filename=(&Apache::lonnet::decode_symb($symb))[2];
    $filename=~s|^adm/wrapper/||;
    $realsymb=&Apache::lonnet::symbread($filename);
       }
     if (&discussion_open(undef,$realsymb) &&      if (&discussion_open(undef,$realsymb) &&
         (&Apache::lonnet::allowed('pch',$env{'request.course.id'}.   &Apache::lonnet::allowed('pch',$env{'request.course.id'}.
          ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')) ||          ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
          (($group ne '') && (&check_group_priv($group,'pgd') eq 'ok') &&  
          ($symb =~ m{^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$})))) {  
   
     my %contrib=('message'      => $email,      my %contrib=('message'      => $email,
                  'sendername'   => $env{'user.name'},                   'sendername'   => $env{'user.name'},
Line 3145  sub adddiscuss { Line 2853  sub adddiscuss {
                      $env{'course.'.$env{'request.course.id'}.'.domain'},                       $env{'course.'.$env{'request.course.id'}.'.domain'},
      $env{'course.'.$env{'request.course.id'}.'.num'});       $env{'course.'.$env{'request.course.id'}.'.num'});
     }      }
     my %record=&getdiscussionrecords();      my %record=&Apache::lonnet::restore('_discussion');
     my ($temp)=keys(%record);      my ($temp)=keys(%record);
     unless ($temp=~/^error\:/) {      unless ($temp=~/^error\:/) {
        my %newrecord=();         my %newrecord=();
Line 3153  sub adddiscuss { Line 2861  sub adddiscuss {
        $newrecord{'subnumber'}=$record{'subnumber'}+1;         $newrecord{'subnumber'}=$record{'subnumber'}+1;
        $status.='<br />'.&mt('Registering').': '.         $status.='<br />'.&mt('Registering').': '.
                &Apache::lonnet::cstore(\%newrecord,'_discussion');                 &Apache::lonnet::cstore(\%newrecord,'_discussion');
        &updatekarma();  
     }      }
     } else {      } else {
  $status.='Failed.';   $status.='Failed.';
Line 3161  sub adddiscuss { Line 2868  sub adddiscuss {
     return $status.'<br />';         return $status.'<br />';   
 }  }
   
 # Routine to get the complete discussion records  
   
 sub getdiscussionrecords {  
     my ($uname,$udom,$course)=@_;  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my %record=&Apache::lonnet::restore('_discussion',$course,$udom,$uname);  
     return %record;  
 }  
   
 # Routine to get discussion statistics  
   
 sub getdiscussionstats {  
     my %record=&getdiscussionrecords(@_);  
     my $totalvotes = $record{'totallikes'} + $record{'totalunlikes'};  
     return ($record{'subnumber'},$record{'points'},$record{'totallikes'},$totalvotes);  
 }  
   
 # Calculate discussion karma  
   
 sub calcdiscussionkarma {  
     my ($subs,$pts,$likes,$votes)=&getdiscussionstats(@_);  
     my $karma=0;  
     if ($votes>0) {  
         $karma=int(.1+5.*(1.-exp(-$subs/10.))*$likes/$votes);  
         if ($karma<0) { $karma=0; }  
         if ($karma>5) { $karma=5; }  
     }  
     return $karma;  
 }  
   
 # Update karma  
   
 sub updatekarma {  
     my ($uname,$udom,$course)=@_;  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my $karma=&calcdiscussionkarma($uname,$udom,$course);  
     &Apache::lonnet::cstore({ 'karma' => $karma },'_discussion',$course,$udom,$uname);  
     &Apache::lonnet::do_cache_new('karma',$uname.':'.$udom.':'.$course,$karma,3600);  
     return $karma;  
 }  
   
 # Retrieve karma  
   
 sub userkarma {  
     my ($uname,$udom,$course)=@_;  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my $hashkey=$uname.':'.$udom.':'.$course;  
     my ($karma,$cached)=&Apache::lonnet::is_cached_new('karma',$hashkey);  
     if ($cached) {  
         return $karma;  
     }  
     my %userdisc=&getdiscussionrecords($uname,$udom,$course);  
     $karma=$userdisc{'karma'};  
     &Apache::lonnet::do_cache_new('karma',$hashkey,$karma,3600);  
     return $karma;  
 }  
   
 # Store discussion credit  
   
 sub storediscussionpoints {  
     my ($points,$uname,$udom,$course)=@_;  
     unless ($points) { $points=0; }  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my %record=('grader_user'   => $env{'user.name'},  
                 'grader_domain' => $env{'user.domain'},  
                 'points' => $points);  
     return &Apache::lonnet::cstore(\%record,'_discussion',$course,$udom,$uname);  
 }  
   
 # Store discussion "likes"  
   
 sub storediscussionlikes {  
     my ($chglikes,$chgunlikes,$uname,$udom,$course,$context)=@_;  
     unless ($uname) { $uname=$env{'user.name'}; }  
     unless ($udom)  { $udom=$env{'user.domain'}; }  
     unless ($course) { $course=$env{'request.course.id'}; }  
     my %record=&getdiscussionrecords($uname,$udom,$course);  
     my $totallikes=$record{'totallikes'};  
     my $totalunlikes=$record{'totalunlikes'};  
     $totallikes += $chglikes;  
     $totalunlikes += $chgunlikes;  
     my %newrecord=('likes_user'   => $env{'user.name'},  
                    'likes_domain' => $env{'user.domain'},  
                    'totallikes'   => $totallikes,  
                    'totalunlikes' => $totalunlikes,  
                    'context'      => $context);  
     my $status=&Apache::lonnet::cstore(\%newrecord,'_discussion',$course,$udom,$uname);  
     if ($status eq 'ok') {  
         &updatekarma($uname,$udom,$course);  
     }  
     return $status;  
 }  
   
 sub get_discussion_info {  sub get_discussion_info {
     my ($idx,%contrib) = @_;      my ($idx,%contrib) = @_;
     my $changelast = 0;      my $changelast = 0;
Line 3318  sub show_preview { Line 2924  sub show_preview {
     &newline_to_br(\$message);      &newline_to_br(\$message);
     $message=&Apache::lonspeller::markeduptext($message);      $message=&Apache::lonspeller::markeduptext($message);
     $message=&Apache::lontexconvert::msgtexconverted($message);      $message=&Apache::lontexconvert::msgtexconverted($message);
     my $subject=&clear_out_html($env{'form.subject'});      my $subject=&clear_out_html($env{'form.subject'},undef,1);
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
     $subject=&Apache::lontexconvert::msgtexconverted($subject);      $subject=&Apache::lontexconvert::msgtexconverted($subject);
   
Line 3430  END Line 3036  END
                                    {'bread_crumbs' => $brcrum,});                                     {'bread_crumbs' => $brcrum,});
   
     my $orig_subject = &unescape($env{'form.subject'});      my $orig_subject = &unescape($env{'form.subject'});
     my $subject=&clear_out_html($orig_subject);      my $subject=&clear_out_html($orig_subject,undef,1);
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
     $subject=&Apache::lontexconvert::msgtexconverted($subject);      $subject=&Apache::lontexconvert::msgtexconverted($subject);
     my $timestamp=$env{'form.timestamp'};      my $timestamp=$env{'form.timestamp'};
Line 3788  sub handler { Line 3394  sub handler {
 # --------------------------- Get query string for limited number of parameters  # --------------------------- Get query string for limited number of parameters
   
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
          ['like','unlike','hide','unhide','deldisc','undeleteall','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','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);           ['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','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);
   my $group = $env{'form.group'};    my $group = $env{'form.group'};
   my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
   my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
   my %attachmax = (    my %attachmax = (
                     text => &mt('(128 KB max size)'),                      text => &mt('(128 KB max size)'),
                     num  => 131072,                      num  => 131072,
                   );                    );
   if ($env{'form.editdisc'}) {    if ($env{'form.editdisc'}) {
       if (!(&editing_allowed($env{'form.editdisc'},$group))) {        if (!(&editing_allowed($env{'form.editdisc'},$env{'form.group'}))) {
           my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];            my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
           my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);            my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
           my $feedurl=&Apache::lonnet::clutter($url);            my $feedurl=&Apache::lonnet::clutter($url);
Line 3846  sub handler { Line 3450  sub handler {
                                                {'bread_crumbs' => $brcrum,})                                                 {'bread_crumbs' => $brcrum,})
       );        );
   
         my $crs='/'.$env{'request.course.id'};
         if ($env{'request.course.sec'}) {
             $crs.='_'.$env{'request.course.sec'};
         }
         $crs=~s|_|/|g;
         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});
       ($symb, my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb)=&get_feedurl_and_clean_symb($symb);
       my $ressymb = &wrap_symb($symb);        my $ressymb = &wrap_symb($symb);
         my $group = $env{'form.group'};
       my $seeid;        my $seeid;
       if (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {        if (($group ne '') && (($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|))) {
           $seeid = 1;            if (&check_group_priv($group,'dgp') eq 'ok') {
                 $seeid = 1;
             }
         } else {
             $seeid = &Apache::lonnet::allowed('rin',$crs);
       }        }
       my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);  
       if ($idx > 0) {        if ($idx > 0) {
           my %messages = ();            my %messages = ();
           my %subjects = ();            my %subjects = ();
           my %attachmsgs = ();            my %attachmsgs = ();
           my %allattachments = ();            my %allattachments = ();
           my %imsfiles = ();            my %imsfiles = ();
           my ($screenname,$plainname,$showaboutme);            my ($screenname,$plainname);
           my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},            my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                                $cdom,$cnum);                             $env{'course.'.$env{'request.course.id'}.'.domain'},
           $r->print(&get_post_contents(\%contrib,$idx,$seeid,$seehidden,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname,\$showaboutme));                             $env{'course.'.$env{'request.course.id'}.'.num'});
             $r->print(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname));
       }        }
       $r->print(&Apache::loncommon::end_page());        $r->print(&Apache::loncommon::end_page());
       return OK;        return OK;
Line 3936  sub handler { Line 3552  sub handler {
       $r->send_http_header;        $r->send_http_header;
       my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');        my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
       my %onload;        my %onload;
       if ($env{'environment.remote'} ne 'off') {  
   $onload{'onload'} =  
       "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }";  
       }  
   
       my $start_page=        my $start_page=
   &Apache::loncommon::start_page('New posts marked as read',undef,    &Apache::loncommon::start_page('New posts marked as read',undef,
Line 4005  ENDREDIR Line 3617  ENDREDIR
       my $entry=$env{'form.hide'}?$env{'form.hide'}:$env{'form.unhide'};        my $entry=$env{'form.hide'}?$env{'form.hide'}:$env{'form.unhide'};
       my ($symb,$idx)=split(/\:\:\:/,$entry);        my ($symb,$idx)=split(/\:\:\:/,$entry);
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
       my $ressymb = &wrap_symb($symb);  
   
       my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);        my $crs='/'.$env{'request.course.id'};
       unless (($seehidden) || (&editing_allowed($env{'form.hide'},$group))) {        if ($env{'request.course.sec'}) {
           &redirect_back($r,$feedurl,&mt('Hiding not permitted').'<br />',            $crs.='_'.$env{'request.course.sec'};
                          '0','0','','',$env{'form.previous'},'','','','',        }
                          undef,undef,$group,);        $crs=~s/\_/\//g;
         my $seeid=&Apache::lonnet::allowed('rin',$crs);
   
         if ($env{'form.hide'} && !$seeid && !(&editing_allowed($env{'form.hide'},$env{'form.group'}))) {
             &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',                 '0','0','','',$env{'form.previous'},'','','','',
                    undef,undef,$group,);
           return OK;            return OK;
       }        }
   
       my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},        my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                            $cdom,$cnum);                            $env{'course.'.$env{'request.course.id'}.'.domain'},
             $env{'course.'.$env{'request.course.id'}.'.num'});
   
       my $currenthidden=$contrib{'hidden'};        my $currenthidden=$contrib{'hidden'};
       my $currentstudenthidden=$contrib{'studenthidden'};        my $currentstudenthidden=$contrib{'studenthidden'};
   
       if ($env{'form.hide'}) {        if ($env{'form.hide'}) {
   $currenthidden.='.'.$idx.'.';    $currenthidden.='.'.$idx.'.';
   unless ($seehidden) {    unless ($seeid) {
       $currentstudenthidden.='.'.$idx.'.';        $currentstudenthidden.='.'.$idx.'.';
   }    }
       } else {        } else {
   $currenthidden=~s/\.$idx\.//g;    $currenthidden=~s/\.$idx\.//g;
       }        }
       my %newhash=('hidden' => $currenthidden);        my %newhash=('hidden' => $currenthidden);
       if ( ($env{'form.hide'}) && (!$seehidden) ) {        if ( ($env{'form.hide'}) && (!$seeid) ) {
   $newhash{'studenthidden'} = $currentstudenthidden;    $newhash{'studenthidden'} = $currentstudenthidden;
       }        }
       if ($env{'form.hide'}) {        if ($env{'form.hide'}) {
Line 4039  ENDREDIR Line 3656  ENDREDIR
           ($changelast,$newlast) = &get_discussion_info($idx,%contrib);            ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
           if ($changelast) {            if ($changelast) {
               &Apache::lonnet::put('discussiontimes',{$symb => $newlast},                &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                                    $cdom,$cnum);                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                        $env{'course.'.$env{'request.course.id'}.'.num'});
           }            }
       }        }
       my $result;        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
       if (&Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},                             $env{'course.'.$env{'request.course.id'}.'.domain'},
                                  $cdom,$cnum) eq 'ok') {     $env{'course.'.$env{'request.course.id'}.'.num'});
           my $prefix=$symb.':'.$idx.':';  
           my %likes=&Apache::lonnet::dump('disclikes',$cdom,$cnum,  
                                           '^'.$prefix);  
           my ($totallikes,$totalunlikes);  
           if (ref($likes{$prefix.'likers'}) eq 'HASH') {  
               $totallikes = scalar(keys(%{$likes{$prefix.'likers'}}));  
           }  
           if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {  
               $totalunlikes = scalar(keys(%{$likes{$prefix.'unlikers'}}));  
           }  
           if ($totallikes || $totalunlikes) {  
               my ($chglikes,$chgunlikes,$context);  
               if ($env{'form.hide'}) {  
                   $chglikes = -1 * $totallikes;  
                   $chgunlikes = -1 * $totalunlikes;  
                   $context = 'hide';  
               } else {  
                   $chglikes = $totallikes;  
                   $chgunlikes = $totalunlikes;  
                   $context = 'unhide';  
               }  
               &storediscussionlikes($chglikes,$chgunlikes,  
                                     $contrib{$idx.':sendername'},  
                                     $contrib{$idx.':senderdomain'},  
                                     $env{'request.course.id'},  
                                     $context);  
   
           }        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
           $result = &mt('Changed discussion status');       '0','0','','',$env{'form.previous'},undef,undef,undef,
       } else {  
           $result = &mt('Discussion status unchanged');  
       }  
       &redirect_back($r,$feedurl,$result.'<br />','0','0','','',  
                      $env{'form.previous'},undef,undef,undef,  
                      undef,undef,undef,$group);  
       return OK;  
   } elsif (($env{'form.like'}) || ($env{'form.unlike'})) {  
 # ----------------------------------------------------------------- Like/unlike  
       my $entry=$env{'form.like'}?$env{'form.like'}:$env{'form.unlike'};  
       my ($symb,$idx)=split(/\:\:\:/,$entry);  
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);  
       my $result;  
       if ($idx > 0) {  
           my $realsymb = &get_realsymb($symb);  
           my $status='OPEN';  
           if ($Apache::lonhomework::parsing_a_problem ||  
               $Apache::lonhomework::parsing_a_task) {  
               $status=$Apache::inputtags::status[-1];  
           }  
           if (&discussion_vote_available($status,$realsymb)) {  
               my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},  
                                                    $cdom,$cnum);  
               my $ownpost;  
               if (($contrib{$idx.':sendername'} eq $env{'user.name'}) &&  
                   ($contrib{$idx.':senderdomain'} eq $env{'user.domain'})) {  
                   $ownpost = 1;  
               }  
               if ($ownpost || $contrib{$idx.':hidden'} || $contrib{$idx.':deleted'}) {  
                   $result = &mt('Vote not registered.').' ';  
               }  
               if ($ownpost) {  
                   $result .= &mt('No voting for your own posts.');  
               } elsif ($contrib{$idx.':hidden'}) {  
                   $result .= &mt('No voting for hidden posts.');  
               } elsif ($contrib{$idx.':deleted'}) {  
                   $result .= &mt('No voting for deleted posts.');  
               } else {  
 #  
 # Likes and unlikes are in db-file "disclikes" of the course  
 # The prefix is the $symb to identify the resource discussion,  
 # and the $idx to identify the entry  
 #  
                   my $prefix=$symb.':'.$idx.':';  
                   my %likes=&Apache::lonnet::dump('disclikes',$cdom,$cnum,  
                                                   '^'.$prefix);  
   
 # Get current like or unlike status for the $idx for this user.  
                   my $thisuser=$env{'user.name'}.':'.$env{'user.domain'};  
                   my ($userlikes,$userunlikes);  
                   if (ref($likes{$prefix.'likers'}) eq 'HASH') {  
                       if (exists($likes{$prefix.'likers'}{$thisuser})) {  
                           $userlikes = 1;  
                       }  
                   }  
                   if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {  
                       if (exists($likes{$prefix.'unlikers'}{$thisuser})) {  
                           $userunlikes = 1;  
                       }  
                   }  
 # Get the current "likes" count  
                   my $likescount=$likes{$prefix.'likes'};  
 # Find out if they already voted  
 # Users cannot like a post twice, or unlike it twice.  
 # They can change their mind, though.  
                   my $alreadyflag=0;  
                   my $votetype;  
                   if ($env{'form.like'}) {  
                       if ($userlikes) {  
                           $alreadyflag=1;  
                       } elsif ($userunlikes) {  
                           delete($likes{$prefix.'unlikers'}{$thisuser});  
                           $votetype = 'switch';  
                           $likescount++;  
                       } else {  
                           if (ref($likes{$prefix.'likers'}) eq 'HASH') {  
                               $likes{$prefix.'likers'}{$thisuser} = 1;  
                           } else {  
                               $likes{$prefix.'likers'} = {$thisuser => 1};  
                           }  
                           $likescount++;  
                       }  
                   } else {  
                       if ($userunlikes) {  
                           $alreadyflag=1;  
                       } elsif ($userlikes) {  
                           delete($likes{$prefix.'likers'}{$thisuser});  
                           $votetype = 'switch';  
                           $likescount--;  
                       } else {  
                           if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {  
                               $likes{$prefix.'unlikers'}{$thisuser} = 1;  
                           } else {  
                               $likes{$prefix.'unlikers'} = {$thisuser => 1};  
                           }  
                           $likescount--;  
                       }  
                   }  
 # $alreadyflag would be 1 if they tried to double-like or double-unlike  
                   if ($alreadyflag) {  
                       if ($env{'form.like'}) {  
                           $result= &mt("'Like' already registered");  
                       } else {  
                           $result= &mt("'Unlike' already registered");  
                       }  
                   } else {  
                       my %newhash=($prefix.'likes'    => $likescount,  
                                    $prefix.'likers'   => $likes{$prefix.'likers'},  
                                    $prefix.'unlikers' => $likes{$prefix.'unlikers'});  
 # Store data in db-file "disclikes"  
                       if (&Apache::lonnet::put('disclikes',\%newhash,$cdom,$cnum) eq 'ok') {  
 # Also store with the person who posted the liked/unliked entry  
                           my ($chglike,$chgunlike);  
                           if ($env{'form.like'}) {  
                               if ($votetype eq 'switch') {  
                                   $chglike = 0;  
                                   $chgunlike = -1;  
                               } else {  
                                   $chglike = 1;  
                                   $chgunlike = 0;  
                               }  
                               &storediscussionlikes($chglike,$chgunlike,  
                                                     $contrib{$idx.':sendername'},  
                                                     $contrib{$idx.':senderdomain'},  
                                                     $env{'request.course.id'},'like');  
                               $result=&mt("Registered 'Like'");  
                           } else {  
                               if ($votetype eq 'switch') {  
                                   $chglike = -1;  
                                   $chgunlike = 0;  
                               } else {  
                                   $chglike = 0;  
                                   $chgunlike = 1;  
                               }  
                              &storediscussionlikes($chglike,$chgunlike,  
                                                    $contrib{$idx.':sendername'},  
                                                    $contrib{$idx.':senderdomain'},  
                                                    $env{'request.course.id'},'unlike');  
                              $result=&mt("Registered 'Unlike'");  
                           }  
                       } else {  
 # Oops, something went wrong  
                           $result=&mt("Failed to register vote");  
                       }  
                   }  
               }  
           } else {  
               $result=&mt('Voting unavailable for this discussion');  
           }  
       } else {  
           $result=&mt('Invalid post number');  
       }  
       &redirect_back($r,$feedurl,$result.'<br />',  
                      '0','0','','',$env{'form.previous'},undef,undef,undef,  
                      undef,undef,undef,$group);                       undef,undef,undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {    } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {
Line 4247  ENDREDIR Line 3685  ENDREDIR
 # --------------------------------------------------------------- Hide for good  # --------------------------------------------------------------- Hide for good
       my ($symb,$idx)=split(/\:\:\:/,$env{'form.deldisc'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.deldisc'});
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
       my $ressymb=&wrap_symb($symb);  
       unless (&can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum)) {  
           &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',  
                          '0','0','','',$env{'form.previous'},'','','','',  
                          undef,undef,$group);  
           return OK;  
       }  
       my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},        my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                            $cdom,$cnum);                            $env{'course.'.$env{'request.course.id'}.'.domain'},
             $env{'course.'.$env{'request.course.id'}.'.num'});
       my ($changelast,$newlast) = &get_discussion_info($idx,%contrib);        my ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
       if ($changelast) {        if ($changelast) {
           &Apache::lonnet::put('discussiontimes',{$symb => $newlast},            &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                                $cdom,$cnum);                     $env{'course.'.$env{'request.course.id'}.'.domain'},                   $env{'course.'.$env{'request.course.id'}.'.num'});
       }        }
       my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");        my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");
         &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
       my $result;     $env{'course.'.$env{'request.course.id'}.'.domain'},
       if (&Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},     $env{'course.'.$env{'request.course.id'}.'.num'});
                              $cdom,$cnum) eq 'ok') {        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
           $result = &mt('Changed discussion status');       '0','0','','',$env{'form.previous'},undef,undef,undef,
           my $prefix=$symb.':'.$idx.':';  
           my %likes=&Apache::lonnet::dump('disclikes',$cdom,$cnum,  
                                           '^'.$prefix);  
           my ($totallikes,$totalunlikes);  
           if (ref($likes{$prefix.'likers'}) eq 'HASH') {  
               $totallikes = scalar(keys(%{$likes{$prefix.'likers'}}));  
           }  
           if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {  
               $totalunlikes = scalar(keys(%{$likes{$prefix.'unlikers'}}));  
           }  
           if ($totallikes || $totalunlikes) {  
               my $chglikes = -1 * $totallikes;  
               my $chgunlikes = -1 * $totalunlikes;  
               &storediscussionlikes($chglikes,$chgunlikes,  
                                     $contrib{$idx.':sendername'},  
                                     $contrib{$idx.':senderdomain'},  
                                     $env{'request.course.id'},  
                                     'delete');  
           }  
       } else {  
           $result = &mt('Discussion status unchanged');  
       }  
       &redirect_back($r,$feedurl,$result.'<br />','0','0','','',  
                      $env{'form.previous'},undef,undef,undef,  
                      undef,undef,undef,$group);                       undef,undef,undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.preview'}) {    } elsif ($env{'form.preview'}) {
Line 4318  ENDREDIR Line 3726  ENDREDIR
       my $idx = $env{'form.idx'};        my $idx = $env{'form.idx'};
       if ($idx) {        if ($idx) {
           my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},            my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                                $cdom,$cnum);                           $env{'course.'.$env{'request.course.id'}.'.domain'},
                            $env{'course.'.$env{'request.course.id'}.'.num'});
           $attachmenturls = $contrib{$idx.':attachmenturl'};            $attachmenturls = $contrib{$idx.':attachmenturl'};
       }        }
       &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,        &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,
Line 4342  ENDREDIR Line 3751  ENDREDIR
   &Apache::loncommon::end_page();    &Apache::loncommon::end_page();
       $r->print($start_page.$discussion.$end_page);        $r->print($start_page.$discussion.$end_page);
       return OK;        return OK;
   } elsif ($env{'form.undeleteall'}) {  
       &Apache::loncommon::content_type($r,'text/html');  
       $r->send_http_header;  
       my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.undeleteall'});  
       my $ressymb=&wrap_symb($symb);  
       $r->print(&Apache::loncommon::start_page('Undelete all deleted discussion entries'));  
       if (&can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum)) {  
           my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},  
                                                 $cdom,$cnum);  
           $contrib{'deleted'} =~ s/^\.//;  
           $contrib{'deleted'} =~ s/\.$//;  
           if ($contrib{'deleted'} ne '') {  
               if (&Apache::lonnet::store({'deleted' => ''},$symb,$env{'request.course.id'},  
                                           $cdom,$cnum) eq 'ok') {  
                   my %likes=&Apache::lonnet::dump('disclikes',$cdom,$cnum,'^'.$symb.':');  
                   my @ids = split(/\.\./,$contrib{'deleted'});  
                   my (%chglikes,%chgunlikes);  
                   foreach my $idx (@ids) {  
                       my $uname = $contrib{$idx.':sendername'};  
                       my $udom = $contrib{$idx.':senderdomain'};  
                       my ($totallikes,$totalunlikes);  
                       if (ref($likes{$symb.':'.$idx.':likers'}) eq 'HASH') {  
                           $totallikes = scalar(keys(%{$likes{$symb.':'.$idx.':likers'}}));  
                       }  
                       if (ref($likes{$symb.':'.$idx.':unlikers'}) eq 'HASH') {  
                           $totalunlikes = scalar(keys(%{$likes{$symb.':'.$idx.':unlikers'}}));  
                       }  
                       if ($totallikes || $totalunlikes) {  
                           $chglikes{$uname.':'.$udom} += $totallikes;  
                           $chgunlikes{$uname.':'.$udom} += $totalunlikes;  
                       }  
                   }  
                   foreach my $user (keys(%chglikes)) {  
                       my ($uname,$udom) = split(/:/,$user);  
                       &storediscussionlikes($chglikes{$user},$chgunlikes{$user},  
                                             $uname,$udom,$env{'request.course.id'},  
                                             'undelete');  
                   }  
                   $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Undeleted all entries")));  
               } else {  
                   $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Failed to undelete entries"),1));  
               }  
           } else {  
               $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("No entries to undelete"),1));  
           }  
           $r->print("<br /><a href='$feedurl'>".&mt("Return and reload")."</a>");  
       }  
       $r->print(&Apache::loncommon::end_page());  
       return OK;  
   } else {    } else {
 # ------------------------------------------------------------- Normal feedback  # ------------------------------------------------------------- Normal feedback
       my $feedurl=$env{'form.postdata'};        my $feedurl=$env{'form.postdata'};
Line 4405  ENDREDIR Line 3765  ENDREDIR
       } elsif ($env{'form.editdisc'}) {        } elsif ($env{'form.editdisc'}) {
   $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];    $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
       } elsif ($env{'form.origpage'}) {        } elsif ($env{'form.origpage'}) {
   $symb="";    $symb=""; 
       } else {        } else {
   $symb=&Apache::lonnet::symbread($feedurl);    $symb=&Apache::lonnet::symbread($feedurl);
       }        }
Line 4458  ENDREDIR Line 3818  ENDREDIR
                   return OK;                    return OK;
               }                }
           }            }
   my $options=&screen_header($feedurl,$symb,$group);    my $options=&screen_header($feedurl,$symb);
   if ($options) {    if ($options) {
       &mail_screen($r,$feedurl,$options,$symb,$attachmax{'text'});        &mail_screen($r,$feedurl,$options,$symb,$attachmax{'text'});
   } else {    } else {
Line 4514  ENDREDIR Line 3874  ENDREDIR
           }            }
       }        }
 # Filter HTML out of message (could be nasty)  # Filter HTML out of message (could be nasty)
       my $override;        my $message=&clear_out_html($env{'form.comment'});
       if ($env{'form.discuss'} =~ /^(?:author|question|course|policy)$/) {  
           $override = 1;  
       }  
       my $message=&clear_out_html($env{'form.comment'},$override);  
          
   
 # Assemble email  # Assemble email
       my ($email,$citations)=&assemble_email($message,$prevattempts,        my ($email,$citations)=&assemble_email($message,$prevattempts,
Line 4529  ENDREDIR Line 3884  ENDREDIR
       my ($typestyle,%to) = &Apache::lonmsg::decide_receiver($feedurl);        my ($typestyle,%to) = &Apache::lonmsg::decide_receiver($feedurl);
   
 # Actually send mail  # Actually send mail
       my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'}),        my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'},
         undef,1),
       $feedurl,$email,$citations,        $feedurl,$email,$citations,
       $attachmenturl,$usersymb,%to);        $attachmenturl,$usersymb,%to);
   
Line 4538  ENDREDIR Line 3894  ENDREDIR
       if (  ($env{'form.discuss'} ne ''        if (  ($env{'form.discuss'} ne ''
      && $env{'form.discuss'} !~ /^(?:author|question|course|policy)/)       && $env{'form.discuss'} !~ /^(?:author|question|course|policy)/)
    || $env{'form.anondiscuss'} ne '') {     || $env{'form.anondiscuss'} ne '') {
   my $subject = &clear_out_html($env{'form.subject'});    my $subject = &clear_out_html($env{'form.subject'},undef,1);
   my $anonmode=($env{'form.discuss'} eq 'anon' || $env{'form.anondiscuss'} );    my $anonmode=($env{'form.discuss'} eq 'anon' || $env{'form.anondiscuss'} );
   $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl,    $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl,
   $subject,$group);    $subject);
   $numpost++;    $numpost++;
       }        }
   
Line 4549  ENDREDIR Line 3905  ENDREDIR
   
       my $blog='';        my $blog='';
       if ($env{'form.blog'}) {        if ($env{'form.blog'}) {
   my $subject = &clear_out_html($env{'form.subject'});    my $subject = &clear_out_html($env{'form.subject'},undef,1);
   $status.=&Apache::lonrss::addentry($env{'user.name'},    $status.=&Apache::lonrss::addentry($env{'user.name'},
     $env{'user.domain'},      $env{'user.domain'},
     'CourseBlog_'.$env{'request.course.id'},      'CourseBlog_'.$env{'request.course.id'},
Line 4585  sub wrap_symb { Line 3941  sub wrap_symb {
     }      }
     return $ressymb;      return $ressymb;
 }  }
   
 sub dewrapper {  sub dewrapper {
     my ($feedurl)=@_;      my ($feedurl)=@_;
     if ($$feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {      if ($$feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
Line 4739  None Line 4094  None
   
 =item discussion_visible()  =item discussion_visible()
   
 =item discussion_vote_available()  
   
 =item get_realsymb()  
   
 =item list_discussion()  =item list_discussion()
   
 =item can_see_hidden()  
   
 =item discussion_link()  
   
 =item send_feedback_link()  =item send_feedback_link()
   
 =item send_message_link()  =item send_message_link()

Removed from v.1.290.2.7.2.6  
changed lines
  Added in v.1.291


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