1
|
|
|
<?php |
2
|
|
|
// This file is part of BOINC. |
3
|
|
|
// http://boinc.berkeley.edu |
4
|
|
|
// Copyright (C) 2008 University of California |
5
|
|
|
// |
6
|
|
|
// BOINC is free software; you can redistribute it and/or modify it |
7
|
|
|
// under the terms of the GNU Lesser General Public License |
8
|
|
|
// as published by the Free Software Foundation, |
9
|
|
|
// either version 3 of the License, or (at your option) any later version. |
10
|
|
|
// |
11
|
|
|
// BOINC is distributed in the hope that it will be useful, |
12
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
13
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
14
|
|
|
// See the GNU Lesser General Public License for more details. |
15
|
|
|
// |
16
|
|
|
// You should have received a copy of the GNU Lesser General Public License |
17
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
18
|
|
|
|
19
|
|
|
require_once("boinc_db.inc"); |
20
|
|
|
require_once("sanitize_html.inc"); |
21
|
|
|
require_once("bbcode_html.inc"); |
22
|
|
|
|
23
|
|
|
define('PM_LH_PCT', '30%'); |
24
|
|
|
|
25
|
|
|
function pm_header() { |
26
|
|
|
echo "<div>\n"; |
27
|
|
|
echo " <a href=\"pm.php?action=inbox\">".tra("Inbox")."</a>\n"; |
28
|
|
|
echo " · <a href=\"pm.php?action=new\">".tra("Write")."</a>\n"; |
29
|
|
|
echo "</div>\n"; |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
function pm_rules() { |
33
|
|
|
if (defined('PM_RULES')) return PM_RULES; |
34
|
|
|
$x = '<span style="text-align: left"><p>'; |
35
|
|
|
$x .= tra(" |
36
|
|
|
<ul> |
37
|
|
|
<li> Messages may not contain content that is obscene, hate-related, |
38
|
|
|
sexually explicit or suggestive. |
39
|
|
|
<li> No commercial advertisements. |
40
|
|
|
<li> No links to web sites involving sexual content, |
41
|
|
|
gambling, or intolerance of others. |
42
|
|
|
<li> No messages intended to annoy or antagonize other people. |
43
|
|
|
<li> No messages that are deliberately hostile, threatening, or insulting. |
44
|
|
|
<li> No abusive comments involving race, religion, |
45
|
|
|
nationality, gender, class or sexuality. |
46
|
|
|
<li> The privileges of violators may be suspended or revoked. |
47
|
|
|
<li> If your account is suspended, don't create a new one. |
48
|
|
|
</ul> |
49
|
|
|
"); |
50
|
|
|
$x .= "</span>"; |
51
|
|
|
return $x; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
function pm_team_form($user, $teamid, $error=null) { |
55
|
|
|
global $bbcode_html, $bbcode_js; |
56
|
|
|
$team = BoincTeam::lookup_id($teamid); |
57
|
|
|
if (!$team) { |
58
|
|
|
error_page("no such team"); |
59
|
|
|
} |
60
|
|
|
if (!is_team_admin($user, $team)) { |
61
|
|
|
error_page("not admin"); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
page_head(tra("Send message to team"),'','','', $bbcode_js); |
65
|
|
|
|
66
|
|
|
$subject = post_str("subject", true); |
67
|
|
|
$content = post_str("content", true); |
68
|
|
|
if (post_str("preview", true) == tra("Preview")) { |
69
|
|
|
panel(tra('Preview'), |
70
|
|
|
function() use($content) { |
|
|
|
|
71
|
|
|
echo output_transform($content, null); |
72
|
|
|
} |
73
|
|
|
); |
74
|
|
|
} |
75
|
|
|
if ($error) { |
76
|
|
|
echo "<p class=\"text-danger\">".$error."</p>\n"; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
echo "<form action=\"pm.php\" method=\"post\" name=\"post\" onsubmit=\"return checkForm(this)\">\n"; |
80
|
|
|
echo "<input type=\"hidden\" name=\"action\" value=\"send\">\n"; |
81
|
|
|
echo "<input type=\"hidden\" name=\"teamid\" value=\"$teamid\">\n"; |
82
|
|
|
echo form_tokens($user->authenticator); |
83
|
|
|
start_table(); |
84
|
|
|
row2( |
85
|
|
|
tra("Subject"), |
86
|
|
|
"<input type=\"text\" class=\"form-control\" name=\"subject\" value=\"$subject\">", |
87
|
|
|
null, PM_LH_PCT |
88
|
|
|
); |
89
|
|
|
row2( |
90
|
|
|
tra("Message")."<small>".bbcode_info()."</small>", |
91
|
|
|
$bbcode_html."<textarea name=\"content\" class=\"form-control\" rows=\"18\">$content</textarea>", |
92
|
|
|
null, PM_LH_PCT |
93
|
|
|
); |
94
|
|
|
row2( |
95
|
|
|
'', |
96
|
|
|
sprintf( |
97
|
|
|
'<input class="btn" %s type="submit" name="preview" value="%s"> |
98
|
|
|
<input class="btn" %s type="submit" value="%s"> |
99
|
|
|
', |
100
|
|
|
button_style('blue'), |
101
|
|
|
tra("Preview"), |
102
|
|
|
button_style(), |
103
|
|
|
tra("Send message") |
104
|
|
|
), |
105
|
|
|
null, PM_LH_PCT |
106
|
|
|
); |
107
|
|
|
end_table(); |
108
|
|
|
page_tail(); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
// show the send-PM page, possibly with an error message |
112
|
|
|
// |
113
|
|
|
function pm_form_page($replyto, $userid, $error = null) { |
114
|
|
|
global $bbcode_html, $bbcode_js; |
115
|
|
|
global $g_logged_in_user; |
116
|
|
|
page_head(tra("Send private message"),'','','', $bbcode_js); |
117
|
|
|
|
118
|
|
|
if (post_str("preview", true) == tra("Preview")) { |
119
|
|
|
$content = post_str("content", true); |
120
|
|
|
panel(tra('Preview'), |
121
|
|
|
function() use($content) { |
|
|
|
|
122
|
|
|
echo output_transform($content, null); |
123
|
|
|
} |
124
|
|
|
); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$subject = ''; |
128
|
|
|
$content = ''; |
129
|
|
|
if ($replyto) { |
130
|
|
|
$message = BoincPrivateMessage::lookup_id($replyto); |
131
|
|
|
if (!$message || $message->userid != $g_logged_in_user->id) { |
132
|
|
|
error_page(tra("no such message")); |
133
|
|
|
} |
134
|
|
|
$content = "[quote]".$message->content."[/quote]\n"; |
135
|
|
|
$userid = $message->senderid; |
136
|
|
|
$user = BoincUser::lookup_id($userid); |
137
|
|
|
if (!$user) { |
138
|
|
|
error_page("Sender no longer exists"); |
139
|
|
|
} |
140
|
|
|
$writeto = UNIQUE_USER_NAME?$user->name:$userid." (".$user->name.")"; |
141
|
|
|
$subject = $message->subject; |
142
|
|
|
if (substr($subject, 0, 3) != "re:") { |
143
|
|
|
$subject = "re: ".$subject; |
144
|
|
|
} |
145
|
|
|
} elseif ($userid) { |
146
|
|
|
$user = BoincUser::lookup_id($userid); |
147
|
|
|
if (!$user) { |
148
|
|
|
error_page("Sender no longer exists"); |
149
|
|
|
} |
150
|
|
|
if (is_banished($user)) { |
151
|
|
|
echo sprintf( |
152
|
|
|
"<p> |
153
|
|
|
This user is banished until %s. |
154
|
|
|
You can send them a message, but they can't reply until then. |
155
|
|
|
<p>", |
156
|
|
|
time_str($user->prefs->banished_until) |
157
|
|
|
); |
158
|
|
|
} |
159
|
|
|
$writeto = UNIQUE_USER_NAME?$user->name:$userid." (".$user->name.")"; |
160
|
|
|
} else { |
161
|
|
|
$writeto = sanitize_tags(post_str("to", true)); |
162
|
|
|
$subject = post_str("subject", true); |
163
|
|
|
$content = post_str("content", true); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$content = $content?htmlspecialchars($content):''; |
167
|
|
|
$subject = $subject?htmlspecialchars($subject):''; |
168
|
|
|
|
169
|
|
|
if ($error != null) { |
170
|
|
|
echo "<p class=\"text-danger\">".$error."</p>\n"; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
echo "<form action=\"pm.php\" method=\"post\" name=\"post\" onsubmit=\"return checkForm(this)\">\n"; |
174
|
|
|
echo "<input type=\"hidden\" name=\"action\" value=\"send\">\n"; |
175
|
|
|
echo form_tokens($g_logged_in_user->authenticator); |
176
|
|
|
start_table(); |
177
|
|
|
row2( |
178
|
|
|
sprintf('%s <br><small>%s</small>', |
179
|
|
|
tra("To"), |
180
|
|
|
UNIQUE_USER_NAME |
181
|
|
|
?tra('User names, one per line') |
|
|
|
|
182
|
|
|
:tra("User IDs or unique usernames, one per line") |
|
|
|
|
183
|
|
|
), |
184
|
|
|
sprintf( |
185
|
|
|
'<textarea rows=2 class="form-control" name="to">%s</textarea>', |
186
|
|
|
$writeto |
187
|
|
|
), |
188
|
|
|
null, PM_LH_PCT |
189
|
|
|
); |
190
|
|
|
row2( |
191
|
|
|
tra("Subject"), |
192
|
|
|
"<input type=\"text\" class=\"form-control\" name=\"subject\" value=\"$subject\">", |
193
|
|
|
null, PM_LH_PCT |
194
|
|
|
); |
195
|
|
|
row2( |
196
|
|
|
tra("Message")."<small>".bbcode_info().pm_rules()."</small>", |
197
|
|
|
sprintf( |
198
|
|
|
'%s <textarea name="content" class="form-control" rows="18">%s</textarea>', |
199
|
|
|
$bbcode_html, |
200
|
|
|
$content |
201
|
|
|
), |
202
|
|
|
null, PM_LH_PCT |
203
|
|
|
); |
204
|
|
|
row2( |
205
|
|
|
'', |
206
|
|
|
sprintf( |
207
|
|
|
'<input class="btn btn-primary" type="submit" name="preview" value="%s"> |
208
|
|
|
<input class="btn btn-success" type="submit" value="%s"> |
209
|
|
|
', |
210
|
|
|
tra("Preview"), |
211
|
|
|
tra("Send message") |
212
|
|
|
), |
213
|
|
|
null, PM_LH_PCT |
214
|
|
|
); |
215
|
|
|
end_table(); |
216
|
|
|
|
217
|
|
|
page_tail(); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
function send_pm_notification_email( |
221
|
|
|
$logged_in_user, $to_user, $subject, $content |
|
|
|
|
222
|
|
|
) { |
223
|
|
|
$message = " |
224
|
|
|
You have received a new private message at ".PROJECT.". |
225
|
|
|
|
226
|
|
|
From: $logged_in_user->name (ID $logged_in_user->id) |
227
|
|
|
Subject: $subject |
228
|
|
|
|
229
|
|
|
$content |
230
|
|
|
|
231
|
|
|
-------------------------- |
232
|
|
|
To delete or respond to this message, visit: |
233
|
|
|
".secure_url_base()."pm.php |
234
|
|
|
|
235
|
|
|
To change email preferences, visit: |
236
|
|
|
".secure_url_base()."edit_forum_preferences_form.php |
237
|
|
|
Do not reply to this message. |
238
|
|
|
" ; |
|
|
|
|
239
|
|
|
send_email($to_user, "[".PROJECT."] - private message", $message); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
function pm_email_line($notify) { |
243
|
|
|
$pm = BoincPrivateMessage::lookup_id($notify->opaque); |
244
|
|
|
$from_user = BoincUser::lookup_id($pm->senderid); |
245
|
|
|
if (!$pm || !$from_user) return null; |
246
|
|
|
return "$from_user->name ".tra("sent you a private message; subject:")." '$pm->subject'"; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
function pm_web_line($notify) { |
250
|
|
|
$pm = BoincPrivateMessage::lookup_id($notify->opaque); |
251
|
|
|
$from_user = BoincUser::lookup_id($pm->senderid); |
252
|
|
|
if (!$pm || !$from_user) return null; |
253
|
|
|
return "<a href=pm.php>".tra("Private message%1 from %2, subject:" , "</a>", $from_user->name )." $pm->subject"; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
function pm_send_msg($from_user, $to_user, $subject, $content, $send_email) { |
257
|
|
|
$sql_subject = BoincDb::escape_string(sanitize_tags($subject)); |
258
|
|
|
$sql_content = BoincDb::escape_string($content); |
259
|
|
|
$mid = BoincPrivateMessage::insert("(userid, senderid, date, subject, content) VALUES ($to_user->id, $from_user->id, UNIX_TIMESTAMP(), '$sql_subject', '$sql_content')"); |
260
|
|
|
if (!$mid) { |
261
|
|
|
error_page(tra("Couldn't create message")); |
262
|
|
|
} |
263
|
|
|
// send email notification if needed |
264
|
|
|
// |
265
|
|
|
if ($send_email) { |
266
|
|
|
BoincForumPrefs::lookup($to_user); |
267
|
|
|
switch ($to_user->prefs->pm_notification) { |
268
|
|
|
case 0: |
|
|
|
|
269
|
|
|
case 2: |
|
|
|
|
270
|
|
|
break; |
271
|
|
|
case 1: |
272
|
|
|
send_pm_notification_email( |
273
|
|
|
$from_user, $to_user, $subject, $content |
274
|
|
|
); |
275
|
|
|
break; |
276
|
|
|
} |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
// create notification in any case |
280
|
|
|
// |
281
|
|
|
BoincNotify::insert("(userid, create_time, type, opaque) values ($to_user->id, ".time().", ".NOTIFY_PM.", $mid)"); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
function pm_count($userid, $duration) { |
285
|
|
|
$time = time() - $duration; |
286
|
|
|
|
287
|
|
|
// we don't want to include team messages in this count. |
288
|
|
|
// Kludge for excluding them based on subject. |
289
|
|
|
// Should add a flag to private_message to distinguish them. |
290
|
|
|
// |
291
|
|
|
return BoincPrivateMessage::count( |
292
|
|
|
"senderid=$userid AND date>$time AND subject not like 'Message from team%'" |
293
|
|
|
); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
function check_pm_count($userid) { |
297
|
|
|
if ((pm_count($userid, 60) >= 2) || (pm_count($userid, 600) >= 5) || |
298
|
|
|
(pm_count($userid, 3600) >= 15) || (pm_count($userid, 86400) >= 50)) { |
299
|
|
|
error_page(tra("You are not allowed to send privates messages so often. Please wait some time before sending more messages.")); |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
function pm_notification($user) { |
304
|
|
|
$output = ""; |
305
|
|
|
$unread = BoincPrivateMessage::count("userid=$user->id AND opened=0"); |
306
|
|
|
|
307
|
|
|
$output .= "<a href=\"pm.php?action=inbox\">".tra("Inbox")."</a>"; |
308
|
|
|
if ($unread) { |
309
|
|
|
$output .= "<span class=\"inboxunread\"> ($unread ".tra("unread").")</span>\n"; |
310
|
|
|
} |
311
|
|
|
$output .= " · <a href=\"pm.php?action=new\">".tra("Write")."</a>\n"; |
312
|
|
|
return $output; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
function pm_email_remind($user) { |
316
|
|
|
if (!$user->prefs->pm_notification) { |
317
|
|
|
return "<br><small>" . |
318
|
|
|
tra( |
319
|
|
|
"For email notification, %1 edit community prefs %2", |
320
|
|
|
'<a href="edit_forum_preferences_form.php">', '</a>' |
321
|
|
|
) . |
322
|
|
|
"</small>" |
323
|
|
|
; |
|
|
|
|
324
|
|
|
} |
325
|
|
|
return ""; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
function pm_rss($notify, &$title, &$msg, &$url) { |
329
|
|
|
$pm = BoincPrivateMessage::lookup_id($notify->opaque); |
330
|
|
|
$from_user = BoincUser::lookup_id($pm->senderid); |
331
|
|
|
if (!$pm || !$from_user) { |
332
|
|
|
$msg = null; |
333
|
|
|
return; |
334
|
|
|
} |
335
|
|
|
$title = tra("Private message"); |
336
|
|
|
$msg = "You have received a <a href=".secure_url_base()."pm.php>private message</a>."; |
337
|
|
|
$url = secure_url_base()."pm.php"; |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
function pm_delete_user($user) { |
341
|
|
|
$mm = BoincPrivateMessage::enum("userid=$user->id or senderid=$user->id"); |
342
|
|
|
foreach ($mm as $m) { |
343
|
|
|
$m->delete(); |
344
|
|
|
} |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
?> |
348
|
|
|
|