--- loncom/interface/lonfeedback.pm 2010/05/17 14:22:37 1.293 +++ loncom/interface/lonfeedback.pm 2010/11/20 01:07:05 1.304 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.293 2010/05/17 14:22:37 wenzelju Exp $ +# $Id: lonfeedback.pm,v 1.304 2010/11/20 01:07:05 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -49,13 +49,22 @@ use LONCAPA; sub discussion_open { my ($status,$symb)=@_; +# Advanced roles can always discuss 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) && !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER' || $status eq 'OPEN')) { return 0; } - my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb); +# The problem is available, but check if the instructor explictly closed discussion if (defined($close) && $close ne '' && $close < time) { return 0; } @@ -313,6 +322,7 @@ sub list_discussion { 'dpwn' => 'Deleted posts will no longer be visible to you and other students', 'bwco' => 'but will continue to be visible to your instructor', 'depo' => 'Deleted posts will no longer be visible to you or anyone else.', + 'discussions' => 'DISCUSSIONS' ); my $currdisp = $lt{'allposts'}; @@ -364,8 +374,7 @@ sub list_discussion { # Print the discusssion if ($outputtarget eq 'tex') { $discussion.='{\tiny \vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'. - '\textbf{DISCUSSIONS}\makebox[2 cm][b]{\hrulefill}'. - '\vskip 0 mm\noindent\textbf{'.$lt{'cuse'}.'}:\vskip 0 mm'. + '\textbf{'.$lt{'discussions'}.'}\makebox[2 cm][b]{\hrulefill}\vskip 0 mm'. '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'. '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}}'; } elsif ($outputtarget eq 'export') { @@ -509,7 +518,6 @@ imscp_v1p1.xsd http://www.imsglobal.org/ $threadinsert='
Reply: '.$thisdepth.''; } $discussionitems[$alldiscussion{$post}]=~s/<\/td>]*)>/$threadinsert<\/td>/; - $discussionitems[$alldiscussion{$post}]=~s/]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g; $discussionitems[$alldiscussion{$post}]=~s/(|<\/b>|<\/a>|]+)>)//g; $discussionitems[$alldiscussion{$post}]='\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.$discussionitems[$alldiscussion{$post}]; @@ -714,9 +722,10 @@ END $attachnum += @{$currnewattach}; } } - if (&discussion_open($status)) { + if ((&discussion_open($status)) && ($outputtarget ne 'tex')) { 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 .= &postingform_display($mode,$ressymb,$now,$subject, $comment,$outputtarget,$attachnum, @@ -724,26 +733,41 @@ END $group,$crstype); } } else { - $discussion.= - &postingform_display($mode,$ressymb,$now,$subject, - $comment,$outputtarget,$attachnum, - $currnewattach,$currdelold,'',$crstype); + if (&Apache::lonnet::allowed('pch',$env{'request.course.id'}. + ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) { + + $discussion.= + &postingform_display($mode,$ressymb,$now,$subject, + $comment,$outputtarget,$attachnum, + $currnewattach,$currdelold,'',$crstype); + } else { + $discussion.= ''. + &mt('This discussion is closed.').''; + } } } - } else { + if (!(&discussion_open($status)) && ($outputtarget ne 'tex')) { + $discussion.= ''. + &mt('This discussion is closed.').''; + } + } elsif ($outputtarget ne 'tex') { $discussion.=''; + $discussion.= &send_message_link($ressymb).''; } return $discussion; } @@ -775,7 +799,7 @@ sub action_links_bar { ''. '
'; my $escsymb=&escape($ressymb); - if ($visible>2) { + if ($visible) { $discussion .= ' @@ -842,7 +876,7 @@ sub postingform_display {
$lt{'note'}
$lt{'title'}: 

- + ENDDISCUSS if ($env{'form.origpage'}) { $postingform .= '\n"; - if ($outputtarget ne 'tex') { - $postingform .= &generate_attachments_button('',$attachnum,$ressymb, + $postingform .= &generate_attachments_button('',$attachnum,$ressymb, $now,$currnewattach, $currdelold,'',$mode, $blockblog); - if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) { - $newattachmsg = '
'.$lt{'newa'}.'
'; - if (@{$currnewattach} > 1) { - $newattachmsg .= '
    '; - foreach my $item (@{$currnewattach}) { - $item =~ m#.*/([^/]+)$#; - $newattachmsg .= '
  1. '.$1.'
  2. '."\n"; - } - $newattachmsg .= '
'."\n"; - } else { - $$currnewattach[0] =~ m#.*/([^/]+)$#; - $newattachmsg .= ''.$1.'
'."\n"; - } - } - $postingform .= $newattachmsg; - $postingform .= &generate_preview_button(); + if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) { + $newattachmsg = '
'.$lt{'newa'}.'
'; + if (@{$currnewattach} > 1) { + $newattachmsg .= '
    '; + foreach my $item (@{$currnewattach}) { + $item =~ m#.*/([^/]+)$#; + $newattachmsg .= '
  1. '.$1.'
  2. '."\n"; + } + $newattachmsg .= '
'."\n"; + } else { + $$currnewattach[0] =~ m#.*/([^/]+)$#; + $newattachmsg .= ''.$1.'
'."\n"; + } } + $postingform .= $newattachmsg; + $postingform .= &generate_preview_button(); return $postingform; } @@ -906,6 +938,19 @@ sub build_posting_display { if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) { $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'}) { my $oldest = $contrib{'1:timestamp'}; if ($prevread eq '0') { @@ -919,13 +964,13 @@ sub build_posting_display { } for (my $id=1;$id<=$contrib{'version'};$id++) { my $idx=$id; + next if ($contrib{$idx.':deleted'}); + next if ($contrib{$idx.':hidden'}); my $posttime = $contrib{$idx.':timestamp'}; if ($prevread <= $posttime) { $$newpostsflag = 1; } - my $hidden=($contrib{'hidden'}=~/\.$idx\./); my $studenthidden=($contrib{'studenthidden'}=~/\.$idx\./); - my $deleted=($contrib{'deleted'}=~/\.$idx\./); my $origindex='0.'; my $numoldver=0; if ($contrib{$idx.':replyto'}) { @@ -949,7 +994,7 @@ sub build_posting_display { } else { $$replies[$$depth[$idx]]=1; } - unless ((($hidden) && (!$seeid)) || ($deleted)) { + unless ((($hiddens{$idx}) && (!$seeid)) || ($deletions{$idx})) { $$visible++; if ($contrib{$idx.':history'}) { if ($contrib{$idx.':history'} =~ /:/) { @@ -983,7 +1028,7 @@ sub build_posting_display { $message.=$attachtxt{$numoldver}; $subject=$subjects{$numoldver}; if ($message) { - if ($hidden) { + if ($hiddens{$idx}) { $message=''.$message.''; if ($studenthidden) { $message .='

Deleted by poster (student).'; @@ -1047,48 +1092,50 @@ sub build_posting_display { } else { @{$$namesort{$lastname}{$firstname}} = ("$idx"); } - if (&editing_allowed($escsymb.':::'.$idx,$group)) { - if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) { - $sender.=' '.&mt('Edit').''; + if ($outputtarget ne 'tex') { + if (&editing_allowed($escsymb.':::'.$idx,$group)) { + if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) { + $sender.=' '.&mt('Edit').''; - unless ($seeid) { - my $grpargs = &group_args($group); - $sender.=" '; + unless ($seeid) { + my $grpargs = &group_args($group); + $sender.=" '; + } } } - } - if ($seeid) { - if ($hidden) { - unless ($studenthidden) { - $sender.=' '; + } + } else { + $sender.=' '.&mt('Make Visible').''; - } - } else { - $sender.=' '.&mt('Hide').''; - } - my $grpargs = &group_args($group); - $sender.= - " "; - $sender .= &mt('Delete').''; + $sender .= &group_args($group); + $sender .= '">'.&mt('Hide').''; + } + my $grpargs = &group_args($group); + $sender.= + " "; + $sender .= &mt('Delete').''; + } } - } else { + } else { if ($screenname) { $sender=''.$screenname.''; } else { @@ -1114,36 +1161,38 @@ sub build_posting_display { @{$$namesort{'__anon'}{'__anon'}} = ("$idx"); } } - if (&discussion_open($status)) { - if (($group ne '') && - (&check_group_priv($group,'pgd') eq 'ok')) { - $sender.=' '.&mt('Reply').''; - } elsif (&Apache::lonnet::allowed('pch', - $env{'request.course.id'}. - ($env{'request.course.sec'}?'/'. - $env{'request.course.sec'}:''))) { - $sender.=' '.&mt('Reply').''; + } elsif (&Apache::lonnet::allowed('pch', + $env{'request.course.id'}. + ($env{'request.course.sec'}?'/'. + $env{'request.course.sec'}:''))) { + $sender.=' '.&mt('Reply').''; } - $sender .= '" '.$target.'>'.&mt('Reply').''; } - } - if ($viewgrades) { + if ($viewgrades) { $vgrlink=&Apache::loncommon::submlink(&mt('Submissions'), - $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb); - } - if ($$dischash{$readkey}=~/\.$idx\./) { - $ctlink = ''; - } else { - $ctlink = ''; + $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb); + } + if ($$dischash{$readkey}=~/\.$idx\./) { + $ctlink = ''; + } else { + $ctlink = ''; + } } } #figure out at what position this needs to print @@ -1160,7 +1209,7 @@ sub build_posting_display { if ($outputtarget eq 'export') { %{$$imsitems{$idx}} = (); $$imsitems{$idx}{'isvisible'}='true'; - if ($hidden) { + if ($hiddens{$idx}) { $$imsitems{$idx}{'isvisible'}='false'; } $$imsitems{$idx}{'title'}=$subjects{$numoldver}; @@ -1242,7 +1291,7 @@ sub build_posting_display { $$newitem{$idx} = 1; $$discussionitems[$idx] .= ' - '; + '; } else { $$newitem{$idx} = 0; $$discussionitems[$idx] .= ' @@ -1663,6 +1712,17 @@ 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 my $brcrum = [{'href' => '', 'text' => 'Resource Feedback and Discussion'}]; @@ -1702,14 +1762,16 @@ END $r->print(< $quote -

$lt{'myqu'}

+

$lt{'myqu'} +$textareaheader +

$latexHelp

$lt{'title'}:

-

END if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) { @@ -1787,7 +1849,6 @@ END } } $r->print(&generate_preview_button(). - &Apache::lonhtmlcommon::htmlareaselectactive('comment'). &Apache::loncommon::end_page()); } @@ -2236,7 +2297,7 @@ sub print_showposters { my $group = $env{'form.group'}; my $ressymb = &wrap_symb($symb); if (($group ne '') && - ($ressymb =~ m|^bulletin___ \d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) { + ($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; } @@ -2569,7 +2630,7 @@ ENDNOREDIRTWO } sub screen_header { - my ($feedurl,$symb) = @_; + my ($feedurl,$symb,$group) = @_; my $crscontent = &mt('Question/Comment/Feedback about course content'); my $crspolicy = &mt('Question/Comment/Feedback about course policy'); my $contribdisc = &mt('Contribution to course discussion of resource'); @@ -2618,10 +2679,19 @@ sub screen_header { } if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) { my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards'); - if (!$blocked && &discussion_open(undef,$symb) && - &Apache::lonnet::allowed('pch', - $env{'request.course.id'}. - ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $realsymb = $symb; + if ($symb=~/^bulletin___/) { + my $filename=(&Apache::lonnet::decode_symb($symb))[2]; + $filename=~s|^adm/wrapper/||; + $realsymb=&Apache::lonnet::symbread($filename); + } + if (!$blocked && &discussion_open(undef,$realsymb) && + (&Apache::lonnet::allowed('pch', + $env{'request.course.id'}. + ($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='
'.&mt('NEW').'
'.&mt('NEW').' 
%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, DIV=>1, IMG=>1, - M=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1, + BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, PRE=>1, DIV=>1, IMG=>1, + M=>1, CHEM=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1, H1=>1, H2=>1, H3=>1, H4=>1, H5=>1, H6=>1, TABLE=>1, TR=>1, TD=>1, TH=>1, TBODY=>1); } @@ -2762,7 +2830,7 @@ sub send_msg { } sub adddiscuss { - my ($symb,$email,$anon,$attachmenturl,$subject)=@_; + my ($symb,$email,$anon,$attachmenturl,$subject,$group)=@_; my $status=''; my $realsymb; if ($symb=~/^bulletin___/) { @@ -2770,9 +2838,16 @@ sub adddiscuss { $filename=~s|^adm/wrapper/||; $realsymb=&Apache::lonnet::symbread($filename); } + my ($cnum,$cdom); + if ($env{'request.course.id'}) { + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + } if (&discussion_open(undef,$realsymb) && - &Apache::lonnet::allowed('pch',$env{'request.course.id'}. - ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) { + (&Apache::lonnet::allowed('pch',$env{'request.course.id'}. + ($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, 'sendername' => $env{'user.name'}, @@ -2923,7 +2998,7 @@ sub show_preview { &newline_to_br(\$message); $message=&Apache::lonspeller::markeduptext($message); $message=&Apache::lontexconvert::msgtexconverted($message); - my $subject=&clear_out_html($env{'form.subject'},undef,1); + my $subject=&clear_out_html($env{'form.subject'}); $subject=~s/\n/\
/g; $subject=&Apache::lontexconvert::msgtexconverted($subject); @@ -3035,7 +3110,7 @@ END {'bread_crumbs' => $brcrum,}); my $orig_subject = &unescape($env{'form.subject'}); - my $subject=&clear_out_html($orig_subject,undef,1); + my $subject=&clear_out_html($orig_subject); $subject=~s/\n/\
/g; $subject=&Apache::lontexconvert::msgtexconverted($subject); my $timestamp=$env{'form.timestamp'}; @@ -3817,7 +3892,7 @@ ENDREDIR return OK; } } - my $options=&screen_header($feedurl,$symb); + my $options=&screen_header($feedurl,$symb,$group); if ($options) { &mail_screen($r,$feedurl,$options,$symb,$attachmax{'text'}); } else { @@ -3873,7 +3948,11 @@ ENDREDIR } } # Filter HTML out of message (could be nasty) - my $message=&clear_out_html($env{'form.comment'}); + my $override; + if ($env{'form.discuss'} =~ /^(?:author|question|course|policy)$/) { + $override = 1; + } + my $message=&clear_out_html($env{'form.comment'},$override); # Assemble email my ($email,$citations)=&assemble_email($message,$prevattempts, @@ -3883,8 +3962,7 @@ ENDREDIR my ($typestyle,%to) = &Apache::lonmsg::decide_receiver($feedurl); # Actually send mail - my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'}, - undef,1), + my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'}), $feedurl,$email,$citations, $attachmenturl,$usersymb,%to); @@ -3893,10 +3971,10 @@ ENDREDIR if ( ($env{'form.discuss'} ne '' && $env{'form.discuss'} !~ /^(?:author|question|course|policy)/) || $env{'form.anondiscuss'} ne '') { - my $subject = &clear_out_html($env{'form.subject'},undef,1); + my $subject = &clear_out_html($env{'form.subject'}); my $anonmode=($env{'form.discuss'} eq 'anon' || $env{'form.anondiscuss'} ); $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl, - $subject); + $subject,$group); $numpost++; } @@ -3904,7 +3982,7 @@ ENDREDIR my $blog=''; if ($env{'form.blog'}) { - my $subject = &clear_out_html($env{'form.subject'},undef,1); + my $subject = &clear_out_html($env{'form.subject'}); $status.=&Apache::lonrss::addentry($env{'user.name'}, $env{'user.domain'}, 'CourseBlog_'.$env{'request.course.id'},