mourningdove/htdocs/support/append_request.bml
2026-05-24 01:03:05 +00:00

268 lines
10 KiB
Text

<?_c
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
_c?>
<?page
title=><?_ml .title _ml?>
body<=
<?_code
{
use strict;
use vars qw(%FORM %POST);
my $r = DW::Request->get;
my $status = "";
my $spid = $FORM{'spid'}+0;
my $sp = LJ::Support::load_request($spid);
return "<?h1 $ML{'Error'} h1?><?p $ML{'.unknown.request'} p?>" unless $sp;
return "<?h1 $ML{'.closed.title'} h1?><?p $ML{'.closed.text'} p?>"
if $sp->{'state'} eq "closed";
my $remote = LJ::get_remote();
LJ::Support::init_remote($remote);
unless (LJ::Support::can_append($sp, $remote, $FORM{'auth'}) || $remote) {
return "<?needlogin?>";
}
my $scat = $sp->{_cat};
my $problemarea = $scat->{'catname'};
my $catkey = $scat->{'catkey'};
return LJ::bad_input($ML{'.invalid.noid'}) unless $FORM{'spid'};
return LJ::bad_input("<?requirepost?>") unless LJ::did_post();
$FORM{'summary'} = LJ::trim($FORM{'summary'});
return LJ::bad_input($ML{'.invalid.nosummary'})
if $FORM{'changesum'} && !$FORM{'summary'};
### links to show on success
my $auth_arg = $FORM{'auth'} ? "&amp;auth=$FORM{'auth'}" : "";
my $successlinks = BML::ml('.successlinks2',
{ 'number' => $sp->{'spid'},
'aopts1' => "href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}$auth_arg'",
'aopts2' => "href='$LJ::SITEROOT/support/help'",
'aopts3' => "href='$LJ::SITEROOT/support/help?cat=$scat->{'catkey'}'",
'aopts8' => "href='$LJ::SITEROOT/support/help?cat=$scat->{'catkey'}&amp;state=green'",
'aopts4' => "href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&amp;find=prev'",
'aopts5' => "href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&amp;find=next'",
'aopts6' => "href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&amp;find=cprev'",
'aopts7' => "href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&amp;find=cnext'",
});
### insert record
my $faqid = $FORM{'faqid'}+0;
my %answer_types = LJ::Support::get_answer_types($sp, $remote, $FORM{'auth'});
my $userfacing_action_type = $FORM{replytype};
my $internal_action_type = $FORM{internaltype};
return LJ::bad_input($ML{'.invalid.type'})
if ! $userfacing_action_type && ! $internal_action_type # we need at least one of these to be defined
|| $userfacing_action_type && ! defined $answer_types{$userfacing_action_type}
|| $internal_action_type && ! defined $answer_types{$internal_action_type};
## can we do the action we want?
return LJ::bad_input($ML{'.internal.approve'})
if $FORM{'approveans'} && ($internal_action_type ne "internal" || ! LJ::Support::can_help($sp, $remote));
return LJ::bad_input($ML{'.internal.changecat'})
if $FORM{'changecat'} && ($internal_action_type ne "internal" || ! LJ::Support::can_perform_actions($sp, $remote));
return LJ::bad_input($ML{'.internal.touch'})
if ($FORM{'touch'} || $FORM{'untouch'}) &&
($internal_action_type ne "internal" || ! LJ::Support::can_perform_actions($sp, $remote));
return LJ::bad_input($ML{'.internal.changesum'})
if $FORM{'changesum'} && ($internal_action_type ne "internal" || ! LJ::Support::can_change_summary($sp, $remote));
return LJ::bad_input($ML{'.invalid.blank'})
if $FORM{reply} !~ /\S/ && $FORM{internal} !~ /\S/ # no text AND
&& !$FORM{'approveans'} && !$FORM{'changecat'} && !$FORM{'changesum'} # no action taken
&& !$FORM{'touch'} && !$FORM{'untouch'} && !$FORM{'bounce_email'};
# Load up vars for approvals
my $res;
my $splid;
if ($FORM{'approveans'}) {
$splid = $FORM{'approveans'}+0;
$res = LJ::Support::load_response($splid);
return LJ::bad_input($ML{'.invalid.noanswer'})
if ($res->{'spid'} == $spid && $res->{'type'} ne "screened");
return LJ::bad_input('Invalid type to approve screened response as.')
if (($FORM{'approveas'} ne 'answer') && ($FORM{'approveas'} ne 'comment'));
}
# Load up vars for category moves
my $newcat;
my $cats;
if ($FORM{'changecat'}) {
$newcat = $FORM{'changecat'}+0;
$cats = LJ::Support::load_cats($newcat);
return LJ::bad_input($ML{'.invalid.notcat'})
unless ($cats->{$newcat});
}
# get dbh now, it's always needed
my $dbh = LJ::get_db_writer();
## touch/untouch request
if ($FORM{'touch'}) {
$dbh->do("UPDATE support SET state='open', timetouched=UNIX_TIMESTAMP(), timeclosed=0, timemodified=UNIX_TIMESTAMP() WHERE spid=$spid");
$status .= "(Inserting request into queue)\n\n";
}
if ($FORM{'untouch'}) {
$dbh->do("UPDATE support SET timelasthelp=UNIX_TIMESTAMP(), timemodified=UNIX_TIMESTAMP() WHERE spid=$spid");
$status .= "(Removing request from queue)\n\n";
}
## bounce request to email
if ($internal_action_type eq 'bounce') {
return LJ::bad_input($ML{'.bounce.noemail'})
unless $FORM{'bounce_email'};
return LJ::bad_input($ML{'.bounce.notauth'})
unless LJ::Support::can_bounce($sp, $remote);
# check given emails using LJ::check_email
my @form_emails = split(/\s*,\s*/, $FORM{'bounce_email'});
return LJ::bad_input($ML{'.bounce.toomany'})
if @form_emails > 5;
my @emails; # error-checked, good emails
my @email_errors;
foreach my $email (@form_emails) {
# see if it's a valid username
unless ($email =~ /\@/) {
my $eu = LJ::load_user($email); # $email is a username
$email = $eu->email_raw if $eu;
}
LJ::check_email( $email, \@email_errors, \%POST );
@email_errors = map { "<strong>$email:</strong> $_" } @email_errors;
return LJ::bad_input(@email_errors) if @email_errors;
# push onto our list of valid emails
push @emails, $email;
}
# append notice that this message was bounced
my $splid = LJ::Support::append_request($sp, {
'body' => "(Bouncing mail to '" . join(', ', @emails) . "' and closing)\n\n" . $FORM{'body'},
'posterid' => $remote,
'type' => 'internal',
'uniq' => $r->note('uniq'),
'remote' => $remote,
});
# bounce original request to email
my $message = $dbh->selectrow_array("SELECT message FROM supportlog " .
"WHERE spid=? ORDER BY splid LIMIT 1",
undef, $sp->{'spid'});
LJ::send_mail({
'to' => join(", ", @emails),
'from' => $sp->{'reqemail'},
'fromname' => $sp->{'reqname'},
'headers' => { 'X-Bounced-By' => $remote->{'user'} },
'subject' => "$sp->{'subject'} (support request #$sp->{'spid'})",
'body' => "$message\n\n$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}",
});
# close request, nobody gets credited
$dbh->do("UPDATE support SET state='closed', timeclosed=UNIX_TIMESTAMP(), timemodified=UNIX_TIMESTAMP() WHERE spid=?",
undef, $sp->{'spid'});
return BML::ml('.bounced.success', { 'addresslist' => "<strong>".join(', ', @emails)."</strong>" })
.$successlinks;
}
$dbh->do("UPDATE support SET state='open', timetouched=UNIX_TIMESTAMP(), timeclosed=0, timemodified=UNIX_TIMESTAMP() WHERE spid=$spid")
if LJ::Support::is_poster($sp, $remote, $FORM{'auth'});
## change category
if ($FORM{'changecat'}) {
# $newcat, $cats defined above
$dbh->do("UPDATE support SET spcatid=$newcat WHERE spid=$spid");
$status .= "Changing from $catkey => $cats->{$newcat}->{'catkey'}\n\n";
$sp->{'spcatid'} = $newcat; # update category so IC e-mail goes to right place
LJ::Hooks::run_hook("support_changecat_extra_actions", spid => $spid, catkey => $cats->{$newcat}->{catkey});
}
## approving a screened response
if ($FORM{'approveans'}) {
# $res, $splid defined above
# approve
my $qtype = $dbh->quote($FORM{'approveas'});
$dbh->do("UPDATE supportlog SET type=$qtype WHERE splid=$splid");
$status .= "(Approving $FORM{'approveas'} \#$splid)\n\n";
LJ::Support::mail_response_to_user($sp, $splid);
}
## change summary
if ($FORM{'changesum'}) {
$FORM{'summary'} =~ s/[\n\r]//g;
my $qnewsub = $dbh->quote($FORM{'summary'});
$dbh->do("UPDATE support SET subject=$qnewsub WHERE spid=$spid");
$status .= "Changing subject from \"$sp->{'subject'}\" to \"$FORM{'summary'}\".\n\n";
}
my $splid;
# user-facing
if ( $FORM{reply} ) {
$splid = LJ::Support::append_request($sp, {
'body' => $FORM{reply},
'type' => $userfacing_action_type,
'faqid' => $faqid,
'uniq' => $r->note('uniq'),
'remote' => $remote
});
LJ::Support::mail_response_to_user($sp, $splid)
unless LJ::Support::is_poster($sp, $remote, $FORM{'auth'});
}
# then any internal status changes
if ( $status || $FORM{internal} ) {
$splid = LJ::Support::append_request($sp, {
'body' => $status . $FORM{internal},
'type' => $internal_action_type,
'uniq' => $r->note('uniq'),
'remote' => $remote
});
LJ::Support::mail_response_to_user($sp, $splid)
unless LJ::Support::is_poster($sp, $remote, $FORM{'auth'});
}
return "<?h1 $ML{'.logged.title'} h1?><?p $ML{'.logged.text'} p?>" . $successlinks;
}
_code?>
<?hr?>
<?_code return BML::ml('.back.support2', {'aopts' => "href='$LJ::SITEROOT/support/'"}); _code?>
<=body
page?>