721 lines
31 KiB
Plaintext
Executable File
721 lines
31 KiB
Plaintext
Executable File
<?page
|
|
title=>Request #<?_code return ($FORM{'id'}+0); _code?>
|
|
head<=
|
|
<?_code return LJ::robot_meta_tags(); _code?>
|
|
<script language="JavaScript"><!--
|
|
function check_replytype (e) {
|
|
if (! e) var e = window.event;
|
|
if (! document.getElementById) return false;
|
|
|
|
f = document.supportForm;
|
|
if (! f) return false;
|
|
|
|
var replytype = f.replytype;
|
|
if (! replytype) return false;
|
|
|
|
var bounce_email = document.getElementById('bounce_email');
|
|
if (! bounce_email) return false;
|
|
|
|
if (replytype.value == 'bounce')
|
|
bounce_email.style.display = 'inline';
|
|
else
|
|
bounce_email.style.display = 'none';
|
|
|
|
if (e) {
|
|
e.cancelBubble = true;
|
|
if (e.stopPropagation) e.stopPropagation();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function updateFaqLink () {
|
|
if (! document.getElementById) return false;
|
|
|
|
f = document.supportForm;
|
|
if (! f) return false;
|
|
|
|
var faqDropdown = f.faqid;
|
|
if (! faqDropdown) return false;
|
|
|
|
var faqUrl = document.getElementById('faqlink');
|
|
if (! faqUrl) return false;
|
|
|
|
if (faqDropdown.value == 0)
|
|
faqUrl.style.display = 'none';
|
|
else
|
|
{
|
|
faqUrl.style.display = 'inline';
|
|
faqUrl.href = 'faqbrowse.bml?faqid=' + faqDropdown.value;
|
|
}
|
|
return false;
|
|
}
|
|
// -->
|
|
</script>
|
|
<=head
|
|
bodyopts=>onLoad="check_replytype();updateFaqLink();"
|
|
body<=
|
|
|
|
<?_code
|
|
{
|
|
use strict;
|
|
use vars qw(%FORM);
|
|
|
|
LJ::set_dynamic_crumb('Request #' . ($FORM{'id'}+0), 'supporthelp');
|
|
|
|
my $spid = $FORM{'id'}+0;
|
|
my $sp = LJ::Support::load_request($spid);
|
|
my $props = LJ::Support::load_props($spid);
|
|
my $cats = LJ::Support::load_cats();
|
|
my $remote = LJ::get_remote();
|
|
LJ::Support::init_remote($remote);
|
|
|
|
if ($FORM{'find'}) {
|
|
my $find = $FORM{'find'};
|
|
my $op = '<';
|
|
my $sort = 'DESC';
|
|
if ($find eq 'next' || $find eq 'cnext' || $find eq 'first') {
|
|
$op = '>';
|
|
$sort = 'ASC';
|
|
}
|
|
my $spcatand = '';
|
|
if ($sp && ($find eq 'cnext' || $find eq 'cprev')) {
|
|
my $spcatid = $sp->{_cat}->{'spcatid'} + 0;
|
|
$spcatand = "AND spcatid=$spcatid";
|
|
} else {
|
|
my @filter_cats = LJ::Support::filter_cats($remote, $cats);
|
|
return "<?h1 Error h1?><?p You do not appear to have permission to read any support categories. p?>"
|
|
unless @filter_cats;
|
|
my $cats_in = join(",", map { $_->{'spcatid'} } @filter_cats);
|
|
$spcatand = "AND spcatid IN ($cats_in)";
|
|
}
|
|
my $clause = "";
|
|
$clause = "AND spid$op$spid" unless ($find eq 'first' || $find eq 'last');
|
|
my $dbr = LJ::get_db_reader();
|
|
my ($foundspid) = $dbr->selectrow_array("SELECT spid FROM support WHERE state='open' $spcatand $clause ".
|
|
"ORDER BY spid $sort LIMIT 1");
|
|
if ($foundspid) {
|
|
return BML::redirect("see_request.bml?id=$foundspid");
|
|
} else {
|
|
my $goback = "<?p Go back to <a href='see_request.bml?id=$spid'>Request #$spid</a> p?>" if $sp;
|
|
my $what = $find eq 'next' || $find eq 'cnext' ? 'next' : 'previous';
|
|
my $cat = "in the same category" if $find eq 'cnext' || $find eq 'cprev';
|
|
return "<?h1 Error h1?><?p No $what open request $cat found. p?>$goback";
|
|
}
|
|
}
|
|
|
|
unless ($sp) { return "<?h1 Error h1?><?p Unknown support number. p?>"; }
|
|
my $sth;
|
|
my $auth = $FORM{'auth'};
|
|
|
|
my $email = $sp->{'reqemail'};
|
|
|
|
my $u = {};
|
|
my $clusterdown = 0;
|
|
if ($sp->{'reqtype'} eq "user") {
|
|
$u = LJ::load_userid($sp->{'requserid'});
|
|
|
|
# now do a check for a down cluster?
|
|
my $dbr = LJ::get_cluster_reader($u);
|
|
$clusterdown = 1 unless $dbr;
|
|
|
|
$email = $u->{'email'};
|
|
LJ::load_user_props($u, "s1_lastn_style", "s1_calendar_style", "s1_day_style",
|
|
"s1_friends_style", "stylesys", "s2_style", )
|
|
unless $clusterdown;
|
|
}
|
|
|
|
my $winner; # who closed it?
|
|
if ($sp->{'state'} eq "closed") {
|
|
my $dbr = LJ::get_db_reader();
|
|
$sth = $dbr->prepare("SELECT u.user, sp.points FROM useridmap u, supportpoints sp ".
|
|
"WHERE u.userid=sp.userid AND sp.spid=?");
|
|
$sth->execute($spid);
|
|
$winner = $sth->fetchrow_hashref;
|
|
}
|
|
|
|
# load category this request is in
|
|
my $problemarea = $sp->{_cat}->{'catname'};
|
|
my $catkey = $sp->{_cat}->{'catkey'};
|
|
|
|
unless (LJ::Support::can_read($sp, $remote, $auth)) {
|
|
return "<?h1 Error h1?><?p You don't have the necessary privilege to view this request. p?>";
|
|
}
|
|
|
|
# helper variables for commonly called methods
|
|
my $owner_mode = LJ::Support::can_close($sp, $remote, $auth) ? 1 : 0;
|
|
my $helper_mode = LJ::Support::can_help($sp, $remote) ? 1 : 0;
|
|
my $is_poster = LJ::Support::is_poster($sp, $remote, $auth) ? 1 : 0;
|
|
|
|
# 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];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
### request info table
|
|
|
|
my $ret = "";
|
|
$ret .= "<table>\n";
|
|
$ret .= "<tr><td valign='bottom' align='right'><b>From:</b></td><td>";
|
|
if ($u->{'defaultpicid'} && $u->{'statusvis'} ne 'S') {
|
|
my %pic;
|
|
my $picid = $u->{'defaultpicid'};
|
|
LJ::load_userpics(\%pic, [ $u, $picid ]);
|
|
$ret .= "<a href='$LJ::SITEROOT/allpics.bml?user=$u->{'user'}'>";
|
|
$ret .= "<img align='baseline' src='$LJ::USERPIC_ROOT/$picid/$u->{'userid'}' width='$pic{$picid}->{'width'}' ".
|
|
"height='$pic{$picid}->{'height'}' align='absmiddle' hspace='3' border='0' alt='$u->{'user'}' />";
|
|
$ret .= "</a>";
|
|
}
|
|
|
|
# show requester name + email
|
|
{
|
|
my $visemail = $email;
|
|
if ($sp->{_cat}->{'public_read'}) {
|
|
$visemail =~ s/^.+\@/********\@/;
|
|
}
|
|
my $ename = $sp->{'reqtype'} eq 'user' ? LJ::ljuser($u) : LJ::ehtml($sp->{reqname});
|
|
|
|
# we show links to the history page if the user is a helper in this category or if it's a
|
|
# private category and the person has supporthelp somewhere (which is the general rule of
|
|
# thumb to use the history viewer)
|
|
my $show_history = !$sp->{_cat}->{public_read} && LJ::check_priv($remote, 'supporthelp');
|
|
if ($helper_mode || $show_history) {
|
|
$ret .= $sp->{reqtype} eq 'user' ?
|
|
"$ename <a href=\"history.bml?user=$u->{user}\">$u->{name}</a>" :
|
|
"$ename";
|
|
$ret .= $owner_mode || $show_history ?
|
|
" (<a href=\"history.bml?email=" . LJ::eurl($email) . "\">$visemail</a>)" :
|
|
" ($visemail)";
|
|
} else {
|
|
# default view
|
|
$ret .= "$ename ($visemail)";
|
|
}
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
|
|
# uniq
|
|
if (LJ::check_priv($remote, 'sysban', 'uniq') || LJ::check_priv($remote, 'sysban', '*')) {
|
|
my $uniq = $props->{'uniq'} || "<i>none</i>";
|
|
$ret .= "<tr><td valign='bottom' align='right'><b>Uniq:</b></td><td>$uniq</td></tr>\n";
|
|
}
|
|
|
|
# account type
|
|
$ret .= "<tr><td align='right' valign='top'><b><a href='$LJ::SITEROOT/support/faqbrowse.bml?faqid=38'><span style='white-space: nowrap'>Account type</span></a>:</b></td><td>";
|
|
$ret .= LJ::name_caps($u->{'caps'}) || "<i>Unknown</i>";
|
|
$ret .= "</td></tr>\n";
|
|
|
|
$ret .= "<tr valign='top'><td align='right'><b>$LJ::SITENAMESHORT:</b></td><td>";
|
|
if ($clusterdown) {
|
|
$ret .= "<span style='color: red; font-weight: bold;'>" .
|
|
"(unable to connect to cluster, some data temporarily unavailable)</span><br />";
|
|
}
|
|
|
|
# check isu because requests don't always come from users and sometimes we
|
|
# fake the user hash
|
|
if (LJ::isu($u) && $u->readonly) {
|
|
$ret .= "<span style='color: red; font-weight: bold;'>" .
|
|
"(this user is currently in read-only mode)</span><br />";
|
|
}
|
|
|
|
|
|
if ($u->{'userid'}) {
|
|
$ret .= "username: <?ljuserf $u->{'user'} ljuserf?>";
|
|
$ret .= "<br />style: ";
|
|
if ($u->{'stylesys'} == 2) {
|
|
$ret .= "(S2) ";
|
|
if ($u->{'s2_style'}) {
|
|
my $s2style = LJ::S2::load_style($u->{'s2_style'});
|
|
my $pub = LJ::S2::get_public_layers(); # cached
|
|
foreach my $lay (sort { $a cmp $b } keys %{$s2style->{'layer'}}) {
|
|
my $lid = $s2style->{'layer'}->{$lay};
|
|
$ret .= "$lay: <a href='$LJ::SITEROOT/customize/advanced/layerbrowse.bml?id=$lid'>";
|
|
$ret .= (defined $pub->{$lid} ? 'public' : 'user') . "</a>, ";
|
|
}
|
|
} else {
|
|
$ret .= "none";
|
|
}
|
|
} else {
|
|
$ret .= "(S1) ";
|
|
foreach my $view (@LJ::views) {
|
|
my $styid = $u->{"s1_${view}_style"};
|
|
my $viewuri = $view eq "lastn" ? "/users/$u->{'user'}/" : "/users/$u->{'user'}/$view";
|
|
if ($view eq "day") {
|
|
my (undef,undef,undef,$dday,$dmon,$dyear) = localtime(time); $dyear+=1900; $dmon++;
|
|
$dmon = $dmon <= 9 ? "0$dmon" : $dmon; $dday = $dday <= 9 ? "0$dday" : $dday;
|
|
$viewuri = "/users/$u->{'user'}/$dyear/$dmon/$dday/";
|
|
}
|
|
$ret .= "<a href='$viewuri'>$view</a>: <a href='$LJ::SITEROOT/styles/browse/styleinfo.bml?styleid=$styid'>$styid</a> ";
|
|
}
|
|
if ($u->{'useoverrides'} eq 'Y') {
|
|
$ret .= "<br />overrides: <a href='see_overrides.bml?user=$u->{'user'}'>view</a> ";
|
|
}
|
|
}
|
|
|
|
# if the user has siteadmin:users or siteadmin:* show them link to resend validation email?
|
|
my $extraval = sub {
|
|
return '' unless LJ::check_priv($remote, 'siteadmin', 'users') ||
|
|
LJ::check_priv($remote, 'siteadmin', '*');
|
|
return " (<a href='$LJ::SITEROOT/register.bml?foruser=$u->{user}'>resend validation email</a>)";
|
|
};
|
|
|
|
$ret .= "<br />email validated? ";
|
|
if ($u->{'status'} eq "A") { $ret .= "<b>yes</b>"; }
|
|
if ($u->{'status'} eq "N") { $ret .= "<b>no</b>" . $extraval->(); }
|
|
if ($u->{'status'} eq "T") { $ret .= "<b>transitioning</b> (used to be validated, but changed email addresses and hasn't reconfirmed)" . $extraval->(); }
|
|
if ($u->{clusterid}) { $ret .= "<br />cluster: " . LJ::get_cluster_description($u->{clusterid}, 1); }
|
|
$ret .= "<br />data version: <b>$u->{dversion}</b>";
|
|
$ret .= "<br />underage? ";
|
|
if ($clusterdown) {
|
|
$ret .= "<strong>cluster unavailable</strong>";
|
|
} else {
|
|
if ($u->underage) {
|
|
$ret .= "<strong>yes because of ";
|
|
$ret .= "birthday" if $u->underage_status eq 'Y';
|
|
$ret .= "unique cookie" if $u->underage_status eq 'O';
|
|
$ret .= "manual set" if $u->underage_status eq 'M';
|
|
$ret .= "</strong>";
|
|
} else {
|
|
$ret .= "<strong>no";
|
|
if ($u->underage_status) {
|
|
$ret .= "; was by ";
|
|
$ret .= "birthday" if $u->underage_status eq 'Y';
|
|
$ret .= "unique cookie" if $u->underage_status eq 'O';
|
|
$ret .= "manual set" if $u->underage_status eq 'M';
|
|
}
|
|
$ret .= "</strong>";
|
|
}
|
|
}
|
|
|
|
if (LJ::check_priv($remote, 'historyview')) {
|
|
$ret .= "<br />view: ";
|
|
$ret .= "<a href='$LJ::SITEROOT/admin/statushistory.bml?user=$u->{user}'>statushistory</a>";
|
|
}
|
|
} else {
|
|
$ret .= "<i>not a user</i>";
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
$ret .= "<tr><td align='right' nowrap='nowrap'><b>Support category:</b></td><td>";
|
|
if (LJ::Support::can_read_cat($sp->{_cat}, $remote)) {
|
|
$ret .= "<a href='$LJ::SITEROOT/support/help.bml?cat=$sp->{_cat}->{'catkey'}'>$problemarea</a>";
|
|
$ret .= " [<a href='$LJ::SITEROOT/support/see_request.bml?id=$sp->{'spid'}&find=cprev'>previous</a>|";
|
|
$ret .= "<a href='$LJ::SITEROOT/support/see_request.bml?id=$sp->{'spid'}&find=cnext'>next</a>]";
|
|
} else {
|
|
$ret .= $problemarea;
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
|
|
my $timecreate = LJ::time_to_http($sp->{'timecreate'});
|
|
my $age = LJ::ago_text(time() - $sp->{'timecreate'});
|
|
$ret .= "<tr><td align='right'><b>Time posted:</b></td><td>$timecreate ($age)</td></tr>\n";
|
|
my $state = $sp->{'state'};
|
|
if ($state eq "open") {
|
|
# check if it's still open or needing help or what
|
|
if ($sp->{'timelasthelp'} > ($sp->{'timetouched'}+5)) {
|
|
# open, answered
|
|
$state = "<b><span style='color: #ff0000;'>answered</span></b> (awaiting close)";
|
|
} elsif ($sp->{'timelasthelp'} && $sp->{'timetouched'} > $sp->{'timelasthelp'}+5) {
|
|
# open, still needs help
|
|
$state = "<b><span style='color: #ff0000;'>answered</span></b> (<b>still needs help</b>)";
|
|
} else {
|
|
# default
|
|
$state = "<b><span style='color: #ff0000;'>open</span></b>";
|
|
}
|
|
}
|
|
if ($state eq "closed" && $winner && LJ::Support::can_see_helper($sp, $remote)) {
|
|
my $s = $winner->{'points'} > 1 ? "s" : "";
|
|
my $wuser = $winner->{'user'};
|
|
$state .= " (<b>$winner->{'points'}</b> point$s to ";
|
|
$state .= LJ::ljuser($wuser, { 'full' => 1 }) . ")";
|
|
}
|
|
$ret .= "<tr><td align='right'><b>Status:</b></td><td>$state";
|
|
if ($owner_mode) {
|
|
$ret .= $sp->{'state'} eq "open" ? ", <a href='act.bml?close;$sp->{'spid'};$sp->{'authcode'}'><b>close without credit</b></a>" : "";
|
|
if ($sp->{state} eq 'closed') {
|
|
my $permastatus = LJ::Support::is_locked($sp);
|
|
$ret .= $sp->{'state'} eq "closed" && !$permastatus ?
|
|
", <a href='act.bml?touch;$sp->{'spid'};$sp->{'authcode'}'><b>reopen this request</b></a>" : "";
|
|
if (LJ::Support::can_lock($sp, $remote)) {
|
|
$ret .= $permastatus ?
|
|
", <a href='act.bml?unlock;$sp->{spid};$sp->{authcode}'><b>unlock request</b></a>" :
|
|
", <a href='act.bml?lock;$sp->{spid};$sp->{authcode}'><b>lock request</b></a>";
|
|
}
|
|
}
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
$ret .= "<tr><td align='right'><b>Summary:</b></td><td><span style='font-size: 1.1em'><b>" . LJ::ehtml($sp->{'subject'}) . "</b></span></td></tr>\n";
|
|
$ret .= "</table>\n";
|
|
|
|
### end request info table
|
|
|
|
LJ::run_hooks("support_see_request_html", {
|
|
'u' => $u,
|
|
'email' => $email,
|
|
'sp' => $sp,
|
|
'retref' => \$ret,
|
|
'remote' => $remote,
|
|
});
|
|
|
|
# put in a "this is private!" box if this is a private request and the user viewing
|
|
# this page is the person who opened the request
|
|
if (!$sp->{_cat}->{public_read} && $is_poster) {
|
|
$ret .= "<div style='margin-top: 15px; margin-bottom: 15px; padding: 5px; " .
|
|
"text-align: center; background-color: #ffff00; border: solid 2px red;'>" .
|
|
"<b>This is a private request.</b> It is not publicly visible.</div>";
|
|
}
|
|
|
|
my %userpics; # id -> {..}
|
|
|
|
my @screened;
|
|
|
|
### reply loop
|
|
my $dbr = LJ::get_db_reader();
|
|
$sth = $dbr->prepare("SELECT splid, timelogged, UNIX_TIMESTAMP()-timelogged AS 'age', type, faqid, userid, message " .
|
|
"FROM supportlog WHERE spid=? ORDER BY timelogged");
|
|
$sth->execute($spid);
|
|
while (my $le = $sth->fetchrow_hashref)
|
|
{
|
|
next if ($le->{'type'} eq "internal" && ! (LJ::Support::can_read_internal($sp, $remote) ||
|
|
($remote && $remote->{'userid'} == $le->{'userid'} )));
|
|
next if ($le->{'type'} eq "screened" && ! (LJ::Support::can_read_screened($sp, $remote) ||
|
|
($remote && $remote->{'userid'} == $le->{'userid'} )));
|
|
|
|
if ($le->{'type'} eq "screened") {
|
|
push @screened, $le;
|
|
}
|
|
|
|
my $message = $le->{'message'};
|
|
my %url;
|
|
my $urlN = 0;
|
|
|
|
$message = LJ::ehtml($message);
|
|
$message =~ s/^\s+//;
|
|
$message =~ s/\s+$//;
|
|
$message =~ s/\n( +)/"\n" . " "x length($1)/eg;
|
|
$message =~ s/\n/<br \/>\n/g;
|
|
$message = LJ::auto_linkify($message);
|
|
|
|
# special case: original request
|
|
if ($le->{'type'} eq "req") {
|
|
# insert support diagnostics from props
|
|
$message .= "<?hr?><strong>Diagnostics:</strong> $props->{useragent}" if $props->{useragent};
|
|
|
|
$ret .= "<div style='margin-top: 15px;'>\n";
|
|
$ret .= "<b>Original Request:</b><br />\n";
|
|
$ret .= "<div style='border: 3px solid #000000; margin-left: auto; margin-right: auto; padding: 3px;'>\n$message\n</div></div>";
|
|
next;
|
|
}
|
|
|
|
# reply header
|
|
my $header = "";
|
|
if ($le->{'userid'} && LJ::Support::can_see_helper($sp, $remote)) {
|
|
my $up = LJ::load_userid($le->{'userid'});
|
|
my $picid = $up->{'defaultpicid'};
|
|
$userpics{$picid} or LJ::load_userpics(\%userpics, [[ $up, $picid ]]);
|
|
$header = "<table style='margin-top: 15px;'><tr valign='bottom'>";
|
|
if ($picid && $up->{'statusvis'} ne 'S') {
|
|
$header .= "<td><img src='$LJ::USERPIC_ROOT/$picid/$up->{'userid'}' width='$userpics{$picid}->{'width'}' height='$userpics{$picid}->{'height'}' hspace='3' alt='$up->{'user'}'/></td>";
|
|
}
|
|
$header .= "<td>" . LJ::ljuser($up->{'user'}, { 'full' => 1 });
|
|
if ($up->{'statusvis'} ne 'S') {
|
|
$header .= " - " . LJ::ehtml($up->{'name'});
|
|
}
|
|
$header .= "</td></tr></table>\n"
|
|
}
|
|
|
|
my $what = "Answer";
|
|
if ($le->{'type'} eq "internal") { $what = "Internal Comment"; }
|
|
elsif ($le->{'type'} eq "comment") { $what = "Comment"; }
|
|
elsif ($le->{'type'} eq "screened") { $what = "Screened Response"; }
|
|
|
|
$header .= "<span style='font-size: 0.9em;'><b>$what</b> (\#$le->{'splid'})</span><br />";
|
|
my $timehelped = LJ::time_to_http($le->{'timelogged'});
|
|
my $age = LJ::ago_text($le->{'age'});
|
|
$header .= "<b>Posted:</b> $timehelped ($age)";
|
|
if ($owner_mode && $sp->{'state'} eq "open" && $le->{'type'} eq "answer") {
|
|
$header .= ", <a href='act.bml?close;$sp->{'spid'};$sp->{'authcode'};$le->{'splid'}'><b>credit fix here</b></a>";
|
|
}
|
|
|
|
my $bordercolor = "#000000";
|
|
if ($le->{'type'} eq "internal") { $bordercolor = "#ff0000"; }
|
|
if ($le->{'type'} eq "answer") { $bordercolor = "#00c000"; }
|
|
if ($le->{'type'} eq "screened") { $bordercolor = "#afaf00"; }
|
|
|
|
# reply
|
|
$ret .= "$header<br />\n";
|
|
$ret .= "<table align='center' style='margin-top: 5px; border: 3px solid $bordercolor;' cellpadding='3' width='100%'>\n";
|
|
$ret .= "<tr><td align='center'>\n";
|
|
if ($le->{'faqid'}) {
|
|
# faq question
|
|
my $dbr = LJ::get_db_reader();
|
|
my $sth = $dbr->prepare("SELECT question FROM faq WHERE faqid=?");
|
|
$sth->execute($le->{'faqid'});
|
|
my $faqname = $sth->fetchrow_array;
|
|
$ret .= "<div style='display: table; padding: 3px; background: <?emcolor?>; border: 1px solid #000000; margin-left: auto; margin-right: auto;'>\n";
|
|
# whitespace between these two DIVs is necessary for proper
|
|
# rendering in IE 5 for Mac OS < X
|
|
$ret .= "<div style='text-align:center;'>";
|
|
$ret .= "<b>FAQ Reference:</b><br /><a href='faqbrowse.bml?faqid=$le->{'faqid'}'>$faqname</a></div></div>\n";
|
|
}
|
|
$ret .= "<p align='left' style='margin-top: 0px; margin-bottom: 0px;'>$message</p>\n";
|
|
$ret .= "</td></tr></table>\n";
|
|
}
|
|
### end reply loop
|
|
|
|
# return if support item is closed
|
|
if ($sp->{'state'} eq "closed") {
|
|
return $ret;
|
|
}
|
|
|
|
# underage users can't interact with this
|
|
return $ret if $remote && $remote->underage;
|
|
|
|
$ret .= "<p style='margin-bottom: 0px;'><b>Post a comment or solution:</b></p>\n";
|
|
|
|
unless ($remote || $is_poster) {
|
|
$ret .= "You must <a href='$LJ::SITEROOT/login.bml?ret=1'>login</a> to help people out.\n";
|
|
return $ret;
|
|
}
|
|
|
|
unless (LJ::Support::can_append($sp, $remote, $auth))
|
|
{
|
|
$ret .= "Sorry, you do not have access to answer people's support requests in this category.\n";
|
|
return $ret;
|
|
}
|
|
|
|
my @ans_type = LJ::Support::get_answer_types($sp, $remote, $auth);
|
|
my %ans_type = @ans_type;
|
|
|
|
if ($ans_type{'answer'} || $ans_type{'screened'})
|
|
{
|
|
$ret .= "<?standout <b>Important Notes:</b>";
|
|
$ret .= "<ul>";
|
|
$ret .= "<li>Before answering somebody's question, read the <b><a href='$LJ::SITEROOT/doc/guide/support.bml'>support guide</a></b>.</li>";
|
|
$ret .= "<li>Do <b>NOT</b> answer people if you're not sure of your answer. Don't answer if your solution is just a guess. Only answer if you really know what you're talking about ... guessing only makes other people in the support area think you might be right and spread the misinformation further, until it's accepted as truth.</li>";
|
|
if ($LJ::LJDOTCOM) {
|
|
$ret .= "<li>Never recommend asking someone else, or somewhere else. That qualifies as not knowing the answer. If a support request is open for a day or two, one of the support leaders will find out the answer and reply, and likely post about it in <?ljuser lj_support ljuser?> so all the support people will know the answer in the future.</li>";
|
|
}
|
|
$ret .= "</ul>Thanks! standout?>\n";
|
|
}
|
|
|
|
# append_request form
|
|
|
|
$ret .= "<br /><form method='post' action='append_request.bml' name='supportForm'>\n";
|
|
|
|
# hidden values
|
|
$ret .= LJ::html_hidden('spid', $spid, 'auth', $auth) . "\n";
|
|
|
|
# form
|
|
$ret .= "<table border='0'>\n";
|
|
$ret .= "<tr valign='middle'><td align='right'>From:</td><td>";
|
|
if ($remote && $remote->{'userid'}) {
|
|
$ret .= "<?ljuser $remote->{'user'} ljuser?>";
|
|
} else {
|
|
$ret .= "(not logged in)";
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
|
|
if ($ans_type{'answer'} || $ans_type{'screened'})
|
|
{
|
|
my $dbr = LJ::get_db_reader();
|
|
# FAQ reference
|
|
$ret .= "<tr valign='middle'><td align='right'>Reference <a href='faq.bml'>FAQ</a>:</td><td colspan='2'>\n";
|
|
|
|
my %faqcat;
|
|
my %faqq;
|
|
$sth = $dbr->prepare("SELECT faqcat, faqcatname, catorder FROM faqcat WHERE faqcat<>'int-abuse'");
|
|
$sth->execute;
|
|
while ($_ = $sth->fetchrow_hashref) {
|
|
$faqcat{$_->{'faqcat'}} = $_;
|
|
}
|
|
|
|
$sth = $dbr->prepare("SELECT faqid, question, sortorder, faqcat, lastmodtime FROM faq WHERE faqcat<>'int-abuse'");
|
|
$sth->execute;
|
|
while ($_ = $sth->fetchrow_hashref) {
|
|
$faqq{$_->{'faqid'}} = $_;
|
|
}
|
|
|
|
my @faqlist = ('0', "(don't reference FAQ)");
|
|
foreach my $faqcat (sort { $faqcat{$a}->{'catorder'} <=> $faqcat{$b}->{'catorder'} } keys %faqcat)
|
|
{
|
|
push @faqlist, ('0', "[ $faqcat{$faqcat}->{'faqcatname'} ]");
|
|
foreach my $faqid (sort { $faqq{$a}->{'sortorder'} <=> $faqq{$b}->{'sortorder'} }
|
|
grep { $faqq{$_}->{'faqcat'} eq $faqcat } keys %faqq)
|
|
{
|
|
next unless ($faqq{$faqid}->{'question'});
|
|
my $q = "... $faqq{$faqid}->{'question'}";
|
|
$q =~ s/^\s+//;
|
|
$q =~ s/\s+$//;
|
|
$q =~ s/\n/ /g;
|
|
if (length($q) > 50) {
|
|
$q = substr($q, 0, 50) . "...";
|
|
}
|
|
push @faqlist, ($faqid, $q);
|
|
}
|
|
}
|
|
$ret .= LJ::html_select({ 'name' => 'faqid', 'onchange' => 'updateFaqLink()' }, @faqlist) . "\n";
|
|
$ret .= qq(<script language="JavaScript"><!--
|
|
if (document.getElementById)
|
|
document.write("<a href='faq.bml' id='faqlink'>View FAQ</a>");
|
|
//--></script>);
|
|
$ret .= "</td></tr>\n";
|
|
}
|
|
|
|
# answer type
|
|
{
|
|
$ret .= "<tr><td align='right'>Reply Type:</td><td>";
|
|
|
|
# if less than 2, remote is the person filing the request
|
|
# so all they can do is add more info
|
|
if (@ans_type > 2) {
|
|
$ret .= LJ::html_select({ 'name' => 'replytype',
|
|
'onchange' => "check_replytype()" },
|
|
@ans_type) . "\n";
|
|
$ret .= "<div id='bounce_email' style='display:none'>";
|
|
$ret .= " Email/User: " . LJ::html_text({ 'name' => 'bounce_email', 'size' => '25' });
|
|
$ret .= "</div>";
|
|
} else {
|
|
$ret .= LJ::html_hidden('replytype', $ans_type[0]) . "\n";
|
|
$ret .= "<b>$ans_type[1]</b>";
|
|
}
|
|
$ret .= "</td></tr>\n";
|
|
}
|
|
|
|
# helpers can do actions:
|
|
if (LJ::Support::can_perform_actions($sp, $remote) && ! $is_poster)
|
|
{
|
|
$ret .= "<tr><td align='right'></td><td>\n";
|
|
|
|
$ret .= "<table cellpadding='5'>";
|
|
|
|
$ret .= "<tr><td>Change Category:<br />";
|
|
$ret .= LJ::html_select({ 'name' => 'changecat' },
|
|
('', $sp->{'_cat'}->{'catname'}),
|
|
map { $_->{'spcatid'}, "---> $_->{'catname'}" }
|
|
LJ::Support::sorted_cats($cats));
|
|
$ret .= "</td>";
|
|
|
|
if (@screened && $helper_mode) {
|
|
$ret .= "<td>Approve Screened Response:<br />";
|
|
$ret .= LJ::html_select({ 'name' => 'approveans' },
|
|
('', ''),
|
|
map { $_->{'splid'}, "\#$_->{'splid'} (" . LJ::get_username($_->{'userid'}) . ")" }
|
|
@screened);
|
|
$ret .= LJ::html_select({ 'name' => 'approveas' },
|
|
("answer" => "as answer", "comment" => "as comment",));
|
|
$ret .= "</td>";
|
|
}
|
|
$ret .= "</tr></table>\n";
|
|
|
|
$ret .= "</td></tr>\n";
|
|
if ($sp->{'timelasthelp'} > ($sp->{'timetouched'}+5)) {
|
|
$ret .= "<tr><td align='right'>Put in Queue:</td><td>";
|
|
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'touch' });
|
|
$ret .= "<?de (Use this to re-open the request.) de?>\n";
|
|
$ret .= "</td></tr>\n";
|
|
} else {
|
|
$ret .= "<tr><td align='right'>Take out of Queue:</td><td>";
|
|
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'untouch' });
|
|
$ret .= "<?de (Use this to change status to "awaiting close".) de?>\n";
|
|
$ret .= "</td></tr>\n";
|
|
}
|
|
if (LJ::Support::can_change_summary($sp, $remote)) {
|
|
$ret .= "<tr><td>Change summary:</td><td>";
|
|
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'changesum' });
|
|
$ret .= LJ::html_text({ 'type' => 'text', 'name' => 'summary', 'size' => '50', 'maxlength' => '80', 'value' => $sp->{'subject'} });
|
|
$ret .= "</td></tr>\n";
|
|
$ret .= "<tr><td> </td><td>";
|
|
$ret .= "<?de (Use this to change the request summary.) de?>\n";
|
|
$ret .= "</td></tr>\n";
|
|
}
|
|
}
|
|
# Prefill an e-mail validation nag, if needed.
|
|
my $validationnag;
|
|
if (!(LJ::isu($u) && ($u->underage && $u->{'status'} eq 'T')) &&
|
|
($u->{'status'} eq "N" || $u->{'status'} eq "T") &&
|
|
! $is_poster) {
|
|
my $reminder = LJ::load_include('validationreminder');
|
|
$validationnag .= "\n\n$reminder" if $reminder;
|
|
}
|
|
|
|
# add in canned answers if there are any for this category and the user can use them
|
|
if ($helper_mode && ! $is_poster) {
|
|
my $rows = $dbr->selectall_arrayref('SELECT subject, body FROM support_answers WHERE spcatid = ? ORDER BY subject',
|
|
undef, $sp->{_cat}->{spcatid});
|
|
if ($rows && @$rows) {
|
|
$ret .= "<tr valign='top'><td align='right'>Stock answers:</td><td colspan='2'>\n";
|
|
$ret .= "<script type='text/javascript'>\n";
|
|
$ret .= "var Iarr = new Array();\n";
|
|
my $i = 0;
|
|
foreach my $row (@$rows) {
|
|
$ret .= "Iarr[$i] = '" . LJ::ejs($row->[1]) . "';\n";
|
|
$i++;
|
|
}
|
|
$ret .= "function insertCanned(i) {\n";
|
|
$ret .= " var obj = document.getElementById('body');\n";
|
|
$ret .= " var canned = document.getElementById('canned');\n";
|
|
$ret .= " if (canned && canned.value > -1 && obj) {\n";
|
|
$ret .= " obj.value = obj.value + Iarr[canned.value];\n";
|
|
$ret .= " }\n";
|
|
$ret .= "}\n";
|
|
$ret .= "</script>\n";
|
|
$ret .= "<select id='canned' onChange='insertCanned();'>\n";
|
|
$ret .= "<option value='-1' selected>( select canned to insert )</option>\n";
|
|
$i = 0;
|
|
foreach my $row (@$rows) {
|
|
$ret .= "<option value='$i'>$row->[0]</option>\n";
|
|
$i++;
|
|
}
|
|
$ret .= "</input>\n";
|
|
$ret .= "</td></tr>";
|
|
}
|
|
}
|
|
|
|
# textarea for their message body
|
|
$ret .= "<tr valign='top'><td align='right'>Message:</td><td colspan='2'>";
|
|
$ret .= LJ::html_textarea({ 'rows' => '12', 'cols' => '80', 'wrap' => 'virtual', 'id' => 'body', 'name' => 'body', 'value' => $validationnag }) . "<br />";
|
|
$ret .= "<?de No HTML allowed, so don't worry about about escaping < and ><br />URLs are automatically link-ified, so just reference those. de?><br />";
|
|
$ret .= LJ::html_submit('submitpost', "Post Comment/Solution");
|
|
$ret .= "</td></tr></table>\n";
|
|
|
|
$ret .= "</form>\n";
|
|
|
|
return $ret;
|
|
|
|
}
|
|
_code?>
|
|
<?hr?>
|
|
<?_code
|
|
{
|
|
use strict;
|
|
use vars qw(%FORM);
|
|
return '' if $FORM{'find'};
|
|
my $spid = $FORM{'id'}+0;
|
|
return "Go to: <a href='$LJ::SITEROOT/support/see_request.bml?id=$spid&find=prev'>previous open request</a>, " .
|
|
"<a href='$LJ::SITEROOT/support/see_request.bml?id=$spid&find=next'>next open request</a>"
|
|
}
|
|
_code?>
|
|
<br />
|
|
Back to the <a href="help.bml">list of open requests</a>.<br />
|
|
Back to the <a href="./">support area</a>.
|
|
|
|
<=body
|
|
page?><?_c <LJDEP>
|
|
link: htdocs/support/faqbrowse.bml, htdocs/styles/browse/styleinfo.bml
|
|
link: htdocs/support/help.bml, htdocs/support/act.bml, htdocs/login.bml
|
|
link: htdocs/guide/support.bml, htdocs/support/faq.bml, htdocs/support/index.bml
|
|
link: htdocs/allpics.bml
|
|
img: htdocs/userpic
|
|
post: htdocs/support/append_request.bml
|
|
</LJDEP> _c?>
|