ljr/livejournal/htdocs/support/help.bml

352 lines
13 KiB
Plaintext
Raw Normal View History

2019-02-05 21:49:12 +00:00
<?page
head<=
<style type='text/css'>
.green {
background-color: #d0eed0;
}
.yellow {
background-color: #eeeed0;
}
.red {
background-color: #eed0d0;
}
.clicked {
background-color: #d0d0ee;
}
</style>
<script type='text/javascript'>
<!--
function doClick(spid) {
if (!document.getElementById) { return; }
var row = document.getElementById('r' + spid);
var check = document.getElementById('check_' + spid);
check.checked = !check.checked;
if (check.checked) {
row.className = 'clicked';
} else {
var hid = document.getElementById('c' + spid);
row.className = hid.value;
}
return true;
}
// -->
</script>
<=head
title=>Support Requests
body<=
<?_code
use strict;
use vars qw(%FORM);
LJ::set_active_crumb('supporthelp');
my ($ret, $sth);
my $dbr = LJ::get_db_reader();
my $r = Apache->request;
my $remote = LJ::get_remote();
LJ::Support::init_remote($remote);
return $ML{'.interim'} if
(!$remote || !$remote->{'_priv'}) &&
$r->header_in("Referer") eq "$LJ::SITEROOT/support/";
my $cats = LJ::Support::load_cats();
my $state = $FORM{'state'};
$state = 'open' unless $state =~ /^(?:open|closed|green|youreplied)$/;
my $filtercat = $FORM{'cat'};
$filtercat = "" unless ($filtercat =~ /^[\w\-]+$/);
my $fcat = LJ::Support::get_cat_by_key($cats, $filtercat);
my $can_read = LJ::Support::can_read_cat($fcat, $remote);
# determine if user can close stuff
my $can_close = 0;
if ($remote && $state =~ /(?:green|open)/ && $filtercat) {
$can_close = 1 if LJ::check_priv($remote, 'supportclose', $filtercat); # private cats/only this cat
$can_close = 1 if $fcat->{public_read} && LJ::check_priv($remote, 'supportclose', ''); # public cats
}
my $append;
if ($state eq "closed") {
$ret .= "<?h1 Recently Closed Support Requests h1?><?p Below are all support requests " .
"that have been recently closed. To return to the open requests, " .
"<a href=\"$LJ::SITEROOT/support/help.bml?cat=$filtercat\">click here</a>. p?>";
} elsif ($state eq "youreplied") {
return "<?h1 Error h1?><?p You must be logged in to filter on requests that you've replied to. p?>"
unless $remote;
$ret .= "<?h1 Requests you replied to h1?><?p This shows all open requests you've replied to. p?>";
} else {
$ret .= "<?h1 Open Support Requests h1?><?p Below are all support requests that are open " .
"(they just came in and haven't been touched yet) or answered (either awaiting to be " .
"closed by the person needing help, or the person requested they still need help). " .
"The <a href=\"$LJ::SITEROOT/support/help.bml?state=closed&amp;cat=$filtercat\">closed reports</a> are also " .
"available. If you help somebody out and they confirm you helped them, you get the number " .
"of points indicated in the status column. These points will show up on your userinfo page. p?>";
$append = 1;
}
my @support_log;
# if we have a cat to filter to and we have abstracts for it
my $rct = 0;
my $abstracts = 0;
if ($filtercat && $LJ::SUPPORT_ABSTRACTS{$filtercat} && $fcat && $can_read && $state ne 'youreplied') {
# yes, we should show abstracts for this category, so do so
if ($state eq "closed") {
$sth = $dbr->prepare("SELECT s.*, SUBSTRING(sl.message, 1, 200) AS 'message' " .
"FROM support s, supportlog sl " .
"WHERE s.state='closed' AND s.spid = sl.spid AND sl.type = 'req' " .
"AND s.timeclosed > (UNIX_TIMESTAMP() - (3600*24)) " .
"AND s.spcatid = ?");
} else { # triggers on green, open
$sth = $dbr->prepare("SELECT s.*, SUBSTRING(sl.message, 1, 200) AS 'message' " .
"FROM support s, supportlog sl " .
"WHERE s.state='open' AND s.spid = sl.spid AND sl.type = 'req' " .
"AND s.spcatid = ?");
}
$sth->execute($fcat->{spcatid});
push @support_log, $_ while $_ = $sth->fetchrow_hashref();
$rct = scalar(@support_log);
$abstracts = 1;
} else {
my $filterwhere;
if ($filtercat eq "_nonpublic") {
$filterwhere = " AND s.spcatid IN (0";
foreach my $cat (values %$cats) {
$filterwhere .= ", $cat->{'spcatid'}"
if !$cat->{'public_read'} && LJ::Support::can_read_cat($cat, $remote);
}
$filterwhere .= ")";
} elsif ($filtercat eq "_nonprivate") {
$filterwhere = " AND s.spcatid IN (0";
foreach my $cat (values %$cats) {
$filterwhere .= ", $cat->{'spcatid'}" if $cat->{public_read};
}
$filterwhere .= ")";
} else {
if ($can_read) {
$filterwhere = " AND s.spcatid=$fcat->{'spcatid'}";
} else {
$filtercat = "";
}
}
my $dbr = LJ::get_db_reader();
if ($state eq "closed") {
$sth = $dbr->prepare("SELECT s.* FROM support s WHERE s.state='closed' AND " .
"s.timeclosed>UNIX_TIMESTAMP()-(3600*24) $filterwhere");
} elsif ($state eq "youreplied") {
$sth = $dbr->prepare("SELECT s.* FROM support s, support_youreplied yr " .
"WHERE yr.userid=$remote->{'userid'} AND s.spid=yr.spid $filterwhere " .
"AND (s.state='open' OR (s.state='closed' AND s.timeclosed>UNIX_TIMESTAMP()-(3600*24)))");
} else { # triggers on green, open
$sth = $dbr->prepare("SELECT s.* FROM support s WHERE s.state='open' $filterwhere");
}
$sth->execute;
# For the You Replied filter, we might be getting some rows multiple times (when
# multiple log rows exist for $remote), which is still better than using DISTINCT
# in the query which uses a temporary table, so ensure uniqueness here.
my %spids_seen;
while (my $sprow = $sth->fetchrow_hashref) {
next if $spids_seen{$sprow->{'spid'}};
$spids_seen{$sprow->{'spid'}} = 1;
push @support_log, $sprow;
$rct++;
}
}
my $sort = $FORM{sort};
$sort = 'date' unless $sort =~ /^id|summary|area|date$/;
$ret .= "<p>[<b>$rct</b> total open requests]</p>" if $append;
if ($sort eq 'id') {
@support_log = sort { $a->{spid} <=> $b->{spid} } @support_log;
} elsif ($sort eq 'date') {
@support_log = sort { $b->{timecreate} <=> $a->{timecreate} } @support_log;
} elsif ($sort eq 'summary') {
@support_log = sort { $a->{subject} cmp $b->{subject} } @support_log;
} elsif ($sort eq 'area') {
@support_log = sort { $cats->{$a->{spcatid}}->{catname} cmp $cats->{$b->{spcatid}}->{catname} } @support_log;
}
# filter line:
$ret .= "<form method='get' action='help.bml'>Show only ";
$ret .= "<input type='hidden' name='sort' value='$sort' />";
$ret .= "<select name='state'>";
{
my @states = ("" => "Open",
"closed" => "Closed",
"green" => "Green");
if ($remote) {
push @states, ("youreplied", "You Replied");
}
while (@states) {
my ($skey, $sname) = splice(@states, 0, 2);
my $sel = $state eq $skey ? " selected='selected'" : "";
$ret .= "<option value=\"$skey\"$sel>$sname</option>";
}
}
$ret .= "</select>";
$ret .= " requests of type: <select name='cat'>";
$ret .= "<option value=\"\">(All)</option>";
my @filter_cats = LJ::Support::filter_cats($remote, $cats);
if (LJ::check_priv($remote, "supportread")) {
unshift @filter_cats, { 'catkey' => '_nonpublic',
'catname' => '(Private)' };
unshift @filter_cats, { 'catkey' => '_nonprivate',
'catname' => '(Public)' };
}
foreach my $cat (@filter_cats)
{
my $sel = $filtercat eq $cat->{'catkey'} ? " selected='selected'" : "";
$ret .= "<option value=\"$cat->{'catkey'}\"$sel>$cat->{'catname'}</option>";
}
$ret .= "</select>\n";
$ret .= "<input type=submit value=\"Filter\" /></form>";
# /filter line
# mass closing table
$ret .= "<form method='post' action='/support/actmulti.bml'>" if $can_close;
# start the rest of the table
my $uri = "$LJ::SITEROOT/support/help.bml?cat=$filtercat&state=$state";
$ret .= "<p><table cellpadding='4' cellspacing='1' border='1' bgcolor='#ffffff'><tr bgcolor='#d0d0d0'>\n";
$ret .= "<td>&nbsp;<b>X</b></td>\n" if $can_close;
my @headers = ( id => "ID#", summary => "Summary", area => "Problem Area", date => "Posted" );
while (my ($sorttype, $desc) = splice(@headers, 0, 2)) {
if ($sort eq $sorttype) {
$ret .= "<td><b>$desc</b></td>\n";
} else {
$ret .= "<td><b><a href='$uri&sort=$sorttype'>$desc</a></b></td>\n";
}
}
$ret .= "<td><b>Status</b></td>\n";
$ret .= "</tr>";
foreach my $sp (@support_log)
{
LJ::Support::fill_request_with_cat($sp, $cats);
next unless (LJ::Support::can_read($sp, $remote));
my $status = "open";
my $barbg = "green";
if ($sp->{'timeclosed'}) {
$status = "closed";
$barbg = "red";
}
elsif ($sp->{'timelasthelp'} > $sp->{'timetouched'}+5) {
$status = "answered<br />awaiting close";
$barbg = "yellow";
}
elsif ($sp->{'timelasthelp'} && $sp->{'timetouched'} > $sp->{'timelasthelp'}+5) {
$status = "answered<br /><b>still needs help</b>";
$barbg = "green";
}
next if $state eq "green" && $barbg ne "green";
# fix up the subject if needed
eval {
if ($sp->{'subject'} =~ /^=\?(utf-8)?/i) {
my @subj_data;
@subj_data = MIME::Words::decode_mimewords($sp->{'subject'});
if (scalar(@subj_data)) {
if (!$1) {
$sp->{'subject'} = Unicode::MapUTF8::to_utf8({-string=>$subj_data[0][0], -charset=>$subj_data[0][1]});
} else {
$sp->{'subject'} = $subj_data[0][0];
}
}
}
};
# fix up the message if we have one
my $temp = LJ::text_trim($sp->{message}, 0, 100); # 100 character max
if ($temp ne $sp->{message}) {
$sp->{message} = LJ::ehtml($temp) . " ...";
} else {
$sp->{message} = LJ::ehtml($sp->{message}) . " <b>&#x00b6;</b>";
}
my $des = $abstracts ? "<br /><i>$sp->{message}</i>" : '';
# other content for this request
my $summary = LJ::ehtml($sp->{'subject'});
my $secold = time() - $sp->{'timecreate'};
my $age = LJ::ago_text($secold);
my $probarea = $sp->{_cat}->{'catname'};
my $points = LJ::Support::calc_points($sp, $secold);
unless ($status eq "closed") {
$status .= "<br />($points point";
if ($points > 1) { $status .= "s"; }
$status .= ")";
}
my ($style, $js) = ("class='$barbg'", '');
if ($can_close) {
$js = "id='r$sp->{spid}' onclick='doClick($sp->{spid});'";
}
# generate the HTML for this row
$ret .= "<tr valign='top' $style $js>\n";
if ($can_close) {
$ret .= "<td>" . LJ::html_check({ name => "check_$sp->{spid}", id => "check_$sp->{spid}",
onclick => "doClick($sp->{spid});", }) .
"<input type='hidden' name='c$sp->{spid}' id='c$sp->{spid}' value='$barbg' /></td>\n";
$js = "onclick='return doClick($sp->{spid});'";
}
$ret .= "<td><b><a href=\"$LJ::SITEROOT/support/see_request.bml?id=$sp->{'spid'}\" $js>$sp->{'spid'}</a></b></td>";
$ret .= "<td><b>$summary</b>$des</td>\n";
$ret .= "<td>$probarea</td>\n";
$ret .= "<td nowrap='nowrap'><font size='-1'>$age</font></td>\n";
$ret .= "<td nowrap='nowrap'><font size='-1'>$status</font></td>\n";
$ret .= "</tr>";
}
$ret .= "</table>\n";
# mass close button
if ($can_close && $rct) {
my $time = time();
$ret .= LJ::html_hidden('ids', join(':', map { $_->{spid} } @support_log),
'spcatid', $fcat->{spcatid},
'ret', "/support/help.bml?state=$state&cat=$filtercat&time=$time");
$ret .= "<br />";
$ret .= LJ::html_submit('action:move', 'Move Marked Requests');
$ret .= " to ";
$ret .= LJ::html_select({ 'name' => 'changecat', selected => '' },
'', '(no change)',
map { $_->{'spcatid'}, "---> $_->{'catname'}" }
LJ::Support::sorted_cats($cats));
$ret .= "<br /><br />";
$ret .= LJ::html_submit('action:close', 'Close Marked Requests',
{ onclick => 'return confirm("Are you sure you want to close the marked requests?");' });
$ret .= " (this is permanent)";
$ret .= "</form>";
}
return $ret;
_code?>
<?hr?>
<p>Back to the <a href="<?siteroot?>/support/">support area</a>.</p>
<=body
page?><?_c <LJDEP>
link: htdocs/support/help.bml, htdocs/support/see_request.bml
link: htdocs/support/index.bml
form: htdocs/support/help.bml
</LJDEP> _c?>