352 lines
13 KiB
Plaintext
Executable File
352 lines
13 KiB
Plaintext
Executable File
<?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&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> <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>¶</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?>
|