version 1.313, 2012/01/03 01:51:00
|
version 1.333, 2012/01/10 14:52:57
|
Line 296 sub list_discussion {
|
Line 296 sub list_discussion {
|
my $copyresult; |
my $copyresult; |
|
|
my $function = &Apache::loncommon::get_users_function(); |
my $function = &Apache::loncommon::get_users_function(); |
my $color = &Apache::loncommon::designparm($function.'.tabbg', |
|
$env{'user.domain'}); |
|
my %lt = &Apache::lonlocal::texthash( |
my %lt = &Apache::lonlocal::texthash( |
'cuse' => 'Current discussion settings', |
'cuse' => 'My settings for this discussion', |
'allposts' => 'All posts', |
'allposts' => 'All posts', |
'unread' => 'New posts only', |
'unread' => 'New posts only', |
'unmark' => 'Unread only', |
'unmark' => 'Unread only', |
Line 441 imscp_v1p1.xsd http://www.imsglobal.org/
|
Line 439 imscp_v1p1.xsd http://www.imsglobal.org/
|
} |
} |
|); |
|); |
$discussion.='<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$ressymb.'" >'. |
$discussion.='<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$ressymb.'" >'. |
"\n".'<table class="LC_discussion">'; |
"\n".'<table width="100%" class="LC_discussion">'; |
$discussion .= &action_links_bar($colspan,$ressymb,$visible, |
$discussion .= &action_links_bar($colspan,$ressymb,$visible, |
$newpostsflag,$group, |
$newpostsflag,$group, |
$prevread,$markondisp); |
$prevread,$markondisp); |
Line 504 imscp_v1p1.xsd http://www.imsglobal.org/
|
Line 502 imscp_v1p1.xsd http://www.imsglobal.org/
|
my $thisdepth=$depth[$alldiscussion{$post}]; |
my $thisdepth=$depth[$alldiscussion{$post}]; |
if ($outputtarget ne 'tex' && $outputtarget ne 'export') { |
if ($outputtarget ne 'tex' && $outputtarget ne 'export') { |
for (1..$thisdepth) { |
for (1..$thisdepth) { |
$discussion.='<td> </td>'; |
$discussion.='<td> </td>'; |
} |
} |
} |
} |
my $colspan=$maxdepth-$thisdepth+1; |
my $colspan=$maxdepth-$thisdepth+1; |
Line 562 imscp_v1p1.xsd http://www.imsglobal.org/
|
Line 560 imscp_v1p1.xsd http://www.imsglobal.org/
|
unless ($outputtarget eq 'tex' || $outputtarget eq 'export') { |
unless ($outputtarget eq 'tex' || $outputtarget eq 'export') { |
my $colspan=$maxdepth+1; |
my $colspan=$maxdepth+1; |
$discussion .= <<END; |
$discussion .= <<END; |
<tr bgcolor="#FFFFFF"> |
<tr> |
<td colspan="$colspan" class="LC_disc_action_links_bar"> |
<td colspan="$colspan"> |
<table class="LC_disc_action_table"> |
<table width="100%"> |
<tr> |
<tr> |
<td align="left"> |
<td class="LC_disc_action_left"> |
<table border="0" cellpadding="0" cellspacing="4"> |
<font size="-1"><b>$lt{'cuse'}</b>: |
<tr> |
|
<td> |
|
<font size="-1"><b>$lt{'cuse'}</b>:</font></td> |
|
<td> </td> |
|
<td><font size="-1"> |
|
END |
END |
if ($newpostsflag) { |
if ($newpostsflag) { |
$discussion .= |
$discussion .= |
Line 589 END
|
Line 582 END
|
} |
} |
} |
} |
$discussion .= <<END; |
$discussion .= <<END; |
</font></td> |
<b><a href="$chglink">$lt{'chgt'}</a></b></font> |
<td> </td> |
|
<td align="left"> |
|
<font size="-1"><b><a href="$chglink">$lt{'chgt'}</a>?</b></font> |
|
</td> |
|
</tr> |
|
</table> |
|
</td> |
</td> |
END |
END |
if ($sortposts) { |
if ($sortposts) { |
Line 604 END
|
Line 591 END
|
my %status_types = (); |
my %status_types = (); |
&sort_filter_names(\%sort_types,\%role_types,\%status_types,$crstype); |
&sort_filter_names(\%sort_types,\%role_types,\%status_types,$crstype); |
|
|
$discussion .= '<td><font size="-1"><b>'.&mt('Sorted by').'</b>: '.$sort_types{$sortposts}.'<br />'; |
$discussion .= '<td class="LC_disc_action_right"><font size="-1"><b>'.&mt('Sorted by').'</b>: '.$sort_types{$sortposts}.'<br />'; |
if (defined($env{'form.totposters'})) { |
if (defined($env{'form.totposters'})) { |
$discussion .= &mt('Posts by').':'; |
$discussion .= &mt('Posts by').':'; |
if ($totposters > 0) { |
if ($totposters > 0) { |
Line 660 END
|
Line 647 END
|
$discussion .= &action_links_bar($colspan,$ressymb,$visible, |
$discussion .= &action_links_bar($colspan,$ressymb,$visible, |
$newpostsflag,$group, |
$newpostsflag,$group, |
$prevread,$markondisp); |
$prevread,$markondisp); |
$discussion .= " |
$discussion .= "</table></form>\n"; |
</table> |
|
<br /><br /></form>\n"; |
|
} |
} |
if ($outputtarget eq 'export') { |
if ($outputtarget eq 'export') { |
if ($manifestok) { |
if ($manifestok) { |
Line 774 END
|
Line 759 END
|
|
|
|
|
sub discussion_link { |
sub discussion_link { |
my ($ressymb,$linktext,$cmd,$item,$flag,$prev,$adds)=@_; |
my ($ressymb,$linktext,$cmd,$item,$flag,$prev,$adds,$title)=@_; |
my $link='/adm/feedback?inhibitmenu=yes&modal=yes&'.$cmd.'='.&escape($ressymb).':::'.$item; |
my $link='/adm/feedback?inhibitmenu=yes&modal=yes&'.$cmd.'='.&escape($ressymb).':::'.$item; |
if ($flag) { $link .= '&previous='.$prev; } |
if ($flag) { $link .= '&previous='.$prev; } |
if ($adds) { $link .= $adds; } |
if ($adds) { $link .= $adds; } |
return &Apache::loncommon::modal_link($link,$linktext,600,600); |
my $width=600; |
|
my $height=600; |
|
if (($cmd eq 'hide') || ($cmd eq 'unhide') || ($cmd eq 'like') || ($cmd eq 'unlike')) { |
|
$width=300; |
|
$height=200; |
|
} |
|
return &Apache::loncommon::modal_link($link,$linktext,$width,$height,undef,undef,$title); |
} |
} |
|
|
|
|
Line 796 sub send_feedback_link {
|
Line 787 sub send_feedback_link {
|
sub send_message_link { |
sub send_message_link { |
my ($ressymb) = @_; |
my ($ressymb) = @_; |
my $output = '<span class="LC_message_link">'. |
my $output = '<span class="LC_message_link">'. |
' <a href="/adm/feedback?sendmessageonly=1&symb='. |
&discussion_link($ressymb, |
&escape($ressymb).'"><img alt="" class="LC_noBorder" src="'. |
'<img alt="" class="LC_noBorder" src="'. |
&Apache::loncommon::lonhttpdurl('/res/adm/pages/feedback.png'). |
&Apache::loncommon::lonhttpdurl('/res/adm/pages/feedback.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>', |
|
'sendmessageonly'). |
|
'</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) = @_; |
my $discussion = '<tr><td class="LC_disc_action_links_bar" colspan="'.$colspan.'">'. |
my $discussion = '<tr><td colspan="'.$colspan.'">'. |
'<table width="100%" class="LC_disc_action_table"><tr>'. |
'<table width="100%"><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) { |
Line 829 sub action_links_bar {
|
Line 822 sub action_links_bar {
|
} |
} |
$otherviewurl .= &group_args($group); |
$otherviewurl .= &group_args($group); |
$discussion .= &Apache::loncommon::modal_link($otherviewurl,&mt('Other Views ...'),800,340); |
$discussion .= &Apache::loncommon::modal_link($otherviewurl,&mt('Other Views ...'),800,340); |
$discussion .=(' ' x2); |
$discussion .= '<br />'; |
} |
} |
$discussion .='<a href="/adm/feedback?export='.$escsymb; |
$discussion .='<a href="/adm/feedback?export='.$escsymb; |
if ($newpostsflag) { |
if ($newpostsflag) { |
$discussion .= '&previous='.$prevread; |
$discussion .= '&previous='.$prevread; |
} |
} |
$discussion .= &group_args($group); |
$discussion .= &group_args($group); |
$discussion .= '">'.&mt('Export').'?</a> </td>'; |
$discussion .= '">'.&mt('Export').'</a>'; |
|
if (&Apache::lonnet::allowed('rin',$env{'request.course.id'})) { |
|
$discussion .= ' '; |
|
$discussion .='<a href="/adm/feedback?undeleteall='.$escsymb; |
|
if ($newpostsflag) { |
|
$discussion .= '&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'; |
$discussion .= &group_args($group); |
$discussion .= &group_args($group); |
$discussion .= '">'. |
$discussion .= '">'. |
&mt('Preferences on what is marked as NEW'). |
&mt('My general preferences on what is marked as NEW'). |
'</a><br /><a href="/adm/feedback?markread=1&symb='.$escsymb; |
'</a><br /><a href="/adm/feedback?markread=1&symb='.$escsymb; |
$discussion .= &group_args($group); |
$discussion .= &group_args($group); |
$discussion .= '">'.&mt('Mark NEW posts no longer new').'</a></td>'; |
$discussion .= '">'.&mt('Mark NEW posts no longer new').'</a></td>'; |
Line 885 sub postingform_display {
|
Line 888 sub postingform_display {
|
<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" /> |
<input type="hidden" name="timestamp" value="$now" /> |
<input type="hidden" name="timestamp" value="$now" /> |
<br /><a name="newpost"></a> |
<a name="newpost"></a> |
<font size="1">$lt{'note'}</font><br /> |
<font size="1">$lt{'note'}</font><br /> |
<b>$lt{'title'}:</b> <input type="text" name="subject" value="$subject" size="30" /><br /><br /> |
<b>$lt{'title'}:</b> <input type="text" name="subject" value="$subject" size="30" /><br /> |
<textarea name="comment" cols="80" rows="14" id="comment" $textareaclass>$comment</textarea> |
<textarea name="comment" cols="80" rows="14" id="comment" $textareaclass>$comment</textarea> |
ENDDISCUSS |
ENDDISCUSS |
if ($env{'form.origpage'}) { |
if ($env{'form.origpage'}) { |
Line 940 sub build_posting_display {
|
Line 943 sub build_posting_display {
|
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'}); |
|
# And these are the likes/unlikes |
|
my %likes=&Apache::lonnet::dump('disclikes', |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'}, |
|
'^'.$symb.':'); |
|
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
|
# Array with likes to figure out averages, etc. |
|
my @theselikes=(); |
|
# 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; |
} |
} |
|
# Deletions and hiddens are just lists. Split them up into a hash for quicker lookup |
my (%deletions,%hiddens); |
my (%deletions,%hiddens); |
if ($contrib{'deleted'}) { |
if ($contrib{'deleted'}) { |
my $deleted = $contrib{'deleted'}; |
my $deleted = $contrib{'deleted'}; |
Line 963 sub build_posting_display {
|
Line 976 sub build_posting_display {
|
$hidden =~ s/\.$//; |
$hidden =~ s/\.$//; |
%hiddens = map { $_ => 1 } (split(/\.\./,$hidden)); |
%hiddens = map { $_ => 1 } (split(/\.\./,$hidden)); |
} |
} |
|
# Versions if store/restore are used to actually store the messages. |
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 973 sub build_posting_display {
|
Line 987 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; |
} |
} |
|
# 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}) && (!$seeid)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) { |
|
push(@theselikes,$likes{$symb.':'.$idx.':likes'}); |
|
} |
|
} |
|
# 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 |
|
my $oneplus=$ave+$stddev; |
|
my $twoplus=$ave+2.*$stddev; |
|
my $oneminus=$ave-$stddev; |
|
my $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.':deleted'}); |
next if ($contrib{$idx.':hidden'}); |
next if ($contrib{$idx.':hidden'}); |
|
# If we get here, we are actually going to display the message - we don't know where and we don't know if we display |
|
# previous edits, but it counts as one entry |
my $posttime = $contrib{$idx.':timestamp'}; |
my $posttime = $contrib{$idx.':timestamp'}; |
if ($prevread <= $posttime) { |
if ($prevread <= $posttime) { |
$$newpostsflag = 1; |
$$newpostsflag = 1; |
Line 1105 sub build_posting_display {
|
Line 1155 sub build_posting_display {
|
@{$$namesort{$lastname}{$firstname}} = ("$idx"); |
@{$$namesort{$lastname}{$firstname}} = ("$idx"); |
} |
} |
if ($outputtarget ne 'tex') { |
if ($outputtarget ne 'tex') { |
|
my $karma=&userkarma($contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
|
for (my $i=1;$i<=$karma;$i++) { |
|
$sender.='<img border="0" src="/res/adm/pages/star.gif" alt="'.&mt('Contributor Kudos').'" />'; |
|
} |
|
unless ($likes{$symb.':'.$idx.':likers'}=~/\,\Q$thisuser\E\,/) { |
|
$sender.=' '.&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")); |
|
} |
|
unless ($likes{$symb.':'.$idx.':unlikers'}=~/\,\Q$thisuser\E\,/) { |
|
$sender.=' '.&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")); |
|
} |
|
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
|
if ($thislikes>0) { |
|
$sender.=' ('.&mt("[_1] likes",$thislikes).')'; |
|
} elsif ($thislikes<0) { |
|
$sender.=' ('.&mt("[_1] unlikes",abs($thislikes)).')'; |
|
} |
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.=' '. |
$sender.=' '. |
Line 1277 sub build_posting_display {
|
Line 1343 sub build_posting_display {
|
unless ($$notshown{$idx} == 1) { |
unless ($$notshown{$idx} == 1) { |
if ($prevread > 0 && $prevread <= $posttime) { |
if ($prevread > 0 && $prevread <= $posttime) { |
$$newitem{$idx} = 1; |
$$newitem{$idx} = 1; |
$$discussionitems[$idx] .= ' |
$$discussionitems[$idx] .= '<font color="#FF0000"><b>'.&mt('NEW').' </b></font>'; |
<table border="0" width="100%"> |
|
<tr><td align="left"><font color="#FF0000"><b>'.&mt('NEW').' </b></font></td>'; |
|
} else { |
} else { |
$$newitem{$idx} = 0; |
$$newitem{$idx} = 0; |
$$discussionitems[$idx] .= ' |
|
<table border="0" width="100%"> |
|
<tr><td align="left"> </td>'; |
|
} |
} |
$$discussionitems[$idx] .= '<td align="left"> '. |
$$discussionitems[$idx] .= '<b>'.$subject.'</b> '. |
'<b>'.$subject.'</b> '. |
|
$sender.' '.$vgrlink.' ('. |
$sender.' '.$vgrlink.' ('. |
&Apache::lonlocal::locallocaltime($posttime).')</td>'; |
&Apache::lonlocal::locallocaltime($posttime).')'; |
if ($$dischash{$toggkey}) { |
if ($$dischash{$toggkey}) { |
$$discussionitems[$idx].='<td align="right"> '. |
$$discussionitems[$idx].=' '.$ctlink; |
$ctlink.'</td>'; |
|
} |
} |
$$discussionitems[$idx].= '</tr></table><blockquote>'. |
# Figure out size based on likes |
$message.'</blockquote>'; |
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
|
my $likesize="100"; |
|
if ($thislikes>$twoplus) { |
|
$likesize="200"; |
|
} elsif ($thislikes>$oneplus) { |
|
$likesize="150"; |
|
} |
|
if ($thislikes<$twominus) { |
|
$likesize="50"; |
|
} elsif ($thislikes<$oneminus) { |
|
$likesize="75"; |
|
} |
|
$$discussionitems[$idx].= '<br /><blockquote>'. |
|
"<div style='font-size:$likesize%'>". |
|
$message. |
|
'</div></blockquote>'; |
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.'); |
Line 1314 sub build_posting_display {
|
Line 1388 sub build_posting_display {
|
$$discussionitems[$idx] .= '<b>'.$version.'.</b> - '.&Apache::lonlocal::locallocaltime($postversions[$i]).' '; |
$$discussionitems[$idx] .= '<b>'.$version.'.</b> - '.&Apache::lonlocal::locallocaltime($postversions[$i]).' '; |
} |
} |
} |
} |
|
# end of unless ($$notshown ...) |
} |
} |
|
# end of if ($message) ... |
} |
} |
|
# end of the else-branch of target being export |
} |
} |
|
# end of unless hidden or deleted |
} |
} |
|
# end of the loop over all discussion entries |
} |
} |
|
# end of "if there actually are any discussions |
} |
} |
|
# end of subroutine "build_posting_display" |
} |
} |
|
|
sub filter_regexp { |
sub filter_regexp { |
Line 2605 sub no_redirect_back {
|
Line 2686 sub no_redirect_back {
|
'add_entries' => \%onload,); |
'add_entries' => \%onload,); |
|
|
if ($feedurl !~ m{^/adm/feedback}) { |
if ($feedurl !~ m{^/adm/feedback}) { |
$body_options{'rediect'} = [2,$feedurl]; |
$body_options{'redirect'} = [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 2647 sub screen_header {
|
Line 2728 sub screen_header {
|
unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) { |
unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) { |
if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/) && ($env{'user.adv'})) { |
if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/) && ($env{'user.adv'})) { |
$msgoptions= |
$msgoptions= |
'<p><label><input type="radio" name="discuss" value="author" /> '. |
'<label><input type="radio" name="discuss" value="author" /> '. |
&mt('Feedback to resource author').'</label></p>'; |
&mt('Feedback to resource author').'</label><br />'; |
} |
} |
my %optionhash=(); |
my %optionhash=(); |
foreach my $type ('question','comment','policy') { |
foreach my $type ('question','comment','policy') { |
Line 2656 sub screen_header {
|
Line 2737 sub screen_header {
|
} |
} |
if (&feedback_available(1)) { |
if (&feedback_available(1)) { |
$msgoptions.= |
$msgoptions.= |
'<p><label><input type="radio" name="discuss" value="question" /> '. |
'<label><input type="radio" name="discuss" value="question" /> '. |
($optionhash{'question'}?$optionhash{'question'}:&mt('Question about resource content')).'</label></p>'; |
($optionhash{'question'}?$optionhash{'question'}:&mt('Question about resource content')).'</label><br />'; |
} |
} |
if (&feedback_available(0,1)) { |
if (&feedback_available(0,1)) { |
$msgoptions.= |
$msgoptions.= |
'<p><label><input type="radio" name="discuss" value="course" /> '. |
'<label><input type="radio" name="discuss" value="course" /> '. |
($optionhash{'comment'}?$optionhash{'comment'}:$crscontent). |
($optionhash{'comment'}?$optionhash{'comment'}:$crscontent). |
'</label></p>'; |
'</label><br />'; |
} |
} |
if (&feedback_available(0,0,1)) { |
if (&feedback_available(0,0,1)) { |
$msgoptions.= |
$msgoptions.= |
'<p><label><input type="radio" name="discuss" value="policy" /> '. |
'<label><input type="radio" name="discuss" value="policy" /> '. |
($optionhash{'policy'}?$optionhash{'policy'}:$crspolicy). |
($optionhash{'policy'}?$optionhash{'policy'}:$crspolicy). |
'</label></p>'; |
'</label><br />'; |
} |
} |
} |
} |
if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) { |
if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) { |
Line 2809 sub send_msg {
|
Line 2890 sub send_msg {
|
} |
} |
} |
} |
|
|
|
# Records of number of feedback messages are kept under the "symb" called "_feedback" |
my %record=&Apache::lonnet::restore('_feedback'); |
# There are two entries within the framework of a course: |
my ($temp)=keys(%record); |
# - the URLs for which feedback was provided |
unless ($temp=~/^error\:/) { |
# - the total number of contributions |
my %newrecord=(); |
if ($sendsomething) { |
$newrecord{'resource'}=$feedurl; |
my %record=&getfeedbackrecords(); |
$newrecord{'subnumber'}=$record{'subnumber'}+1; |
my ($temp)=keys(%record); |
unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') { |
unless ($temp=~/^error\:/) { |
$status.='<br />'.&mt('Not registered').'<br />'; |
my %newrecord=(); |
} |
$newrecord{'resource'}=$feedurl; |
|
$newrecord{'subnumber'}=$record{'subnumber'}+1; |
|
unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') { |
|
$status.='<br />'.&mt('Not registered').'<br />'; |
|
} |
|
} |
} |
} |
|
|
return ($status,$sendsomething); |
return ($status,$sendsomething); |
} |
} |
|
|
|
# Routine to get the complete feedback records |
|
|
|
sub getfeedbackrecords { |
|
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('_feedback',$course,$udom,$uname); |
|
return %record; |
|
} |
|
|
|
# Routine to get feedback statistics |
|
|
|
sub getfeedbackstats { |
|
my %record=&getfeedbackrecords(@_); |
|
return ($record{'subnumber'},$record{'points'},$record{'totallikes'}); |
|
} |
|
|
|
# Store feedback credit |
|
|
|
sub storefeedbackpoints { |
|
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,'_feedback',$course,$udom,$uname); |
|
} |
|
|
|
# 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,$group)=@_; |
my $status=''; |
my $status=''; |
Line 2922 sub adddiscuss {
|
Line 3060 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=&Apache::lonnet::restore('_discussion'); |
my %record=&getdiscussionrecords(); |
my ($temp)=keys(%record); |
my ($temp)=keys(%record); |
unless ($temp=~/^error\:/) { |
unless ($temp=~/^error\:/) { |
my %newrecord=(); |
my %newrecord=(); |
Line 2930 sub adddiscuss {
|
Line 3068 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 2937 sub adddiscuss {
|
Line 3076 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(@_); |
|
return ($record{'subnumber'},$record{'points'},$record{'totallikes'},$record{'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 ($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=&getdiscussionrecords($uname,$udom,$course); |
|
my $totallikes=$record{'totallikes'}; |
|
my $totalvotes=$record{'totalvotes'}; |
|
$totallikes+=$likes; |
|
$totalvotes++; |
|
my %newrecord=('likes_user' => $env{'user.name'}, |
|
'likes_domain' => $env{'user.domain'}, |
|
'likes' => $likes, |
|
'totallikes' => $totallikes, |
|
'totalvotes' => $totalvotes); |
|
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 3465 sub handler {
|
Line 3708 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'}, |
['modal','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']); |
['like','unlike','modal','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']); |
my $group = $env{'form.group'}; |
my $group = $env{'form.group'}; |
my %attachmax = ( |
my %attachmax = ( |
text => &mt('(128 KB max size)'), |
text => &mt('(128 KB max size)'), |
Line 3740 ENDREDIR
|
Line 3983 ENDREDIR
|
'0','0','','',$env{'form.previous'},undef,undef,undef, |
'0','0','','',$env{'form.previous'},undef,undef,undef, |
undef,undef,undef,$group); |
undef,undef,undef,$group); |
return OK; |
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); |
|
# |
|
# 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 %contrib=&Apache::lonnet::dump('disclikes', |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'}, |
|
'^'.$prefix); |
|
# Get all who like or unlike this |
|
my $currentlikers=$contrib{$prefix.'likers'}; |
|
my $currentunlikers=$contrib{$prefix.'unlikers'}; |
|
# Get the current "likes" count |
|
my $likes=$contrib{$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 $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
|
if ($env{'form.like'}) { |
|
if ($currentlikers=~/\,\Q$thisuser\E\,/) { |
|
$alreadyflag=1; |
|
} else { |
|
if ($currentunlikers=~/\,\Q$thisuser\E\,/) { |
|
$currentunlikers=~s/\,\Q$thisuser\E\,//g; |
|
} else { |
|
$currentlikers.=','.$thisuser.','; |
|
} |
|
$likes++; |
|
} |
|
} else { |
|
if ($currentunlikers=~/\,\Q$thisuser\E\,/) { |
|
$alreadyflag=1; |
|
} else { |
|
if ($currentlikers=~/\,\Q$thisuser\E\,/) { |
|
$currentlikers=~s/\,\Q$thisuser\E\,//g; |
|
} else { |
|
$currentunlikers.=','.$thisuser.','; |
|
} |
|
$likes--; |
|
} |
|
} |
|
my $result; |
|
# $alreadyflag would be 1 if they tried to double-like or double-unlike |
|
unless ($alreadyflag) { |
|
my %newhash=($prefix.'likes' => $likes, |
|
$prefix.'likers' => $currentlikers, |
|
$prefix.'unlikers' => $currentunlikers); |
|
# Store data in db-file "disclikes" |
|
if (&Apache::lonnet::put('disclikes', |
|
\%newhash, |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { |
|
# Also store with the person who posted the liked/unliked entry |
|
if ($env{'form.like'}) { |
|
&storediscussionlikes(1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
|
$result=&mt("Registered 'Like'"); |
|
} else { |
|
&storediscussionlikes(-1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
|
$result=&mt("Registered 'Unlike'"); |
|
} |
|
} else { |
|
# Oops, something went wrong |
|
$result=&mt("Failed to register vote"); |
|
} |
|
} |
|
&redirect_back($r,$feedurl,$result.'<br />', |
|
'0','0','','',$env{'form.previous'},undef,undef,undef, |
|
undef,undef,undef,$group); |
|
return OK; |
} elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) { |
} elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) { |
my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'}); |
my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'}); |
if ($env{'form.cmd'} eq 'threadedon') { |
if ($env{'form.cmd'} eq 'threadedon') { |
Line 3823 ENDREDIR
|
Line 4141 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'}); |
|
$r->print(&Apache::loncommon::start_page('Undelete all deleted discussion entries')); |
|
if (&Apache::lonnet::allowed('rin',$env{'request.course.id'})) { |
|
if (&Apache::lonnet::store({'deleted' => ''},$symb,$env{'request.course.id'}, |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { |
|
$r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Undeleted all entries"))); |
|
} else { |
|
$r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Failed to undelete entries"),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 3838 ENDREDIR
|
Line 4174 ENDREDIR
|
$symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0]; |
$symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0]; |
} elsif ($env{'form.origpage'}) { |
} elsif ($env{'form.origpage'}) { |
$symb=""; |
$symb=""; |
|
} elsif ($env{'form.sendmessageonly'}) { |
|
$symb=(split(/\:\:\:/,$env{'form.sendmessageonly'}))[0]; |
} else { |
} else { |
$symb=&Apache::lonnet::symbread($feedurl); |
$symb=&Apache::lonnet::symbread($feedurl); |
} |
} |