|
afuna@2144
|
1 |
<?_c
|
|
afuna@2144
|
2 |
# This code was forked from the LiveJournal project owned and operated
|
|
afuna@2144
|
3 |
# by Live Journal, Inc. The code has been modified and expanded by
|
|
afuna@2144
|
4 |
# Dreamwidth Studios, LLC. These files were originally licensed under
|
|
afuna@2144
|
5 |
# the terms of the license supplied by Live Journal, Inc, which can
|
|
afuna@2144
|
6 |
# currently be found at:
|
|
afuna@2144
|
7 |
#
|
|
afuna@2144
|
8 |
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
|
afuna@2144
|
9 |
#
|
|
afuna@2144
|
10 |
# In accordance with the original license, this code and all its
|
|
afuna@2144
|
11 |
# modifications are provided under the GNU General Public License.
|
|
afuna@2144
|
12 |
# A copy of that license can be found in the LICENSE file included as
|
|
afuna@2144
|
13 |
# part of this distribution.
|
|
afuna@2144
|
14 |
_c?>
|
|
mark@3
|
15 |
<?page
|
|
mark@3
|
16 |
title=><?_code return BML::ml('.title', { 'reqid' => $FORM{'id'}+0 }); _code?>
|
|
mark@3
|
17 |
head<=
|
|
mark@3
|
18 |
<?_code return LJ::robot_meta_tags(); _code?>
|
|
mark@3
|
19 |
<script language="JavaScript"><!--
|
|
mark@84
|
20 |
var tier_cell = document.getElementById('tier_cell');
|
|
mark@84
|
21 |
var approveans = document.getElementById('approveans');
|
|
mark@84
|
22 |
|
|
mark@84
|
23 |
if (tier_cell && !approveans) {
|
|
mark@84
|
24 |
tier_cell.style.display = 'none';
|
|
mark@84
|
25 |
}
|
|
mark@84
|
26 |
|
|
mark@3
|
27 |
function check_replytype (e) {
|
|
mark@3
|
28 |
if (! e) var e = window.event;
|
|
mark@3
|
29 |
if (! document.getElementById) return false;
|
|
mark@3
|
30 |
|
|
mark@3
|
31 |
f = document.supportForm;
|
|
mark@3
|
32 |
if (! f) return false;
|
|
mark@3
|
33 |
|
|
mark@3
|
34 |
var replytype = f.replytype;
|
|
mark@3
|
35 |
if (! replytype) return false;
|
|
mark@3
|
36 |
|
|
mark@3
|
37 |
var bounce_email = document.getElementById('bounce_email');
|
|
mark@3
|
38 |
if (! bounce_email) return false;
|
|
mark@3
|
39 |
|
|
mark@3
|
40 |
if (replytype.value == 'bounce')
|
|
mark@3
|
41 |
bounce_email.style.display = 'inline';
|
|
mark@3
|
42 |
else
|
|
mark@3
|
43 |
bounce_email.style.display = 'none';
|
|
mark@3
|
44 |
|
|
mark@84
|
45 |
var tier_cell = document.getElementById('tier_cell');
|
|
mark@84
|
46 |
var approveans = document.getElementById('approveans');
|
|
mark@84
|
47 |
|
|
mark@84
|
48 |
if (tier_cell && !approveans) {
|
|
mark@84
|
49 |
if (replytype.value == 'answer' || replytype.value == 'internal')
|
|
mark@84
|
50 |
tier_cell.style.display = 'block';
|
|
mark@84
|
51 |
else
|
|
mark@84
|
52 |
tier_cell.style.display = 'none';
|
|
mark@84
|
53 |
}
|
|
mark@84
|
54 |
|
|
mark@3
|
55 |
if (e) {
|
|
mark@3
|
56 |
e.cancelBubble = true;
|
|
mark@3
|
57 |
if (e.stopPropagation) e.stopPropagation();
|
|
mark@3
|
58 |
}
|
|
mark@3
|
59 |
|
|
mark@3
|
60 |
return false;
|
|
mark@3
|
61 |
}
|
|
mark@3
|
62 |
|
|
mark@3
|
63 |
function updateFaqLink () {
|
|
mark@3
|
64 |
if (! document.getElementById) return false;
|
|
mark@3
|
65 |
|
|
mark@3
|
66 |
f = document.supportForm;
|
|
mark@3
|
67 |
if (! f) return false;
|
|
mark@3
|
68 |
|
|
mark@3
|
69 |
var faqDropdown = f.faqid;
|
|
mark@3
|
70 |
if (! faqDropdown) return false;
|
|
mark@3
|
71 |
|
|
mark@3
|
72 |
var faqUrl = document.getElementById('faqlink');
|
|
mark@3
|
73 |
if (! faqUrl) return false;
|
|
mark@3
|
74 |
|
|
mark@3
|
75 |
if (faqDropdown.value == 0)
|
|
mark@3
|
76 |
faqUrl.style.display = 'none';
|
|
mark@3
|
77 |
else
|
|
mark@3
|
78 |
{
|
|
mark@3
|
79 |
faqUrl.style.display = 'inline';
|
|
afuna@1354
|
80 |
faqUrl.href = 'faqbrowse?faqid=' + faqDropdown.value + '&view=full';
|
|
mark@3
|
81 |
}
|
|
mark@3
|
82 |
return false;
|
|
mark@3
|
83 |
}
|
|
mark@3
|
84 |
|
|
mark@3
|
85 |
function doSummaryChanged () {
|
|
mark@3
|
86 |
if (! document.getElementById) return false;
|
|
mark@3
|
87 |
|
|
mark@3
|
88 |
var summaryBox = document.getElementById('changesum');
|
|
mark@3
|
89 |
if (! summaryBox) return false;
|
|
mark@3
|
90 |
|
|
mark@3
|
91 |
summaryBox.checked = true;
|
|
mark@3
|
92 |
|
|
mark@3
|
93 |
return doSetReplyType('internal');
|
|
mark@3
|
94 |
}
|
|
mark@3
|
95 |
|
|
mark@3
|
96 |
function doSetReplyType (replytype) {
|
|
mark@3
|
97 |
if (! document.getElementById) return false;
|
|
mark@3
|
98 |
|
|
mark@3
|
99 |
var replytypeBox = document.getElementById('replytype');
|
|
mark@3
|
100 |
if (! replytypeBox) return false;
|
|
mark@3
|
101 |
|
|
mark@3
|
102 |
replytypeBox.value = replytype;
|
|
mark@3
|
103 |
return false;
|
|
mark@3
|
104 |
}
|
|
mark@3
|
105 |
|
|
mark@3
|
106 |
function doChangeCategory () {
|
|
mark@3
|
107 |
return doSetReplyType('internal');
|
|
mark@3
|
108 |
}
|
|
mark@3
|
109 |
|
|
mark@84
|
110 |
function doChangeLanguage () {
|
|
mark@84
|
111 |
return doSetReplyType('internal');
|
|
mark@84
|
112 |
}
|
|
mark@84
|
113 |
|
|
mark@3
|
114 |
function doDegreen () {
|
|
mark@3
|
115 |
return doSetReplyType('internal');
|
|
mark@3
|
116 |
}
|
|
mark@3
|
117 |
|
|
mark@3
|
118 |
function doRegreen () {
|
|
mark@3
|
119 |
return doSetReplyType('internal');
|
|
mark@3
|
120 |
}
|
|
mark@3
|
121 |
|
|
mark@3
|
122 |
function doApproveAnswer () {
|
|
mark@3
|
123 |
return doSetReplyType('internal');
|
|
mark@3
|
124 |
}
|
|
mark@3
|
125 |
|
|
mark@3
|
126 |
function doSummaryClick () {
|
|
mark@3
|
127 |
if (! document.getElementById) return false;
|
|
mark@3
|
128 |
|
|
mark@3
|
129 |
var summaryBox = document.getElementById('changesum');
|
|
mark@3
|
130 |
if (! summaryBox) return false;
|
|
mark@3
|
131 |
|
|
mark@3
|
132 |
if (summaryBox.checked) {
|
|
mark@3
|
133 |
doSetReplyType('internal');
|
|
mark@3
|
134 |
}
|
|
mark@3
|
135 |
|
|
mark@3
|
136 |
return false;
|
|
mark@3
|
137 |
}
|
|
mark@3
|
138 |
|
|
mark@3
|
139 |
function doClearMessage () {
|
|
mark@3
|
140 |
if (! document.getElementById) return false;
|
|
mark@3
|
141 |
|
|
mark@3
|
142 |
var bodyBox = document.getElementById('body');
|
|
mark@3
|
143 |
if (! bodyBox) return false;
|
|
mark@3
|
144 |
|
|
mark@3
|
145 |
bodyBox.value = "";
|
|
mark@3
|
146 |
|
|
mark@3
|
147 |
return false;
|
|
mark@3
|
148 |
}
|
|
mark@3
|
149 |
|
|
mark@3
|
150 |
function doClearFocus () {
|
|
mark@3
|
151 |
if (! document.getElementById) return false;
|
|
mark@3
|
152 |
|
|
mark@3
|
153 |
var submitBox = document.getElementById('submitpost');
|
|
mark@3
|
154 |
if (! submitBox) return false;
|
|
mark@3
|
155 |
|
|
mark@3
|
156 |
submitBox.focus();
|
|
mark@3
|
157 |
|
|
mark@3
|
158 |
return false;
|
|
mark@3
|
159 |
}
|
|
mark@3
|
160 |
|
|
mark@3
|
161 |
// -->
|
|
mark@3
|
162 |
</script>
|
|
mark@3
|
163 |
<=head
|
|
mark@3
|
164 |
bodyopts=>onLoad="check_replytype();updateFaqLink();"
|
|
mark@3
|
165 |
body<=
|
|
mark@3
|
166 |
|
|
mark@3
|
167 |
<?_code
|
|
mark@3
|
168 |
{
|
|
mark@3
|
169 |
use strict;
|
|
mark@3
|
170 |
use vars qw(%FORM);
|
|
mark@3
|
171 |
|
|
mark@3
|
172 |
LJ::set_dynamic_crumb('Request #' . ($FORM{'id'}+0), 'supporthelp');
|
|
mark@3
|
173 |
|
|
mark@3
|
174 |
my $spid = $FORM{'id'}+0;
|
|
mark@3
|
175 |
my $sp = LJ::Support::load_request($spid);
|
|
mark@3
|
176 |
my $props = LJ::Support::load_props($spid);
|
|
mark@3
|
177 |
my $cats = LJ::Support::load_cats();
|
|
mark@3
|
178 |
my $remote = LJ::get_remote();
|
|
mark@3
|
179 |
LJ::Support::init_remote($remote);
|
|
mark@3
|
180 |
|
|
mark@3
|
181 |
if ($FORM{'find'}) {
|
|
mark@3
|
182 |
my $find = $FORM{'find'};
|
|
mark@3
|
183 |
my $op = '<';
|
|
mark@3
|
184 |
my $sort = 'DESC';
|
|
mark@3
|
185 |
if ($find eq 'next' || $find eq 'cnext' || $find eq 'first') {
|
|
mark@3
|
186 |
$op = '>';
|
|
mark@3
|
187 |
$sort = 'ASC';
|
|
mark@3
|
188 |
}
|
|
mark@3
|
189 |
my $spcatand = '';
|
|
mark@3
|
190 |
if ($sp && ($find eq 'cnext' || $find eq 'cprev')) {
|
|
mark@3
|
191 |
my $spcatid = $sp->{_cat}->{'spcatid'} + 0;
|
|
mark@3
|
192 |
$spcatand = "AND spcatid=$spcatid";
|
|
mark@3
|
193 |
} else {
|
|
mark@3
|
194 |
my @filter_cats = LJ::Support::filter_cats($remote, $cats);
|
|
mark@3
|
195 |
return "<?h1 $ML{'.error'} h1?><?p $ML{'.error.text1'} p?>"
|
|
mark@3
|
196 |
unless @filter_cats;
|
|
mark@3
|
197 |
my $cats_in = join(",", map { $_->{'spcatid'} } @filter_cats);
|
|
mark@3
|
198 |
$spcatand = "AND spcatid IN ($cats_in)";
|
|
mark@3
|
199 |
}
|
|
mark@3
|
200 |
my $clause = "";
|
|
mark@3
|
201 |
$clause = "AND spid$op$spid" unless ($find eq 'first' || $find eq 'last');
|
|
mark@3
|
202 |
my $dbr = LJ::get_db_reader();
|
|
mark@3
|
203 |
my ($foundspid) = $dbr->selectrow_array("SELECT spid FROM support WHERE state='open' $spcatand $clause ".
|
|
mark@3
|
204 |
"ORDER BY spid $sort LIMIT 1");
|
|
mark@3
|
205 |
if ($foundspid) {
|
|
afuna@1354
|
206 |
return BML::redirect("see_request?id=$foundspid");
|
|
mark@3
|
207 |
} else {
|
|
fu@4239
|
208 |
my $goback = $sp ? BML::ml('.goback.text', {request_link=>"href='see_request?id=$spid'", spid=>$spid}) : undef;
|
|
mark@3
|
209 |
my $what = $find eq 'next' || $find eq 'cnext' ? $ML{'.next'} : $ML{'.previous'};
|
|
fu@4239
|
210 |
my $cat = $find eq 'cnext' || $find eq 'cprev' ? $ML{'.incat'} : undef;
|
|
mark@3
|
211 |
return "<?h1 $ML{'.error'} h1?>".BML::ml('.error.text2', {what=>$what, cat=>$cat})." $goback";
|
|
mark@3
|
212 |
}
|
|
mark@3
|
213 |
}
|
|
mark@3
|
214 |
|
|
mark@3
|
215 |
unless ($sp) { return "<?h1 $ML{'.error'} h1?><?p $ML{'.unknownumber'} p?>"; }
|
|
mark@3
|
216 |
my $sth;
|
|
mark@3
|
217 |
my $auth = $FORM{'auth'};
|
|
mark@3
|
218 |
|
|
mark@3
|
219 |
my $email = $sp->{'reqemail'};
|
|
mark@3
|
220 |
|
|
mark@461
|
221 |
my $user;
|
|
mark@461
|
222 |
my $user_url;
|
|
mark@461
|
223 |
|
|
mark@461
|
224 |
# Get remote username and journal URL, or example user's username and journal URL
|
|
mark@461
|
225 |
if ( $remote ) {
|
|
mark@461
|
226 |
$user = $remote->user;
|
|
mark@461
|
227 |
$user_url = $remote->journal_base;
|
|
mark@461
|
228 |
} else {
|
|
mark@461
|
229 |
my $exampleu = LJ::load_user( $LJ::EXAMPLE_USER_ACCOUNT );
|
|
mark@461
|
230 |
$user = $exampleu
|
|
mark@461
|
231 |
? $exampleu->user
|
|
mark@461
|
232 |
: "<b>[Unknown or undefined example username]</b>";
|
|
mark@461
|
233 |
$user_url = $exampleu
|
|
mark@461
|
234 |
? $exampleu->journal_base
|
|
mark@461
|
235 |
: "<b>[Unknown or undefined example username]</b>";
|
|
mark@461
|
236 |
}
|
|
mark@461
|
237 |
|
|
mark@3
|
238 |
my $u;
|
|
mark@3
|
239 |
my $clusterdown = 0;
|
|
mark@84
|
240 |
if ($sp->{'reqtype'} eq "user" && $sp->{'requserid'}) {
|
|
mark@3
|
241 |
$u = LJ::load_userid($sp->{'requserid'});
|
|
mark@84
|
242 |
unless ($u) {
|
|
mark@84
|
243 |
warn "Error: user '$sp->{requserid}' not found in request #$spid";
|
|
mark@84
|
244 |
return "<?h1 $ML{'.error'} h1?><?p Unknown user p?>";
|
|
mark@84
|
245 |
}
|
|
mark@3
|
246 |
|
|
mark@3
|
247 |
# now do a check for a down cluster?
|
|
mark@3
|
248 |
my $dbr = LJ::get_cluster_reader($u);
|
|
mark@3
|
249 |
$clusterdown = 1 unless $dbr;
|
|
mark@3
|
250 |
|
|
mark@3
|
251 |
$email = $u->email_raw if $u->email_raw;
|
|
fu@2406
|
252 |
$u->preload_props( "stylesys", "s2_style", "browselang", "schemepref" )
|
|
mark@3
|
253 |
unless $clusterdown;
|
|
mark@3
|
254 |
}
|
|
mark@3
|
255 |
|
|
mark@3
|
256 |
my $winner; # who closed it?
|
|
mark@3
|
257 |
if ($sp->{'state'} eq "closed") {
|
|
mark@3
|
258 |
my $dbr = LJ::get_db_reader();
|
|
mark@3
|
259 |
$sth = $dbr->prepare("SELECT u.user, sp.points FROM useridmap u, supportpoints sp ".
|
|
mark@3
|
260 |
"WHERE u.userid=sp.userid AND sp.spid=?");
|
|
mark@3
|
261 |
$sth->execute($spid);
|
|
mark@3
|
262 |
$winner = $sth->fetchrow_hashref;
|
|
mark@3
|
263 |
}
|
|
mark@3
|
264 |
|
|
mark@84
|
265 |
# get all replies
|
|
mark@84
|
266 |
my @replies;
|
|
mark@84
|
267 |
my $dbr = LJ::get_db_reader();
|
|
mark@84
|
268 |
my $sql_extra = LJ::is_enabled("support_response_tier") ? ", tier" : "";
|
|
mark@84
|
269 |
$sth = $dbr->prepare("SELECT splid, timelogged, UNIX_TIMESTAMP()-timelogged AS 'age', type, faqid, userid, message$sql_extra " .
|
|
mark@84
|
270 |
"FROM supportlog WHERE spid=? ORDER BY timelogged");
|
|
mark@84
|
271 |
$sth->execute($spid);
|
|
mark@84
|
272 |
while (my $le = $sth->fetchrow_hashref) {
|
|
mark@84
|
273 |
push @replies, $le;
|
|
mark@84
|
274 |
}
|
|
mark@84
|
275 |
|
|
mark@3
|
276 |
# load category this request is in
|
|
mark@3
|
277 |
my $problemarea = $sp->{_cat}->{'catname'};
|
|
mark@3
|
278 |
my $catkey = $sp->{_cat}->{'catkey'};
|
|
mark@3
|
279 |
|
|
mark@3
|
280 |
unless (LJ::Support::can_read($sp, $remote, $auth)) {
|
|
mark@3
|
281 |
return "<?h1 $ML{'.error'} h1?><?p $ML{'.nothaveprivilege'} p?>";
|
|
mark@3
|
282 |
}
|
|
mark@3
|
283 |
|
|
mark@3
|
284 |
# helper variables for commonly called methods
|
|
mark@3
|
285 |
my $can_close = LJ::Support::can_close($sp, $remote, $auth) ? 1 : 0;
|
|
mark@3
|
286 |
my $can_reopen = LJ::Support::can_reopen($sp, $remote, $auth) ? 1 : 0;
|
|
mark@3
|
287 |
my $helper_mode = LJ::Support::can_help($sp, $remote) ? 1 : 0;
|
|
mark@3
|
288 |
my $stock_mode = LJ::Support::can_see_stocks($sp, $remote) ? 1 : 0;
|
|
mark@3
|
289 |
my $is_poster = LJ::Support::is_poster($sp, $remote, $auth) ? 1 : 0;
|
|
mark@3
|
290 |
|
|
mark@3
|
291 |
# fix up the subject if needed
|
|
mark@3
|
292 |
eval {
|
|
mark@3
|
293 |
if ($sp->{'subject'} =~ /^=\?(utf-8)?/i) {
|
|
mark@3
|
294 |
my @subj_data;
|
|
mark@3
|
295 |
require MIME::Words;
|
|
mark@3
|
296 |
@subj_data = MIME::Words::decode_mimewords($sp->{'subject'});
|
|
mark@3
|
297 |
if (scalar(@subj_data)) {
|
|
mark@3
|
298 |
if (!$1) {
|
|
mark@3
|
299 |
$sp->{'subject'} = Unicode::MapUTF8::to_utf8({-string=>$subj_data[0][0], -charset=>$subj_data[0][1]});
|
|
mark@3
|
300 |
} else {
|
|
mark@3
|
301 |
$sp->{'subject'} = $subj_data[0][0];
|
|
mark@3
|
302 |
}
|
|
mark@3
|
303 |
}
|
|
mark@3
|
304 |
}
|
|
mark@3
|
305 |
};
|
|
mark@3
|
306 |
|
|
mark@3
|
307 |
|
|
mark@3
|
308 |
### request info table
|
|
mark@3
|
309 |
|
|
mark@3
|
310 |
my $ret = "";
|
|
fu@3114
|
311 |
$ret .= "<table summary='' class='support-requesttable'>\n";
|
|
mark@3
|
312 |
$ret .= "<tr><td valign='bottom' align='right'><b>$ML{'.from'}</b></td><td>";
|
|
mark@3
|
313 |
|
|
fu@2810
|
314 |
if ( $u->{'defaultpicid'} && !$u->is_suspended ) {
|
|
fu@2810
|
315 |
my $userpic_obj = $u->userpic;
|
|
afuna@1263
|
316 |
$ret .= "<a href='" . $u->allpics_base . "'>";
|
|
afuna@677
|
317 |
$ret .= $userpic_obj->imgtag;
|
|
mark@3
|
318 |
$ret .= "</a>";
|
|
mark@3
|
319 |
}
|
|
mark@3
|
320 |
|
|
mark@3
|
321 |
# show requester name + email
|
|
mark@3
|
322 |
{
|
|
mark@3
|
323 |
my $visemail = $email;
|
|
mark@3
|
324 |
$visemail =~ s/^.+\@/********\@/;
|
|
mark@3
|
325 |
|
|
mark@3
|
326 |
my $ename = $sp->{'reqtype'} eq 'user' ? LJ::ljuser($u) : LJ::ehtml($sp->{reqname});
|
|
mark@3
|
327 |
|
|
mark@3
|
328 |
# we show links to the history page if the user is a helper since
|
|
mark@3
|
329 |
# helpers can always find this information anyway just by taking
|
|
mark@3
|
330 |
# more steps. Show email history link if they have finduser and
|
|
mark@3
|
331 |
# thus once again could get this information anyway.
|
|
afuna@1514
|
332 |
my $has_sh = $remote && $remote->has_priv( 'supporthelp' );
|
|
afuna@1514
|
333 |
my $has_fu = $remote && $remote->has_priv( 'finduser' );
|
|
afuna@1514
|
334 |
my $has_vs = $remote && $remote->has_priv( 'supportviewscreened' );
|
|
mark@3
|
335 |
|
|
mark@3
|
336 |
my %show_history = (
|
|
mark@3
|
337 |
user => $has_sh,
|
|
mark@84
|
338 |
email => ($has_fu || ($has_sh && !$sp->{_cat}->{public_read})),
|
|
mark@3
|
339 |
);
|
|
mark@3
|
340 |
|
|
mark@3
|
341 |
if ($show_history{user} || $show_history{email}) {
|
|
mark@3
|
342 |
$ret .= $sp->{reqtype} eq 'user' && $show_history{user} ?
|
|
afuna@1354
|
343 |
"$ename <a href=\"history?user=$u->{user}\">" . LJ::ehtml($u->{name}) . "</a>" :
|
|
mark@3
|
344 |
"$ename";
|
|
mark@84
|
345 |
|
|
afuna@2095
|
346 |
my $email_string = $has_vs || $has_sh ? " ($visemail)" : "";
|
|
afuna@1354
|
347 |
$email_string = " (<a href=\"history?email=" . LJ::eurl($email) . "\">$email</a>)" if $show_history{email};
|
|
mark@84
|
348 |
$ret .= $email_string;
|
|
mark@3
|
349 |
} else {
|
|
mark@3
|
350 |
# default view
|
|
mark@84
|
351 |
$ret .= $ename;
|
|
mark@84
|
352 |
$ret .= " ($visemail)" if $has_vs || $has_sh;
|
|
mark@3
|
353 |
}
|
|
mark@3
|
354 |
}
|
|
mark@3
|
355 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
356 |
|
|
mark@3
|
357 |
# uniq
|
|
afuna@1514
|
358 |
if ( $remote && ( $remote->has_priv( 'sysban', 'uniq' ) || $remote->has_priv( 'canview', 'userlog' ) ) ) {
|
|
mark@3
|
359 |
my $uniq = $props->{'uniq'} || "<i>$ML{'.none'}</i>";
|
|
mark@3
|
360 |
$ret .= "<tr><td valign='bottom' align='right'><b>$ML{'.uniq'}</b></td><td>$uniq</td></tr>\n";
|
|
mark@3
|
361 |
}
|
|
mark@3
|
362 |
|
|
mark@3
|
363 |
# account type
|
|
mark@549
|
364 |
$ret .= "<tr><td align='right' valign='top'><b><span style='white-space: nowrap'>$ML{'.accounttype'}</span>:</b></td><td>";
|
|
fu@3732
|
365 |
$ret .= LJ::Capabilities::name_caps( $u->{caps} ) || "<i>$ML{'.unknown'}</i>";
|
|
mark@3
|
366 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
367 |
|
|
mark@2670
|
368 |
if ($u->{'userid'}) {
|
|
mark@3
|
369 |
$ret .= "<tr valign='top'><td align='right'><b>$LJ::SITENAMESHORT:</b></td><td>";
|
|
mark@3
|
370 |
|
|
mark@3
|
371 |
if ($u->is_expunged) {
|
|
mark@3
|
372 |
$ret .= $ML{'.status.deleted.and.purged'} . "<br />";
|
|
mark@3
|
373 |
} elsif ($clusterdown) {
|
|
mark@3
|
374 |
$ret .= "<span style='color: red; font-weight: bold;'>" .
|
|
mark@3
|
375 |
$ML{'.unable.connect'} ."</span><br />";
|
|
mark@3
|
376 |
}
|
|
mark@3
|
377 |
|
|
mark@3
|
378 |
if ($u->readonly) {
|
|
mark@3
|
379 |
$ret .= "<span style='color: red; font-weight: bold;'>" .
|
|
mark@3
|
380 |
$ML{'.userreadonly'} ."</span><br />";
|
|
mark@3
|
381 |
}
|
|
mark@3
|
382 |
|
|
mark@3
|
383 |
$ret .= "$ML{'.username'}: <?ljuserf $u->{'user'} ljuserf?>";
|
|
mark@3
|
384 |
$ret .= "<br />$ML{'.style'}: ";
|
|
mark@3
|
385 |
if ($u->{'stylesys'} == 2) {
|
|
mark@3
|
386 |
$ret .= "(S2) ";
|
|
mark@3
|
387 |
if ($u->{'s2_style'}) {
|
|
mark@3
|
388 |
my $s2style = LJ::S2::load_style($u->{'s2_style'});
|
|
mark@3
|
389 |
my $pub = LJ::S2::get_public_layers(); # cached
|
|
mark@3
|
390 |
foreach my $lay (sort { $a cmp $b } keys %{$s2style->{'layer'}}) {
|
|
mark@3
|
391 |
my $lid = $s2style->{'layer'}->{$lay};
|
|
mark@3
|
392 |
unless ($lid) {
|
|
mark@3
|
393 |
$ret .= "$lay: none, ";
|
|
mark@3
|
394 |
next;
|
|
mark@3
|
395 |
}
|
|
afuna@1354
|
396 |
$ret .= "$lay: <a href='$LJ::SITEROOT/customize/advanced/layerbrowse?id=$lid'>";
|
|
mark@3
|
397 |
$ret .= (defined $pub->{$lid} ? 'public' : 'custom') . "</a>, ";
|
|
mark@3
|
398 |
}
|
|
mark@3
|
399 |
} else {
|
|
fu@3808
|
400 |
$ret .= $ML{'.none'};
|
|
mark@3
|
401 |
}
|
|
mark@3
|
402 |
} else {
|
|
mark@151
|
403 |
$ret .= "(User on S1; why?) ";
|
|
mark@3
|
404 |
}
|
|
mark@3
|
405 |
|
|
mark@2019
|
406 |
LJ::Hooks::run_hooks("support_see_request_info_rows", {
|
|
mark@3
|
407 |
'u' => $u,
|
|
mark@3
|
408 |
'email' => $email,
|
|
mark@3
|
409 |
'sp' => $sp,
|
|
mark@3
|
410 |
'retref' => \$ret,
|
|
mark@3
|
411 |
'remote' => $remote,
|
|
mark@3
|
412 |
});
|
|
mark@3
|
413 |
|
|
mark@3
|
414 |
# if the user has siteadmin:users or siteadmin:* show them link to resend validation email?
|
|
mark@3
|
415 |
my $extraval = sub {
|
|
afuna@1514
|
416 |
return '' unless $remote && $remote->has_priv( 'siteadmin', 'users' );
|
|
afuna@1354
|
417 |
return " (<a href='$LJ::SITEROOT/register?foruser=$u->{user}'>$ML{'.resend.validation.email'}</a>)";
|
|
mark@3
|
418 |
};
|
|
mark@3
|
419 |
|
|
kareila@1666
|
420 |
$ret .= "<br />" . $ML{'.email.validated'} . " ";
|
|
mark@3
|
421 |
if ($u->{'status'} eq "A") { $ret .= "<b>$ML{'.yes'}</b>"; }
|
|
mark@3
|
422 |
if ($u->{'status'} eq "N") { $ret .= "<b>$ML{'.no'}</b>" . $extraval->(); }
|
|
mark@3
|
423 |
if ($u->{'status'} eq "T") { $ret .= $ML{'.transitioning'} . $extraval->(); }
|
|
mark@3
|
424 |
$ret .= "<br />";
|
|
fu@4053
|
425 |
$ret .= "$ML{'.cluster'}: <b>" . LJ::DB::get_cluster_description( $u->{clusterid} ) . "</b>; "
|
|
fu@4053
|
426 |
if $u->{clusterid};
|
|
mark@3
|
427 |
$ret .= "$ML{'.dataversion'}: <b>$u->{dversion}</b>";
|
|
mark@3
|
428 |
$ret .= "<br />$ML{'.scheme'}: <b>" . ($u->{schemepref} ? $u->{schemepref} : "default") . "</b>; ";
|
|
mark@3
|
429 |
$ret .= "$ML{'.language'}: <b>" . ($u->{browselang} ? $u->{browselang} : "default") . "</b>";
|
|
mark@3
|
430 |
|
|
afuna@1514
|
431 |
my $view_history = $remote && $remote->has_priv( 'historyview' );
|
|
afuna@1514
|
432 |
my $view_userlog = $remote && $remote->has_priv( 'canview', 'userlog' );
|
|
mark@3
|
433 |
|
|
mark@3
|
434 |
if ($view_history || $view_userlog) {
|
|
mark@3
|
435 |
$ret .= "<br />$ML{'.view'}: ";
|
|
afuna@1354
|
436 |
$ret .= "<a href='$LJ::SITEROOT/admin/statushistory?user=$u->{user}'>$ML{'.statushistory'}</a> "
|
|
mark@3
|
437 |
if $view_history;
|
|
afuna@1354
|
438 |
$ret .= "<a href='$LJ::SITEROOT/admin/userlog?user=$u->{user}'>userlog</a> "
|
|
mark@3
|
439 |
if $view_userlog;
|
|
mark@3
|
440 |
}
|
|
mark@3
|
441 |
|
|
fu@3460
|
442 |
if ( $u->in_class( LJ::BetaFeatures->cap_name )
|
|
fu@3460
|
443 |
&& LJ::Support::has_any_support_priv( $remote ) ) {
|
|
fu@3460
|
444 |
$ret .= "<br />$ML{'.betatesting'}: ";
|
|
fu@3460
|
445 |
$ret .= join ", ", $u->prop( LJ::BetaFeatures->prop_name );
|
|
fu@3460
|
446 |
}
|
|
fu@3460
|
447 |
|
|
mark@3
|
448 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
449 |
}
|
|
mark@3
|
450 |
|
|
mark@3
|
451 |
$ret .= "<tr><td align='right' nowrap='nowrap'><b>$ML{'.supportcategory'}:</b></td><td>";
|
|
mark@3
|
452 |
if (LJ::Support::can_read_cat($sp->{_cat}, $remote)) {
|
|
afuna@1354
|
453 |
$ret .= "<a href='$LJ::SITEROOT/support/help?cat=$sp->{_cat}->{'catkey'}'>$problemarea</a>";
|
|
afuna@1354
|
454 |
$ret .= " [<a href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&find=cprev'>$ML{'.previous'}</a>|";
|
|
afuna@1354
|
455 |
$ret .= "<a href='$LJ::SITEROOT/support/see_request?id=$sp->{'spid'}&find=cnext'>$ML{'.next'}</a>]";
|
|
mark@3
|
456 |
} else {
|
|
mark@3
|
457 |
$ret .= $problemarea;
|
|
mark@3
|
458 |
}
|
|
mark@3
|
459 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
460 |
|
|
mark@84
|
461 |
# figure out the tier of the most recent answer
|
|
mark@84
|
462 |
my %tier_map = (
|
|
mark@84
|
463 |
0 => "0",
|
|
mark@84
|
464 |
10 => "1",
|
|
mark@84
|
465 |
20 => "2",
|
|
mark@84
|
466 |
30 => "3",
|
|
mark@84
|
467 |
);
|
|
afuna@1514
|
468 |
my $can_see_tier = $remote && ( $remote->has_priv( "supporthelp" ) || $remote->has_priv( "supportviewscreened" ) );
|
|
mark@84
|
469 |
if (LJ::is_enabled("support_response_tier") && $can_see_tier) {
|
|
mark@84
|
470 |
my $latest_timelogged = 0;
|
|
mark@84
|
471 |
my $latest_timelogged_tier = 0;
|
|
mark@84
|
472 |
foreach my $reply (@replies) {
|
|
mark@84
|
473 |
next unless $reply->{type} eq "answer" || $reply->{type} eq "internal";
|
|
mark@84
|
474 |
|
|
mark@84
|
475 |
if ($reply->{tier} && $reply->{timelogged} && $reply->{timelogged} > $latest_timelogged) {
|
|
mark@84
|
476 |
$latest_timelogged = $reply->{timelogged};
|
|
mark@84
|
477 |
$latest_timelogged_tier = $reply->{tier};
|
|
mark@84
|
478 |
}
|
|
mark@84
|
479 |
}
|
|
mark@84
|
480 |
$ret .= "<tr><td align='right'><b>$ML{'.tier'}</b></td><td>$tier_map{$latest_timelogged_tier}</td></tr>\n";
|
|
mark@84
|
481 |
}
|
|
mark@84
|
482 |
|
|
fu@2995
|
483 |
my $timecreate = LJ::time_to_http( $sp->{timecreate} );
|
|
fu@2995
|
484 |
my $age = LJ::diff_ago_text( $sp->{timecreate} );
|
|
mark@3
|
485 |
$ret .= "<tr><td align='right'><b>$ML{'.timeposted'}:</b></td><td>$timecreate ($age)</td></tr>\n";
|
|
mark@3
|
486 |
my $state = $sp->{'state'};
|
|
mark@3
|
487 |
if ($state eq "open") {
|
|
mark@3
|
488 |
# check if it's still open or needing help or what
|
|
mark@3
|
489 |
if ($sp->{'timelasthelp'} > ($sp->{'timetouched'}+5)) {
|
|
mark@3
|
490 |
# open, answered
|
|
mark@3
|
491 |
$state = $ML{'.answered'};
|
|
mark@3
|
492 |
} elsif ($sp->{'timelasthelp'} && $sp->{'timetouched'} > $sp->{'timelasthelp'}+5) {
|
|
mark@3
|
493 |
# open, still needs help
|
|
mark@3
|
494 |
$state = $ML{'.answered.need.help'};
|
|
mark@3
|
495 |
} else {
|
|
mark@3
|
496 |
# default
|
|
mark@3
|
497 |
$state = "<b><span style='color: #ff0000;'>$ML{'.open'}</span></b>";
|
|
mark@3
|
498 |
}
|
|
mark@3
|
499 |
}
|
|
mark@3
|
500 |
if ($state eq "closed" && $winner && LJ::Support::can_see_helper($sp, $remote)) {
|
|
mark@3
|
501 |
my $s = $winner->{'points'} > 1 ? "s" : "";
|
|
mark@3
|
502 |
my $wuser = $winner->{'user'};
|
|
mark@3
|
503 |
$state .= " (<b>$winner->{'points'}</b> point$s to ";
|
|
mark@3
|
504 |
$state .= LJ::ljuser($wuser, { 'full' => 1 }) . ")";
|
|
mark@3
|
505 |
}
|
|
mark@3
|
506 |
$ret .= "<tr><td align='right'><b>$ML{'.status'}:</b></td><td>$state";
|
|
mark@3
|
507 |
if ($can_close || $can_reopen) {
|
|
mark@3
|
508 |
if ($sp->{'state'} eq "open" && $can_close) {
|
|
afuna@1354
|
509 |
$ret .= ", <a href='act?close;$sp->{'spid'};$sp->{'authcode'}'><b>$ML{'.close.without.credit'}</b></a>";
|
|
mark@3
|
510 |
} elsif ($sp->{state} eq 'closed') {
|
|
mark@3
|
511 |
my $permastatus = LJ::Support::is_locked($sp);
|
|
mark@3
|
512 |
$ret .= $sp->{'state'} eq "closed" && !$permastatus ?
|
|
afuna@1354
|
513 |
", <a href='act?touch;$sp->{'spid'};$sp->{'authcode'}'><b>$ML{'.reopen.this.request'}</b></a>" : "";
|
|
mark@3
|
514 |
if (LJ::Support::can_lock($sp, $remote)) {
|
|
mark@3
|
515 |
$ret .= $permastatus ?
|
|
afuna@1354
|
516 |
", <a href='act?unlock;$sp->{spid};$sp->{authcode}'><b>$ML{'.unlock.request'}</b></a>" :
|
|
afuna@1354
|
517 |
", <a href='act?lock;$sp->{spid};$sp->{authcode}'><b>$ML{'.lock.request'}</b></a>";
|
|
mark@3
|
518 |
}
|
|
mark@3
|
519 |
}
|
|
mark@3
|
520 |
}
|
|
mark@3
|
521 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
522 |
$ret .= "<tr><td align='right'><b>$ML{'.summary'}:</b></td><td><span style='font-size: 1.1em'><b>" . LJ::ehtml($sp->{'subject'}) . "</b></span></td></tr>\n";
|
|
mark@3
|
523 |
$ret .= "</table>\n";
|
|
mark@3
|
524 |
|
|
mark@3
|
525 |
### end request info table
|
|
mark@3
|
526 |
|
|
mark@2019
|
527 |
LJ::Hooks::run_hooks("support_see_request_html", {
|
|
mark@3
|
528 |
'u' => $u,
|
|
mark@3
|
529 |
'email' => $email,
|
|
mark@3
|
530 |
'sp' => $sp,
|
|
mark@3
|
531 |
'retref' => \$ret,
|
|
mark@3
|
532 |
'remote' => $remote,
|
|
mark@3
|
533 |
});
|
|
mark@3
|
534 |
|
|
mark@3
|
535 |
# put in a "this is private!" box if this is a private request and the user viewing
|
|
mark@3
|
536 |
# this page is the person who opened the request
|
|
mark@3
|
537 |
if (!$sp->{_cat}->{public_read} && $is_poster) {
|
|
mark@3
|
538 |
$ret .= "<div style='margin-top: 15px; margin-bottom: 15px; padding: 5px; " .
|
|
mark@3
|
539 |
"text-align: center; background-color: #ffff00; border: solid 2px red;'>" .
|
|
mark@3
|
540 |
$ML{'.private.request'}."</div>";
|
|
mark@3
|
541 |
}
|
|
mark@3
|
542 |
|
|
mark@3
|
543 |
my @screened;
|
|
mark@84
|
544 |
my $most_recent_tier = 0;
|
|
mark@461
|
545 |
my $curlang = BML::get_language();
|
|
mark@3
|
546 |
|
|
mark@3
|
547 |
### reply loop
|
|
mark@84
|
548 |
foreach my $le (@replies)
|
|
mark@3
|
549 |
{
|
|
mark@84
|
550 |
if (LJ::is_enabled("support_response_tier") && $can_see_tier && ($le->{type} eq "answer" || $le->{type} eq "internal") && $le->{tier}) {
|
|
mark@84
|
551 |
$most_recent_tier = $le->{tier};
|
|
mark@84
|
552 |
}
|
|
mark@84
|
553 |
|
|
kareila@2747
|
554 |
my $up = LJ::load_userid( $le->{userid} );
|
|
kareila@2747
|
555 |
my $remote_is_up = $remote && $remote->equals( $up );
|
|
mark@3
|
556 |
|
|
kareila@2747
|
557 |
next if $le->{type} eq "internal" && ! ( LJ::Support::can_read_internal( $sp, $remote )
|
|
kareila@2747
|
558 |
|| $remote_is_up );
|
|
kareila@2747
|
559 |
next if $le->{type} eq "screened" && ! ( LJ::Support::can_read_screened( $sp, $remote )
|
|
kareila@2747
|
560 |
|| $remote_is_up );
|
|
kareila@2747
|
561 |
next if $le->{type} eq "screened" && $up && !$up->is_visible;
|
|
mark@3
|
562 |
|
|
kareila@2747
|
563 |
push @screened, $le if $le->{type} eq "screened";
|
|
mark@3
|
564 |
|
|
kareila@2747
|
565 |
my $message = $le->{message};
|
|
mark@3
|
566 |
my %url;
|
|
mark@3
|
567 |
my $urlN = 0;
|
|
mark@3
|
568 |
|
|
mark@3
|
569 |
$message = LJ::ehtml($message);
|
|
mark@3
|
570 |
$message =~ s/^\s+//;
|
|
mark@3
|
571 |
$message =~ s/\s+$//;
|
|
mark@3
|
572 |
$message =~ s/\n( +)/"\n" . " "x length($1)/eg;
|
|
mark@3
|
573 |
$message =~ s/\n/<br \/>\n/g;
|
|
mark@3
|
574 |
$message = LJ::auto_linkify($message);
|
|
mark@3
|
575 |
|
|
mark@3
|
576 |
# special case: original request
|
|
mark@3
|
577 |
if ($le->{'type'} eq "req") {
|
|
mark@3
|
578 |
# insert support diagnostics from props
|
|
mark@3
|
579 |
$message .= "<?hr?><strong>$ML{'.diagnostics'}:</strong> " . LJ::ehtml($props->{useragent}) if $props->{useragent};
|
|
mark@3
|
580 |
|
|
mark@3
|
581 |
$ret .= "<div style='margin-top: 15px;'>\n";
|
|
mark@3
|
582 |
$ret .= "<b>$ML{'.original.request'}:</b><br />\n";
|
|
afuna@356
|
583 |
$ret .= "<div class='requestdiv'>\n$message\n</div></div>";
|
|
mark@3
|
584 |
next;
|
|
mark@3
|
585 |
}
|
|
mark@3
|
586 |
|
|
mark@3
|
587 |
# print anchor for links to jump here
|
|
mark@3
|
588 |
$ret .= "<a name='e$le->{splid}'></a>";
|
|
mark@3
|
589 |
|
|
mark@3
|
590 |
# reply header
|
|
mark@3
|
591 |
my $header = "";
|
|
mark@3
|
592 |
if ($up && LJ::Support::can_see_helper($sp, $remote)) {
|
|
fu@2809
|
593 |
my $picid = $up->get_picid_from_keyword( '_support' ) || $up->{defaultpicid};
|
|
fu@2810
|
594 |
my $icon = $picid ? LJ::Userpic->new( $up, $picid ) : undef;
|
|
fu@3114
|
595 |
$header = "<table summary='' style='margin-top: 15px;'><tr valign='bottom'>";
|
|
fu@2810
|
596 |
if ( $icon && !$up->is_suspended ) {
|
|
fu@2810
|
597 |
my $alt = $up->display_name;
|
|
fu@2810
|
598 |
my $src = $icon->url;
|
|
fu@2810
|
599 |
my ( $width, $height ) = $icon->dimensions;
|
|
fu@2810
|
600 |
$header .= "<td><img src='$src' width='$width' height='$height' hspace='3' alt='$alt'/></td>";
|
|
mark@3
|
601 |
}
|
|
kareila@2900
|
602 |
$header .= "<td>" . LJ::ljuser( $up, { full => 1 } );
|
|
fu@2810
|
603 |
$header .= " - " . $up->name_html unless $up->is_suspended;
|
|
mark@3
|
604 |
$header .= "</td></tr></table>\n"
|
|
mark@3
|
605 |
}
|
|
mark@3
|
606 |
|
|
mark@3
|
607 |
my $what = $ML{'.answer'};
|
|
mark@3
|
608 |
if ($le->{'type'} eq "internal") { $what = $ML{'.internal.comment'}; }
|
|
mark@3
|
609 |
elsif ($le->{'type'} eq "comment") { $what = $ML{".comment"}; }
|
|
mark@3
|
610 |
elsif ($le->{'type'} eq "screened") { $what = $ML{'.screened.response'}; }
|
|
mark@3
|
611 |
|
|
afuna@1354
|
612 |
my $link = "<a href='$LJ::SITEROOT/support/see_request?id=$spid#e$le->{splid}'>#$le->{splid}</a>";
|
|
mark@3
|
613 |
$header .= "<span style='font-size: 0.9em;'><b>$what</b> ($link)</span><br />";
|
|
mark@84
|
614 |
if (LJ::is_enabled("support_response_tier") && $can_see_tier && $le->{type} eq "answer") {
|
|
mark@84
|
615 |
# show the answer's tier level, or if there is no tier level, show the tier level at the time of posting
|
|
mark@84
|
616 |
my $display_tier = $le->{tier} ? $le->{tier} : $most_recent_tier;
|
|
mark@84
|
617 |
$header .= "<b>$ML{'.tier'}</b> $tier_map{$display_tier}<br />";
|
|
mark@84
|
618 |
}
|
|
mark@3
|
619 |
my $timehelped = LJ::time_to_http($le->{'timelogged'});
|
|
mark@3
|
620 |
my $age = LJ::ago_text($le->{'age'});
|
|
mark@3
|
621 |
$header .= "<b>$ML{'.posted'}:</b> $timehelped ($age)";
|
|
mark@3
|
622 |
if ($can_close && $sp->{'state'} eq "open" && $le->{'type'} eq "answer") {
|
|
afuna@1354
|
623 |
$header .= ", <a href='act?close;$sp->{'spid'};$sp->{'authcode'};$le->{'splid'}'><b>$ML{'.credit.fix'}</b></a>";
|
|
mark@3
|
624 |
}
|
|
mark@3
|
625 |
|
|
afuna@356
|
626 |
my $bordercolor = "default";
|
|
afuna@356
|
627 |
if ($le->{'type'} eq "internal") { $bordercolor = "internal"; }
|
|
afuna@356
|
628 |
if ($le->{'type'} eq "answer") { $bordercolor = "answer"; }
|
|
afuna@356
|
629 |
if ($le->{'type'} eq "screened") { $bordercolor = "screened"; }
|
|
mark@3
|
630 |
|
|
mark@3
|
631 |
# reply
|
|
mark@3
|
632 |
$ret .= "$header<br />\n";
|
|
fu@3114
|
633 |
$ret .= "<table summary='' class='support-requesttable-$bordercolor'>\n";
|
|
mark@3
|
634 |
$ret .= "<tr><td align='center'>\n";
|
|
mark@461
|
635 |
if ($le->{faqid}) {
|
|
mark@3
|
636 |
# faq question
|
|
mark@461
|
637 |
my $faq = LJ::Faq->load( $le->{faqid}, lang => $curlang );
|
|
mark@461
|
638 |
$faq->render_in_place;
|
|
fu@3713
|
639 |
$ret .= "<div style='display: table; padding: 3px; margin-left: auto; margin-right: auto;'>\n";
|
|
mark@3
|
640 |
# whitespace between these two DIVs is necessary for proper
|
|
mark@3
|
641 |
# rendering in IE 5 for Mac OS < X
|
|
fu@3713
|
642 |
$ret .= "<div class='highlight-box' style='text-align:center;'>";
|
|
afuna@1354
|
643 |
$ret .= "<b>$ML{'.faq.reference'}:</b><br /><a href='faqbrowse?faqid=$le->{faqid}&view=full'>" . $faq->question_html . "</a></div></div>\n";
|
|
mark@3
|
644 |
}
|
|
mark@3
|
645 |
$ret .= "<p align='left' style='margin-top: 0px; margin-bottom: 0px;'>$message</p>\n";
|
|
mark@3
|
646 |
$ret .= "</td></tr></table>\n";
|
|
mark@3
|
647 |
}
|
|
mark@3
|
648 |
### end reply loop
|
|
mark@3
|
649 |
|
|
mark@3
|
650 |
# return if support item is closed
|
|
mark@3
|
651 |
if ($sp->{'state'} eq "closed") {
|
|
mark@3
|
652 |
return $ret;
|
|
mark@3
|
653 |
}
|
|
mark@3
|
654 |
|
|
afuna@1125
|
655 |
if ($is_poster) {
|
|
afuna@1125
|
656 |
$ret .= "<p style='margin-bottom: 0px;'><b>$ML{'.post.moreinformation'}:</b></p>\n";
|
|
afuna@1125
|
657 |
} elsif ($remote) {
|
|
afuna@1125
|
658 |
$ret .= "<p style='margin-bottom: 0px;'><b>$ML{'.post.comment'}:</b></p>\n";
|
|
afuna@1125
|
659 |
} else {
|
|
afuna@1354
|
660 |
$ret .= BML::ml('.mast.login', {loginlink=>"href='$LJ::SITEROOT/login?ret=1'"});
|
|
mark@3
|
661 |
$ret .= "\n";
|
|
mark@3
|
662 |
return $ret;
|
|
mark@3
|
663 |
}
|
|
mark@3
|
664 |
|
|
mark@3
|
665 |
unless (LJ::Support::can_append($sp, $remote, $auth))
|
|
mark@3
|
666 |
{
|
|
mark@3
|
667 |
$ret .= "$ML{'.not.have.access'}\n";
|
|
mark@3
|
668 |
return $ret;
|
|
mark@3
|
669 |
}
|
|
mark@3
|
670 |
|
|
mark@3
|
671 |
my @ans_type = LJ::Support::get_answer_types($sp, $remote, $auth);
|
|
mark@3
|
672 |
my %ans_type = @ans_type;
|
|
mark@3
|
673 |
|
|
mark@3
|
674 |
if ($ans_type{'answer'} || $ans_type{'screened'})
|
|
mark@3
|
675 |
{
|
|
fu@3217
|
676 |
$ret .= "<div class='highlight-box'>";
|
|
fu@3217
|
677 |
$ret .= BML::ml('.important.notes.text2', {
|
|
mark@3
|
678 |
sitenameshort=>$LJ::SITENAMESHORT,
|
|
afuna@1354
|
679 |
supportlink=>"href='$LJ::SITEROOT/doc/guide/support'",
|
|
mark@3
|
680 |
});
|
|
fu@3217
|
681 |
$ret .= "</div>\n";
|
|
mark@3
|
682 |
}
|
|
mark@3
|
683 |
|
|
mark@3
|
684 |
# append_request form
|
|
mark@3
|
685 |
|
|
afuna@1354
|
686 |
$ret .= "<br /><form method='post' action='append_request' name='supportForm'>\n";
|
|
mark@3
|
687 |
|
|
mark@3
|
688 |
# hidden values
|
|
mark@3
|
689 |
$ret .= LJ::html_hidden('spid', $spid, 'auth', $auth) . "\n";
|
|
mark@3
|
690 |
|
|
mark@3
|
691 |
# form
|
|
fu@3114
|
692 |
$ret .= "<table summary='' class='support-requesttable'>\n";
|
|
mark@84
|
693 |
$ret .= "<tr valign='middle'><td align='right'>$ML{'.from'}</td><td>";
|
|
mark@3
|
694 |
|
|
mark@3
|
695 |
if ($remote && $remote->{'userid'}) {
|
|
mark@3
|
696 |
$ret .= "<?ljuser $remote->{'user'} ljuser?>";
|
|
mark@3
|
697 |
} else {
|
|
mark@3
|
698 |
$ret .= "(not logged in)";
|
|
mark@3
|
699 |
}
|
|
mark@3
|
700 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
701 |
|
|
mark@3
|
702 |
if ($ans_type{'answer'} || $ans_type{'screened'})
|
|
mark@3
|
703 |
{
|
|
mark@3
|
704 |
my $dbr = LJ::get_db_reader();
|
|
mark@3
|
705 |
# FAQ reference
|
|
afuna@1354
|
706 |
$ret .= "<tr valign='middle'><td align='right'>$ML{'.reference'} <a href='faq'>$ML{'.faq'}</a>:</td><td colspan='2'>\n";
|
|
mark@3
|
707 |
|
|
mark@3
|
708 |
my %faqcat;
|
|
mark@3
|
709 |
my %faqq;
|
|
mark@461
|
710 |
# FIXME: must refactor that somewhere
|
|
mark@461
|
711 |
my $deflang = BML::get_language_default();
|
|
mark@461
|
712 |
my $mll = LJ::Lang::get_lang( $curlang );
|
|
mark@461
|
713 |
my $mld = LJ::Lang::get_dom( "faq" );
|
|
mark@461
|
714 |
my $altlang = $deflang ne $curlang;
|
|
mark@461
|
715 |
$altlang = 0 unless $mld and $mll;
|
|
mark@461
|
716 |
if ( $altlang ) {
|
|
mark@461
|
717 |
my $sql = qq{SELECT fc.faqcat, t.text, fc.catorder
|
|
mark@461
|
718 |
FROM faqcat fc, ml_text t, ml_latest l, ml_items i
|
|
mark@461
|
719 |
WHERE t.dmid=$mld->{'dmid'} AND l.dmid=$mld->{'dmid'}
|
|
mark@461
|
720 |
AND i.dmid=$mld->{'dmid'} AND l.lnid=$mll->{'lnid'}
|
|
mark@461
|
721 |
AND l.itid=i.itid
|
|
mark@461
|
722 |
AND i.itcode=CONCAT('cat.', fc.faqcat)
|
|
mark@461
|
723 |
AND l.txtid=t.txtid AND fc.faqcat<>'int-abuse'};
|
|
mark@461
|
724 |
$sth = $dbr->prepare( $sql );
|
|
mark@461
|
725 |
} else {
|
|
mark@461
|
726 |
$sth = $dbr->prepare("SELECT faqcat, faqcatname, catorder FROM faqcat ".
|
|
mark@461
|
727 |
"WHERE faqcat<>'int-abuse'");
|
|
mark@461
|
728 |
}
|
|
mark@3
|
729 |
$sth->execute;
|
|
mark@3
|
730 |
while ($_ = $sth->fetchrow_hashref) {
|
|
mark@3
|
731 |
$faqcat{$_->{'faqcat'}} = $_;
|
|
mark@3
|
732 |
}
|
|
mark@3
|
733 |
|
|
mark@461
|
734 |
foreach my $f ( LJ::Faq->load_all( lang => $curlang ) ) {
|
|
mark@461
|
735 |
$f->render_in_place( { user => $user, url => $user_url } );
|
|
mark@518
|
736 |
push @{ $faqq{$f->faqcat} ||= [] }, $f;
|
|
mark@3
|
737 |
}
|
|
mark@3
|
738 |
|
|
mark@3
|
739 |
my @faqlist = ('0', "(don't reference FAQ)");
|
|
mark@3
|
740 |
foreach my $faqcat (sort { $faqcat{$a}->{'catorder'} <=> $faqcat{$b}->{'catorder'} } keys %faqcat)
|
|
mark@3
|
741 |
{
|
|
mark@3
|
742 |
push @faqlist, ('0', "[ $faqcat{$faqcat}->{'faqcatname'} ]");
|
|
mark@461
|
743 |
foreach my $faq ( sort { $a->sortorder <=> $b->sortorder }
|
|
mark@518
|
744 |
@{ $faqq{$faqcat} || [] } ) {
|
|
afuna@910
|
745 |
my $q = $faq->question_raw;
|
|
mark@461
|
746 |
next unless $q;
|
|
mark@461
|
747 |
$q = "... $q";
|
|
mark@3
|
748 |
$q =~ s/^\s+//;
|
|
mark@3
|
749 |
$q =~ s/\s+$//;
|
|
mark@3
|
750 |
$q =~ s/\n/ /g;
|
|
mark@461
|
751 |
$q = substr( $q, 0, 50 ) . "..." if length( $q ) > 50;
|
|
mark@461
|
752 |
push @faqlist, ( $faq->faqid, $q );
|
|
mark@3
|
753 |
}
|
|
mark@3
|
754 |
}
|
|
mark@3
|
755 |
$ret .= LJ::html_select({ 'name' => 'faqid', 'onchange' => 'updateFaqLink()' }, @faqlist) . "\n";
|
|
mark@3
|
756 |
$ret .= qq(<script language="JavaScript"><!--
|
|
mark@3
|
757 |
if (document.getElementById)
|
|
afuna@1354
|
758 |
document.write("<a href='faq' id='faqlink'>View FAQ</a>");
|
|
mark@3
|
759 |
//--></script>);
|
|
mark@3
|
760 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
761 |
}
|
|
mark@3
|
762 |
|
|
mark@3
|
763 |
# answer type
|
|
mark@3
|
764 |
{
|
|
fu@3808
|
765 |
$ret .= "<tr><td align='right'>$ML{'.reply.type'}</td><td>";
|
|
mark@3
|
766 |
|
|
mark@3
|
767 |
# if less than 2, remote is the person filing the request
|
|
mark@3
|
768 |
# so all they can do is add more info
|
|
mark@3
|
769 |
if (@ans_type > 2) {
|
|
mark@3
|
770 |
$ret .= LJ::html_select({ 'name' => 'replytype',
|
|
mark@3
|
771 |
'id' => 'replytype',
|
|
mark@3
|
772 |
'onchange' => "check_replytype()" },
|
|
mark@3
|
773 |
@ans_type) . "\n";
|
|
mark@3
|
774 |
$ret .= "<div id='bounce_email' style='display:none'>";
|
|
mark@3
|
775 |
$ret .= " $ML{'.email.user'} " . LJ::html_text({ 'name' => 'bounce_email', 'size' => '25' });
|
|
mark@3
|
776 |
$ret .= "</div>";
|
|
mark@3
|
777 |
} else {
|
|
mark@3
|
778 |
$ret .= LJ::html_hidden('replytype', $ans_type[0]) . "\n";
|
|
mark@3
|
779 |
$ret .= "<b>$ans_type[1]</b>";
|
|
mark@3
|
780 |
}
|
|
mark@3
|
781 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
782 |
}
|
|
mark@3
|
783 |
|
|
mark@3
|
784 |
# helpers can do actions:
|
|
mark@3
|
785 |
if (LJ::Support::can_perform_actions($sp, $remote) && ! $is_poster)
|
|
mark@3
|
786 |
{
|
|
mark@3
|
787 |
$ret .= "<tr><td align='right'></td><td>\n";
|
|
mark@3
|
788 |
|
|
fu@3114
|
789 |
$ret .= "<table summary='' cellpadding='5'>";
|
|
mark@3
|
790 |
|
|
mark@3
|
791 |
$ret .= "<tr><td>$ML{'.change.cat'}:<br />";
|
|
mark@3
|
792 |
$ret .= LJ::html_select({ 'name' => 'changecat',
|
|
mark@3
|
793 |
'onchange' => 'doChangeCategory();' },
|
|
mark@3
|
794 |
('', $sp->{'_cat'}->{'catname'}),
|
|
mark@3
|
795 |
map { $_->{'spcatid'}, "---> $_->{'catname'}" }
|
|
mark@3
|
796 |
LJ::Support::sorted_cats($cats));
|
|
mark@3
|
797 |
$ret .= "</td>";
|
|
mark@3
|
798 |
|
|
mark@3
|
799 |
if (@screened && $helper_mode) {
|
|
mark@3
|
800 |
$ret .= "<td>$ML{'.approve.screened'}:<br />";
|
|
mark@3
|
801 |
$ret .= LJ::html_select({ 'name' => 'approveans',
|
|
mark@84
|
802 |
'id' => 'approveans',
|
|
mark@3
|
803 |
'onclick' => 'return doApproveAnswer();' },
|
|
mark@3
|
804 |
('', ''),
|
|
mark@3
|
805 |
map { $_->{'splid'}, "\#$_->{'splid'} (" . LJ::get_username($_->{'userid'}) . ")" }
|
|
mark@3
|
806 |
@screened);
|
|
mark@3
|
807 |
$ret .= LJ::html_select({ 'name' => 'approveas' },
|
|
mark@3
|
808 |
("answer" => "as answer", "comment" => "as comment",));
|
|
mark@3
|
809 |
$ret .= "</td>";
|
|
mark@3
|
810 |
}
|
|
mark@3
|
811 |
$ret .= "</tr></table>\n";
|
|
mark@3
|
812 |
|
|
mark@3
|
813 |
$ret .= "</td></tr>\n";
|
|
mark@84
|
814 |
}
|
|
mark@84
|
815 |
|
|
mark@84
|
816 |
my $lang_ret;
|
|
mark@84
|
817 |
my $tier_ret;
|
|
mark@84
|
818 |
|
|
mark@84
|
819 |
if (LJ::is_enabled("support_request_language") && LJ::Support::can_read_internal($sp, $remote) && ! $is_poster) {
|
|
mark@84
|
820 |
# language
|
|
mark@84
|
821 |
my %langs;
|
|
mark@84
|
822 |
my @lang_codes;
|
|
mark@84
|
823 |
my $lang_list = LJ::Lang::get_lang_names();
|
|
mark@84
|
824 |
for (my $i = 0; $i < @$lang_list; $i = $i+2) {
|
|
mark@84
|
825 |
push @lang_codes, $lang_list->[$i];
|
|
mark@84
|
826 |
$langs{$lang_list->[$i]} = $lang_list->[$i+1];
|
|
mark@84
|
827 |
}
|
|
mark@84
|
828 |
@lang_codes = sort { $a cmp $b } @lang_codes;
|
|
mark@84
|
829 |
|
|
mark@84
|
830 |
my $current_lang = $props->{language} ? "[$props->{language}] $langs{$props->{language}}" : $ML{'.change.language.nolang'};
|
|
mark@84
|
831 |
|
|
mark@84
|
832 |
$lang_ret .= "<td>$ML{'.change.language'}<br />";
|
|
mark@84
|
833 |
$lang_ret .= LJ::html_select({ 'name' => 'changelanguage',
|
|
mark@84
|
834 |
'onchange' => 'doChangeLanguage();' },
|
|
mark@84
|
835 |
('', $current_lang),
|
|
mark@84
|
836 |
map { $_, "---> [$_] $langs{$_}" }
|
|
mark@84
|
837 |
@lang_codes);
|
|
mark@84
|
838 |
$lang_ret .= "</td>";
|
|
mark@84
|
839 |
}
|
|
mark@84
|
840 |
|
|
mark@84
|
841 |
if (LJ::is_enabled("support_response_tier") && LJ::Support::can_perform_actions($sp, $remote) && ! $is_poster && $helper_mode) {
|
|
mark@84
|
842 |
my @valid_tiers = (
|
|
mark@84
|
843 |
tier1 => $ML{'.tier.1'},
|
|
mark@84
|
844 |
tier2 => $ML{'.tier.2'},
|
|
mark@84
|
845 |
tier3 => $ML{'.tier.3'},
|
|
mark@84
|
846 |
);
|
|
mark@84
|
847 |
|
|
mark@84
|
848 |
$tier_ret .= "<td id='tier_cell'>$ML{'.tier.set'}<br />";
|
|
mark@84
|
849 |
$tier_ret .= LJ::html_select({
|
|
mark@84
|
850 |
name => 'settier',
|
|
mark@84
|
851 |
}, ('' => $ML{'.tier.selectone'}), @valid_tiers
|
|
mark@84
|
852 |
);
|
|
mark@84
|
853 |
$tier_ret .= "</td>";
|
|
mark@84
|
854 |
}
|
|
mark@84
|
855 |
|
|
mark@84
|
856 |
if ($lang_ret || $tier_ret) {
|
|
mark@84
|
857 |
$ret .= "<tr><td align='right'></td><td>\n";
|
|
fu@3114
|
858 |
$ret .= "<table summary='' cellpadding='5'><tr>";
|
|
mark@84
|
859 |
$ret .= "$lang_ret$tier_ret";
|
|
mark@84
|
860 |
$ret .= "</tr></table>";
|
|
mark@84
|
861 |
$ret .= "</td></tr>\n";
|
|
mark@84
|
862 |
}
|
|
mark@84
|
863 |
|
|
mark@84
|
864 |
if (LJ::Support::can_perform_actions($sp, $remote) && ! $is_poster) {
|
|
mark@3
|
865 |
if ($sp->{'timelasthelp'} > ($sp->{'timetouched'}+5)) {
|
|
mark@3
|
866 |
$ret .= "<tr><td align='right'>$ML{'.put.in.queue'}:</td><td>";
|
|
mark@3
|
867 |
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'touch',
|
|
mark@3
|
868 |
'onclick' => 'doRegreen();' });
|
|
mark@3
|
869 |
$ret .= "<?de $ML{'.use.this.to.re-open'} de?>\n";
|
|
mark@3
|
870 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
871 |
} else {
|
|
mark@3
|
872 |
$ret .= "<tr><td align='right'>$ML{'.take.out.of.queue'}</td><td>";
|
|
mark@3
|
873 |
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'untouch',
|
|
mark@3
|
874 |
'onclick' => 'doDegreen();' });
|
|
mark@3
|
875 |
$ret .= "<?de $ML{'.use.this.to.change.awaiting'} de?>\n";
|
|
mark@3
|
876 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
877 |
}
|
|
mark@3
|
878 |
if (LJ::Support::can_change_summary($sp, $remote)) {
|
|
mark@84
|
879 |
$ret .= "<tr><td align='right'>$ML{'.change.summary'}:</td><td>";
|
|
mark@3
|
880 |
$ret .= LJ::html_check({ 'type' => 'checkbox', 'name' => 'changesum', id => 'changesum', 'onClick' => 'doSummaryClick();' });
|
|
mark@3
|
881 |
$ret .= LJ::html_text({ 'type' => 'text', 'name' => 'summary', 'size' => '50', 'maxlength' => '80', 'value' => $sp->{'subject'}, 'onChange' => 'doSummaryChanged();' });
|
|
mark@3
|
882 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
883 |
$ret .= "<tr><td> </td><td>";
|
|
mark@3
|
884 |
$ret .= "<?de $ML{'.use.this.to.summary'} de?>\n";
|
|
mark@3
|
885 |
$ret .= "</td></tr>\n";
|
|
mark@3
|
886 |
}
|
|
mark@3
|
887 |
}
|
|
mark@3
|
888 |
# Prefill an e-mail validation nag, if needed.
|
|
mark@3
|
889 |
my $validationnag;
|
|
janinedog@503
|
890 |
if (!(LJ::isu($u) && ($u->{'status'} eq 'T')) &&
|
|
mark@3
|
891 |
($u->{'status'} eq "N" || $u->{'status'} eq "T") &&
|
|
kareila@1341
|
892 |
! $u->is_identity && ! $is_poster) {
|
|
mark@3
|
893 |
my $reminder = LJ::load_include('validationreminder');
|
|
mark@3
|
894 |
$validationnag .= "\n\n$reminder" if $reminder;
|
|
mark@3
|
895 |
}
|
|
mark@3
|
896 |
|
|
mark@3
|
897 |
# add in canned answers if there are any for this category and the user can use them
|
|
mark@3
|
898 |
if ($stock_mode && ! $is_poster) {
|
|
mark@3
|
899 |
# if one category's stock answers exactly matches another's
|
|
mark@3
|
900 |
my $stock_spcatid = $LJ::SUPPORT_STOCKS_OVERRIDE{$sp->{_cat}->{catkey}} || $sp->{_cat}->{spcatid};
|
|
mark@3
|
901 |
my $rows = $dbr->selectall_arrayref('SELECT subject, body FROM support_answers WHERE spcatid = ? ORDER BY subject',
|
|
mark@3
|
902 |
undef, $stock_spcatid);
|
|
mark@3
|
903 |
|
|
mark@3
|
904 |
if ($rows && @$rows) {
|
|
afuna@1354
|
905 |
$ret .= "<tr valign='top'><td align='right'><a href='$LJ::SITEROOT/support/stock_answers?spcatid=$stock_spcatid'>Stock answers</a>:</td><td colspan='2'>\n";
|
|
mark@3
|
906 |
$ret .= "<script type='text/javascript'>\n";
|
|
mark@3
|
907 |
$ret .= "var Iarr = new Array();\n";
|
|
mark@3
|
908 |
my $i = 0;
|
|
mark@3
|
909 |
foreach my $row (@$rows) {
|
|
mark@3
|
910 |
$ret .= "Iarr[$i] = '" . LJ::ejs($row->[1]) . "';\n";
|
|
mark@3
|
911 |
$i++;
|
|
mark@3
|
912 |
}
|
|
mark@3
|
913 |
$ret .= "function insertCanned(i) {\n";
|
|
mark@3
|
914 |
$ret .= " var obj = document.getElementById('body');\n";
|
|
mark@3
|
915 |
$ret .= " var canned = document.getElementById('canned');\n";
|
|
mark@3
|
916 |
$ret .= " if (canned && canned.value > -1 && obj) {\n";
|
|
mark@3
|
917 |
$ret .= " obj.value = obj.value + Iarr[canned.value];\n";
|
|
mark@3
|
918 |
$ret .= " }\n";
|
|
mark@3
|
919 |
$ret .= "}\n";
|
|
mark@3
|
920 |
$ret .= "</script>\n";
|
|
mark@3
|
921 |
$ret .= "<select id='canned' onChange='insertCanned();'>\n";
|
|
mark@3
|
922 |
$ret .= "<option value='-1' selected>( $ML{'.select.canned.to.insert'} )</option>\n";
|
|
mark@3
|
923 |
$i = 0;
|
|
mark@3
|
924 |
foreach my $row (@$rows) {
|
|
mark@3
|
925 |
$ret .= "<option value='$i'>" . LJ::ehtml($row->[0]) . "</option>\n";
|
|
mark@3
|
926 |
$i++;
|
|
mark@3
|
927 |
}
|
|
mark@3
|
928 |
$ret .= "</input>\n";
|
|
mark@3
|
929 |
$ret .= "</td></tr>";
|
|
mark@3
|
930 |
}
|
|
mark@3
|
931 |
}
|
|
mark@3
|
932 |
|
|
mark@3
|
933 |
# textarea for their message body
|
|
mark@3
|
934 |
$ret .= "<tr valign='top'><td align='right'>$ML{'.message'}:</td><td colspan='2'>";
|
|
mark@3
|
935 |
$ret .= LJ::html_textarea({ 'rows' => '12', 'cols' => '80', 'wrap' => 'virtual', 'id' => 'body', 'name' => 'body', 'value' => $validationnag }) . "<br />";
|
|
mark@3
|
936 |
$ret .= "<div style='float: right; font-size: smaller;'><a href='javascript://' onClick='doClearMessage();' onFocus='doClearFocus();'>$ML{'.clear'}</a></div>";
|
|
mark@3
|
937 |
$ret .= "<?de $ML{'.no.html.allowed'} de?><br />";
|
|
afuna@1125
|
938 |
if ($is_poster) {
|
|
afuna@1125
|
939 |
$ret .= LJ::html_submit('submitpost', $ML{'.postbuttoninfo'}, { id => 'submitpost' });
|
|
afuna@1125
|
940 |
} else {
|
|
afuna@1125
|
941 |
$ret .= LJ::html_submit('submitpost', $ML{'.postbutton'}, { id => 'submitpost' });
|
|
afuna@1125
|
942 |
}
|
|
mark@3
|
943 |
$ret .= "</td></tr></table>\n";
|
|
mark@3
|
944 |
|
|
mark@3
|
945 |
$ret .= "</form>\n";
|
|
mark@3
|
946 |
|
|
mark@3
|
947 |
|
|
mark@3
|
948 |
return $ret;
|
|
mark@3
|
949 |
}
|
|
mark@3
|
950 |
_code?>
|
|
mark@3
|
951 |
<?hr?>
|
|
mark@3
|
952 |
<?_code
|
|
mark@3
|
953 |
{
|
|
mark@3
|
954 |
use strict;
|
|
mark@3
|
955 |
use vars qw(%FORM);
|
|
mark@3
|
956 |
return '' if $FORM{'find'};
|
|
afuna@356
|
957 |
LJ::need_res( 'stc/support.css' );
|
|
afuna@356
|
958 |
|
|
mark@3
|
959 |
my $spid = $FORM{'id'}+0;
|
|
mark@3
|
960 |
my $ret;
|
|
mark@3
|
961 |
|
|
afuna@1354
|
962 |
$ret .= BML::ml('.see.preview', {preview_link=>"href='$LJ::SITEROOT/support/see_request?id=$spid&find=prev'"});
|
|
afuna@1354
|
963 |
$ret .= BML::ml('.see.next', {next_link=>"href='$LJ::SITEROOT/support/see_request?id=$spid&find=next'"});
|
|
mark@3
|
964 |
|
|
mark@3
|
965 |
return $ret;
|
|
mark@3
|
966 |
}
|
|
mark@3
|
967 |
_code?>
|
|
mark@3
|
968 |
<br>
|
|
mark@3
|
969 |
<?_code
|
|
mark@3
|
970 |
{
|
|
mark@3
|
971 |
my $ret;
|
|
afuna@1354
|
972 |
$ret .= BML::ml('.help.link', {helplink=>'href="help"'});
|
|
mark@3
|
973 |
$ret .= BML::ml('.back.link', {backlink=>'href="./"'});
|
|
mark@3
|
974 |
|
|
mark@3
|
975 |
return $ret;
|
|
mark@3
|
976 |
}
|
|
mark@3
|
977 |
_code?>
|
|
mark@3
|
978 |
|
|
mark@3
|
979 |
<=body
|
|
mark@151
|
980 |
page?>
|