--- loncom/interface/lonfeedback.pm 2010/01/25 03:30:23 1.273.4.5 +++ loncom/interface/lonfeedback.pm 2010/06/05 22:07:05 1.295 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.273.4.5 2010/01/25 03:30:23 raeburn Exp $ +# $Id: lonfeedback.pm,v 1.295 2010/06/05 22:07:05 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -41,6 +41,7 @@ use Apache::lonnavmaps; use Apache::lonenc(); use Apache::lonrss(); use HTML::LCParser(); +#use HTML::Tidy::libXML; use Apache::lonspeller(); use Apache::longroup; use Cwd; @@ -48,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; } @@ -91,7 +101,7 @@ sub list_discussion { if (not &discussion_visible($status)) { if ($mode ne 'board') { &Apache::lonenc::check_encrypt(\$ressymb); - return '
'.&send_message_link($ressymb); + return '
"; } } if ($group ne '' && $mode eq 'board') { @@ -103,9 +113,12 @@ sub list_discussion { my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards'); if ($blocked) { + $blocktext = '
'; + }else{ + $blocktext.=""; } return $blocktext; } @@ -171,7 +184,6 @@ sub list_discussion { my $cnum = $env{'course.'.$cid.'.num'}; my $crstype = &Apache::loncommon::course_type(); - # Get information about students and non-students in course for filtering display of posts my %roleshash = (); my %roleinfo = (); @@ -270,10 +282,6 @@ sub list_discussion { my %anonhash=(); my $anoncnt=0; my $target=''; - unless ($env{'browser.interface'} eq 'textual' || - $env{'environment.remote'} eq 'off' ) { - $target='target="LONcom"'; - } my $now = time; $discinfo{$visitkey} = $visit; @@ -314,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'}; @@ -354,10 +363,10 @@ sub list_discussion { $togglink = 'toggoff'; } - $chglink .= '&changes='.$displinkA.'_'.$displinkB.'_'.$marklink.'_'.$togglink; + $chglink .= '&changes='.$displinkA.'_'.$displinkB.'_'.$marklink.'_'.$togglink; if ($newpostsflag) { - $chglink .= '&previous='.$prevread; + $chglink .= '&previous='.$prevread; } $chglink.=&group_args($group); @@ -365,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') { @@ -400,8 +408,7 @@ sub list_discussion { my $manifestfilename = $tempexport.$manifest; if ($manifestfile = Apache::File->new('>'.$manifestfilename)) { $manifestok=1; - print $manifestfile qq| - + print $manifestfile qq| - |; + |); $discussion.='
'. "\n".''; $discussion .= &action_links_bar($colspan,$ressymb,$visible, @@ -448,7 +453,7 @@ imscp_v1p1.xsd http://www.imsglobal.org/ $discussion.="\n".''; } $discussion .= (<'. - ''.&mt('Post Discussion').''; + '" border="0" />'.&mt('Post Discussion').''; return $output; } @@ -767,9 +776,9 @@ sub send_message_link { my ($ressymb) = @_; my $output = ''. ' '.&mt('Send Feedback').''; + &escape($ressymb).'">'.&mt('Send Feedback').''; return $output; } @@ -782,26 +791,26 @@ sub action_links_bar { if ($visible>2) { $discussion .= ''.&mt('Threaded View').'  '. ''.&mt('Chronological View').'   '.&mt('Sorting/Filtering options').''.(' ' x2); } $discussion .=''.&mt('Export').'?  '; @@ -827,6 +836,7 @@ sub action_links_bar { sub postingform_display { my ($mode,$ressymb,$now,$subject,$comment,$outputtarget,$attachnum, $currnewattach,$currdelold,$group,$crstype) = @_; + if ($outputtarget eq 'tex') { return ''; } my $newattachmsg; my %lt = &Apache::lonlocal::texthash( 'note' => 'Note: in anonymous discussion, your name is visible only to course faculty', @@ -846,7 +856,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; } @@ -1022,7 +1030,6 @@ sub build_posting_display { if ($see_anonymous) { $sender.=&Apache::loncommon::student_image_tag($contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'}); } - $sender = ''.$sender.''; # Set up for sorting by domain, then username unless (defined($$usernamesort{$contrib{$idx.':senderdomain'}})) { %{$$usernamesort{$contrib{$idx.':senderdomain'}}} = (); @@ -1057,7 +1064,7 @@ sub build_posting_display { $sender.=' '.&mt('Edit').''; @@ -1075,7 +1082,7 @@ sub build_posting_display { $sender.=' '.&mt('Make Visible').''; } @@ -1083,7 +1090,7 @@ sub build_posting_display { $sender.=' '.&mt('Hide').''; @@ -1099,6 +1106,7 @@ sub build_posting_display { } else { $sender=''.$$anonhash{$key}.''; } + $sender = ''.$sender.''; # Set up for sorting by domain, then username for anonymous unless (defined($$usernamesort{'__anon'})) { %{$$usernamesort{'__anon'}} = (); @@ -1124,7 +1132,7 @@ sub build_posting_display { $sender.=' '.&mt('Reply').''; @@ -1135,13 +1143,13 @@ sub build_posting_display { $sender.=' '.&mt('Reply').''; } } if ($viewgrades) { - $vgrlink=&Apache::loncommon::submlink('Submissions', + $vgrlink=&Apache::loncommon::submlink(&mt('Submissions'), $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb); } if ($$dischash{$readkey}=~/\.$idx\./) { @@ -1172,7 +1180,7 @@ sub build_posting_display { $$imsitems{$idx}{'attach'}=$attachtxt{$numoldver}; $$imsitems{$idx}{'timestamp'}=$contrib{$idx.':timestamp'}; $$imsitems{$idx}{'sender'}=$plainname.' ('. - $contrib{$idx.':sendername'}.' at '. + $contrib{$idx.':sendername'}.':'. $contrib{$idx.':senderdomain'}.')'; $$imsitems{$idx}{'isanonymous'}='false'; if ($contrib{$idx.':anonymous'}) { @@ -1245,12 +1253,12 @@ sub build_posting_display { if ($prevread > 0 && $prevread <= $posttime) { $$newitem{$idx} = 1; $$discussionitems[$idx] .= ' -

'. ''.&mt('Show all posts').' '.&mt('to display').' '. @@ -528,11 +533,11 @@ imscp_v1p1.xsd http://www.imsglobal.org/ print $manifestfile "\n". ''. - ''.$imsitems{$alldiscussion{$post}}{'title'}.''; + ''.$imsitems{$alldiscussion{$post}}{'title'}.''; $imsresources .= "\n". ''."\n". ''."\n". - $imsfiles{$alldiscussion{$post}}{$imsitems{$alldiscussion{$post}}{'currversion'}}."\n". + $imsfiles{$alldiscussion{$post}}{$imsitems{$alldiscussion{$post}}{'currversion'}}.''."\n". ''; } my $postingfile; @@ -644,7 +649,7 @@ END $discussion.=''. ''."\n". ''."\n". + ' onclick="this.form.submit();" />'."\n". '
- '; +
'.&mt('NEW').'
+ '; } else { $$newitem{$idx} = 0; $$discussionitems[$idx] .= ' -

'.&mt('NEW').' 
+
'; } $$discussionitems[$idx] .= ''; } $$discussionitems[$idx].= '
   '. @@ -1262,7 +1270,7 @@ sub build_posting_display { $ctlink.'
'. - $message.'

'; + $message.''; if ($contrib{$idx.':history'}) { my @postversions = (); $$discussionitems[$idx] .= &mt('This post has been edited by the author.'); @@ -1369,7 +1377,7 @@ sub get_post_contents { $$plainname, $$contrib{$idx.':sendername'}, $$contrib{$idx.':senderdomain'}).' ('. - $$contrib{$idx.':sendername'}.' at '. + $$contrib{$idx.':sendername'}.':'. $$contrib{$idx.':senderdomain'}.')'; my $attachmenturls = $$contrib{$idx.':attachmenturl'}; my @postversions = (); @@ -1397,7 +1405,9 @@ sub get_post_contents { my ($timesent,$attachmsg); my %currattach = (); $timesent = &Apache::lonlocal::locallocaltime($postversions[$i]); - &newline_to_br(\$messages->{$i}); + unless (&contains_block_html($messages->{$i})) { + &newline_to_br(\$messages->{$i}); + } $$messages{$i}=&Apache::lontexconvert::msgtexconverted($$messages{$i}); $$subjects{$i}=~s/\n/\
/g; $$subjects{$i}=&Apache::lontexconvert::msgtexconverted($$subjects{$i}); @@ -1411,7 +1421,7 @@ sub get_post_contents { foreach my $key (sort(keys(%currattach))) { if ($$allattachments{$key}{'filename'} =~ m-^/uploaded/([^/]+/[^/]+)(/feedback)?(/?\d*)/([^/]+)$-) { my $fname = $1.$3.'/'.$4; - $$imsfiles{$idx}{$i} .= ''."\n"; + $$imsfiles{$idx}{$i} .= ''."\n"; $$attachtxt{$i}.= ''.$4.'
'; } } @@ -1665,13 +1675,21 @@ END END + # Breadcrumbs + my $brcrum = [{'href' => '', + 'text' => 'Resource Feedback and Discussion'}]; + my %onload = ('onload' => 'window.focus();setposttype();'); my $start_page= &Apache::loncommon::start_page('Resource Feedback and Discussion',$js, - {'add_entries' => \%onload}); + {'add_entries' => \%onload, + 'bread_crumbs' => $brcrum,}); if ($quote ne '') { - &newline_to_br(\$quote); + $quote = &HTML::Entities::decode($quote); + unless (&contains_block_html($quote)) { + &newline_to_br(\$quote); + } $quote='
'.&Apache::lontexconvert::msgtexconverted($quote).'
'; } @@ -1703,9 +1721,8 @@ $latexHelp

$lt{'title'}:

-

-

END if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) { if ($env{'form.origpage'}) { @@ -1727,6 +1744,7 @@ END } } else { $r->print(< $lt{'atta'} $attachmaxtext:

END @@ -1740,7 +1758,7 @@ END $r->print(< - +

END @@ -1947,9 +1965,9 @@ END $r->print(<$lt{'disa'} $lt{$discdisp} - +
- + END $r->print(&Apache::loncommon::end_data_table_row()); @@ -1964,7 +1982,7 @@ END $r->print(<$lt{'dotm'} $lt{$disctogg} - + END my $save = &mt('Save'); $r->print(&Apache::loncommon::end_data_table_row()); @@ -1978,7 +1996,7 @@ END - + END if (exists($env{'form.group'})) { $r->print(''); @@ -2016,7 +2034,7 @@ sub print_sortfilter_options { $ccrole = 'co'; } push(@courseroles,$ccrole); - + if ($env{'request.course.sec'} !~ /^\s*$/) { #Restrict section choice to current section @sections = ('all',$env{'request.course.sec'}); $numvisible = 2; @@ -2196,7 +2214,7 @@ $start_page
- + END if (exists($env{'form.group'})) { $r->print(''); @@ -2319,7 +2337,7 @@ END
- + $end_page END @@ -2391,7 +2409,7 @@ sub fail_redirect { my ($r,$feedurl) = @_; if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' }; my %lt = &Apache::lonlocal::texthash( - 'sorr' => 'Sorry, no recipients ...', + 'sorr' => 'Sorry, no recipients ...', ); my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif'); $r->print(&Apache::loncommon::start_page('Feedback not sent',undef, @@ -2422,7 +2440,7 @@ sub redirect_back { if ($previous > 0) { $qrystr = 'previous='.$previous; if ($feedurl =~ /\?register=1/) { - $feedurl .= '&'.$qrystr; + $feedurl .= '&'.$qrystr; } else { $feedurl .= '?'.$qrystr; } @@ -2431,18 +2449,18 @@ sub redirect_back { if (defined($sort)) { my $sortqry = 'sortposts='.$sort; if (($feedurl =~ /\?register=1/) || ($feedurl =~ /\?previous=/)) { - $feedurl .= '&'.$sortqry; + $feedurl .= '&'.$sortqry; } else { $feedurl .= '?'.$sortqry; } $sorttag = ''; if (defined($numpicks)) { my $userpickqry = 'totposters='.$numpicks; - $feedurl .= '&'.$userpickqry; + $feedurl .= '&'.$userpickqry; $userpicktag = ''; } else { if (ref($sectionpick) eq 'ARRAY') { - $feedurl .= '§ionpick='; + $feedurl .= '&sectionpick='; $sectag .= ''; } else { - $feedurl .= '§ionpick='.$sectionpick; + $feedurl .= '&sectionpick='.$sectionpick; $sectag = ''; } if (ref($grouppick) eq 'ARRAY') { - $feedurl .= '&grouppick='; + $feedurl .= '&grouppick='; $sectag .= ''; } else { - $feedurl .= '&grouppick='.$grouppick; + $feedurl .= '&grouppick='.$grouppick; $grptag = ''; } if (ref($rolefilter) eq 'ARRAY') { - $feedurl .= '&rolefilter='; + $feedurl .= '&rolefilter='; $roletag .= ''; } else { - $feedurl .= '&rolefilter='.$rolefilter; + $feedurl .= '&rolefilter='.$rolefilter; $roletag = ''; } - $feedurl .= '&statusfilter='.$statusfilter; + $feedurl .= '&statusfilter='.$statusfilter; $statustag =''; } } @@ -2504,10 +2522,6 @@ sub redirect_back { &Apache::lonenc::check_encrypt(\$feedurl); my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif'); my %onload; - if ($env{'environment.remote'} ne 'off') { - $onload{'onload'} = - "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }"; - } my $start_page= &Apache::loncommon::start_page('Feedback sent',undef, {'redirect' => [0,$feedurl], @@ -2538,13 +2552,9 @@ ENDREDIR sub no_redirect_back { my ($r,$feedurl) = @_; - my $nofeed=&mt('Sorry, no feedback possible on this resource ...'); + my $nofeed=&mt('Sorry, no feedback possible on this resource ...'); my %onload; - if ($env{'environment.remote'} ne 'off') { - $onload{'onload'} = - "if (window.name!='loncapaclient') { self.window.close(); }"; - } my %body_options = ('only_body' => 1, 'bgcolor' => '#FFFFFF', @@ -2625,11 +2635,10 @@ sub screen_header { $env{'request.course.id'}. ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) { $discussoptions='
'. - + $contribdisc. + '
'. ''.&mt('Change Screenname').''; my $blockblog = &Apache::loncommon::blocking_status('blogs'); if (!$blockblog) { @@ -2638,12 +2647,12 @@ sub screen_header { } } if ($msgoptions) { - $msgoptions='

' + $msgoptions='

' .' '.&mt('Send Feedback').'

'.&Apache::lonhtmlcommon::coursepreflink(&mt('Feedback Settings'),'feedback').'

' .$msgoptions; } if ($discussoptions) { - $discussoptions='

' + $discussoptions='

' .' '.&mt('Discussion Contributions').'

'.&Apache::lonhtmlcommon::coursepreflink(&mt('Discussion Settings'),'discussion').'

' .$discussoptions; } @@ -2675,11 +2684,12 @@ sub clear_out_html { ($override)) { # allows


      • #

        - # + # %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, - H1=>1, H2=>1, H3=>1, H4=>1, H5=>1); + H1=>1, H2=>1, H3=>1, H4=>1, H5=>1, H6=>1, + TABLE=>1, TR=>1, TD=>1, TH=>1, TBODY=>1); } # Do the substitution of everything that is not explicitly allowed $message =~ s/\<(\/?\s*(\w+)[^\>\<]*)/ @@ -2696,6 +2706,9 @@ sub assemble_email { 'orig' => 'Original screen output (if applicable)', 'corr' => 'Correct Answer(s) (if applicable)', ); + if (&Apache::loncommon::course_type() eq 'Community') { + $lt{'prev'} = &mt('Previous attempts of member (if applicable)'); + } my $email=<<"ENDEMAIL"; $message ENDEMAIL @@ -2945,17 +2958,29 @@ sub show_preview { sub contains_block_html { my ($message)=@_; return ($message =~ m{ - <(br|h1|h2|h3|h4|h5|h6|p|ol|ul|table|pre|address|blockquote|center|div) - \s* - (\w+\=['"]\w+['"])* - \s* - ( - \s*/>| - >.* - )}xs + <(br|h1|h2|h3|h4|h5|h6|p|ol|ul|table|pre|address|blockquote|center|div) + \s* + (\w+\=['"]\w+['"])* + \s* + ( + \s*/>| + >.* + )}xs ); } +sub tidy_html { + my ($message)=@_; +# my $tidy = HTML::Tidy::libXML->new(); +# my $xhtml = $tidy->clean($message, 'utf-8', 1); +# $xhtml =~ m/(.*)<\/body>/is; +# my $clean = $1; +# # remove any empty block-level tags +# $clean =~ s/<(table|p|div|tbody|blockquote|m|pre|algebra|center|ol|ul|span|h1|h2|h3|h4|h5|h6)\s*\/>//i; +# $message=$clean; + return $message; +} + sub newline_to_br { my ($message)=@_; my $newmessage; @@ -2988,7 +3013,7 @@ sub generate_preview_button { +onclick="if (typeof(document.$formname.onsubmit)=='function') {document.$formname.onsubmit();};this.form.comment.value=document.$formname.$fieldname.value;this.form.subject.value=document.$formname.subject.value;this.form.submit();" /> ENDPREVIEW } @@ -3014,8 +3039,12 @@ sub modify_attachments { END + # Breadcrumbs + my $brcrum = [{'href' => '', + 'text' => 'Discussion Post Attachments'}]; my $start_page = - &Apache::loncommon::start_page('Discussion Post Attachments',$js); + &Apache::loncommon::start_page('Discussion Post Attachments',$js, + {'bread_crumbs' => $brcrum,}); my $orig_subject = &unescape($env{'form.subject'}); my $subject=&clear_out_html($orig_subject,undef,1); @@ -3071,7 +3100,7 @@ END @@ -3094,7 +3123,7 @@ END $r->print(''."\n"); } $r->print(< + $end_page END @@ -3141,7 +3170,7 @@ sub generate_attachments_button {
        $lt{'clic'}:  'Roles of any status', - Active => 'Only active roles', - Expired => 'Only past roles', - Future => 'Only future roles', - ); + all => 'Roles of any status', + Active => 'Only active roles', + Expired => 'Only past roles', + Future => 'Only future roles', + ); } } - + sub handler { my $r = shift; if ($r->header_only) { @@ -3424,7 +3453,13 @@ sub handler { &Apache::loncommon::no_cache($r); $r->send_http_header; - $r->print(&Apache::loncommon::start_page('Discussion Post Versions')); + # Breadcrumbs + my $brcrum = [{'href' => '', + 'text' => 'Discussion Post Versions'}]; + + $r->print(&Apache::loncommon::start_page('Discussion Post Versions',undef, + {'bread_crumbs' => $brcrum,}) + ); my $crs='/'.$env{'request.course.id'}; if ($env{'request.course.sec'}) { @@ -3528,10 +3563,6 @@ sub handler { $r->send_http_header; my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif'); my %onload; - if ($env{'environment.remote'} ne 'off') { - $onload{'onload'} = - "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }"; - } my $start_page= &Apache::loncommon::start_page('New posts marked as read',undef, @@ -4130,6 +4161,8 @@ None =item newline_to_br() +=item tidy_html() + =item generate_preview_button() =item modify_attachments()
        - $lt{'adda'} + $lt{'adda'}