1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is mainly meant for controlling the actions related to personal |
5
|
|
|
* messages. It allows viewing, sending, deleting, and marking personal |
6
|
|
|
* messages. For compatibility reasons, they are often called "instant messages". |
7
|
|
|
* |
8
|
|
|
* Simple Machines Forum (SMF) |
9
|
|
|
* |
10
|
|
|
* @package SMF |
11
|
|
|
* @author Simple Machines http://www.simplemachines.org |
12
|
|
|
* @copyright 2017 Simple Machines and individual contributors |
13
|
|
|
* @license http://www.simplemachines.org/about/smf/license.php BSD |
14
|
|
|
* |
15
|
|
|
* @version 2.1 Beta 3 |
16
|
|
|
*/ |
17
|
|
|
|
18
|
|
|
if (!defined('SMF')) |
19
|
|
|
die('No direct access...'); |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* This helps organize things... |
23
|
|
|
* @todo this should be a simple dispatcher.... |
24
|
|
|
*/ |
25
|
|
|
function MessageMain() |
26
|
|
|
{ |
27
|
|
|
global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $smcFunc, $modSettings; |
28
|
|
|
|
29
|
|
|
// No guests! |
30
|
|
|
is_not_guest(); |
31
|
|
|
|
32
|
|
|
// You're not supposed to be here at all, if you can't even read PMs. |
33
|
|
|
isAllowedTo('pm_read'); |
34
|
|
|
|
35
|
|
|
// This file contains the basic functions for sending a PM. |
36
|
|
|
require_once($sourcedir . '/Subs-Post.php'); |
37
|
|
|
|
38
|
|
|
loadLanguage('PersonalMessage+Drafts'); |
39
|
|
|
|
40
|
|
|
if (!isset($_REQUEST['xml'])) |
41
|
|
|
loadTemplate('PersonalMessage'); |
42
|
|
|
|
43
|
|
|
// Load up the members maximum message capacity. |
44
|
|
|
if ($user_info['is_admin']) |
45
|
|
|
$context['message_limit'] = 0; |
46
|
|
|
elseif (($context['message_limit'] = cache_get_data('msgLimit:' . $user_info['id'], 360)) === null) |
47
|
|
|
{ |
48
|
|
|
// @todo Why do we do this? It seems like if they have any limit we should use it. |
49
|
|
|
$request = $smcFunc['db_query']('', ' |
50
|
|
|
SELECT MAX(max_messages) AS top_limit, MIN(max_messages) AS bottom_limit |
51
|
|
|
FROM {db_prefix}membergroups |
52
|
|
|
WHERE id_group IN ({array_int:users_groups})', |
53
|
|
|
array( |
54
|
|
|
'users_groups' => $user_info['groups'], |
55
|
|
|
) |
56
|
|
|
); |
57
|
|
|
list ($maxMessage, $minMessage) = $smcFunc['db_fetch_row']($request); |
58
|
|
|
$smcFunc['db_free_result']($request); |
59
|
|
|
|
60
|
|
|
$context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage; |
61
|
|
|
|
62
|
|
|
// Save us doing it again! |
63
|
|
|
cache_put_data('msgLimit:' . $user_info['id'], $context['message_limit'], 360); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
// Prepare the context for the capacity bar. |
67
|
|
View Code Duplication |
if (!empty($context['message_limit'])) |
|
|
|
|
68
|
|
|
{ |
69
|
|
|
$bar = ($user_info['messages'] * 100) / $context['message_limit']; |
70
|
|
|
|
71
|
|
|
$context['limit_bar'] = array( |
72
|
|
|
'messages' => $user_info['messages'], |
73
|
|
|
'allowed' => $context['message_limit'], |
74
|
|
|
'percent' => $bar, |
75
|
|
|
'bar' => min(100, (int) $bar), |
76
|
|
|
'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1)), |
77
|
|
|
); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
// a previous message was sent successfully? show a small indication. |
81
|
|
|
if (isset($_GET['done']) && ($_GET['done'] == 'sent')) |
82
|
|
|
$context['pm_sent'] = true; |
83
|
|
|
|
84
|
|
|
$context['labels'] = array(); |
85
|
|
|
|
86
|
|
|
// Load the label data. |
87
|
|
|
if ($user_settings['new_pm'] || ($context['labels'] = cache_get_data('labelCounts:' . $user_info['id'], 720)) === null) |
88
|
|
|
{ |
89
|
|
|
// Looks like we need to reseek! |
90
|
|
|
|
91
|
|
|
// Inbox "label" |
92
|
|
|
$context['labels'][-1] = array( |
93
|
|
|
'id' => -1, |
94
|
|
|
'name' => $txt['pm_msg_label_inbox'], |
95
|
|
|
'messages' => 0, |
96
|
|
|
'unread_messages' => 0, |
97
|
|
|
); |
98
|
|
|
|
99
|
|
|
// First get the inbox counts |
100
|
|
|
// The CASE WHEN here is because is_read is set to 3 when you reply to a message |
101
|
|
|
$result = $smcFunc['db_query']('', ' |
102
|
|
|
SELECT COUNT(*) AS total, SUM(is_read & 1) AS num_read |
103
|
|
|
FROM {db_prefix}pm_recipients |
104
|
|
|
WHERE id_member = {int:current_member} |
105
|
|
|
AND in_inbox = {int:in_inbox} |
106
|
|
|
AND deleted = {int:not_deleted}', |
107
|
|
|
array( |
108
|
|
|
'current_member' => $user_info['id'], |
109
|
|
|
'in_inbox' => 1, |
110
|
|
|
'not_deleted' => 0, |
111
|
|
|
) |
112
|
|
|
); |
113
|
|
|
|
114
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
115
|
|
|
{ |
116
|
|
|
$context['labels'][-1]['messages'] = $row['total']; |
117
|
|
|
$context['labels'][-1]['unread_messages'] = $row['total'] - $row['num_read']; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$smcFunc['db_free_result']($result); |
121
|
|
|
|
122
|
|
|
// Now load info about all the other labels |
123
|
|
|
$result = $smcFunc['db_query']('', ' |
124
|
|
|
SELECT l.id_label, l.name, COALESCE(SUM(pr.is_read & 1), 0) AS num_read, COALESCE(COUNT(pr.id_pm), 0) AS total |
125
|
|
|
FROM {db_prefix}pm_labels AS l |
126
|
|
|
LEFT JOIN {db_prefix}pm_labeled_messages AS pl ON (pl.id_label = l.id_label) |
127
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pr ON (pr.id_pm = pl.id_pm) |
128
|
|
|
WHERE l.id_member = {int:current_member} |
129
|
|
|
GROUP BY l.id_label, l.name', |
130
|
|
|
array( |
131
|
|
|
'current_member' => $user_info['id'], |
132
|
|
|
) |
133
|
|
|
); |
134
|
|
|
|
135
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
136
|
|
|
{ |
137
|
|
|
$context['labels'][$row['id_label']] = array( |
138
|
|
|
'id' => $row['id_label'], |
139
|
|
|
'name' => $row['name'], |
140
|
|
|
'messages' => $row['total'], |
141
|
|
|
'unread_messages' => $row['total'] - $row['num_read'] |
142
|
|
|
); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
$smcFunc['db_free_result']($result); |
146
|
|
|
|
147
|
|
|
// Store it please! |
148
|
|
|
cache_put_data('labelCounts:' . $user_info['id'], $context['labels'], 720); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
// Now we have the labels, and assuming we have unsorted mail, apply our rules! |
152
|
|
|
if ($user_settings['new_pm']) |
153
|
|
|
{ |
154
|
|
|
ApplyRules(); |
155
|
|
|
updateMemberData($user_info['id'], array('new_pm' => 0)); |
156
|
|
|
$smcFunc['db_query']('', ' |
157
|
|
|
UPDATE {db_prefix}pm_recipients |
158
|
|
|
SET is_new = {int:not_new} |
159
|
|
|
WHERE id_member = {int:current_member}', |
160
|
|
|
array( |
161
|
|
|
'current_member' => $user_info['id'], |
162
|
|
|
'not_new' => 0, |
163
|
|
|
) |
164
|
|
|
); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
// This determines if we have more labels than just the standard inbox. |
168
|
|
|
$context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0; |
169
|
|
|
|
170
|
|
|
// Some stuff for the labels... |
171
|
|
|
$context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][$_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1; |
172
|
|
|
$context['current_label'] = &$context['labels'][$context['current_label_id']]['name']; |
173
|
|
|
$context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'sent' ? 'inbox' : 'sent'; |
174
|
|
|
|
175
|
|
|
// This is convenient. Do you know how annoying it is to do this every time?! |
176
|
|
|
$context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : ''); |
177
|
|
|
$context['can_issue_warning'] = allowedTo('issue_warning') && $modSettings['warning_settings'][0] == 1; |
178
|
|
|
|
179
|
|
|
// Are PM drafts enabled? |
180
|
|
|
$context['drafts_pm_save'] = !empty($modSettings['drafts_pm_enabled']) && allowedTo('pm_draft'); |
181
|
|
|
$context['drafts_autosave'] = !empty($context['drafts_pm_save']) && !empty($modSettings['drafts_autosave_enabled']); |
182
|
|
|
|
183
|
|
|
// Build the linktree for all the actions... |
184
|
|
|
$context['linktree'][] = array( |
185
|
|
|
'url' => $scripturl . '?action=pm', |
186
|
|
|
'name' => $txt['personal_messages'] |
187
|
|
|
); |
188
|
|
|
|
189
|
|
|
// Preferences... |
190
|
|
|
$context['display_mode'] = $user_settings['pm_prefs'] & 3; |
191
|
|
|
|
192
|
|
|
$subActions = array( |
193
|
|
|
'popup' => 'MessagePopup', |
194
|
|
|
'manlabels' => 'ManageLabels', |
195
|
|
|
'manrules' => 'ManageRules', |
196
|
|
|
'pmactions' => 'MessageActionsApply', |
197
|
|
|
'prune' => 'MessagePrune', |
198
|
|
|
'removeall' => 'MessageKillAllQuery', |
199
|
|
|
'removeall2' => 'MessageKillAll', |
200
|
|
|
'report' => 'ReportMessage', |
201
|
|
|
'search' => 'MessageSearch', |
202
|
|
|
'search2' => 'MessageSearch2', |
203
|
|
|
'send' => 'MessagePost', |
204
|
|
|
'send2' => 'MessagePost2', |
205
|
|
|
'settings' => 'MessageSettings', |
206
|
|
|
'showpmdrafts' => 'MessageDrafts', |
207
|
|
|
); |
208
|
|
|
|
209
|
|
|
if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) |
210
|
|
|
{ |
211
|
|
|
$_REQUEST['sa'] = ''; |
212
|
|
|
MessageFolder(); |
213
|
|
|
} |
214
|
|
View Code Duplication |
else |
|
|
|
|
215
|
|
|
{ |
216
|
|
|
if (!isset($_REQUEST['xml']) && $_REQUEST['sa'] != 'popup') |
217
|
|
|
messageIndexBar($_REQUEST['sa']); |
218
|
|
|
|
219
|
|
|
call_helper($subActions[$_REQUEST['sa']]); |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* A menu to easily access different areas of the PM section |
225
|
|
|
* |
226
|
|
|
* @param string $area The area we're currently in |
227
|
|
|
*/ |
228
|
|
|
function messageIndexBar($area) |
229
|
|
|
{ |
230
|
|
|
global $txt, $context, $scripturl, $sourcedir, $modSettings, $user_info; |
231
|
|
|
|
232
|
|
|
$pm_areas = array( |
233
|
|
|
'folders' => array( |
234
|
|
|
'title' => $txt['pm_messages'], |
235
|
|
|
'areas' => array( |
236
|
|
|
'send' => array( |
237
|
|
|
'label' => $txt['new_message'], |
238
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=send', |
239
|
|
|
'permission' => allowedTo('pm_send'), |
240
|
|
|
), |
241
|
|
|
'inbox' => array( |
242
|
|
|
'label' => $txt['inbox'], |
243
|
|
|
'custom_url' => $scripturl . '?action=pm', |
244
|
|
|
), |
245
|
|
|
'sent' => array( |
246
|
|
|
'label' => $txt['sent_items'], |
247
|
|
|
'custom_url' => $scripturl . '?action=pm;f=sent', |
248
|
|
|
), |
249
|
|
|
'drafts' => array( |
250
|
|
|
'label' => $txt['drafts_show'], |
251
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=showpmdrafts', |
252
|
|
|
'permission' => allowedTo('pm_draft'), |
253
|
|
|
'enabled' => !empty($modSettings['drafts_pm_enabled']), |
254
|
|
|
), |
255
|
|
|
), |
256
|
|
|
), |
257
|
|
|
'labels' => array( |
258
|
|
|
'title' => $txt['pm_labels'], |
259
|
|
|
'areas' => array(), |
260
|
|
|
), |
261
|
|
|
'actions' => array( |
262
|
|
|
'title' => $txt['pm_actions'], |
263
|
|
|
'areas' => array( |
264
|
|
|
'search' => array( |
265
|
|
|
'label' => $txt['pm_search_bar_title'], |
266
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=search', |
267
|
|
|
), |
268
|
|
|
'prune' => array( |
269
|
|
|
'label' => $txt['pm_prune'], |
270
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=prune' |
271
|
|
|
), |
272
|
|
|
), |
273
|
|
|
), |
274
|
|
|
'pref' => array( |
275
|
|
|
'title' => $txt['pm_preferences'], |
276
|
|
|
'areas' => array( |
277
|
|
|
'manlabels' => array( |
278
|
|
|
'label' => $txt['pm_manage_labels'], |
279
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=manlabels', |
280
|
|
|
), |
281
|
|
|
'manrules' => array( |
282
|
|
|
'label' => $txt['pm_manage_rules'], |
283
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=manrules', |
284
|
|
|
), |
285
|
|
|
'settings' => array( |
286
|
|
|
'label' => $txt['pm_settings'], |
287
|
|
|
'custom_url' => $scripturl . '?action=pm;sa=settings', |
288
|
|
|
), |
289
|
|
|
), |
290
|
|
|
), |
291
|
|
|
); |
292
|
|
|
|
293
|
|
|
// Handle labels. |
294
|
|
|
if (empty($context['currently_using_labels'])) |
295
|
|
|
unset($pm_areas['labels']); |
296
|
|
|
else |
297
|
|
|
{ |
298
|
|
|
// Note we send labels by id as it will have less problems in the querystring. |
299
|
|
|
$unread_in_labels = 0; |
300
|
|
|
foreach ($context['labels'] as $label) |
301
|
|
|
{ |
302
|
|
|
if ($label['id'] == -1) |
303
|
|
|
continue; |
304
|
|
|
|
305
|
|
|
// Count the amount of unread items in labels. |
306
|
|
|
$unread_in_labels += $label['unread_messages']; |
307
|
|
|
|
308
|
|
|
// Add the label to the menu. |
309
|
|
|
$pm_areas['labels']['areas']['label' . $label['id']] = array( |
310
|
|
|
'label' => $label['name'] . (!empty($label['unread_messages']) ? ' <span class="amt">' . $label['unread_messages'] . '</span>' : ''), |
311
|
|
|
'custom_url' => $scripturl . '?action=pm;l=' . $label['id'], |
312
|
|
|
'unread_messages' => $label['unread_messages'], |
313
|
|
|
'messages' => $label['messages'], |
314
|
|
|
); |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
if (!empty($unread_in_labels)) |
318
|
|
|
$pm_areas['labels']['title'] .= ' <span class="amt">' . $unread_in_labels . '</span>'; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
$pm_areas['folders']['areas']['inbox']['unread_messages'] = &$context['labels'][-1]['unread_messages']; |
322
|
|
|
$pm_areas['folders']['areas']['inbox']['messages'] = &$context['labels'][-1]['messages']; |
323
|
|
|
if (!empty($context['labels'][-1]['unread_messages'])) |
324
|
|
|
{ |
325
|
|
|
$pm_areas['folders']['areas']['inbox']['label'] .= ' <span class="amt">' . $context['labels'][-1]['unread_messages'] . '</span>'; |
326
|
|
|
$pm_areas['folders']['title'] .= ' <span class="amt">' . $context['labels'][-1]['unread_messages'] . '</span>'; |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
// Do we have a limit on the amount of messages we can keep? |
330
|
|
View Code Duplication |
if (!empty($context['message_limit'])) |
|
|
|
|
331
|
|
|
{ |
332
|
|
|
$bar = round(($user_info['messages'] * 100) / $context['message_limit'], 1); |
333
|
|
|
|
334
|
|
|
$context['limit_bar'] = array( |
335
|
|
|
'messages' => $user_info['messages'], |
336
|
|
|
'allowed' => $context['message_limit'], |
337
|
|
|
'percent' => $bar, |
338
|
|
|
'bar' => $bar > 100 ? 100 : (int) $bar, |
339
|
|
|
'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], $bar) |
340
|
|
|
); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
require_once($sourcedir . '/Subs-Menu.php'); |
344
|
|
|
|
345
|
|
|
// Set a few options for the menu. |
346
|
|
|
$menuOptions = array( |
347
|
|
|
'current_area' => $area, |
348
|
|
|
'disable_url_session_check' => true, |
349
|
|
|
); |
350
|
|
|
|
351
|
|
|
// Actually create the menu! |
352
|
|
|
$pm_include_data = createMenu($pm_areas, $menuOptions); |
353
|
|
|
unset($pm_areas); |
354
|
|
|
|
355
|
|
|
// No menu means no access. |
356
|
|
View Code Duplication |
if (!$pm_include_data && (!$user_info['is_guest'] || validateSession())) |
|
|
|
|
357
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
358
|
|
|
|
359
|
|
|
// Make a note of the Unique ID for this menu. |
360
|
|
|
$context['pm_menu_id'] = $context['max_menu_id']; |
361
|
|
|
$context['pm_menu_name'] = 'menu_data_' . $context['pm_menu_id']; |
362
|
|
|
|
363
|
|
|
// Set the selected item. |
364
|
|
|
$current_area = $pm_include_data['current_area']; |
365
|
|
|
$context['menu_item_selected'] = $current_area; |
366
|
|
|
|
367
|
|
|
// Set the template for this area and add the profile layer. |
368
|
|
|
if (!isset($_REQUEST['xml'])) |
369
|
|
|
$context['template_layers'][] = 'pm'; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* The popup for when we ask for the popup from the user. |
374
|
|
|
*/ |
375
|
|
|
function MessagePopup() |
376
|
|
|
{ |
377
|
|
|
global $context, $modSettings, $smcFunc, $memberContext, $scripturl, $user_settings, $db_show_debug; |
378
|
|
|
|
379
|
|
|
// We do not want to output debug information here. |
380
|
|
|
$db_show_debug = false; |
381
|
|
|
|
382
|
|
|
// We only want to output our little layer here. |
383
|
|
|
$context['template_layers'] = array(); |
384
|
|
|
$context['sub_template'] = 'pm_popup'; |
385
|
|
|
|
386
|
|
|
$context['can_send_pm'] = allowedTo('pm_send'); |
387
|
|
|
$context['can_draft'] = allowedTo('pm_draft') && !empty($modSettings['drafts_pm_enabled']); |
388
|
|
|
|
389
|
|
|
// So are we loading stuff? |
390
|
|
|
$request = $smcFunc['db_query']('', ' |
391
|
|
|
SELECT id_pm |
392
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
393
|
|
|
WHERE pmr.id_member = {int:current_member} |
394
|
|
|
AND is_read = {int:not_read} |
395
|
|
|
ORDER BY id_pm', |
396
|
|
|
array( |
397
|
|
|
'current_member' => $context['user']['id'], |
398
|
|
|
'not_read' => 0, |
399
|
|
|
) |
400
|
|
|
); |
401
|
|
|
$pms = array(); |
402
|
|
|
while ($row = $smcFunc['db_fetch_row']($request)) |
403
|
|
|
$pms[] = $row[0]; |
404
|
|
|
$smcFunc['db_free_result']($request); |
405
|
|
|
|
406
|
|
|
if (!empty($pms)) |
407
|
|
|
{ |
408
|
|
|
// Just quickly, it's possible that the number of PMs can get out of sync. |
409
|
|
|
$count_unread = count($pms); |
410
|
|
|
if ($count_unread != $user_settings['unread_messages']) |
411
|
|
|
{ |
412
|
|
|
updateMemberData($context['user']['id'], array('unread_messages' => $count_unread)); |
413
|
|
|
$context['user']['unread_messages'] = count($pms); |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
// Now, actually fetch me some PMs. Make sure we track the senders, got some work to do for them. |
417
|
|
|
$senders = array(); |
418
|
|
|
|
419
|
|
|
$request = $smcFunc['db_query']('', ' |
420
|
|
|
SELECT pm.id_pm, pm.id_pm_head, COALESCE(mem.id_member, pm.id_member_from) AS id_member_from, |
421
|
|
|
COALESCE(mem.real_name, pm.from_name) AS member_from, pm.msgtime AS timestamp, pm.subject |
422
|
|
|
FROM {db_prefix}personal_messages AS pm |
423
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (pm.id_member_from = mem.id_member) |
424
|
|
|
WHERE pm.id_pm IN ({array_int:id_pms})', |
425
|
|
|
array( |
426
|
|
|
'id_pms' => $pms, |
427
|
|
|
) |
428
|
|
|
); |
429
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
430
|
|
|
{ |
431
|
|
|
if (!empty($row['id_member_from'])) |
432
|
|
|
$senders[] = $row['id_member_from']; |
433
|
|
|
|
434
|
|
|
$row['replied_to_you'] = $row['id_pm'] != $row['id_pm_head']; |
435
|
|
|
$row['time'] = timeformat($row['timestamp']); |
436
|
|
|
$row['pm_link'] = '<a href="' . $scripturl . '?action=pm;f=inbox;pmsg=' . $row['id_pm'] . '">' . $row['subject'] . '</a>'; |
437
|
|
|
$context['unread_pms'][$row['id_pm']] = $row; |
438
|
|
|
} |
439
|
|
|
$smcFunc['db_free_result']($request); |
440
|
|
|
|
441
|
|
|
$senders = loadMemberData($senders); |
442
|
|
|
foreach ($senders as $member) |
443
|
|
|
loadMemberContext($member); |
444
|
|
|
|
445
|
|
|
// Having loaded everyone, attach them to the PMs. |
446
|
|
|
foreach ($context['unread_pms'] as $id_pm => $details) |
447
|
|
|
if (!empty($memberContext[$details['id_member_from']])) |
448
|
|
|
$context['unread_pms'][$id_pm]['member'] = &$memberContext[$details['id_member_from']]; |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* A folder, ie. inbox/sent etc. |
454
|
|
|
*/ |
455
|
|
|
function MessageFolder() |
456
|
|
|
{ |
457
|
|
|
global $txt, $scripturl, $modSettings, $context, $subjects_request; |
458
|
|
|
global $messages_request, $user_info, $recipients, $options, $smcFunc, $user_settings; |
459
|
|
|
|
460
|
|
|
// Changing view? |
461
|
|
|
if (isset($_GET['view'])) |
462
|
|
|
{ |
463
|
|
|
$context['display_mode'] = $context['display_mode'] > 1 ? 0 : $context['display_mode'] + 1; |
464
|
|
|
updateMemberData($user_info['id'], array('pm_prefs' => ($user_settings['pm_prefs'] & 252) | $context['display_mode'])); |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
// Make sure the starting location is valid. |
468
|
|
|
if (isset($_GET['start']) && $_GET['start'] != 'new') |
469
|
|
|
$_GET['start'] = (int) $_GET['start']; |
470
|
|
|
elseif (!isset($_GET['start']) && !empty($options['view_newest_pm_first'])) |
471
|
|
|
$_GET['start'] = 0; |
472
|
|
|
else |
473
|
|
|
$_GET['start'] = 'new'; |
474
|
|
|
|
475
|
|
|
// Set up some basic theme stuff. |
476
|
|
|
$context['from_or_to'] = $context['folder'] != 'sent' ? 'from' : 'to'; |
477
|
|
|
$context['get_pmessage'] = 'prepareMessageContext'; |
478
|
|
|
$context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1; |
479
|
|
|
$context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array(); |
480
|
|
|
|
481
|
|
|
$labelJoin = ''; |
482
|
|
|
$labelQuery = ''; |
483
|
|
|
$labelQuery2 = ''; |
484
|
|
|
|
485
|
|
|
// SMF logic: If you're viewing a label, it's still the inbox |
486
|
|
|
if ($context['folder'] == 'inbox' && $context['current_label_id'] == -1) |
487
|
|
|
{ |
488
|
|
|
$labelQuery = ' |
489
|
|
|
AND pmr.in_inbox = 1'; |
490
|
|
|
} |
491
|
|
|
elseif ($context['folder'] != 'sent') |
492
|
|
|
{ |
493
|
|
|
$labelJoin = ' |
494
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pl ON (pl.id_pm = pmr.id_pm)'; |
495
|
|
|
|
496
|
|
|
$labelQuery2 = ' |
497
|
|
|
AND pl.id_label = ' . $context['current_label_id']; |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
// Set the index bar correct! |
501
|
|
|
messageIndexBar($context['current_label_id'] == -1 ? $context['folder'] : 'label' . $context['current_label_id']); |
502
|
|
|
|
503
|
|
|
// Sorting the folder. |
504
|
|
|
$sort_methods = array( |
505
|
|
|
'date' => 'pm.id_pm', |
506
|
|
|
'name' => 'COALESCE(mem.real_name, \'\')', |
507
|
|
|
'subject' => 'pm.subject', |
508
|
|
|
); |
509
|
|
|
|
510
|
|
|
// They didn't pick one, use the forum default. |
511
|
|
|
if (!isset($_GET['sort']) || !isset($sort_methods[$_GET['sort']])) |
512
|
|
|
{ |
513
|
|
|
$context['sort_by'] = 'date'; |
514
|
|
|
$_GET['sort'] = 'pm.id_pm'; |
515
|
|
|
// An overriding setting? |
516
|
|
|
$descending = !empty($options['view_newest_pm_first']); |
517
|
|
|
} |
518
|
|
|
// Otherwise use the defaults: ascending, by date. |
519
|
|
View Code Duplication |
else |
|
|
|
|
520
|
|
|
{ |
521
|
|
|
$context['sort_by'] = $_GET['sort']; |
522
|
|
|
$_GET['sort'] = $sort_methods[$_GET['sort']]; |
523
|
|
|
$descending = isset($_GET['desc']); |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
$context['sort_direction'] = $descending ? 'down' : 'up'; |
527
|
|
|
|
528
|
|
|
// Set the text to resemble the current folder. |
529
|
|
|
$pmbox = $context['folder'] != 'sent' ? $txt['inbox'] : $txt['sent_items']; |
530
|
|
|
$txt['delete_all'] = str_replace('PMBOX', $pmbox, $txt['delete_all']); |
531
|
|
|
|
532
|
|
|
// Now, build the link tree! |
533
|
|
|
if ($context['current_label_id'] == -1) |
534
|
|
|
$context['linktree'][] = array( |
535
|
|
|
'url' => $scripturl . '?action=pm;f=' . $context['folder'], |
536
|
|
|
'name' => $pmbox |
537
|
|
|
); |
538
|
|
|
|
539
|
|
|
// Build it further for a label. |
540
|
|
|
if ($context['current_label_id'] != -1) |
541
|
|
|
$context['linktree'][] = array( |
542
|
|
|
'url' => $scripturl . '?action=pm;f=' . $context['folder'] . ';l=' . $context['current_label_id'], |
543
|
|
|
'name' => $txt['pm_current_label'] . ': ' . $context['current_label'] |
544
|
|
|
); |
545
|
|
|
|
546
|
|
|
// Figure out how many messages there are. |
547
|
|
|
if ($context['folder'] == 'sent') |
548
|
|
|
$request = $smcFunc['db_query']('', ' |
549
|
|
|
SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') |
550
|
|
|
FROM {db_prefix}personal_messages AS pm |
551
|
|
|
WHERE pm.id_member_from = {int:current_member} |
552
|
|
|
AND pm.deleted_by_sender = {int:not_deleted}', |
553
|
|
|
array( |
554
|
|
|
'current_member' => $user_info['id'], |
555
|
|
|
'not_deleted' => 0, |
556
|
|
|
) |
557
|
|
|
); |
558
|
|
|
else |
559
|
|
|
$request = $smcFunc['db_query']('', ' |
560
|
|
|
SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') |
561
|
|
|
FROM {db_prefix}pm_recipients AS pmr' . ($context['display_mode'] == 2 ? ' |
562
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)' : '') . $labelJoin . ' |
563
|
|
|
WHERE pmr.id_member = {int:current_member} |
564
|
|
|
AND pmr.deleted = {int:not_deleted}' . $labelQuery . $labelQuery2, |
565
|
|
|
array( |
566
|
|
|
'current_member' => $user_info['id'], |
567
|
|
|
'not_deleted' => 0, |
568
|
|
|
) |
569
|
|
|
); |
570
|
|
|
list ($max_messages) = $smcFunc['db_fetch_row']($request); |
571
|
|
|
$smcFunc['db_free_result']($request); |
572
|
|
|
|
573
|
|
|
// Only show the button if there are messages to delete. |
574
|
|
|
$context['show_delete'] = $max_messages > 0; |
575
|
|
|
$maxPerPage = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages']; |
576
|
|
|
|
577
|
|
|
// Start on the last page. |
578
|
|
|
if (!is_numeric($_GET['start']) || $_GET['start'] >= $max_messages) |
579
|
|
|
$_GET['start'] = ($max_messages - 1) - (($max_messages - 1) % $maxPerPage); |
580
|
|
|
elseif ($_GET['start'] < 0) |
581
|
|
|
$_GET['start'] = 0; |
582
|
|
|
|
583
|
|
|
// ... but wait - what if we want to start from a specific message? |
584
|
|
|
if (isset($_GET['pmid'])) |
585
|
|
|
{ |
586
|
|
|
$pmID = (int) $_GET['pmid']; |
587
|
|
|
|
588
|
|
|
// Make sure you have access to this PM. |
589
|
|
View Code Duplication |
if (!isAccessiblePM($pmID, $context['folder'] == 'sent' ? 'outbox' : 'inbox')) |
|
|
|
|
590
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
591
|
|
|
|
592
|
|
|
$context['current_pm'] = $pmID; |
593
|
|
|
|
594
|
|
|
// With only one page of PM's we're gonna want page 1. |
595
|
|
|
if ($max_messages <= $maxPerPage) |
596
|
|
|
$_GET['start'] = 0; |
597
|
|
|
// If we pass kstart we assume we're in the right place. |
598
|
|
|
elseif (!isset($_GET['kstart'])) |
599
|
|
|
{ |
600
|
|
|
if ($context['folder'] == 'sent') |
601
|
|
|
$request = $smcFunc['db_query']('', ' |
602
|
|
|
SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') |
603
|
|
|
FROM {db_prefix}personal_messages |
604
|
|
|
WHERE id_member_from = {int:current_member} |
605
|
|
|
AND deleted_by_sender = {int:not_deleted} |
606
|
|
|
AND id_pm ' . ($descending ? '>' : '<') . ' {int:id_pm}', |
607
|
|
|
array( |
608
|
|
|
'current_member' => $user_info['id'], |
609
|
|
|
'not_deleted' => 0, |
610
|
|
|
'id_pm' => $pmID, |
611
|
|
|
) |
612
|
|
|
); |
613
|
|
|
else |
614
|
|
|
$request = $smcFunc['db_query']('', ' |
615
|
|
|
SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') |
616
|
|
|
FROM {db_prefix}pm_recipients AS pmr' . ($context['display_mode'] == 2 ? ' |
617
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)' : '') . $labelJoin . ' |
618
|
|
|
WHERE pmr.id_member = {int:current_member} |
619
|
|
|
AND pmr.deleted = {int:not_deleted}' . $labelQuery . $labelQuery2 . ' |
620
|
|
|
AND pmr.id_pm ' . ($descending ? '>' : '<') . ' {int:id_pm}', |
621
|
|
|
array( |
622
|
|
|
'current_member' => $user_info['id'], |
623
|
|
|
'not_deleted' => 0, |
624
|
|
|
'id_pm' => $pmID, |
625
|
|
|
) |
626
|
|
|
); |
627
|
|
|
|
628
|
|
|
list ($_GET['start']) = $smcFunc['db_fetch_row']($request); |
629
|
|
|
$smcFunc['db_free_result']($request); |
630
|
|
|
|
631
|
|
|
// To stop the page index's being abnormal, start the page on the page the message would normally be located on... |
632
|
|
|
$_GET['start'] = $maxPerPage * (int) ($_GET['start'] / $maxPerPage); |
633
|
|
|
} |
634
|
|
|
} |
635
|
|
|
|
636
|
|
|
// Sanitize and validate pmsg variable if set. |
637
|
|
|
if (isset($_GET['pmsg'])) |
638
|
|
|
{ |
639
|
|
|
$pmsg = (int) $_GET['pmsg']; |
640
|
|
|
|
641
|
|
View Code Duplication |
if (!isAccessiblePM($pmsg, $context['folder'] == 'sent' ? 'outbox' : 'inbox')) |
|
|
|
|
642
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
// Set up the page index. |
646
|
|
|
$context['page_index'] = constructPageIndex($scripturl . '?action=pm;f=' . $context['folder'] . (isset($_REQUEST['l']) ? ';l=' . (int) $_REQUEST['l'] : '') . ';sort=' . $context['sort_by'] . ($descending ? ';desc' : ''), $_GET['start'], $max_messages, $maxPerPage); |
647
|
|
|
$context['start'] = $_GET['start']; |
648
|
|
|
|
649
|
|
|
// Determine the navigation context. |
650
|
|
|
$context['links'] = array( |
651
|
|
|
'first' => $_GET['start'] >= $maxPerPage ? $scripturl . '?action=pm;start=0' : '', |
652
|
|
|
'prev' => $_GET['start'] >= $maxPerPage ? $scripturl . '?action=pm;start=' . ($_GET['start'] - $maxPerPage) : '', |
653
|
|
|
'next' => $_GET['start'] + $maxPerPage < $max_messages ? $scripturl . '?action=pm;start=' . ($_GET['start'] + $maxPerPage) : '', |
654
|
|
|
'last' => $_GET['start'] + $maxPerPage < $max_messages ? $scripturl . '?action=pm;start=' . (floor(($max_messages - 1) / $maxPerPage) * $maxPerPage) : '', |
655
|
|
|
'up' => $scripturl, |
656
|
|
|
); |
657
|
|
|
$context['page_info'] = array( |
658
|
|
|
'current_page' => $_GET['start'] / $maxPerPage + 1, |
659
|
|
|
'num_pages' => floor(($max_messages - 1) / $maxPerPage) + 1 |
660
|
|
|
); |
661
|
|
|
|
662
|
|
|
// First work out what messages we need to see - if grouped is a little trickier... |
663
|
|
|
if ($context['display_mode'] == 2) |
664
|
|
|
{ |
665
|
|
|
if ($context['folder'] != 'sent' && $context['folder'] != 'inbox') |
666
|
|
|
{ |
667
|
|
|
$labelJoin = ' |
668
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pl ON (pl.id_pm = pm.id_pm)'; |
669
|
|
|
|
670
|
|
|
$labelQuery = ''; |
671
|
|
|
$labelQuery2 = ' |
672
|
|
|
AND pl.id_label = ' . $context['current_label_id']; |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
$request = $smcFunc['db_query']('pm_conversation_list', ' |
676
|
|
|
SELECT MAX(pm.id_pm) AS id_pm, pm.id_pm_head |
677
|
|
|
FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? ($context['sort_by'] == 'name' ? ' |
678
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '') : ' |
679
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm |
680
|
|
|
AND pmr.id_member = {int:current_member} |
681
|
|
|
AND pmr.deleted = {int:deleted_by} |
682
|
|
|
' . $labelQuery . ')') . $labelJoin . ($context['sort_by'] == 'name' ? (' |
683
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:pm_member})') : '') . ' |
684
|
|
|
WHERE ' . ($context['folder'] == 'sent' ? 'pm.id_member_from = {int:current_member} |
685
|
|
|
AND pm.deleted_by_sender = {int:deleted_by}' : '1=1') . (empty($pmsg) ? '' : ' |
686
|
|
|
AND pm.id_pm = {int:pmsg}') . $labelQuery2 . ' |
687
|
|
|
GROUP BY pm.id_pm_head'.($_GET['sort'] != 'pm.id_pm' ? ',' . $_GET['sort'] : '') . ' |
688
|
|
|
ORDER BY ' . ($_GET['sort'] == 'pm.id_pm' && $context['folder'] != 'sent' ? 'id_pm' : '{raw:sort}') . ($descending ? ' DESC' : ' ASC') . (empty($_GET['pmsg']) ? ' |
689
|
|
|
LIMIT ' . $_GET['start'] . ', ' . $maxPerPage : ''), |
690
|
|
|
array( |
691
|
|
|
'current_member' => $user_info['id'], |
692
|
|
|
'deleted_by' => 0, |
693
|
|
|
'sort' => $_GET['sort'], |
694
|
|
|
'pm_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from', |
695
|
|
|
'pmsg' => isset($pmsg) ? (int) $pmsg : 0, |
696
|
|
|
) |
697
|
|
|
); |
698
|
|
|
|
699
|
|
|
} |
700
|
|
|
// This is kinda simple! |
701
|
|
|
else |
702
|
|
|
{ |
703
|
|
|
// @todo SLOW This query uses a filesort. (inbox only.) |
704
|
|
|
$request = $smcFunc['db_query']('', ' |
705
|
|
|
SELECT pm.id_pm, pm.id_pm_head, pm.id_member_from |
706
|
|
|
FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? '' . ($context['sort_by'] == 'name' ? ' |
707
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '') : ' |
708
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm |
709
|
|
|
AND pmr.id_member = {int:current_member} |
710
|
|
|
AND pmr.deleted = {int:is_deleted} |
711
|
|
|
' . $labelQuery . ')') . $labelJoin . ($context['sort_by'] == 'name' ? (' |
712
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:pm_member})') : '') . ' |
713
|
|
|
WHERE ' . ($context['folder'] == 'sent' ? 'pm.id_member_from = {raw:current_member} |
714
|
|
|
AND pm.deleted_by_sender = {int:is_deleted}' : '1=1') . (empty($pmsg) ? '' : ' |
715
|
|
|
AND pm.id_pm = {int:pmsg}') . $labelQuery2 . ' |
716
|
|
|
ORDER BY ' . ($_GET['sort'] == 'pm.id_pm' && $context['folder'] != 'sent' ? 'pmr.id_pm' : '{raw:sort}') . ($descending ? ' DESC' : ' ASC') . (empty($pmsg) ? ' |
717
|
|
|
LIMIT ' . $_GET['start'] . ', ' . $maxPerPage : ''), |
718
|
|
|
array( |
719
|
|
|
'current_member' => $user_info['id'], |
720
|
|
|
'is_deleted' => 0, |
721
|
|
|
'sort' => $_GET['sort'], |
722
|
|
|
'pm_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from', |
723
|
|
|
'pmsg' => isset($pmsg) ? (int) $pmsg : 0, |
724
|
|
|
) |
725
|
|
|
); |
726
|
|
|
} |
727
|
|
|
// Load the id_pms and initialize recipients. |
728
|
|
|
$pms = array(); |
729
|
|
|
$lastData = array(); |
730
|
|
|
$posters = $context['folder'] == 'sent' ? array($user_info['id']) : array(); |
731
|
|
|
$recipients = array(); |
732
|
|
|
|
733
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
734
|
|
|
{ |
735
|
|
|
if (!isset($recipients[$row['id_pm']])) |
736
|
|
|
{ |
737
|
|
|
if (isset($row['id_member_from'])) |
738
|
|
|
$posters[$row['id_pm']] = $row['id_member_from']; |
739
|
|
|
$pms[$row['id_pm']] = $row['id_pm']; |
740
|
|
|
$recipients[$row['id_pm']] = array( |
741
|
|
|
'to' => array(), |
742
|
|
|
'bcc' => array() |
743
|
|
|
); |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
// Keep track of the last message so we know what the head is without another query! |
747
|
|
|
if ((empty($pmID) && (empty($options['view_newest_pm_first']) || !isset($lastData))) || empty($lastData) || (!empty($pmID) && $pmID == $row['id_pm'])) |
748
|
|
|
$lastData = array( |
749
|
|
|
'id' => $row['id_pm'], |
750
|
|
|
'head' => $row['id_pm_head'], |
751
|
|
|
); |
752
|
|
|
} |
753
|
|
|
$smcFunc['db_free_result']($request); |
754
|
|
|
|
755
|
|
|
// Make sure that we have been given a correct head pm id! |
756
|
|
|
if ($context['display_mode'] == 2 && !empty($pmID) && $pmID != $lastData['id']) |
757
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
758
|
|
|
|
759
|
|
|
if (!empty($pms)) |
760
|
|
|
{ |
761
|
|
|
// Select the correct current message. |
762
|
|
|
if (empty($pmID)) |
763
|
|
|
$context['current_pm'] = $lastData['id']; |
764
|
|
|
|
765
|
|
|
// This is a list of the pm's that are used for "full" display. |
766
|
|
|
if ($context['display_mode'] == 0) |
767
|
|
|
$display_pms = $pms; |
768
|
|
|
else |
769
|
|
|
$display_pms = array($context['current_pm']); |
770
|
|
|
|
771
|
|
|
// At this point we know the main id_pm's. But - if we are looking at conversations we need the others! |
772
|
|
|
if ($context['display_mode'] == 2) |
773
|
|
|
{ |
774
|
|
|
$request = $smcFunc['db_query']('', ' |
775
|
|
|
SELECT pm.id_pm, pm.id_member_from, pm.deleted_by_sender, pmr.id_member, pmr.deleted |
776
|
|
|
FROM {db_prefix}personal_messages AS pm |
777
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm) |
778
|
|
|
WHERE pm.id_pm_head = {int:id_pm_head} |
779
|
|
|
AND ((pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:not_deleted}) |
780
|
|
|
OR (pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted})) |
781
|
|
|
ORDER BY pm.id_pm', |
782
|
|
|
array( |
783
|
|
|
'current_member' => $user_info['id'], |
784
|
|
|
'id_pm_head' => $lastData['head'], |
785
|
|
|
'not_deleted' => 0, |
786
|
|
|
) |
787
|
|
|
); |
788
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
789
|
|
|
{ |
790
|
|
|
// This is, frankly, a joke. We will put in a workaround for people sending to themselves - yawn! |
791
|
|
|
if ($context['folder'] == 'sent' && $row['id_member_from'] == $user_info['id'] && $row['deleted_by_sender'] == 1) |
792
|
|
|
continue; |
793
|
|
|
elseif ($row['id_member'] == $user_info['id'] & $row['deleted'] == 1) |
|
|
|
|
794
|
|
|
continue; |
795
|
|
|
|
796
|
|
|
if (!isset($recipients[$row['id_pm']])) |
797
|
|
|
$recipients[$row['id_pm']] = array( |
798
|
|
|
'to' => array(), |
799
|
|
|
'bcc' => array() |
800
|
|
|
); |
801
|
|
|
$display_pms[] = $row['id_pm']; |
802
|
|
|
$posters[$row['id_pm']] = $row['id_member_from']; |
803
|
|
|
} |
804
|
|
|
$smcFunc['db_free_result']($request); |
805
|
|
|
} |
806
|
|
|
|
807
|
|
|
// This is pretty much EVERY pm! |
808
|
|
|
$all_pms = array_merge($pms, $display_pms); |
809
|
|
|
$all_pms = array_unique($all_pms); |
810
|
|
|
|
811
|
|
|
// Get recipients (don't include bcc-recipients for your inbox, you're not supposed to know :P). |
812
|
|
|
$request = $smcFunc['db_query']('', ' |
813
|
|
|
SELECT pmr.id_pm, mem_to.id_member AS id_member_to, mem_to.real_name AS to_name, pmr.bcc, pmr.in_inbox, pmr.is_read |
814
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
815
|
|
|
LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member) |
816
|
|
|
WHERE pmr.id_pm IN ({array_int:pm_list})', |
817
|
|
|
array( |
818
|
|
|
'pm_list' => $all_pms, |
819
|
|
|
) |
820
|
|
|
); |
821
|
|
|
$context['message_labels'] = array(); |
822
|
|
|
$context['message_replied'] = array(); |
823
|
|
|
$context['message_unread'] = array(); |
824
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
825
|
|
|
{ |
826
|
|
|
if ($context['folder'] == 'sent' || empty($row['bcc'])) |
827
|
|
|
{ |
828
|
|
|
$recipients[$row['id_pm']][empty($row['bcc']) ? 'to' : 'bcc'][] = empty($row['id_member_to']) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . '">' . $row['to_name'] . '</a>'; |
829
|
|
|
|
830
|
|
|
$context['folder'] == 'sent' && $context['display_mode'] != 2 ? $context['message_replied'][$row['id_pm']] = $row['is_read'] & 2 : ''; |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
if ($row['id_member_to'] == $user_info['id'] && $context['folder'] != 'sent') |
834
|
|
|
{ |
835
|
|
|
$context['message_replied'][$row['id_pm']] = $row['is_read'] & 2; |
836
|
|
|
$context['message_unread'][$row['id_pm']] = $row['is_read'] == 0; |
837
|
|
|
|
838
|
|
|
// Get the labels for this PM |
839
|
|
|
$request2 = $smcFunc['db_query']('', ' |
840
|
|
|
SELECT id_label |
841
|
|
|
FROM {db_prefix}pm_labeled_messages |
842
|
|
|
WHERE id_pm = {int:current_pm}', |
843
|
|
|
array( |
844
|
|
|
'current_pm' => $row['id_pm'], |
845
|
|
|
) |
846
|
|
|
); |
847
|
|
|
|
848
|
|
|
while ($row2 = $smcFunc['db_fetch_assoc']($request2)) |
849
|
|
|
{ |
850
|
|
|
$l_id = $row2['id_label']; |
851
|
|
View Code Duplication |
if (isset($context['labels'][$l_id])) |
|
|
|
|
852
|
|
|
$context['message_labels'][$row['id_pm']][$l_id] = array('id' => $l_id, 'name' => $context['labels'][$l_id]['name']); |
853
|
|
|
} |
854
|
|
|
|
855
|
|
|
$smcFunc['db_free_result']($request2); |
856
|
|
|
|
857
|
|
|
// Is this in the inbox as well? |
858
|
|
View Code Duplication |
if ($row['in_inbox'] == 1) |
|
|
|
|
859
|
|
|
{ |
860
|
|
|
$context['message_labels'][$row['id_pm']][-1] = array('id' => -1, 'name' => $context['labels'][-1]['name']); |
861
|
|
|
} |
862
|
|
|
} |
863
|
|
|
} |
864
|
|
|
$smcFunc['db_free_result']($request); |
865
|
|
|
|
866
|
|
|
// Make sure we don't load unnecessary data. |
867
|
|
|
if ($context['display_mode'] == 1) |
868
|
|
|
{ |
869
|
|
|
foreach ($posters as $k => $v) |
870
|
|
|
if (!in_array($k, $display_pms)) |
871
|
|
|
unset($posters[$k]); |
872
|
|
|
} |
873
|
|
|
|
874
|
|
|
// Load any users.... |
875
|
|
|
loadMemberData($posters); |
876
|
|
|
|
877
|
|
|
// If we're on grouped/restricted view get a restricted list of messages. |
878
|
|
|
if ($context['display_mode'] != 0) |
879
|
|
|
{ |
880
|
|
|
// Get the order right. |
881
|
|
|
$orderBy = array(); |
882
|
|
|
foreach (array_reverse($pms) as $pm) |
883
|
|
|
$orderBy[] = 'pm.id_pm = ' . $pm; |
884
|
|
|
|
885
|
|
|
// Seperate query for these bits! |
886
|
|
|
$subjects_request = $smcFunc['db_query']('', ' |
887
|
|
|
SELECT pm.id_pm, pm.subject, COALESCE(pm.id_member_from, 0) AS id_member_from, pm.msgtime, COALESCE(mem.real_name, pm.from_name) AS from_name, |
888
|
|
|
mem.id_member |
889
|
|
|
FROM {db_prefix}personal_messages AS pm |
890
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) |
891
|
|
|
WHERE pm.id_pm IN ({array_int:pm_list}) |
892
|
|
|
ORDER BY ' . implode(', ', $orderBy) . ' |
893
|
|
|
LIMIT {int:limit}', |
894
|
|
|
array( |
895
|
|
|
'pm_list' => $pms, |
896
|
|
|
'limit' => count($pms), |
897
|
|
|
) |
898
|
|
|
); |
899
|
|
|
} |
900
|
|
|
|
901
|
|
|
// Execute the query! |
902
|
|
|
$messages_request = $smcFunc['db_query']('', ' |
903
|
|
|
SELECT pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name |
904
|
|
|
FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? ' |
905
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '') . ($context['sort_by'] == 'name' ? ' |
906
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:id_member})' : '') . ' |
907
|
|
|
WHERE pm.id_pm IN ({array_int:display_pms})' . ($context['folder'] == 'sent' ? ' |
908
|
|
|
GROUP BY pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name' : '') . ' |
909
|
|
|
ORDER BY ' . ($context['display_mode'] == 2 ? 'pm.id_pm' : '{raw:sort}') . ($descending ? ' DESC' : ' ASC') . ' |
910
|
|
|
LIMIT {int:limit}', |
911
|
|
|
array( |
912
|
|
|
'display_pms' => $display_pms, |
913
|
|
|
'id_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from', |
914
|
|
|
'limit' => count($display_pms), |
915
|
|
|
'sort' => $_GET['sort'], |
916
|
|
|
) |
917
|
|
|
); |
918
|
|
|
|
919
|
|
|
// Build the conversation button array. |
920
|
|
|
if ($context['display_mode'] == 2) |
921
|
|
|
{ |
922
|
|
|
$context['conversation_buttons'] = array( |
923
|
|
|
'delete' => array('text' => 'delete_conversation', 'image' => 'delete.png', 'url' => $scripturl . '?action=pm;sa=pmactions;pm_actions[' . $context['current_pm'] . ']=delete;conversation;f=' . $context['folder'] . ';start=' . $context['start'] . ($context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'custom' => 'data-confirm="' . $txt['remove_conversation'] . '"', 'class' => 'you_sure'), |
924
|
|
|
); |
925
|
|
|
|
926
|
|
|
// Allow mods to add additional buttons here |
927
|
|
|
call_integration_hook('integrate_conversation_buttons'); |
928
|
|
|
} |
929
|
|
|
} |
930
|
|
|
else |
931
|
|
|
$messages_request = false; |
932
|
|
|
|
933
|
|
|
$context['can_send_pm'] = allowedTo('pm_send'); |
934
|
|
|
$context['can_send_email'] = allowedTo('moderate_forum'); |
935
|
|
|
$context['sub_template'] = 'folder'; |
936
|
|
|
$context['page_title'] = $txt['pm_inbox']; |
937
|
|
|
|
938
|
|
|
// Finally mark the relevant messages as read. |
939
|
|
|
if ($context['folder'] != 'sent' && !empty($context['labels'][(int) $context['current_label_id']]['unread_messages'])) |
940
|
|
|
{ |
941
|
|
|
// If the display mode is "old sk00l" do them all... |
942
|
|
|
if ($context['display_mode'] == 0) |
943
|
|
|
markMessages(null, $context['current_label_id']); |
944
|
|
|
// Otherwise do just the current one! |
945
|
|
|
elseif (!empty($context['current_pm'])) |
946
|
|
|
markMessages($display_pms, $context['current_label_id']); |
|
|
|
|
947
|
|
|
} |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
/** |
951
|
|
|
* Get a personal message for the theme. (used to save memory.) |
952
|
|
|
* |
953
|
|
|
* @param string $type The type of message |
954
|
|
|
* @param bool $reset Whether to reset the internal pointer |
955
|
|
|
* @return bool|array False on failure, otherwise an array of info |
956
|
|
|
*/ |
957
|
|
|
function prepareMessageContext($type = 'subject', $reset = false) |
958
|
|
|
{ |
959
|
|
|
global $txt, $scripturl, $modSettings, $context, $messages_request, $memberContext, $recipients, $smcFunc; |
960
|
|
|
global $user_info, $subjects_request; |
961
|
|
|
|
962
|
|
|
// Count the current message number.... |
963
|
|
|
static $counter = null; |
964
|
|
|
if ($counter === null || $reset) |
965
|
|
|
$counter = $context['start']; |
966
|
|
|
|
967
|
|
|
static $temp_pm_selected = null; |
968
|
|
|
if ($temp_pm_selected === null) |
969
|
|
|
{ |
970
|
|
|
$temp_pm_selected = isset($_SESSION['pm_selected']) ? $_SESSION['pm_selected'] : array(); |
971
|
|
|
$_SESSION['pm_selected'] = array(); |
972
|
|
|
} |
973
|
|
|
|
974
|
|
|
// If we're in non-boring view do something exciting! |
975
|
|
|
if ($context['display_mode'] != 0 && $subjects_request && $type == 'subject') |
976
|
|
|
{ |
977
|
|
|
$subject = $smcFunc['db_fetch_assoc']($subjects_request); |
978
|
|
|
if (!$subject) |
979
|
|
|
{ |
980
|
|
|
$smcFunc['db_free_result']($subjects_request); |
981
|
|
|
return false; |
982
|
|
|
} |
983
|
|
|
|
984
|
|
|
$subject['subject'] = $subject['subject'] == '' ? $txt['no_subject'] : $subject['subject']; |
985
|
|
|
censorText($subject['subject']); |
986
|
|
|
|
987
|
|
|
$output = array( |
988
|
|
|
'id' => $subject['id_pm'], |
989
|
|
|
'member' => array( |
990
|
|
|
'id' => $subject['id_member_from'], |
991
|
|
|
'name' => $subject['from_name'], |
992
|
|
|
'link' => ($subject['id_member_from'] != 0) ? '<a href="' . $scripturl . '?action=profile;u=' . $subject['id_member_from'] . '">' . $subject['from_name'] . '</a>' : $subject['from_name'], |
993
|
|
|
), |
994
|
|
|
'recipients' => &$recipients[$subject['id_pm']], |
995
|
|
|
'subject' => $subject['subject'], |
996
|
|
|
'time' => timeformat($subject['msgtime']), |
997
|
|
|
'timestamp' => forum_time(true, $subject['msgtime']), |
998
|
|
|
'number_recipients' => count($recipients[$subject['id_pm']]['to']), |
999
|
|
|
'labels' => &$context['message_labels'][$subject['id_pm']], |
1000
|
|
|
'fully_labeled' => count($context['message_labels'][$subject['id_pm']]) == count($context['labels']), |
1001
|
|
|
'is_replied_to' => &$context['message_replied'][$subject['id_pm']], |
1002
|
|
|
'is_unread' => &$context['message_unread'][$subject['id_pm']], |
1003
|
|
|
'is_selected' => !empty($temp_pm_selected) && in_array($subject['id_pm'], $temp_pm_selected), |
1004
|
|
|
); |
1005
|
|
|
|
1006
|
|
|
return $output; |
1007
|
|
|
} |
1008
|
|
|
|
1009
|
|
|
// Bail if it's false, ie. no messages. |
1010
|
|
|
if ($messages_request == false) |
1011
|
|
|
return false; |
1012
|
|
|
|
1013
|
|
|
// Reset the data? |
1014
|
|
|
if ($reset == true) |
|
|
|
|
1015
|
|
|
return @$smcFunc['db_data_seek']($messages_request, 0); |
1016
|
|
|
|
1017
|
|
|
// Get the next one... bail if anything goes wrong. |
1018
|
|
|
$message = $smcFunc['db_fetch_assoc']($messages_request); |
1019
|
|
|
if (!$message) |
1020
|
|
|
{ |
1021
|
|
|
if ($type != 'subject') |
1022
|
|
|
$smcFunc['db_free_result']($messages_request); |
1023
|
|
|
|
1024
|
|
|
return false; |
1025
|
|
|
} |
1026
|
|
|
|
1027
|
|
|
// Use '(no subject)' if none was specified. |
1028
|
|
|
$message['subject'] = $message['subject'] == '' ? $txt['no_subject'] : $message['subject']; |
1029
|
|
|
|
1030
|
|
|
// Load the message's information - if it's not there, load the guest information. |
1031
|
|
|
if (!loadMemberContext($message['id_member_from'], true)) |
1032
|
|
|
{ |
1033
|
|
|
$memberContext[$message['id_member_from']]['name'] = $message['from_name']; |
1034
|
|
|
$memberContext[$message['id_member_from']]['id'] = 0; |
1035
|
|
|
|
1036
|
|
|
// Sometimes the forum sends messages itself (Warnings are an example) - in this case don't label it from a guest. |
1037
|
|
|
$memberContext[$message['id_member_from']]['group'] = $message['from_name'] == $context['forum_name_html_safe'] ? '' : $txt['guest_title']; |
1038
|
|
|
$memberContext[$message['id_member_from']]['link'] = $message['from_name']; |
1039
|
|
|
$memberContext[$message['id_member_from']]['email'] = ''; |
1040
|
|
|
$memberContext[$message['id_member_from']]['show_email'] = false; |
1041
|
|
|
$memberContext[$message['id_member_from']]['is_guest'] = true; |
1042
|
|
|
} |
1043
|
|
|
else |
1044
|
|
|
{ |
1045
|
|
|
$memberContext[$message['id_member_from']]['can_view_profile'] = allowedTo('profile_view') || ($message['id_member_from'] == $user_info['id'] && !$user_info['is_guest']); |
1046
|
|
|
$memberContext[$message['id_member_from']]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$message['id_member_from']]['warning_status'] && ($context['user']['can_mod'] || (!empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $message['id_member_from'] == $user_info['id']))); |
1047
|
|
|
// Show the email if it's your own PM |
1048
|
|
|
$memberContext[$message['id_member_from']]['show_email'] |= $message['id_member_from'] == $user_info['id']; |
1049
|
|
|
} |
1050
|
|
|
|
1051
|
|
|
$memberContext[$message['id_member_from']]['show_profile_buttons'] = $modSettings['show_profile_buttons'] && (!empty($memberContext[$message['id_member_from']]['can_view_profile']) || (!empty($memberContext[$message['id_member_from']]['website']['url']) && !isset($context['disabled_fields']['website'])) || $memberContext[$message['id_member_from']]['show_email'] || $context['can_send_pm']); |
1052
|
|
|
|
1053
|
|
|
// Censor all the important text... |
1054
|
|
|
censorText($message['body']); |
1055
|
|
|
censorText($message['subject']); |
1056
|
|
|
|
1057
|
|
|
// Run UBBC interpreter on the message. |
1058
|
|
|
$message['body'] = parse_bbc($message['body'], true, 'pm' . $message['id_pm']); |
1059
|
|
|
|
1060
|
|
|
// Send the array. |
1061
|
|
|
$output = array( |
1062
|
|
|
'id' => $message['id_pm'], |
1063
|
|
|
'member' => &$memberContext[$message['id_member_from']], |
1064
|
|
|
'subject' => $message['subject'], |
1065
|
|
|
'time' => timeformat($message['msgtime']), |
1066
|
|
|
'timestamp' => forum_time(true, $message['msgtime']), |
1067
|
|
|
'counter' => $counter, |
1068
|
|
|
'body' => $message['body'], |
1069
|
|
|
'recipients' => &$recipients[$message['id_pm']], |
1070
|
|
|
'number_recipients' => count($recipients[$message['id_pm']]['to']), |
1071
|
|
|
'labels' => &$context['message_labels'][$message['id_pm']], |
1072
|
|
|
'fully_labeled' => count($context['message_labels'][$message['id_pm']]) == count($context['labels']), |
1073
|
|
|
'is_replied_to' => &$context['message_replied'][$message['id_pm']], |
1074
|
|
|
'is_unread' => &$context['message_unread'][$message['id_pm']], |
1075
|
|
|
'is_selected' => !empty($temp_pm_selected) && in_array($message['id_pm'], $temp_pm_selected), |
1076
|
|
|
'is_message_author' => $message['id_member_from'] == $user_info['id'], |
1077
|
|
|
'can_report' => !empty($modSettings['enableReportPM']), |
1078
|
|
|
'can_see_ip' => allowedTo('moderate_forum') || ($message['id_member_from'] == $user_info['id'] && !empty($user_info['id'])), |
1079
|
|
|
); |
1080
|
|
|
|
1081
|
|
|
$counter++; |
1082
|
|
|
|
1083
|
|
|
// Any custom profile fields? |
1084
|
|
|
if (!empty($memberContext[$message['id_member_from']]['custom_fields'])) |
1085
|
|
|
foreach ($memberContext[$message['id_member_from']]['custom_fields'] as $custom) |
1086
|
|
|
switch ($custom['placement']) |
1087
|
|
|
{ |
1088
|
|
|
case 1: |
1089
|
|
|
$output['custom_fields']['icons'][] = $custom; |
1090
|
|
|
break; |
1091
|
|
|
case 2: |
1092
|
|
|
$output['custom_fields']['above_signature'][] = $custom; |
1093
|
|
|
break; |
1094
|
|
|
case 3: |
1095
|
|
|
$output['custom_fields']['below_signature'][] = $custom; |
1096
|
|
|
break; |
1097
|
|
|
case 4: |
1098
|
|
|
$output['custom_fields']['below_avatar'][] = $custom; |
1099
|
|
|
break; |
1100
|
|
|
case 5: |
1101
|
|
|
$output['custom_fields']['above_member'][] = $custom; |
1102
|
|
|
break; |
1103
|
|
|
case 6: |
1104
|
|
|
$output['custom_fields']['bottom_poster'][] = $custom; |
1105
|
|
|
break; |
1106
|
|
|
default: |
1107
|
|
|
$output['custom_fields']['standard'][] = $custom; |
1108
|
|
|
} |
1109
|
|
|
|
1110
|
|
|
call_integration_hook('integrate_prepare_pm_context', array(&$output, &$message, $counter)); |
1111
|
|
|
|
1112
|
|
|
return $output; |
1113
|
|
|
} |
1114
|
|
|
|
1115
|
|
|
/** |
1116
|
|
|
* Allows searching through personal messages. |
1117
|
|
|
*/ |
1118
|
|
|
function MessageSearch() |
1119
|
|
|
{ |
1120
|
|
|
global $context, $txt, $scripturl, $smcFunc; |
1121
|
|
|
|
1122
|
|
|
if (isset($_REQUEST['params'])) |
1123
|
|
|
{ |
1124
|
|
|
$temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+')))); |
1125
|
|
|
$context['search_params'] = array(); |
1126
|
|
View Code Duplication |
foreach ($temp_params as $i => $data) |
|
|
|
|
1127
|
|
|
{ |
1128
|
|
|
@list ($k, $v) = explode('|\'|', $data); |
|
|
|
|
1129
|
|
|
$context['search_params'][$k] = $v; |
1130
|
|
|
} |
1131
|
|
|
} |
1132
|
|
View Code Duplication |
if (isset($_REQUEST['search'])) |
|
|
|
|
1133
|
|
|
$context['search_params']['search'] = un_htmlspecialchars($_REQUEST['search']); |
1134
|
|
|
|
1135
|
|
View Code Duplication |
if (isset($context['search_params']['search'])) |
|
|
|
|
1136
|
|
|
$context['search_params']['search'] = $smcFunc['htmlspecialchars']($context['search_params']['search']); |
1137
|
|
View Code Duplication |
if (isset($context['search_params']['userspec'])) |
|
|
|
|
1138
|
|
|
$context['search_params']['userspec'] = $smcFunc['htmlspecialchars']($context['search_params']['userspec']); |
1139
|
|
|
|
1140
|
|
|
if (!empty($context['search_params']['searchtype'])) |
1141
|
|
|
$context['search_params']['searchtype'] = 2; |
1142
|
|
|
|
1143
|
|
View Code Duplication |
if (!empty($context['search_params']['minage'])) |
|
|
|
|
1144
|
|
|
$context['search_params']['minage'] = (int) $context['search_params']['minage']; |
1145
|
|
|
|
1146
|
|
View Code Duplication |
if (!empty($context['search_params']['maxage'])) |
|
|
|
|
1147
|
|
|
$context['search_params']['maxage'] = (int) $context['search_params']['maxage']; |
1148
|
|
|
|
1149
|
|
|
$context['search_params']['subject_only'] = !empty($context['search_params']['subject_only']); |
1150
|
|
|
$context['search_params']['show_complete'] = !empty($context['search_params']['show_complete']); |
1151
|
|
|
|
1152
|
|
|
// Create the array of labels to be searched. |
1153
|
|
|
$context['search_labels'] = array(); |
1154
|
|
|
$searchedLabels = isset($context['search_params']['labels']) && $context['search_params']['labels'] != '' ? explode(',', $context['search_params']['labels']) : array(); |
1155
|
|
|
foreach ($context['labels'] as $label) |
1156
|
|
|
{ |
1157
|
|
|
$context['search_labels'][] = array( |
1158
|
|
|
'id' => $label['id'], |
1159
|
|
|
'name' => $label['name'], |
1160
|
|
|
'checked' => !empty($searchedLabels) ? in_array($label['id'], $searchedLabels) : true, |
1161
|
|
|
); |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
// Are all the labels checked? |
1165
|
|
|
$context['check_all'] = empty($searchedLabels) || count($context['search_labels']) == count($searchedLabels); |
1166
|
|
|
|
1167
|
|
|
// Load the error text strings if there were errors in the search. |
1168
|
|
|
if (!empty($context['search_errors'])) |
1169
|
|
|
{ |
1170
|
|
|
loadLanguage('Errors'); |
1171
|
|
|
$context['search_errors']['messages'] = array(); |
1172
|
|
|
foreach ($context['search_errors'] as $search_error => $dummy) |
|
|
|
|
1173
|
|
|
{ |
1174
|
|
|
if ($search_error == 'messages') |
1175
|
|
|
continue; |
1176
|
|
|
|
1177
|
|
|
$context['search_errors']['messages'][] = $txt['error_' . $search_error]; |
1178
|
|
|
} |
1179
|
|
|
} |
1180
|
|
|
|
1181
|
|
|
$context['page_title'] = $txt['pm_search_title']; |
1182
|
|
|
$context['sub_template'] = 'search'; |
1183
|
|
|
$context['linktree'][] = array( |
1184
|
|
|
'url' => $scripturl . '?action=pm;sa=search', |
1185
|
|
|
'name' => $txt['pm_search_bar_title'], |
1186
|
|
|
); |
1187
|
|
|
} |
1188
|
|
|
|
1189
|
|
|
/** |
1190
|
|
|
* Actually do the search of personal messages. |
1191
|
|
|
*/ |
1192
|
|
|
function MessageSearch2() |
1193
|
|
|
{ |
1194
|
|
|
global $scripturl, $modSettings, $user_info, $context, $txt; |
1195
|
|
|
global $memberContext, $smcFunc; |
1196
|
|
|
|
1197
|
|
View Code Duplication |
if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) |
|
|
|
|
1198
|
|
|
fatal_lang_error('loadavg_search_disabled', false); |
|
|
|
|
1199
|
|
|
|
1200
|
|
|
/** |
1201
|
|
|
* @todo For the moment force the folder to the inbox. |
1202
|
|
|
* @todo Maybe set the inbox based on a cookie or theme setting? |
1203
|
|
|
*/ |
1204
|
|
|
$context['folder'] = 'inbox'; |
1205
|
|
|
|
1206
|
|
|
// Some useful general permissions. |
1207
|
|
|
$context['can_send_pm'] = allowedTo('pm_send'); |
1208
|
|
|
|
1209
|
|
|
// Some hardcoded veriables that can be tweaked if required. |
1210
|
|
|
$maxMembersToSearch = 500; |
1211
|
|
|
|
1212
|
|
|
// Extract all the search parameters. |
1213
|
|
|
$search_params = array(); |
1214
|
|
|
if (isset($_REQUEST['params'])) |
1215
|
|
|
{ |
1216
|
|
|
$temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+')))); |
1217
|
|
View Code Duplication |
foreach ($temp_params as $i => $data) |
|
|
|
|
1218
|
|
|
{ |
1219
|
|
|
@list ($k, $v) = explode('|\'|', $data); |
|
|
|
|
1220
|
|
|
$search_params[$k] = $v; |
1221
|
|
|
} |
1222
|
|
|
} |
1223
|
|
|
|
1224
|
|
|
$context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0; |
1225
|
|
|
|
1226
|
|
|
// Store whether simple search was used (needed if the user wants to do another query). |
1227
|
|
View Code Duplication |
if (!isset($search_params['advanced'])) |
|
|
|
|
1228
|
|
|
$search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1; |
1229
|
|
|
|
1230
|
|
|
// 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'. |
1231
|
|
View Code Duplication |
if (!empty($search_params['searchtype']) || (!empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2)) |
|
|
|
|
1232
|
|
|
$search_params['searchtype'] = 2; |
1233
|
|
|
|
1234
|
|
|
// Minimum age of messages. Default to zero (don't set param in that case). |
1235
|
|
View Code Duplication |
if (!empty($search_params['minage']) || (!empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0)) |
|
|
|
|
1236
|
|
|
$search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage']; |
1237
|
|
|
|
1238
|
|
|
// Maximum age of messages. Default to infinite (9999 days: param not set). |
1239
|
|
View Code Duplication |
if (!empty($search_params['maxage']) || (!empty($_REQUEST['maxage']) && $_REQUEST['maxage'] != 9999)) |
|
|
|
|
1240
|
|
|
$search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage']; |
1241
|
|
|
|
1242
|
|
|
$search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']); |
1243
|
|
|
$search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']); |
1244
|
|
|
|
1245
|
|
|
// Default the user name to a wildcard matching every user (*). |
1246
|
|
View Code Duplication |
if (!empty($search_params['user_spec']) || (!empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*')) |
|
|
|
|
1247
|
|
|
$search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec']; |
1248
|
|
|
|
1249
|
|
|
// This will be full of all kinds of parameters! |
1250
|
|
|
$searchq_parameters = array(); |
1251
|
|
|
|
1252
|
|
|
// If there's no specific user, then don't mention it in the main query. |
1253
|
|
|
if (empty($search_params['userspec'])) |
1254
|
|
|
$userQuery = ''; |
1255
|
|
|
else |
1256
|
|
|
{ |
1257
|
|
|
$userString = strtr($smcFunc['htmlspecialchars']($search_params['userspec'], ENT_QUOTES), array('"' => '"')); |
1258
|
|
|
$userString = strtr($userString, array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_')); |
1259
|
|
|
|
1260
|
|
|
preg_match_all('~"([^"]+)"~', $userString, $matches); |
1261
|
|
|
$possible_users = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $userString))); |
1262
|
|
|
|
1263
|
|
View Code Duplication |
for ($k = 0, $n = count($possible_users); $k < $n; $k++) |
|
|
|
|
1264
|
|
|
{ |
1265
|
|
|
$possible_users[$k] = trim($possible_users[$k]); |
1266
|
|
|
|
1267
|
|
|
if (strlen($possible_users[$k]) == 0) |
1268
|
|
|
unset($possible_users[$k]); |
1269
|
|
|
} |
1270
|
|
|
|
1271
|
|
|
if (!empty($possible_users)) |
1272
|
|
|
{ |
1273
|
|
|
// We need to bring this into the query and do it nice and cleanly. |
1274
|
|
|
$where_params = array(); |
1275
|
|
|
$where_clause = array(); |
1276
|
|
|
foreach ($possible_users as $k => $v) |
1277
|
|
|
{ |
1278
|
|
|
$where_params['name_' . $k] = $v; |
1279
|
|
|
$where_clause[] = '{raw:real_name} LIKE {string:name_' . $k . '}'; |
1280
|
|
|
if (!isset($where_params['real_name'])) |
1281
|
|
|
$where_params['real_name'] = $smcFunc['db_case_sensitive'] ? 'LOWER(real_name)' : 'real_name'; |
1282
|
|
|
} |
1283
|
|
|
|
1284
|
|
|
// Who matches those criteria? |
1285
|
|
|
// @todo This doesn't support sent item searching. |
1286
|
|
|
$request = $smcFunc['db_query']('', ' |
1287
|
|
|
SELECT id_member |
1288
|
|
|
FROM {db_prefix}members |
1289
|
|
|
WHERE ' . implode(' OR ', $where_clause), |
1290
|
|
|
$where_params |
1291
|
|
|
); |
1292
|
|
|
|
1293
|
|
|
// Simply do nothing if there're too many members matching the criteria. |
1294
|
|
|
if ($smcFunc['db_num_rows']($request) > $maxMembersToSearch) |
1295
|
|
|
$userQuery = ''; |
1296
|
|
|
elseif ($smcFunc['db_num_rows']($request) == 0) |
1297
|
|
|
{ |
1298
|
|
|
$userQuery = 'AND pm.id_member_from = 0 AND ({raw:pm_from_name} LIKE {raw:guest_user_name_implode})'; |
1299
|
|
|
$searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR ' . ($smcFunc['db_case_sensitive'] ? 'LOWER(pm.from_name)' : 'pm.from_name') . ' LIKE \'', $possible_users) . '\''; |
1300
|
|
|
$searchq_parameters['pm_from_name'] = $smcFunc['db_case_sensitive'] ? 'LOWER(pm.from_name)' : 'pm.from_name'; |
1301
|
|
|
} |
1302
|
|
|
else |
1303
|
|
|
{ |
1304
|
|
|
$memberlist = array(); |
1305
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1306
|
|
|
$memberlist[] = $row['id_member']; |
1307
|
|
|
$userQuery = 'AND (pm.id_member_from IN ({array_int:member_list}) OR (pm.id_member_from = 0 AND ({raw:pm_from_name} LIKE {raw:guest_user_name_implode})))'; |
1308
|
|
|
$searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR ' . ($smcFunc['db_case_sensitive'] ? 'LOWER(pm.from_name)' : 'pm.from_name') . ' LIKE \'', $possible_users) . '\''; |
1309
|
|
|
$searchq_parameters['member_list'] = $memberlist; |
1310
|
|
|
$searchq_parameters['pm_from_name'] = $smcFunc['db_case_sensitive'] ? 'LOWER(pm.from_name)' : 'pm.from_name'; |
1311
|
|
|
} |
1312
|
|
|
$smcFunc['db_free_result']($request); |
1313
|
|
|
} |
1314
|
|
|
else |
1315
|
|
|
$userQuery = ''; |
1316
|
|
|
} |
1317
|
|
|
|
1318
|
|
|
// Setup the sorting variables... |
1319
|
|
|
// @todo Add more in here! |
1320
|
|
|
$sort_columns = array( |
1321
|
|
|
'pm.id_pm', |
1322
|
|
|
); |
1323
|
|
View Code Duplication |
if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) |
|
|
|
|
1324
|
|
|
list ($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, ''); |
1325
|
|
|
$search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'pm.id_pm'; |
1326
|
|
|
$search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc'; |
1327
|
|
|
|
1328
|
|
|
// Sort out any labels we may be searching by. |
1329
|
|
|
$labelQuery = ''; |
1330
|
|
|
$labelJoin = ''; |
1331
|
|
|
if ($context['folder'] == 'inbox' && !empty($search_params['advanced']) && $context['currently_using_labels']) |
1332
|
|
|
{ |
1333
|
|
|
// Came here from pagination? Put them back into $_REQUEST for sanitization. |
1334
|
|
|
if (isset($search_params['labels'])) |
1335
|
|
|
$_REQUEST['searchlabel'] = explode(',', $search_params['labels']); |
1336
|
|
|
|
1337
|
|
|
// Assuming we have some labels - make them all integers. |
1338
|
|
|
if (!empty($_REQUEST['searchlabel']) && is_array($_REQUEST['searchlabel'])) |
1339
|
|
|
{ |
1340
|
|
|
foreach ($_REQUEST['searchlabel'] as $key => $id) |
1341
|
|
|
$_REQUEST['searchlabel'][$key] = (int) $id; |
1342
|
|
|
} |
1343
|
|
|
else |
1344
|
|
|
$_REQUEST['searchlabel'] = array(); |
1345
|
|
|
|
1346
|
|
|
// Now that everything is cleaned up a bit, make the labels a param. |
1347
|
|
|
$search_params['labels'] = implode(',', $_REQUEST['searchlabel']); |
1348
|
|
|
|
1349
|
|
|
// No labels selected? That must be an error! |
1350
|
|
|
if (empty($_REQUEST['searchlabel'])) |
1351
|
|
|
$context['search_errors']['no_labels_selected'] = true; |
1352
|
|
|
// Otherwise prepare the query! |
1353
|
|
|
elseif (count($_REQUEST['searchlabel']) != count($context['labels'])) |
1354
|
|
|
{ |
1355
|
|
|
// Special case here... "inbox" isn't a real label anymore... |
1356
|
|
|
if (in_array(-1, $_REQUEST['searchlabel'])) |
1357
|
|
|
{ |
1358
|
|
|
$labelQuery = ' AND pmr.in_inbox = {int:in_inbox}'; |
1359
|
|
|
$searchq_parameters['in_inbox'] = 1; |
1360
|
|
|
|
1361
|
|
|
// Now we get rid of that... |
1362
|
|
|
$temp = array_diff($_REQUEST['searchlabel'], array(-1)); |
1363
|
|
|
$_REQUEST['searchlabel'] = $temp; |
1364
|
|
|
} |
1365
|
|
|
|
1366
|
|
|
// Still have something? |
1367
|
|
|
if (!empty($_REQUEST['searchlabel'])) |
1368
|
|
|
{ |
1369
|
|
|
if ($labelQuery == '') |
1370
|
|
|
{ |
1371
|
|
|
// Not searching the inbox - PM must be labeled |
1372
|
|
|
$labelQuery = ' AND pml.id_label IN ({array_int:labels})'; |
1373
|
|
|
$labelJoin = ' INNER JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_pm = pmr.id_pm)'; |
1374
|
|
|
} |
1375
|
|
|
else |
1376
|
|
|
{ |
1377
|
|
|
// Searching the inbox - PM doesn't have to be labeled |
1378
|
|
|
$labelQuery = ' AND (' . substr($labelQuery, 5) . ' OR pml.id_label IN ({array_int:labels}))'; |
1379
|
|
|
$labelJoin = ' LEFT JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_pm = pmr.id_pm)'; |
1380
|
|
|
} |
1381
|
|
|
|
1382
|
|
|
$searchq_parameters['labels'] = $_REQUEST['searchlabel']; |
1383
|
|
|
} |
1384
|
|
|
} |
1385
|
|
|
} |
1386
|
|
|
|
1387
|
|
|
// What are we actually searching for? |
1388
|
|
|
$search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? $_REQUEST['search'] : ''); |
1389
|
|
|
// If we ain't got nothing - we should error! |
1390
|
|
|
if (!isset($search_params['search']) || $search_params['search'] == '') |
1391
|
|
|
$context['search_errors']['invalid_search_string'] = true; |
1392
|
|
|
|
1393
|
|
|
// Extract phrase parts first (e.g. some words "this is a phrase" some more words.) |
1394
|
|
|
preg_match_all('~(?:^|\s)([-]?)"([^"]+)"(?:$|\s)~' . ($context['utf8'] ? 'u' : ''), $search_params['search'], $matches, PREG_PATTERN_ORDER); |
1395
|
|
|
$searchArray = $matches[2]; |
1396
|
|
|
|
1397
|
|
|
// Remove the phrase parts and extract the words. |
1398
|
|
|
$tempSearch = explode(' ', preg_replace('~(?:^|\s)(?:[-]?)"(?:[^"]+)"(?:$|\s)~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search'])); |
1399
|
|
|
|
1400
|
|
|
// A minus sign in front of a word excludes the word.... so... |
1401
|
|
|
$excludedWords = array(); |
1402
|
|
|
|
1403
|
|
|
// .. first, we check for things like -"some words", but not "-some words". |
1404
|
|
View Code Duplication |
foreach ($matches[1] as $index => $word) |
|
|
|
|
1405
|
|
|
if ($word == '-') |
1406
|
|
|
{ |
1407
|
|
|
$word = $smcFunc['strtolower'](trim($searchArray[$index])); |
1408
|
|
|
if (strlen($word) > 0) |
1409
|
|
|
$excludedWords[] = $word; |
1410
|
|
|
unset($searchArray[$index]); |
1411
|
|
|
} |
1412
|
|
|
|
1413
|
|
|
// Now we look for -test, etc.... normaller. |
1414
|
|
|
foreach ($tempSearch as $index => $word) |
1415
|
|
|
{ |
1416
|
|
|
if (strpos(trim($word), '-') === 0) |
1417
|
|
|
{ |
1418
|
|
|
$word = substr($smcFunc['strtolower']($word), 1); |
1419
|
|
|
if (strlen($word) > 0) |
1420
|
|
|
$excludedWords[] = $word; |
1421
|
|
|
unset($tempSearch[$index]); |
1422
|
|
|
} |
1423
|
|
|
} |
1424
|
|
|
|
1425
|
|
|
$searchArray = array_merge($searchArray, $tempSearch); |
1426
|
|
|
|
1427
|
|
|
// Trim everything and make sure there are no words that are the same. |
1428
|
|
|
foreach ($searchArray as $index => $value) |
1429
|
|
|
{ |
1430
|
|
|
$searchArray[$index] = $smcFunc['strtolower'](trim($value)); |
1431
|
|
|
if ($searchArray[$index] == '') |
1432
|
|
|
unset($searchArray[$index]); |
1433
|
|
|
else |
1434
|
|
|
{ |
1435
|
|
|
// Sort out entities first. |
1436
|
|
|
$searchArray[$index] = $smcFunc['htmlspecialchars']($searchArray[$index]); |
1437
|
|
|
} |
1438
|
|
|
} |
1439
|
|
|
$searchArray = array_unique($searchArray); |
1440
|
|
|
|
1441
|
|
|
// Create an array of replacements for highlighting. |
1442
|
|
|
$context['mark'] = array(); |
1443
|
|
|
foreach ($searchArray as $word) |
1444
|
|
|
$context['mark'][$word] = '<strong class="highlight">' . $word . '</strong>'; |
1445
|
|
|
|
1446
|
|
|
// This contains *everything* |
1447
|
|
|
$searchWords = array_merge($searchArray, $excludedWords); |
1448
|
|
|
|
1449
|
|
|
// Make sure at least one word is being searched for. |
1450
|
|
|
if (empty($searchArray)) |
1451
|
|
|
$context['search_errors']['invalid_search_string'] = true; |
1452
|
|
|
|
1453
|
|
|
// Sort out the search query so the user can edit it - if they want. |
1454
|
|
|
$context['search_params'] = $search_params; |
1455
|
|
View Code Duplication |
if (isset($context['search_params']['search'])) |
|
|
|
|
1456
|
|
|
$context['search_params']['search'] = $smcFunc['htmlspecialchars']($context['search_params']['search']); |
1457
|
|
View Code Duplication |
if (isset($context['search_params']['userspec'])) |
|
|
|
|
1458
|
|
|
$context['search_params']['userspec'] = $smcFunc['htmlspecialchars']($context['search_params']['userspec']); |
1459
|
|
|
|
1460
|
|
|
// Now we have all the parameters, combine them together for pagination and the like... |
1461
|
|
|
$context['params'] = array(); |
1462
|
|
|
foreach ($search_params as $k => $v) |
1463
|
|
|
$context['params'][] = $k . '|\'|' . $v; |
1464
|
|
|
$context['params'] = base64_encode(implode('|"|', $context['params'])); |
1465
|
|
|
|
1466
|
|
|
// Compile the subject query part. |
1467
|
|
|
$andQueryParts = array(); |
1468
|
|
|
|
1469
|
|
|
foreach ($searchWords as $index => $word) |
1470
|
|
|
{ |
1471
|
|
|
if ($word == '') |
1472
|
|
|
continue; |
1473
|
|
|
|
1474
|
|
|
if ($search_params['subject_only']) |
1475
|
|
|
$andQueryParts[] = 'pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '}'; |
1476
|
|
|
else |
1477
|
|
|
$andQueryParts[] = '(pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '} ' . (in_array($word, $excludedWords) ? 'AND pm.body NOT' : 'OR pm.body') . ' LIKE {string:search_' . $index . '})'; |
1478
|
|
|
$searchq_parameters['search_' . $index] = '%' . strtr($word, array('_' => '\\_', '%' => '\\%')) . '%'; |
1479
|
|
|
} |
1480
|
|
|
|
1481
|
|
|
$searchQuery = ' 1=1'; |
1482
|
|
|
if (!empty($andQueryParts)) |
1483
|
|
|
$searchQuery = implode(!empty($search_params['searchtype']) && $search_params['searchtype'] == 2 ? ' OR ' : ' AND ', $andQueryParts); |
1484
|
|
|
|
1485
|
|
|
// Age limits? |
1486
|
|
|
$timeQuery = ''; |
1487
|
|
|
if (!empty($search_params['minage'])) |
1488
|
|
|
$timeQuery .= ' AND pm.msgtime < ' . (time() - $search_params['minage'] * 86400); |
1489
|
|
|
if (!empty($search_params['maxage'])) |
1490
|
|
|
$timeQuery .= ' AND pm.msgtime > ' . (time() - $search_params['maxage'] * 86400); |
1491
|
|
|
|
1492
|
|
|
// If we have errors - return back to the first screen... |
1493
|
|
View Code Duplication |
if (!empty($context['search_errors'])) |
|
|
|
|
1494
|
|
|
{ |
1495
|
|
|
$_REQUEST['params'] = $context['params']; |
1496
|
|
|
return MessageSearch(); |
1497
|
|
|
} |
1498
|
|
|
|
1499
|
|
|
// Get the amount of results. |
1500
|
|
|
$request = $smcFunc['db_query']('', ' |
1501
|
|
|
SELECT COUNT(*) |
1502
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
1503
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) |
1504
|
|
|
' . $labelJoin . ' |
1505
|
|
|
WHERE ' . ($context['folder'] == 'inbox' ? ' |
1506
|
|
|
pmr.id_member = {int:current_member} |
1507
|
|
|
AND pmr.deleted = {int:not_deleted}' : ' |
1508
|
|
|
pm.id_member_from = {int:current_member} |
1509
|
|
|
AND pm.deleted_by_sender = {int:not_deleted}') . ' |
1510
|
|
|
' . $userQuery . $labelQuery . $timeQuery . ' |
1511
|
|
|
AND (' . $searchQuery . ')', |
1512
|
|
|
array_merge($searchq_parameters, array( |
1513
|
|
|
'current_member' => $user_info['id'], |
1514
|
|
|
'not_deleted' => 0, |
1515
|
|
|
)) |
1516
|
|
|
); |
1517
|
|
|
list ($numResults) = $smcFunc['db_fetch_row']($request); |
1518
|
|
|
$smcFunc['db_free_result']($request); |
1519
|
|
|
|
1520
|
|
|
// Get all the matching messages... using standard search only (No caching and the like!) |
1521
|
|
|
// @todo This doesn't support sent item searching yet. |
1522
|
|
|
$request = $smcFunc['db_query']('', ' |
1523
|
|
|
SELECT pm.id_pm, pm.id_pm_head, pm.id_member_from |
1524
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
1525
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) |
1526
|
|
|
' . $labelJoin . ' |
1527
|
|
|
WHERE ' . ($context['folder'] == 'inbox' ? ' |
1528
|
|
|
pmr.id_member = {int:current_member} |
1529
|
|
|
AND pmr.deleted = {int:not_deleted}' : ' |
1530
|
|
|
pm.id_member_from = {int:current_member} |
1531
|
|
|
AND pm.deleted_by_sender = {int:not_deleted}') . ' |
1532
|
|
|
' . $userQuery . $labelQuery . $timeQuery . ' |
1533
|
|
|
AND (' . $searchQuery . ') |
1534
|
|
|
ORDER BY {raw:sort} {raw:sort_dir} |
1535
|
|
|
LIMIT {int:start}, {int:max}', |
1536
|
|
|
array_merge($searchq_parameters, array( |
1537
|
|
|
'current_member' => $user_info['id'], |
1538
|
|
|
'not_deleted' => 0, |
1539
|
|
|
'sort' => $search_params['sort'], |
1540
|
|
|
'sort_dir' => $search_params['sort_dir'], |
1541
|
|
|
'start' => $context['start'], |
1542
|
|
|
'max' => $modSettings['search_results_per_page'], |
1543
|
|
|
)) |
1544
|
|
|
); |
1545
|
|
|
$foundMessages = array(); |
1546
|
|
|
$posters = array(); |
1547
|
|
|
$head_pms = array(); |
1548
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1549
|
|
|
{ |
1550
|
|
|
$foundMessages[] = $row['id_pm']; |
1551
|
|
|
$posters[] = $row['id_member_from']; |
1552
|
|
|
$head_pms[$row['id_pm']] = $row['id_pm_head']; |
1553
|
|
|
} |
1554
|
|
|
$smcFunc['db_free_result']($request); |
1555
|
|
|
|
1556
|
|
|
// Find the real head pms! |
1557
|
|
|
if ($context['display_mode'] == 2 && !empty($head_pms)) |
1558
|
|
|
{ |
1559
|
|
|
$request = $smcFunc['db_query']('', ' |
1560
|
|
|
SELECT MAX(pm.id_pm) AS id_pm, pm.id_pm_head |
1561
|
|
|
FROM {db_prefix}personal_messages AS pm |
1562
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm) |
1563
|
|
|
WHERE pm.id_pm_head IN ({array_int:head_pms}) |
1564
|
|
|
AND pmr.id_member = {int:current_member} |
1565
|
|
|
AND pmr.deleted = {int:not_deleted} |
1566
|
|
|
GROUP BY pm.id_pm_head |
1567
|
|
|
LIMIT {int:limit}', |
1568
|
|
|
array( |
1569
|
|
|
'head_pms' => array_unique($head_pms), |
1570
|
|
|
'current_member' => $user_info['id'], |
1571
|
|
|
'not_deleted' => 0, |
1572
|
|
|
'limit' => count($head_pms), |
1573
|
|
|
) |
1574
|
|
|
); |
1575
|
|
|
$real_pm_ids = array(); |
1576
|
|
View Code Duplication |
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
|
|
|
1577
|
|
|
$real_pm_ids[$row['id_pm_head']] = $row['id_pm']; |
1578
|
|
|
$smcFunc['db_free_result']($request); |
1579
|
|
|
} |
1580
|
|
|
|
1581
|
|
|
// Load the users... |
1582
|
|
|
loadMemberData($posters); |
1583
|
|
|
|
1584
|
|
|
// Sort out the page index. |
1585
|
|
|
$context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=search2;params=' . $context['params'], $_GET['start'], $numResults, $modSettings['search_results_per_page'], false); |
1586
|
|
|
|
1587
|
|
|
$context['message_labels'] = array(); |
1588
|
|
|
$context['message_replied'] = array(); |
1589
|
|
|
$context['personal_messages'] = array(); |
1590
|
|
|
|
1591
|
|
|
if (!empty($foundMessages)) |
1592
|
|
|
{ |
1593
|
|
|
// Now get recipients (but don't include bcc-recipients for your inbox, you're not supposed to know :P!) |
1594
|
|
|
$request = $smcFunc['db_query']('', ' |
1595
|
|
|
SELECT |
1596
|
|
|
pmr.id_pm, mem_to.id_member AS id_member_to, mem_to.real_name AS to_name, |
1597
|
|
|
pmr.bcc, pmr.in_inbox, pmr.is_read |
1598
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
1599
|
|
|
LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member) |
1600
|
|
|
WHERE pmr.id_pm IN ({array_int:message_list})', |
1601
|
|
|
array( |
1602
|
|
|
'message_list' => $foundMessages, |
1603
|
|
|
) |
1604
|
|
|
); |
1605
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1606
|
|
|
{ |
1607
|
|
|
if ($context['folder'] == 'sent' || empty($row['bcc'])) |
1608
|
|
|
$recipients[$row['id_pm']][empty($row['bcc']) ? 'to' : 'bcc'][] = empty($row['id_member_to']) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . '">' . $row['to_name'] . '</a>'; |
|
|
|
|
1609
|
|
|
|
1610
|
|
|
if ($row['id_member_to'] == $user_info['id'] && $context['folder'] != 'sent') |
1611
|
|
|
{ |
1612
|
|
|
$context['message_replied'][$row['id_pm']] = $row['is_read'] & 2; |
1613
|
|
|
|
1614
|
|
|
$row['labels'] = ''; |
1615
|
|
|
|
1616
|
|
|
// Get the labels for this PM |
1617
|
|
|
$request2 = $smcFunc['db_query']('', ' |
1618
|
|
|
SELECT id_label |
1619
|
|
|
FROM {db_prefix}pm_labeled_messages |
1620
|
|
|
WHERE id_pm = {int:current_pm}', |
1621
|
|
|
array( |
1622
|
|
|
'current_pm' => $row['id_pm'], |
1623
|
|
|
) |
1624
|
|
|
); |
1625
|
|
|
|
1626
|
|
|
while ($row2 = $smcFunc['db_fetch_assoc']($request2)) |
1627
|
|
|
{ |
1628
|
|
|
$l_id = $row2['id_label']; |
1629
|
|
View Code Duplication |
if (isset($context['labels'][$l_id])) |
|
|
|
|
1630
|
|
|
$context['message_labels'][$row['id_pm']][$l_id] = array('id' => $l_id, 'name' => $context['labels'][$l_id]['name']); |
1631
|
|
|
|
1632
|
|
|
// Here we find the first label on a message - for linking to posts in results |
1633
|
|
|
if (!isset($context['first_label'][$row['id_pm']]) && $row['in_inbox'] != 1) |
1634
|
|
|
$context['first_label'][$row['id_pm']] = $l_id; |
1635
|
|
|
} |
1636
|
|
|
|
1637
|
|
|
$smcFunc['db_free_result']($request2); |
1638
|
|
|
|
1639
|
|
|
// Is this in the inbox as well? |
1640
|
|
View Code Duplication |
if ($row['in_inbox'] == 1) |
|
|
|
|
1641
|
|
|
{ |
1642
|
|
|
$context['message_labels'][$row['id_pm']][-1] = array('id' => -1, 'name' => $context['labels'][-1]['name']); |
1643
|
|
|
} |
1644
|
|
|
|
1645
|
|
|
$row['labels'] = $row['labels'] == '' ? array() : explode(',', $row['labels']); |
1646
|
|
|
} |
1647
|
|
|
} |
1648
|
|
|
|
1649
|
|
|
// Prepare the query for the callback! |
1650
|
|
|
$request = $smcFunc['db_query']('', ' |
1651
|
|
|
SELECT pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name |
1652
|
|
|
FROM {db_prefix}personal_messages AS pm |
1653
|
|
|
WHERE pm.id_pm IN ({array_int:message_list}) |
1654
|
|
|
ORDER BY {raw:sort} {raw:sort_dir} |
1655
|
|
|
LIMIT {int:limit}', |
1656
|
|
|
array( |
1657
|
|
|
'message_list' => $foundMessages, |
1658
|
|
|
'limit' => count($foundMessages), |
1659
|
|
|
'sort' => $search_params['sort'], |
1660
|
|
|
'sort_dir' => $search_params['sort_dir'], |
1661
|
|
|
) |
1662
|
|
|
); |
1663
|
|
|
$counter = 0; |
1664
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1665
|
|
|
{ |
1666
|
|
|
// If there's no message subject, use the default. |
1667
|
|
|
$row['subject'] = $row['subject'] == '' ? $txt['no_subject'] : $row['subject']; |
1668
|
|
|
|
1669
|
|
|
// Load this posters context info, if it ain't there then fill in the essentials... |
1670
|
|
|
if (!loadMemberContext($row['id_member_from'], true)) |
1671
|
|
|
{ |
1672
|
|
|
$memberContext[$row['id_member_from']]['name'] = $row['from_name']; |
1673
|
|
|
$memberContext[$row['id_member_from']]['id'] = 0; |
1674
|
|
|
$memberContext[$row['id_member_from']]['group'] = $txt['guest_title']; |
1675
|
|
|
$memberContext[$row['id_member_from']]['link'] = $row['from_name']; |
1676
|
|
|
$memberContext[$row['id_member_from']]['email'] = ''; |
1677
|
|
|
$memberContext[$row['id_member_from']]['is_guest'] = true; |
1678
|
|
|
} |
1679
|
|
|
|
1680
|
|
|
// Censor anything we don't want to see... |
1681
|
|
|
censorText($row['body']); |
1682
|
|
|
censorText($row['subject']); |
1683
|
|
|
|
1684
|
|
|
// Parse out any BBC... |
1685
|
|
|
$row['body'] = parse_bbc($row['body'], true, 'pm' . $row['id_pm']); |
1686
|
|
|
|
1687
|
|
|
$href = $scripturl . '?action=pm;f=' . $context['folder'] . (isset($context['first_label'][$row['id_pm']]) ? ';l=' . $context['first_label'][$row['id_pm']] : '') . ';pmid=' . ($context['display_mode'] == 2 && isset($real_pm_ids[$head_pms[$row['id_pm']]]) ? $real_pm_ids[$head_pms[$row['id_pm']]] : $row['id_pm']) . '#msg' . $row['id_pm']; |
1688
|
|
|
$context['personal_messages'][] = array( |
1689
|
|
|
'id' => $row['id_pm'], |
1690
|
|
|
'member' => &$memberContext[$row['id_member_from']], |
1691
|
|
|
'subject' => $row['subject'], |
1692
|
|
|
'body' => $row['body'], |
1693
|
|
|
'time' => timeformat($row['msgtime']), |
1694
|
|
|
'recipients' => &$recipients[$row['id_pm']], |
|
|
|
|
1695
|
|
|
'labels' => &$context['message_labels'][$row['id_pm']], |
1696
|
|
|
'fully_labeled' => count($context['message_labels'][$row['id_pm']]) == count($context['labels']), |
1697
|
|
|
'is_replied_to' => &$context['message_replied'][$row['id_pm']], |
1698
|
|
|
'href' => $href, |
1699
|
|
|
'link' => '<a href="' . $href . '">' . $row['subject'] . '</a>', |
1700
|
|
|
'counter' => ++$counter, |
1701
|
|
|
); |
1702
|
|
|
} |
1703
|
|
|
$smcFunc['db_free_result']($request); |
1704
|
|
|
} |
1705
|
|
|
|
1706
|
|
|
call_integration_hook('integrate_search_pm_context'); |
1707
|
|
|
|
1708
|
|
|
// Finish off the context. |
1709
|
|
|
$context['page_title'] = $txt['pm_search_title']; |
1710
|
|
|
$context['sub_template'] = 'search_results'; |
1711
|
|
|
$context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'search'; |
1712
|
|
|
$context['linktree'][] = array( |
1713
|
|
|
'url' => $scripturl . '?action=pm;sa=search', |
1714
|
|
|
'name' => $txt['pm_search_bar_title'], |
1715
|
|
|
); |
1716
|
|
|
} |
1717
|
|
|
|
1718
|
|
|
/** |
1719
|
|
|
* Send a new message? |
1720
|
|
|
*/ |
1721
|
|
|
function MessagePost() |
1722
|
|
|
{ |
1723
|
|
|
global $txt, $sourcedir, $scripturl, $modSettings; |
1724
|
|
|
global $context, $smcFunc, $language, $user_info; |
1725
|
|
|
|
1726
|
|
|
isAllowedTo('pm_send'); |
1727
|
|
|
|
1728
|
|
|
loadLanguage('PersonalMessage'); |
1729
|
|
|
// Just in case it was loaded from somewhere else. |
1730
|
|
|
loadTemplate('PersonalMessage'); |
1731
|
|
|
loadJavaScriptFile('PersonalMessage.js', array('defer' => false), 'smf_pms'); |
1732
|
|
|
loadJavaScriptFile('suggest.js', array('defer' => false), 'smf_suggest'); |
1733
|
|
|
$context['sub_template'] = 'send'; |
1734
|
|
|
|
1735
|
|
|
// Extract out the spam settings - cause it's neat. |
1736
|
|
|
list ($modSettings['max_pm_recipients'], $modSettings['pm_posts_verification'], $modSettings['pm_posts_per_hour']) = explode(',', $modSettings['pm_spam_settings']); |
1737
|
|
|
|
1738
|
|
|
// Set the title... |
1739
|
|
|
$context['page_title'] = $txt['send_message']; |
1740
|
|
|
|
1741
|
|
|
$context['reply'] = isset($_REQUEST['pmsg']) || isset($_REQUEST['quote']); |
1742
|
|
|
|
1743
|
|
|
// Check whether we've gone over the limit of messages we can send per hour. |
1744
|
|
|
if (!empty($modSettings['pm_posts_per_hour']) && !allowedTo(array('admin_forum', 'moderate_forum', 'send_mail')) && $user_info['mod_cache']['bq'] == '0=1' && $user_info['mod_cache']['gq'] == '0=1') |
1745
|
|
|
{ |
1746
|
|
|
// How many messages have they sent this last hour? |
1747
|
|
|
$request = $smcFunc['db_query']('', ' |
1748
|
|
|
SELECT COUNT(pr.id_pm) AS post_count |
1749
|
|
|
FROM {db_prefix}personal_messages AS pm |
1750
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pr ON (pr.id_pm = pm.id_pm) |
1751
|
|
|
WHERE pm.id_member_from = {int:current_member} |
1752
|
|
|
AND pm.msgtime > {int:msgtime}', |
1753
|
|
|
array( |
1754
|
|
|
'current_member' => $user_info['id'], |
1755
|
|
|
'msgtime' => time() - 3600, |
1756
|
|
|
) |
1757
|
|
|
); |
1758
|
|
|
list ($postCount) = $smcFunc['db_fetch_row']($request); |
1759
|
|
|
$smcFunc['db_free_result']($request); |
1760
|
|
|
|
1761
|
|
|
if (!empty($postCount) && $postCount >= $modSettings['pm_posts_per_hour']) |
1762
|
|
|
fatal_lang_error('pm_too_many_per_hour', true, array($modSettings['pm_posts_per_hour'])); |
|
|
|
|
1763
|
|
|
} |
1764
|
|
|
|
1765
|
|
|
// Quoting/Replying to a message? |
1766
|
|
|
if (!empty($_REQUEST['pmsg'])) |
1767
|
|
|
{ |
1768
|
|
|
$pmsg = (int) $_REQUEST['pmsg']; |
1769
|
|
|
|
1770
|
|
|
// Make sure this is yours. |
1771
|
|
|
if (!isAccessiblePM($pmsg)) |
1772
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
1773
|
|
|
|
1774
|
|
|
// Work out whether this is one you've received? |
1775
|
|
|
$request = $smcFunc['db_query']('', ' |
1776
|
|
|
SELECT |
1777
|
|
|
id_pm |
1778
|
|
|
FROM {db_prefix}pm_recipients |
1779
|
|
|
WHERE id_pm = {int:id_pm} |
1780
|
|
|
AND id_member = {int:current_member} |
1781
|
|
|
LIMIT 1', |
1782
|
|
|
array( |
1783
|
|
|
'current_member' => $user_info['id'], |
1784
|
|
|
'id_pm' => $pmsg, |
1785
|
|
|
) |
1786
|
|
|
); |
1787
|
|
|
$isReceived = $smcFunc['db_num_rows']($request) != 0; |
1788
|
|
|
$smcFunc['db_free_result']($request); |
1789
|
|
|
|
1790
|
|
|
// Get the quoted message (and make sure you're allowed to see this quote!). |
1791
|
|
|
$request = $smcFunc['db_query']('', ' |
1792
|
|
|
SELECT |
1793
|
|
|
pm.id_pm, CASE WHEN pm.id_pm_head = {int:id_pm_head_empty} THEN pm.id_pm ELSE pm.id_pm_head END AS pm_head, |
1794
|
|
|
pm.body, pm.subject, pm.msgtime, mem.member_name, COALESCE(mem.id_member, 0) AS id_member, |
1795
|
|
|
COALESCE(mem.real_name, pm.from_name) AS real_name |
1796
|
|
|
FROM {db_prefix}personal_messages AS pm' . (!$isReceived ? '' : ' |
1797
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = {int:id_pm})') . ' |
1798
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) |
1799
|
|
|
WHERE pm.id_pm = {int:id_pm}' . (!$isReceived ? ' |
1800
|
|
|
AND pm.id_member_from = {int:current_member}' : ' |
1801
|
|
|
AND pmr.id_member = {int:current_member}') . ' |
1802
|
|
|
LIMIT 1', |
1803
|
|
|
array( |
1804
|
|
|
'current_member' => $user_info['id'], |
1805
|
|
|
'id_pm_head_empty' => 0, |
1806
|
|
|
'id_pm' => $pmsg, |
1807
|
|
|
) |
1808
|
|
|
); |
1809
|
|
|
if ($smcFunc['db_num_rows']($request) == 0) |
1810
|
|
|
fatal_lang_error('pm_not_yours', false); |
|
|
|
|
1811
|
|
|
$row_quoted = $smcFunc['db_fetch_assoc']($request); |
1812
|
|
|
$smcFunc['db_free_result']($request); |
1813
|
|
|
|
1814
|
|
|
// Censor the message. |
1815
|
|
|
censorText($row_quoted['subject']); |
1816
|
|
|
censorText($row_quoted['body']); |
1817
|
|
|
|
1818
|
|
|
// Add 'Re: ' to it.... |
1819
|
|
View Code Duplication |
if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) |
|
|
|
|
1820
|
|
|
{ |
1821
|
|
|
if ($language === $user_info['language']) |
1822
|
|
|
$context['response_prefix'] = $txt['response_prefix']; |
1823
|
|
|
else |
1824
|
|
|
{ |
1825
|
|
|
loadLanguage('index', $language, false); |
1826
|
|
|
$context['response_prefix'] = $txt['response_prefix']; |
1827
|
|
|
loadLanguage('index'); |
1828
|
|
|
} |
1829
|
|
|
cache_put_data('response_prefix', $context['response_prefix'], 600); |
1830
|
|
|
} |
1831
|
|
|
$form_subject = $row_quoted['subject']; |
1832
|
|
View Code Duplication |
if ($context['reply'] && trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) |
|
|
|
|
1833
|
|
|
$form_subject = $context['response_prefix'] . $form_subject; |
1834
|
|
|
|
1835
|
|
|
if (isset($_REQUEST['quote'])) |
1836
|
|
|
{ |
1837
|
|
|
// Remove any nested quotes and <br>... |
1838
|
|
|
$form_message = preg_replace('~<br ?/?' . '>~i', "\n", $row_quoted['body']); |
1839
|
|
View Code Duplication |
if (!empty($modSettings['removeNestedQuotes'])) |
|
|
|
|
1840
|
|
|
$form_message = preg_replace(array('~\n?\[quote.*?\].+?\[/quote\]\n?~is', '~^\n~', '~\[/quote\]~'), '', $form_message); |
1841
|
|
|
if (empty($row_quoted['id_member'])) |
1842
|
|
|
$form_message = '[quote author="' . $row_quoted['real_name'] . '"]' . "\n" . $form_message . "\n" . '[/quote]'; |
1843
|
|
|
else |
1844
|
|
|
$form_message = '[quote author=' . $row_quoted['real_name'] . ' link=action=profile;u=' . $row_quoted['id_member'] . ' date=' . $row_quoted['msgtime'] . ']' . "\n" . $form_message . "\n" . '[/quote]'; |
1845
|
|
|
} |
1846
|
|
|
else |
1847
|
|
|
$form_message = ''; |
1848
|
|
|
|
1849
|
|
|
// Do the BBC thang on the message. |
1850
|
|
|
$row_quoted['body'] = parse_bbc($row_quoted['body'], true, 'pm' . $row_quoted['id_pm']); |
1851
|
|
|
|
1852
|
|
|
// Set up the quoted message array. |
1853
|
|
|
$context['quoted_message'] = array( |
1854
|
|
|
'id' => $row_quoted['id_pm'], |
1855
|
|
|
'pm_head' => $row_quoted['pm_head'], |
1856
|
|
|
'member' => array( |
1857
|
|
|
'name' => $row_quoted['real_name'], |
1858
|
|
|
'username' => $row_quoted['member_name'], |
1859
|
|
|
'id' => $row_quoted['id_member'], |
1860
|
|
|
'href' => !empty($row_quoted['id_member']) ? $scripturl . '?action=profile;u=' . $row_quoted['id_member'] : '', |
1861
|
|
|
'link' => !empty($row_quoted['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_quoted['id_member'] . '">' . $row_quoted['real_name'] . '</a>' : $row_quoted['real_name'], |
1862
|
|
|
), |
1863
|
|
|
'subject' => $row_quoted['subject'], |
1864
|
|
|
'time' => timeformat($row_quoted['msgtime']), |
1865
|
|
|
'timestamp' => forum_time(true, $row_quoted['msgtime']), |
1866
|
|
|
'body' => $row_quoted['body'] |
1867
|
|
|
); |
1868
|
|
|
} |
1869
|
|
|
else |
1870
|
|
|
{ |
1871
|
|
|
$context['quoted_message'] = false; |
1872
|
|
|
$form_subject = ''; |
1873
|
|
|
$form_message = ''; |
1874
|
|
|
} |
1875
|
|
|
|
1876
|
|
|
$context['recipients'] = array( |
1877
|
|
|
'to' => array(), |
1878
|
|
|
'bcc' => array(), |
1879
|
|
|
); |
1880
|
|
|
|
1881
|
|
|
// Sending by ID? Replying to all? Fetch the real_name(s). |
1882
|
|
|
if (isset($_REQUEST['u'])) |
1883
|
|
|
{ |
1884
|
|
|
// If the user is replying to all, get all the other members this was sent to.. |
1885
|
|
|
if ($_REQUEST['u'] == 'all' && isset($row_quoted)) |
1886
|
|
|
{ |
1887
|
|
|
// Firstly, to reply to all we clearly already have $row_quoted - so have the original member from. |
1888
|
|
|
if ($row_quoted['id_member'] != $user_info['id']) |
1889
|
|
|
$context['recipients']['to'][] = array( |
1890
|
|
|
'id' => $row_quoted['id_member'], |
1891
|
|
|
'name' => $smcFunc['htmlspecialchars']($row_quoted['real_name']), |
1892
|
|
|
); |
1893
|
|
|
|
1894
|
|
|
// Now to get the others. |
1895
|
|
|
$request = $smcFunc['db_query']('', ' |
1896
|
|
|
SELECT mem.id_member, mem.real_name |
1897
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
1898
|
|
|
INNER JOIN {db_prefix}members AS mem ON (mem.id_member = pmr.id_member) |
1899
|
|
|
WHERE pmr.id_pm = {int:id_pm} |
1900
|
|
|
AND pmr.id_member != {int:current_member} |
1901
|
|
|
AND pmr.bcc = {int:not_bcc}', |
1902
|
|
|
array( |
1903
|
|
|
'current_member' => $user_info['id'], |
1904
|
|
|
'id_pm' => $pmsg, |
|
|
|
|
1905
|
|
|
'not_bcc' => 0, |
1906
|
|
|
) |
1907
|
|
|
); |
1908
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1909
|
|
|
$context['recipients']['to'][] = array( |
1910
|
|
|
'id' => $row['id_member'], |
1911
|
|
|
'name' => $row['real_name'], |
1912
|
|
|
); |
1913
|
|
|
$smcFunc['db_free_result']($request); |
1914
|
|
|
} |
1915
|
|
|
else |
1916
|
|
|
{ |
1917
|
|
|
$_REQUEST['u'] = explode(',', $_REQUEST['u']); |
1918
|
|
|
foreach ($_REQUEST['u'] as $key => $uID) |
1919
|
|
|
$_REQUEST['u'][$key] = (int) $uID; |
1920
|
|
|
|
1921
|
|
|
$_REQUEST['u'] = array_unique($_REQUEST['u']); |
1922
|
|
|
|
1923
|
|
|
$request = $smcFunc['db_query']('', ' |
1924
|
|
|
SELECT id_member, real_name |
1925
|
|
|
FROM {db_prefix}members |
1926
|
|
|
WHERE id_member IN ({array_int:member_list}) |
1927
|
|
|
LIMIT {int:limit}', |
1928
|
|
|
array( |
1929
|
|
|
'member_list' => $_REQUEST['u'], |
1930
|
|
|
'limit' => count($_REQUEST['u']), |
1931
|
|
|
) |
1932
|
|
|
); |
1933
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
1934
|
|
|
$context['recipients']['to'][] = array( |
1935
|
|
|
'id' => $row['id_member'], |
1936
|
|
|
'name' => $row['real_name'], |
1937
|
|
|
); |
1938
|
|
|
$smcFunc['db_free_result']($request); |
1939
|
|
|
} |
1940
|
|
|
|
1941
|
|
|
// Get a literal name list in case the user has JavaScript disabled. |
1942
|
|
|
$names = array(); |
1943
|
|
|
foreach ($context['recipients']['to'] as $to) |
1944
|
|
|
$names[] = $to['name']; |
1945
|
|
|
$context['to_value'] = empty($names) ? '' : '"' . implode('", "', $names) . '"'; |
1946
|
|
|
} |
1947
|
|
|
else |
1948
|
|
|
$context['to_value'] = ''; |
1949
|
|
|
|
1950
|
|
|
// Set the defaults... |
1951
|
|
|
$context['subject'] = $form_subject; |
1952
|
|
|
$context['message'] = str_replace(array('"', '<', '>', ' '), array('"', '<', '>', ' '), $form_message); |
1953
|
|
|
$context['post_error'] = array(); |
1954
|
|
|
|
1955
|
|
|
// And build the link tree. |
1956
|
|
|
$context['linktree'][] = array( |
1957
|
|
|
'url' => $scripturl . '?action=pm;sa=send', |
1958
|
|
|
'name' => $txt['new_message'] |
1959
|
|
|
); |
1960
|
|
|
|
1961
|
|
|
$modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']); |
1962
|
|
|
|
1963
|
|
|
// Generate a list of drafts that they can load in to the editor |
1964
|
|
|
if (!empty($context['drafts_pm_save'])) |
1965
|
|
|
{ |
1966
|
|
|
require_once($sourcedir . '/Drafts.php'); |
1967
|
|
|
$pm_seed = isset($_REQUEST['pmsg']) ? $_REQUEST['pmsg'] : (isset($_REQUEST['quote']) ? $_REQUEST['quote'] : 0); |
1968
|
|
|
ShowDrafts($user_info['id'], $pm_seed, 1); |
|
|
|
|
1969
|
|
|
} |
1970
|
|
|
|
1971
|
|
|
// Needed for the WYSIWYG editor. |
1972
|
|
|
require_once($sourcedir . '/Subs-Editor.php'); |
1973
|
|
|
|
1974
|
|
|
// Now create the editor. |
1975
|
|
|
$editorOptions = array( |
1976
|
|
|
'id' => 'message', |
1977
|
|
|
'value' => $context['message'], |
1978
|
|
|
'height' => '250px', |
1979
|
|
|
'width' => '100%', |
1980
|
|
|
'labels' => array( |
1981
|
|
|
'post_button' => $txt['send_message'], |
1982
|
|
|
), |
1983
|
|
|
'preview_type' => 2, |
1984
|
|
|
'required' => true, |
1985
|
|
|
); |
1986
|
|
|
create_control_richedit($editorOptions); |
1987
|
|
|
|
1988
|
|
|
// Store the ID for old compatibility. |
1989
|
|
|
$context['post_box_name'] = $editorOptions['id']; |
1990
|
|
|
|
1991
|
|
|
$context['bcc_value'] = ''; |
1992
|
|
|
|
1993
|
|
|
$context['require_verification'] = !$user_info['is_admin'] && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification']; |
1994
|
|
View Code Duplication |
if ($context['require_verification']) |
|
|
|
|
1995
|
|
|
{ |
1996
|
|
|
$verificationOptions = array( |
1997
|
|
|
'id' => 'pm', |
1998
|
|
|
); |
1999
|
|
|
$context['require_verification'] = create_control_verification($verificationOptions); |
2000
|
|
|
$context['visual_verification_id'] = $verificationOptions['id']; |
2001
|
|
|
} |
2002
|
|
|
|
2003
|
|
|
call_integration_hook('integrate_pm_post'); |
2004
|
|
|
|
2005
|
|
|
// Register this form and get a sequence number in $context. |
2006
|
|
|
checkSubmitOnce('register'); |
2007
|
|
|
} |
2008
|
|
|
|
2009
|
|
|
/** |
2010
|
|
|
* This function allows the user to view their PM drafts |
2011
|
|
|
*/ |
2012
|
|
|
function MessageDrafts() |
2013
|
|
|
{ |
2014
|
|
|
global $sourcedir, $user_info; |
2015
|
|
|
|
2016
|
|
|
// validate with loadMemberData() |
2017
|
|
|
$memberResult = loadMemberData($user_info['id'], false); |
2018
|
|
|
if (!$memberResult) |
|
|
|
|
2019
|
|
|
fatal_lang_error('not_a_user', false); |
|
|
|
|
2020
|
|
|
list ($memID) = $memberResult; |
2021
|
|
|
|
2022
|
|
|
// drafts is where the functions reside |
2023
|
|
|
require_once($sourcedir . '/Drafts.php'); |
2024
|
|
|
showPMDrafts($memID); |
2025
|
|
|
} |
2026
|
|
|
|
2027
|
|
|
/** |
2028
|
|
|
* An error in the message... |
2029
|
|
|
* |
2030
|
|
|
* @param array $error_types An array of strings indicating which type of errors occurred |
2031
|
|
|
* @param array $named_recipients |
2032
|
|
|
* @param $recipient_ids |
2033
|
|
|
*/ |
2034
|
|
|
function messagePostError($error_types, $named_recipients, $recipient_ids = array()) |
2035
|
|
|
{ |
2036
|
|
|
global $txt, $context, $scripturl, $modSettings; |
2037
|
|
|
global $smcFunc, $user_info, $sourcedir; |
2038
|
|
|
|
2039
|
|
|
if (!isset($_REQUEST['xml'])) |
2040
|
|
|
{ |
2041
|
|
|
$context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'send'; |
2042
|
|
|
$context['sub_template'] = 'send'; |
2043
|
|
|
loadJavaScriptFile('PersonalMessage.js', array('defer' => false), 'smf_pms'); |
2044
|
|
|
loadJavaScriptFile('suggest.js', array('defer' => false), 'smf_suggest'); |
2045
|
|
|
} |
2046
|
|
|
else |
2047
|
|
|
$context['sub_template'] = 'pm'; |
2048
|
|
|
|
2049
|
|
|
$context['page_title'] = $txt['send_message']; |
2050
|
|
|
|
2051
|
|
|
// Got some known members? |
2052
|
|
|
$context['recipients'] = array( |
2053
|
|
|
'to' => array(), |
2054
|
|
|
'bcc' => array(), |
2055
|
|
|
); |
2056
|
|
|
if (!empty($recipient_ids['to']) || !empty($recipient_ids['bcc'])) |
2057
|
|
|
{ |
2058
|
|
|
$allRecipients = array_merge($recipient_ids['to'], $recipient_ids['bcc']); |
2059
|
|
|
|
2060
|
|
|
$request = $smcFunc['db_query']('', ' |
2061
|
|
|
SELECT id_member, real_name |
2062
|
|
|
FROM {db_prefix}members |
2063
|
|
|
WHERE id_member IN ({array_int:member_list})', |
2064
|
|
|
array( |
2065
|
|
|
'member_list' => $allRecipients, |
2066
|
|
|
) |
2067
|
|
|
); |
2068
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
2069
|
|
|
{ |
2070
|
|
|
$recipientType = in_array($row['id_member'], $recipient_ids['bcc']) ? 'bcc' : 'to'; |
2071
|
|
|
$context['recipients'][$recipientType][] = array( |
2072
|
|
|
'id' => $row['id_member'], |
2073
|
|
|
'name' => $row['real_name'], |
2074
|
|
|
); |
2075
|
|
|
} |
2076
|
|
|
$smcFunc['db_free_result']($request); |
2077
|
|
|
} |
2078
|
|
|
|
2079
|
|
|
// Set everything up like before.... |
2080
|
|
|
$context['subject'] = isset($_REQUEST['subject']) ? $smcFunc['htmlspecialchars']($_REQUEST['subject']) : ''; |
2081
|
|
|
$context['message'] = isset($_REQUEST['message']) ? str_replace(array(' '), array(' '), $smcFunc['htmlspecialchars']($_REQUEST['message'])) : ''; |
2082
|
|
|
$context['reply'] = !empty($_REQUEST['replied_to']); |
2083
|
|
|
|
2084
|
|
|
if ($context['reply']) |
2085
|
|
|
{ |
2086
|
|
|
$_REQUEST['replied_to'] = (int) $_REQUEST['replied_to']; |
2087
|
|
|
|
2088
|
|
|
$request = $smcFunc['db_query']('', ' |
2089
|
|
|
SELECT |
2090
|
|
|
pm.id_pm, CASE WHEN pm.id_pm_head = {int:no_id_pm_head} THEN pm.id_pm ELSE pm.id_pm_head END AS pm_head, |
2091
|
|
|
pm.body, pm.subject, pm.msgtime, mem.member_name, COALESCE(mem.id_member, 0) AS id_member, |
2092
|
|
|
COALESCE(mem.real_name, pm.from_name) AS real_name |
2093
|
|
|
FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? '' : ' |
2094
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = {int:replied_to})') . ' |
2095
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) |
2096
|
|
|
WHERE pm.id_pm = {int:replied_to}' . ($context['folder'] == 'sent' ? ' |
2097
|
|
|
AND pm.id_member_from = {int:current_member}' : ' |
2098
|
|
|
AND pmr.id_member = {int:current_member}') . ' |
2099
|
|
|
LIMIT 1', |
2100
|
|
|
array( |
2101
|
|
|
'current_member' => $user_info['id'], |
2102
|
|
|
'no_id_pm_head' => 0, |
2103
|
|
|
'replied_to' => $_REQUEST['replied_to'], |
2104
|
|
|
) |
2105
|
|
|
); |
2106
|
|
|
if ($smcFunc['db_num_rows']($request) == 0) |
2107
|
|
|
{ |
2108
|
|
|
if (!isset($_REQUEST['xml'])) |
2109
|
|
|
fatal_lang_error('pm_not_yours', false); |
|
|
|
|
2110
|
|
|
else |
2111
|
|
|
$error_types[] = 'pm_not_yours'; |
2112
|
|
|
} |
2113
|
|
|
$row_quoted = $smcFunc['db_fetch_assoc']($request); |
2114
|
|
|
$smcFunc['db_free_result']($request); |
2115
|
|
|
|
2116
|
|
|
censorText($row_quoted['subject']); |
2117
|
|
|
censorText($row_quoted['body']); |
2118
|
|
|
|
2119
|
|
|
$context['quoted_message'] = array( |
2120
|
|
|
'id' => $row_quoted['id_pm'], |
2121
|
|
|
'pm_head' => $row_quoted['pm_head'], |
2122
|
|
|
'member' => array( |
2123
|
|
|
'name' => $row_quoted['real_name'], |
2124
|
|
|
'username' => $row_quoted['member_name'], |
2125
|
|
|
'id' => $row_quoted['id_member'], |
2126
|
|
|
'href' => !empty($row_quoted['id_member']) ? $scripturl . '?action=profile;u=' . $row_quoted['id_member'] : '', |
2127
|
|
|
'link' => !empty($row_quoted['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_quoted['id_member'] . '">' . $row_quoted['real_name'] . '</a>' : $row_quoted['real_name'], |
2128
|
|
|
), |
2129
|
|
|
'subject' => $row_quoted['subject'], |
2130
|
|
|
'time' => timeformat($row_quoted['msgtime']), |
2131
|
|
|
'timestamp' => forum_time(true, $row_quoted['msgtime']), |
2132
|
|
|
'body' => parse_bbc($row_quoted['body'], true, 'pm' . $row_quoted['id_pm']), |
2133
|
|
|
); |
2134
|
|
|
} |
2135
|
|
|
|
2136
|
|
|
// Build the link tree.... |
2137
|
|
|
$context['linktree'][] = array( |
2138
|
|
|
'url' => $scripturl . '?action=pm;sa=send', |
2139
|
|
|
'name' => $txt['new_message'] |
2140
|
|
|
); |
2141
|
|
|
|
2142
|
|
|
// Set each of the errors for the template. |
2143
|
|
|
loadLanguage('Errors'); |
2144
|
|
|
|
2145
|
|
|
$context['error_type'] = 'minor'; |
2146
|
|
|
|
2147
|
|
|
$context['post_error'] = array( |
2148
|
|
|
'messages' => array(), |
2149
|
|
|
// @todo error handling: maybe fatal errors can be error_type => serious |
2150
|
|
|
'error_type' => '', |
2151
|
|
|
); |
2152
|
|
|
|
2153
|
|
|
foreach ($error_types as $error_type) |
2154
|
|
|
{ |
2155
|
|
|
$context['post_error'][$error_type] = true; |
2156
|
|
|
if (isset($txt['error_' . $error_type])) |
2157
|
|
|
{ |
2158
|
|
|
if ($error_type == 'long_message') |
2159
|
|
|
$txt['error_' . $error_type] = sprintf($txt['error_' . $error_type], $modSettings['max_messageLength']); |
2160
|
|
|
$context['post_error']['messages'][] = $txt['error_' . $error_type]; |
2161
|
|
|
} |
2162
|
|
|
|
2163
|
|
|
// If it's not a minor error flag it as such. |
2164
|
|
|
if (!in_array($error_type, array('new_reply', 'not_approved', 'new_replies', 'old_topic', 'need_qr_verification', 'no_subject'))) |
2165
|
|
|
$context['error_type'] = 'serious'; |
2166
|
|
|
} |
2167
|
|
|
|
2168
|
|
|
// We need to load the editor once more. |
2169
|
|
|
require_once($sourcedir . '/Subs-Editor.php'); |
2170
|
|
|
|
2171
|
|
|
// Create it... |
2172
|
|
|
$editorOptions = array( |
2173
|
|
|
'id' => 'message', |
2174
|
|
|
'value' => $context['message'], |
2175
|
|
|
'width' => '90%', |
2176
|
|
|
'height' => '250px', |
2177
|
|
|
'labels' => array( |
2178
|
|
|
'post_button' => $txt['send_message'], |
2179
|
|
|
), |
2180
|
|
|
'preview_type' => 2, |
2181
|
|
|
); |
2182
|
|
|
create_control_richedit($editorOptions); |
2183
|
|
|
|
2184
|
|
|
// ... and store the ID again... |
2185
|
|
|
$context['post_box_name'] = $editorOptions['id']; |
2186
|
|
|
|
2187
|
|
|
// Check whether we need to show the code again. |
2188
|
|
|
$context['require_verification'] = !$user_info['is_admin'] && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification']; |
2189
|
|
|
if ($context['require_verification'] && !isset($_REQUEST['xml'])) |
2190
|
|
|
{ |
2191
|
|
|
require_once($sourcedir . '/Subs-Editor.php'); |
2192
|
|
|
$verificationOptions = array( |
2193
|
|
|
'id' => 'pm', |
2194
|
|
|
); |
2195
|
|
|
$context['require_verification'] = create_control_verification($verificationOptions); |
2196
|
|
|
$context['visual_verification_id'] = $verificationOptions['id']; |
2197
|
|
|
} |
2198
|
|
|
|
2199
|
|
|
$context['to_value'] = empty($named_recipients['to']) ? '' : '"' . implode('", "', $named_recipients['to']) . '"'; |
2200
|
|
|
$context['bcc_value'] = empty($named_recipients['bcc']) ? '' : '"' . implode('", "', $named_recipients['bcc']) . '"'; |
2201
|
|
|
|
2202
|
|
|
call_integration_hook('integrate_pm_error'); |
2203
|
|
|
|
2204
|
|
|
// No check for the previous submission is needed. |
2205
|
|
|
checkSubmitOnce('free'); |
2206
|
|
|
|
2207
|
|
|
// Acquire a new form sequence number. |
2208
|
|
|
checkSubmitOnce('register'); |
2209
|
|
|
} |
2210
|
|
|
|
2211
|
|
|
/** |
2212
|
|
|
* Send it! |
2213
|
|
|
*/ |
2214
|
|
|
function MessagePost2() |
2215
|
|
|
{ |
2216
|
|
|
global $txt, $context, $sourcedir; |
2217
|
|
|
global $user_info, $modSettings, $smcFunc; |
2218
|
|
|
|
2219
|
|
|
isAllowedTo('pm_send'); |
2220
|
|
|
require_once($sourcedir . '/Subs-Auth.php'); |
2221
|
|
|
|
2222
|
|
|
// PM Drafts enabled and needed? |
2223
|
|
|
if ($context['drafts_pm_save'] && (isset($_POST['save_draft']) || isset($_POST['id_pm_draft']))) |
2224
|
|
|
require_once($sourcedir . '/Drafts.php'); |
2225
|
|
|
|
2226
|
|
|
loadLanguage('PersonalMessage', '', false); |
2227
|
|
|
|
2228
|
|
|
// Extract out the spam settings - it saves database space! |
2229
|
|
|
list ($modSettings['max_pm_recipients'], $modSettings['pm_posts_verification'], $modSettings['pm_posts_per_hour']) = explode(',', $modSettings['pm_spam_settings']); |
2230
|
|
|
|
2231
|
|
|
// Initialize the errors we're about to make. |
2232
|
|
|
$post_errors = array(); |
2233
|
|
|
|
2234
|
|
|
// Check whether we've gone over the limit of messages we can send per hour - fatal error if fails! |
2235
|
|
|
if (!empty($modSettings['pm_posts_per_hour']) && !allowedTo(array('admin_forum', 'moderate_forum', 'send_mail')) && $user_info['mod_cache']['bq'] == '0=1' && $user_info['mod_cache']['gq'] == '0=1') |
2236
|
|
|
{ |
2237
|
|
|
// How many have they sent this last hour? |
2238
|
|
|
$request = $smcFunc['db_query']('', ' |
2239
|
|
|
SELECT COUNT(pr.id_pm) AS post_count |
2240
|
|
|
FROM {db_prefix}personal_messages AS pm |
2241
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pr ON (pr.id_pm = pm.id_pm) |
2242
|
|
|
WHERE pm.id_member_from = {int:current_member} |
2243
|
|
|
AND pm.msgtime > {int:msgtime}', |
2244
|
|
|
array( |
2245
|
|
|
'current_member' => $user_info['id'], |
2246
|
|
|
'msgtime' => time() - 3600, |
2247
|
|
|
) |
2248
|
|
|
); |
2249
|
|
|
list ($postCount) = $smcFunc['db_fetch_row']($request); |
2250
|
|
|
$smcFunc['db_free_result']($request); |
2251
|
|
|
|
2252
|
|
|
if (!empty($postCount) && $postCount >= $modSettings['pm_posts_per_hour']) |
2253
|
|
|
{ |
2254
|
|
|
if (!isset($_REQUEST['xml'])) |
2255
|
|
|
fatal_lang_error('pm_too_many_per_hour', true, array($modSettings['pm_posts_per_hour'])); |
|
|
|
|
2256
|
|
|
else |
2257
|
|
|
$post_errors[] = 'pm_too_many_per_hour'; |
2258
|
|
|
} |
2259
|
|
|
} |
2260
|
|
|
|
2261
|
|
|
// If your session timed out, show an error, but do allow to re-submit. |
2262
|
|
|
if (!isset($_REQUEST['xml']) && checkSession('post', '', false) != '') |
2263
|
|
|
$post_errors[] = 'session_timeout'; |
2264
|
|
|
|
2265
|
|
|
$_REQUEST['subject'] = isset($_REQUEST['subject']) ? trim($_REQUEST['subject']) : ''; |
2266
|
|
|
$_REQUEST['to'] = empty($_POST['to']) ? (empty($_GET['to']) ? '' : $_GET['to']) : $_POST['to']; |
2267
|
|
|
$_REQUEST['bcc'] = empty($_POST['bcc']) ? (empty($_GET['bcc']) ? '' : $_GET['bcc']) : $_POST['bcc']; |
2268
|
|
|
|
2269
|
|
|
// Route the input from the 'u' parameter to the 'to'-list. |
2270
|
|
|
if (!empty($_POST['u'])) |
2271
|
|
|
$_POST['recipient_to'] = explode(',', $_POST['u']); |
2272
|
|
|
|
2273
|
|
|
// Construct the list of recipients. |
2274
|
|
|
$recipientList = array(); |
2275
|
|
|
$namedRecipientList = array(); |
2276
|
|
|
$namesNotFound = array(); |
2277
|
|
|
foreach (array('to', 'bcc') as $recipientType) |
2278
|
|
|
{ |
2279
|
|
|
// First, let's see if there's user ID's given. |
2280
|
|
|
$recipientList[$recipientType] = array(); |
2281
|
|
|
if (!empty($_POST['recipient_' . $recipientType]) && is_array($_POST['recipient_' . $recipientType])) |
2282
|
|
|
{ |
2283
|
|
|
foreach ($_POST['recipient_' . $recipientType] as $recipient) |
2284
|
|
|
$recipientList[$recipientType][] = (int) $recipient; |
2285
|
|
|
} |
2286
|
|
|
|
2287
|
|
|
// Are there also literal names set? |
2288
|
|
|
if (!empty($_REQUEST[$recipientType])) |
2289
|
|
|
{ |
2290
|
|
|
// We're going to take out the "s anyway ;). |
2291
|
|
|
$recipientString = strtr($_REQUEST[$recipientType], array('\\"' => '"')); |
2292
|
|
|
|
2293
|
|
|
preg_match_all('~"([^"]+)"~', $recipientString, $matches); |
2294
|
|
|
$namedRecipientList[$recipientType] = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $recipientString)))); |
2295
|
|
|
|
2296
|
|
View Code Duplication |
foreach ($namedRecipientList[$recipientType] as $index => $recipient) |
|
|
|
|
2297
|
|
|
{ |
2298
|
|
|
if (strlen(trim($recipient)) > 0) |
2299
|
|
|
$namedRecipientList[$recipientType][$index] = $smcFunc['htmlspecialchars']($smcFunc['strtolower'](trim($recipient))); |
2300
|
|
|
else |
2301
|
|
|
unset($namedRecipientList[$recipientType][$index]); |
2302
|
|
|
} |
2303
|
|
|
|
2304
|
|
|
if (!empty($namedRecipientList[$recipientType])) |
2305
|
|
|
{ |
2306
|
|
|
$foundMembers = findMembers($namedRecipientList[$recipientType]); |
2307
|
|
|
|
2308
|
|
|
// Assume all are not found, until proven otherwise. |
2309
|
|
|
$namesNotFound[$recipientType] = $namedRecipientList[$recipientType]; |
2310
|
|
|
|
2311
|
|
|
foreach ($foundMembers as $member) |
2312
|
|
|
{ |
2313
|
|
|
$testNames = array( |
2314
|
|
|
$smcFunc['strtolower']($member['username']), |
2315
|
|
|
$smcFunc['strtolower']($member['name']), |
2316
|
|
|
$smcFunc['strtolower']($member['email']), |
2317
|
|
|
); |
2318
|
|
|
|
2319
|
|
|
if (count(array_intersect($testNames, $namedRecipientList[$recipientType])) !== 0) |
2320
|
|
|
{ |
2321
|
|
|
$recipientList[$recipientType][] = $member['id']; |
2322
|
|
|
|
2323
|
|
|
// Get rid of this username, since we found it. |
2324
|
|
|
$namesNotFound[$recipientType] = array_diff($namesNotFound[$recipientType], $testNames); |
2325
|
|
|
} |
2326
|
|
|
} |
2327
|
|
|
} |
2328
|
|
|
} |
2329
|
|
|
|
2330
|
|
|
// Selected a recipient to be deleted? Remove them now. |
2331
|
|
|
if (!empty($_POST['delete_recipient'])) |
2332
|
|
|
$recipientList[$recipientType] = array_diff($recipientList[$recipientType], array((int) $_POST['delete_recipient'])); |
2333
|
|
|
|
2334
|
|
|
// Make sure we don't include the same name twice |
2335
|
|
|
$recipientList[$recipientType] = array_unique($recipientList[$recipientType]); |
2336
|
|
|
} |
2337
|
|
|
|
2338
|
|
|
// Are we changing the recipients some how? |
2339
|
|
|
$is_recipient_change = !empty($_POST['delete_recipient']) || !empty($_POST['to_submit']) || !empty($_POST['bcc_submit']); |
2340
|
|
|
|
2341
|
|
|
// Check if there's at least one recipient. |
2342
|
|
|
if (empty($recipientList['to']) && empty($recipientList['bcc'])) |
2343
|
|
|
$post_errors[] = 'no_to'; |
2344
|
|
|
|
2345
|
|
|
// Make sure that we remove the members who did get it from the screen. |
2346
|
|
|
if (!$is_recipient_change) |
2347
|
|
|
{ |
2348
|
|
|
foreach ($recipientList as $recipientType => $dummy) |
2349
|
|
|
{ |
2350
|
|
|
if (!empty($namesNotFound[$recipientType])) |
2351
|
|
|
{ |
2352
|
|
|
$post_errors[] = 'bad_' . $recipientType; |
2353
|
|
|
|
2354
|
|
|
// Since we already have a post error, remove the previous one. |
2355
|
|
|
$post_errors = array_diff($post_errors, array('no_to')); |
2356
|
|
|
|
2357
|
|
|
foreach ($namesNotFound[$recipientType] as $name) |
2358
|
|
|
$context['send_log']['failed'][] = sprintf($txt['pm_error_user_not_found'], $name); |
2359
|
|
|
} |
2360
|
|
|
} |
2361
|
|
|
} |
2362
|
|
|
|
2363
|
|
|
// Did they make any mistakes? |
2364
|
|
|
if ($_REQUEST['subject'] == '') |
2365
|
|
|
$post_errors[] = 'no_subject'; |
2366
|
|
|
if (!isset($_REQUEST['message']) || $_REQUEST['message'] == '') |
2367
|
|
|
$post_errors[] = 'no_message'; |
2368
|
|
View Code Duplication |
elseif (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_REQUEST['message']) > $modSettings['max_messageLength']) |
|
|
|
|
2369
|
|
|
$post_errors[] = 'long_message'; |
2370
|
|
|
else |
2371
|
|
|
{ |
2372
|
|
|
// Preparse the message. |
2373
|
|
|
$message = $_REQUEST['message']; |
2374
|
|
|
preparsecode($message); |
2375
|
|
|
|
2376
|
|
|
// Make sure there's still some content left without the tags. |
2377
|
|
View Code Duplication |
if ($smcFunc['htmltrim'](strip_tags(parse_bbc($smcFunc['htmlspecialchars']($message, ENT_QUOTES), false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($message, '[html]') === false)) |
|
|
|
|
2378
|
|
|
$post_errors[] = 'no_message'; |
2379
|
|
|
} |
2380
|
|
|
|
2381
|
|
|
// Wrong verification code? |
2382
|
|
|
if (!$user_info['is_admin'] && !isset($_REQUEST['xml']) && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification']) |
2383
|
|
|
{ |
2384
|
|
|
require_once($sourcedir . '/Subs-Editor.php'); |
2385
|
|
|
$verificationOptions = array( |
2386
|
|
|
'id' => 'pm', |
2387
|
|
|
); |
2388
|
|
|
$context['require_verification'] = create_control_verification($verificationOptions, true); |
2389
|
|
|
|
2390
|
|
|
if (is_array($context['require_verification'])) |
2391
|
|
|
$post_errors = array_merge($post_errors, $context['require_verification']); |
2392
|
|
|
} |
2393
|
|
|
|
2394
|
|
|
// If they did, give a chance to make ammends. |
2395
|
|
|
if (!empty($post_errors) && !$is_recipient_change && !isset($_REQUEST['preview']) && !isset($_REQUEST['xml'])) |
2396
|
|
|
return messagePostError($post_errors, $namedRecipientList, $recipientList); |
2397
|
|
|
|
2398
|
|
|
// Want to take a second glance before you send? |
2399
|
|
|
if (isset($_REQUEST['preview'])) |
2400
|
|
|
{ |
2401
|
|
|
// Set everything up to be displayed. |
2402
|
|
|
$context['preview_subject'] = $smcFunc['htmlspecialchars']($_REQUEST['subject']); |
2403
|
|
|
$context['preview_message'] = $smcFunc['htmlspecialchars']($_REQUEST['message'], ENT_QUOTES); |
2404
|
|
|
preparsecode($context['preview_message'], true); |
2405
|
|
|
|
2406
|
|
|
// Parse out the BBC if it is enabled. |
2407
|
|
|
$context['preview_message'] = parse_bbc($context['preview_message']); |
2408
|
|
|
|
2409
|
|
|
// Censor, as always. |
2410
|
|
|
censorText($context['preview_subject']); |
2411
|
|
|
censorText($context['preview_message']); |
2412
|
|
|
|
2413
|
|
|
// Set a descriptive title. |
2414
|
|
|
$context['page_title'] = $txt['preview'] . ' - ' . $context['preview_subject']; |
2415
|
|
|
|
2416
|
|
|
// Pretend they messed up but don't ignore if they really did :P. |
2417
|
|
|
return messagePostError($post_errors, $namedRecipientList, $recipientList); |
2418
|
|
|
} |
2419
|
|
|
|
2420
|
|
|
// Adding a recipient cause javascript ain't working? |
2421
|
|
|
elseif ($is_recipient_change) |
2422
|
|
|
{ |
2423
|
|
|
// Maybe we couldn't find one? |
2424
|
|
|
foreach ($namesNotFound as $recipientType => $names) |
2425
|
|
|
{ |
2426
|
|
|
$post_errors[] = 'bad_' . $recipientType; |
2427
|
|
|
foreach ($names as $name) |
2428
|
|
|
$context['send_log']['failed'][] = sprintf($txt['pm_error_user_not_found'], $name); |
2429
|
|
|
} |
2430
|
|
|
|
2431
|
|
|
return messagePostError(array(), $namedRecipientList, $recipientList); |
2432
|
|
|
} |
2433
|
|
|
|
2434
|
|
|
// Want to save this as a draft and think about it some more? |
2435
|
|
|
if ($context['drafts_pm_save'] && isset($_POST['save_draft'])) |
2436
|
|
|
{ |
2437
|
|
|
SavePMDraft($post_errors, $recipientList); |
|
|
|
|
2438
|
|
|
return messagePostError($post_errors, $namedRecipientList, $recipientList); |
|
|
|
|
2439
|
|
|
} |
2440
|
|
|
|
2441
|
|
|
// Before we send the PM, let's make sure we don't have an abuse of numbers. |
2442
|
|
|
elseif (!empty($modSettings['max_pm_recipients']) && count($recipientList['to']) + count($recipientList['bcc']) > $modSettings['max_pm_recipients'] && !allowedTo(array('moderate_forum', 'send_mail', 'admin_forum'))) |
2443
|
|
|
{ |
2444
|
|
|
$context['send_log'] = array( |
2445
|
|
|
'sent' => array(), |
2446
|
|
|
'failed' => array(sprintf($txt['pm_too_many_recipients'], $modSettings['max_pm_recipients'])), |
2447
|
|
|
); |
2448
|
|
|
return messagePostError($post_errors, $namedRecipientList, $recipientList); |
2449
|
|
|
} |
2450
|
|
|
|
2451
|
|
|
// Protect from message spamming. |
2452
|
|
|
spamProtection('pm'); |
2453
|
|
|
|
2454
|
|
|
// Prevent double submission of this form. |
2455
|
|
|
checkSubmitOnce('check'); |
2456
|
|
|
|
2457
|
|
|
// Do the actual sending of the PM. |
2458
|
|
|
if (!empty($recipientList['to']) || !empty($recipientList['bcc'])) |
2459
|
|
|
$context['send_log'] = sendpm($recipientList, $_REQUEST['subject'], $_REQUEST['message'], true, null, !empty($_REQUEST['pm_head']) ? (int) $_REQUEST['pm_head'] : 0); |
2460
|
|
|
else |
2461
|
|
|
$context['send_log'] = array( |
2462
|
|
|
'sent' => array(), |
2463
|
|
|
'failed' => array() |
2464
|
|
|
); |
2465
|
|
|
|
2466
|
|
|
// Mark the message as "replied to". |
2467
|
|
|
if (!empty($context['send_log']['sent']) && !empty($_REQUEST['replied_to']) && isset($_REQUEST['f']) && $_REQUEST['f'] == 'inbox') |
2468
|
|
|
{ |
2469
|
|
|
$smcFunc['db_query']('', ' |
2470
|
|
|
UPDATE {db_prefix}pm_recipients |
2471
|
|
|
SET is_read = is_read | 2 |
2472
|
|
|
WHERE id_pm = {int:replied_to} |
2473
|
|
|
AND id_member = {int:current_member}', |
2474
|
|
|
array( |
2475
|
|
|
'current_member' => $user_info['id'], |
2476
|
|
|
'replied_to' => (int) $_REQUEST['replied_to'], |
2477
|
|
|
) |
2478
|
|
|
); |
2479
|
|
|
} |
2480
|
|
|
|
2481
|
|
|
// If one or more of the recipient were invalid, go back to the post screen with the failed usernames. |
2482
|
|
|
if (!empty($context['send_log']['failed'])) |
2483
|
|
|
return messagePostError($post_errors, $namesNotFound, array( |
2484
|
|
|
'to' => array_intersect($recipientList['to'], $context['send_log']['failed']), |
2485
|
|
|
'bcc' => array_intersect($recipientList['bcc'], $context['send_log']['failed']) |
2486
|
|
|
)); |
2487
|
|
|
|
2488
|
|
|
// Message sent successfully? |
2489
|
|
|
if (!empty($context['send_log']) && empty($context['send_log']['failed'])) |
2490
|
|
|
{ |
2491
|
|
|
$context['current_label_redirect'] = $context['current_label_redirect'] . ';done=sent'; |
2492
|
|
|
|
2493
|
|
|
// If we had a PM draft for this one, then its time to remove it since it was just sent |
2494
|
|
|
if ($context['drafts_pm_save'] && !empty($_POST['id_pm_draft'])) |
2495
|
|
|
DeleteDraft($_POST['id_pm_draft']); |
|
|
|
|
2496
|
|
|
} |
2497
|
|
|
|
2498
|
|
|
// Go back to the where they sent from, if possible... |
2499
|
|
|
redirectexit($context['current_label_redirect']); |
2500
|
|
|
} |
2501
|
|
|
/** |
2502
|
|
|
* This function performs all additional stuff... |
2503
|
|
|
*/ |
2504
|
|
|
function MessageActionsApply() |
2505
|
|
|
{ |
2506
|
|
|
global $context, $user_info, $options, $smcFunc; |
2507
|
|
|
|
2508
|
|
|
checkSession('request'); |
2509
|
|
|
|
2510
|
|
|
if (isset($_REQUEST['del_selected'])) |
2511
|
|
|
$_REQUEST['pm_action'] = 'delete'; |
2512
|
|
|
|
2513
|
|
|
if (isset($_REQUEST['pm_action']) && $_REQUEST['pm_action'] != '' && !empty($_REQUEST['pms']) && is_array($_REQUEST['pms'])) |
2514
|
|
|
{ |
2515
|
|
|
foreach ($_REQUEST['pms'] as $pm) |
2516
|
|
|
$_REQUEST['pm_actions'][(int) $pm] = $_REQUEST['pm_action']; |
2517
|
|
|
} |
2518
|
|
|
|
2519
|
|
|
if (empty($_REQUEST['pm_actions'])) |
2520
|
|
|
redirectexit($context['current_label_redirect']); |
2521
|
|
|
|
2522
|
|
|
// If we are in conversation, we may need to apply this to every message in the conversation. |
2523
|
|
|
if ($context['display_mode'] == 2 && isset($_REQUEST['conversation'])) |
2524
|
|
|
{ |
2525
|
|
|
$id_pms = array(); |
2526
|
|
|
foreach ($_REQUEST['pm_actions'] as $pm => $dummy) |
2527
|
|
|
$id_pms[] = (int) $pm; |
2528
|
|
|
|
2529
|
|
|
$request = $smcFunc['db_query']('', ' |
2530
|
|
|
SELECT id_pm_head, id_pm |
2531
|
|
|
FROM {db_prefix}personal_messages |
2532
|
|
|
WHERE id_pm IN ({array_int:id_pms})', |
2533
|
|
|
array( |
2534
|
|
|
'id_pms' => $id_pms, |
2535
|
|
|
) |
2536
|
|
|
); |
2537
|
|
|
$pm_heads = array(); |
2538
|
|
View Code Duplication |
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
|
|
|
2539
|
|
|
$pm_heads[$row['id_pm_head']] = $row['id_pm']; |
2540
|
|
|
$smcFunc['db_free_result']($request); |
2541
|
|
|
|
2542
|
|
|
$request = $smcFunc['db_query']('', ' |
2543
|
|
|
SELECT id_pm, id_pm_head |
2544
|
|
|
FROM {db_prefix}personal_messages |
2545
|
|
|
WHERE id_pm_head IN ({array_int:pm_heads})', |
2546
|
|
|
array( |
2547
|
|
|
'pm_heads' => array_keys($pm_heads), |
2548
|
|
|
) |
2549
|
|
|
); |
2550
|
|
|
// Copy the action from the single to PM to the others. |
2551
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
2552
|
|
|
{ |
2553
|
|
|
if (isset($pm_heads[$row['id_pm_head']]) && isset($_REQUEST['pm_actions'][$pm_heads[$row['id_pm_head']]])) |
2554
|
|
|
$_REQUEST['pm_actions'][$row['id_pm']] = $_REQUEST['pm_actions'][$pm_heads[$row['id_pm_head']]]; |
2555
|
|
|
} |
2556
|
|
|
$smcFunc['db_free_result']($request); |
2557
|
|
|
} |
2558
|
|
|
|
2559
|
|
|
$to_delete = array(); |
2560
|
|
|
$to_label = array(); |
2561
|
|
|
$label_type = array(); |
2562
|
|
|
$labels = array(); |
2563
|
|
|
foreach ($_REQUEST['pm_actions'] as $pm => $action) |
2564
|
|
|
{ |
2565
|
|
|
if ($action === 'delete') |
2566
|
|
|
$to_delete[] = (int) $pm; |
2567
|
|
|
else |
2568
|
|
|
{ |
2569
|
|
|
if (substr($action, 0, 4) == 'add_') |
2570
|
|
|
{ |
2571
|
|
|
$type = 'add'; |
2572
|
|
|
$action = substr($action, 4); |
2573
|
|
|
} |
2574
|
|
View Code Duplication |
elseif (substr($action, 0, 4) == 'rem_') |
|
|
|
|
2575
|
|
|
{ |
2576
|
|
|
$type = 'rem'; |
2577
|
|
|
$action = substr($action, 4); |
2578
|
|
|
} |
2579
|
|
|
else |
2580
|
|
|
$type = 'unk'; |
2581
|
|
|
|
2582
|
|
|
if ($action == '-1' || (int) $action > 0) |
2583
|
|
|
{ |
2584
|
|
|
$to_label[(int) $pm] = (int) $action; |
2585
|
|
|
$label_type[(int) $pm] = $type; |
2586
|
|
|
} |
2587
|
|
|
} |
2588
|
|
|
} |
2589
|
|
|
|
2590
|
|
|
// Deleting, it looks like? |
2591
|
|
|
if (!empty($to_delete)) |
2592
|
|
|
deleteMessages($to_delete, $context['display_mode'] == 2 ? null : $context['folder']); |
2593
|
|
|
|
2594
|
|
|
// Are we labeling anything? |
2595
|
|
|
if (!empty($to_label) && $context['folder'] == 'inbox') |
2596
|
|
|
{ |
2597
|
|
|
// Are we dealing with conversation view? If so, get all the messages in each conversation |
2598
|
|
|
if ($context['display_mode'] == 2) |
2599
|
|
|
{ |
2600
|
|
|
$get_pms = $smcFunc['db_query']('', ' |
2601
|
|
|
SELECT pm.id_pm_head, pm.id_pm |
2602
|
|
|
FROM {db_prefix}personal_messages AS pm |
2603
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm) |
2604
|
|
|
WHERE pm.id_pm_head IN ({array_int:head_pms}) |
2605
|
|
|
AND pm.id_pm NOT IN ({array_int:head_pms}) |
2606
|
|
|
AND pmr.id_member = {int:current_member}', |
2607
|
|
|
array( |
2608
|
|
|
'head_pms' => array_keys($to_label), |
2609
|
|
|
'current_member' => $user_info['id'], |
2610
|
|
|
) |
2611
|
|
|
); |
2612
|
|
|
|
2613
|
|
|
while ($other_pms = $smcFunc['db_query']($get_pms)) |
2614
|
|
|
{ |
2615
|
|
|
$to_label[$other_pms['id_pm']] = $to_label[$other_pms['id_pm_head']]; |
2616
|
|
|
} |
2617
|
|
|
|
2618
|
|
|
$smcFunc['db_free_result']($get_pms); |
2619
|
|
|
} |
2620
|
|
|
|
2621
|
|
|
// Get information about each message... |
2622
|
|
|
$request = $smcFunc['db_query']('', ' |
2623
|
|
|
SELECT id_pm, in_inbox |
2624
|
|
|
FROM {db_prefix}pm_recipients |
2625
|
|
|
WHERE id_member = {int:current_member} |
2626
|
|
|
AND id_pm IN ({array_int:to_label}) |
2627
|
|
|
LIMIT ' . count($to_label), |
2628
|
|
|
array( |
2629
|
|
|
'current_member' => $user_info['id'], |
2630
|
|
|
'to_label' => array_keys($to_label), |
2631
|
|
|
) |
2632
|
|
|
); |
2633
|
|
|
|
2634
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
2635
|
|
|
{ |
2636
|
|
|
// Get the labels as well, but only if we're not dealing with the inbox |
2637
|
|
|
if ($to_label[$row['id_pm']] != '-1') |
2638
|
|
|
{ |
2639
|
|
|
// The JOIN here ensures we only get labels that this user has applied to this PM |
2640
|
|
|
$request2 = $smcFunc['db_query']('', ' |
2641
|
|
|
SELECT l.id_label, pml.id_pm |
2642
|
|
|
FROM {db_prefix}pm_labels AS l |
2643
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_label = l.id_label) |
2644
|
|
|
WHERE l.id_member = {int:current_member} |
2645
|
|
|
AND pml.id_pm = {int:current_pm}', |
2646
|
|
|
array( |
2647
|
|
|
'current_member' => $user_info['id'], |
2648
|
|
|
'current_pm' => $row['id_pm'], |
2649
|
|
|
) |
2650
|
|
|
); |
2651
|
|
|
|
2652
|
|
|
while ($row2 = $smcFunc['db_fetch_assoc']($request2)) |
2653
|
|
|
{ |
2654
|
|
|
$labels[$row2['id_label']] = $row2['id_label']; |
2655
|
|
|
} |
2656
|
|
|
|
2657
|
|
|
$smcFunc['db_free_result']($request2); |
2658
|
|
|
} |
2659
|
|
|
elseif ($type == 'rem') |
|
|
|
|
2660
|
|
|
{ |
2661
|
|
|
// If we're removing from the inbox, see if we have at least one other label. |
2662
|
|
|
// This query is faster than the one above |
2663
|
|
|
$request2 = $smcFunc['db_query']('', ' |
2664
|
|
|
SELECT COUNT(l.id_label) |
2665
|
|
|
FROM {db_prefix}pm_labels AS l |
2666
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_label = l.id_label) |
2667
|
|
|
WHERE l.id_member = {int:current_member} |
2668
|
|
|
AND pml.id_pm = {int:current_pm}', |
2669
|
|
|
array( |
2670
|
|
|
'current_member' => $user_info['id'], |
2671
|
|
|
'current_pm' => $row['id_pm'], |
2672
|
|
|
) |
2673
|
|
|
); |
2674
|
|
|
|
2675
|
|
|
// How many labels do you have? |
2676
|
|
|
list ($num_labels) = $smcFunc['db_fetch_assoc']($request2); |
2677
|
|
|
|
2678
|
|
|
if ($num_labels > 0); |
2679
|
|
|
$context['can_remove_inbox'] = true; |
2680
|
|
|
|
2681
|
|
|
$smcFunc['db_free_result']($request2); |
2682
|
|
|
} |
2683
|
|
|
|
2684
|
|
|
// Use this to determine what to do later on... |
2685
|
|
|
$original_labels = $labels; |
2686
|
|
|
|
2687
|
|
|
// Ignore inbox for now - we'll deal with it later |
2688
|
|
|
if ($to_label[$row['id_pm']] != '-1') |
2689
|
|
|
{ |
2690
|
|
|
// If this label is in the list and we're not adding it, remove it |
2691
|
|
|
if (array_key_exists($to_label[$row['id_pm']], $labels) && $type !== 'add') |
2692
|
|
|
unset($labels[$to_label[$row['id_pm']]]); |
2693
|
|
|
else if ($type !== 'rem') |
2694
|
|
|
$labels[$to_label[$row['id_pm']]] = $to_label[$row['id_pm']]; |
2695
|
|
|
} |
2696
|
|
|
|
2697
|
|
|
// Removing all labels or just removing the inbox label |
2698
|
|
|
if ($type == 'rem' && empty($labels)) |
2699
|
|
|
$in_inbox = (empty($context['can_remove_inbox']) ? 1 : 0); |
2700
|
|
|
// Adding new labels, but removing inbox and applying new ones |
2701
|
|
|
elseif ($type == 'add' && !empty($options['pm_remove_inbox_label']) && !empty($labels)) |
2702
|
|
|
$in_inbox = 0; |
2703
|
|
|
// Just adding it to the inbox |
2704
|
|
|
else |
2705
|
|
|
$in_inbox = 1; |
2706
|
|
|
|
2707
|
|
|
// Are we adding it to or removing it from the inbox? |
2708
|
|
|
if ($in_inbox != $row['in_inbox']) |
2709
|
|
|
{ |
2710
|
|
|
$smcFunc['db_query']('', ' |
2711
|
|
|
UPDATE {db_prefix}pm_recipients |
2712
|
|
|
SET in_inbox = {int:in_inbox} |
2713
|
|
|
WHERE id_pm = {int:id_pm} |
2714
|
|
|
AND id_member = {int:current_member}', |
2715
|
|
|
array( |
2716
|
|
|
'current_member' => $user_info['id'], |
2717
|
|
|
'id_pm' => $row['id_pm'], |
2718
|
|
|
'in_inbox' => $in_inbox, |
2719
|
|
|
) |
2720
|
|
|
); |
2721
|
|
|
} |
2722
|
|
|
|
2723
|
|
|
// Which labels do we not want now? |
2724
|
|
|
$labels_to_remove = array_diff($original_labels, $labels); |
2725
|
|
|
|
2726
|
|
|
// Don't apply it if it's already applied |
2727
|
|
|
$labels_to_apply = array_diff($labels, $original_labels); |
2728
|
|
|
|
2729
|
|
|
// Remove labels |
2730
|
|
|
if (!empty($labels_to_remove)) |
2731
|
|
|
{ |
2732
|
|
|
$smcFunc['db_query']('', ' |
2733
|
|
|
DELETE FROM {db_prefix}pm_labeled_messages |
2734
|
|
|
WHERE id_pm = {int:current_pm} |
2735
|
|
|
AND id_label IN ({array_int:labels_to_remove})', |
2736
|
|
|
array( |
2737
|
|
|
'current_pm' => $row['id_pm'], |
2738
|
|
|
'labels_to_remove' => $labels_to_remove, |
2739
|
|
|
) |
2740
|
|
|
); |
2741
|
|
|
} |
2742
|
|
|
|
2743
|
|
|
// Add new ones |
2744
|
|
View Code Duplication |
if (!empty($labels_to_apply)) |
|
|
|
|
2745
|
|
|
{ |
2746
|
|
|
$inserts = array(); |
2747
|
|
|
foreach ($labels_to_apply as $label) |
2748
|
|
|
$inserts[] = array($row['id_pm'], $label); |
2749
|
|
|
|
2750
|
|
|
$smcFunc['db_insert']('', |
2751
|
|
|
'{db_prefix}pm_labeled_messages', |
2752
|
|
|
array('id_pm' => 'int', 'id_label' => 'int'), |
2753
|
|
|
$inserts, |
2754
|
|
|
array() |
2755
|
|
|
); |
2756
|
|
|
} |
2757
|
|
|
} |
2758
|
|
|
$smcFunc['db_free_result']($request); |
2759
|
|
|
} |
2760
|
|
|
|
2761
|
|
|
// Back to the folder. |
2762
|
|
|
$_SESSION['pm_selected'] = array_keys($to_label); |
2763
|
|
|
redirectexit($context['current_label_redirect'] . (count($to_label) == 1 ? '#msg' . $_SESSION['pm_selected'][0] : ''), count($to_label) == 1 && isBrowser('ie')); |
2764
|
|
|
} |
2765
|
|
|
|
2766
|
|
|
/** |
2767
|
|
|
* Are you sure you want to PERMANENTLY (mostly) delete ALL your messages? |
2768
|
|
|
*/ |
2769
|
|
|
function MessageKillAllQuery() |
2770
|
|
|
{ |
2771
|
|
|
global $txt, $context; |
2772
|
|
|
|
2773
|
|
|
// Only have to set up the template.... |
2774
|
|
|
$context['sub_template'] = 'ask_delete'; |
2775
|
|
|
$context['page_title'] = $txt['delete_all']; |
2776
|
|
|
$context['delete_all'] = $_REQUEST['f'] == 'all'; |
2777
|
|
|
|
2778
|
|
|
// And set the folder name... |
2779
|
|
|
$txt['delete_all'] = str_replace('PMBOX', $context['folder'] != 'sent' ? $txt['inbox'] : $txt['sent_items'], $txt['delete_all']); |
2780
|
|
|
} |
2781
|
|
|
|
2782
|
|
|
/** |
2783
|
|
|
* Delete ALL the messages! |
2784
|
|
|
*/ |
2785
|
|
|
function MessageKillAll() |
2786
|
|
|
{ |
2787
|
|
|
global $context; |
2788
|
|
|
|
2789
|
|
|
checkSession('get'); |
2790
|
|
|
|
2791
|
|
|
// If all then delete all messages the user has. |
2792
|
|
|
if ($_REQUEST['f'] == 'all') |
2793
|
|
|
deleteMessages(null, null); |
2794
|
|
|
// Otherwise just the selected folder. |
2795
|
|
|
else |
2796
|
|
|
deleteMessages(null, $_REQUEST['f'] != 'sent' ? 'inbox' : 'sent'); |
2797
|
|
|
|
2798
|
|
|
// Done... all gone. |
2799
|
|
|
redirectexit($context['current_label_redirect']); |
2800
|
|
|
} |
2801
|
|
|
|
2802
|
|
|
/** |
2803
|
|
|
* This function allows the user to delete all messages older than so many days. |
2804
|
|
|
*/ |
2805
|
|
|
function MessagePrune() |
2806
|
|
|
{ |
2807
|
|
|
global $txt, $context, $user_info, $scripturl, $smcFunc; |
2808
|
|
|
|
2809
|
|
|
// Actually delete the messages. |
2810
|
|
|
if (isset($_REQUEST['age'])) |
2811
|
|
|
{ |
2812
|
|
|
checkSession(); |
2813
|
|
|
|
2814
|
|
|
// Calculate the time to delete before. |
2815
|
|
|
$deleteTime = max(0, time() - (86400 * (int) $_REQUEST['age'])); |
2816
|
|
|
|
2817
|
|
|
// Array to store the IDs in. |
2818
|
|
|
$toDelete = array(); |
2819
|
|
|
|
2820
|
|
|
// Select all the messages they have sent older than $deleteTime. |
2821
|
|
|
$request = $smcFunc['db_query']('', ' |
2822
|
|
|
SELECT id_pm |
2823
|
|
|
FROM {db_prefix}personal_messages |
2824
|
|
|
WHERE deleted_by_sender = {int:not_deleted} |
2825
|
|
|
AND id_member_from = {int:current_member} |
2826
|
|
|
AND msgtime < {int:msgtime}', |
2827
|
|
|
array( |
2828
|
|
|
'current_member' => $user_info['id'], |
2829
|
|
|
'not_deleted' => 0, |
2830
|
|
|
'msgtime' => $deleteTime, |
2831
|
|
|
) |
2832
|
|
|
); |
2833
|
|
|
while ($row = $smcFunc['db_fetch_row']($request)) |
2834
|
|
|
$toDelete[] = $row[0]; |
2835
|
|
|
$smcFunc['db_free_result']($request); |
2836
|
|
|
|
2837
|
|
|
// Select all messages in their inbox older than $deleteTime. |
2838
|
|
|
$request = $smcFunc['db_query']('', ' |
2839
|
|
|
SELECT pmr.id_pm |
2840
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
2841
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) |
2842
|
|
|
WHERE pmr.deleted = {int:not_deleted} |
2843
|
|
|
AND pmr.id_member = {int:current_member} |
2844
|
|
|
AND pm.msgtime < {int:msgtime}', |
2845
|
|
|
array( |
2846
|
|
|
'current_member' => $user_info['id'], |
2847
|
|
|
'not_deleted' => 0, |
2848
|
|
|
'msgtime' => $deleteTime, |
2849
|
|
|
) |
2850
|
|
|
); |
2851
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
2852
|
|
|
$toDelete[] = $row['id_pm']; |
2853
|
|
|
$smcFunc['db_free_result']($request); |
2854
|
|
|
|
2855
|
|
|
// Delete the actual messages. |
2856
|
|
|
deleteMessages($toDelete); |
2857
|
|
|
|
2858
|
|
|
// Go back to their inbox. |
2859
|
|
|
redirectexit($context['current_label_redirect']); |
2860
|
|
|
} |
2861
|
|
|
|
2862
|
|
|
// Build the link tree elements. |
2863
|
|
|
$context['linktree'][] = array( |
2864
|
|
|
'url' => $scripturl . '?action=pm;sa=prune', |
2865
|
|
|
'name' => $txt['pm_prune'] |
2866
|
|
|
); |
2867
|
|
|
|
2868
|
|
|
$context['sub_template'] = 'prune'; |
2869
|
|
|
$context['page_title'] = $txt['pm_prune']; |
2870
|
|
|
} |
2871
|
|
|
|
2872
|
|
|
/** |
2873
|
|
|
* Delete the specified personal messages. |
2874
|
|
|
* |
2875
|
|
|
* @param array|null $personal_messages An array containing the IDs of PMs to delete or null to delete all of them |
2876
|
|
|
* @param string|null $folder Which "folder" to delete PMs from - 'sent' to delete them from the outbox, null or anything else to delete from the inbox |
2877
|
|
|
* @param array|int|null $owner An array of IDs of users whose PMs are being deleted, the ID of a single user or null to use the current user's ID |
2878
|
|
|
*/ |
2879
|
|
|
function deleteMessages($personal_messages, $folder = null, $owner = null) |
2880
|
|
|
{ |
2881
|
|
|
global $user_info, $smcFunc; |
2882
|
|
|
|
2883
|
|
|
if ($owner === null) |
2884
|
|
|
$owner = array($user_info['id']); |
2885
|
|
|
elseif (empty($owner)) |
2886
|
|
|
return; |
2887
|
|
|
elseif (!is_array($owner)) |
2888
|
|
|
$owner = array($owner); |
2889
|
|
|
|
2890
|
|
|
if ($personal_messages !== null) |
2891
|
|
|
{ |
2892
|
|
|
if (empty($personal_messages) || !is_array($personal_messages)) |
2893
|
|
|
return; |
2894
|
|
|
|
2895
|
|
|
foreach ($personal_messages as $index => $delete_id) |
2896
|
|
|
$personal_messages[$index] = (int) $delete_id; |
2897
|
|
|
|
2898
|
|
|
$where = ' |
2899
|
|
|
AND id_pm IN ({array_int:pm_list})'; |
2900
|
|
|
} |
2901
|
|
|
else |
2902
|
|
|
$where = ''; |
2903
|
|
|
|
2904
|
|
|
if ($folder == 'sent' || $folder === null) |
2905
|
|
|
{ |
2906
|
|
|
$smcFunc['db_query']('', ' |
2907
|
|
|
UPDATE {db_prefix}personal_messages |
2908
|
|
|
SET deleted_by_sender = {int:is_deleted} |
2909
|
|
|
WHERE id_member_from IN ({array_int:member_list}) |
2910
|
|
|
AND deleted_by_sender = {int:not_deleted}' . $where, |
2911
|
|
|
array( |
2912
|
|
|
'member_list' => $owner, |
2913
|
|
|
'is_deleted' => 1, |
2914
|
|
|
'not_deleted' => 0, |
2915
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
2916
|
|
|
) |
2917
|
|
|
); |
2918
|
|
|
} |
2919
|
|
|
if ($folder != 'sent' || $folder === null) |
2920
|
|
|
{ |
2921
|
|
|
// Calculate the number of messages each member's gonna lose... |
2922
|
|
|
$request = $smcFunc['db_query']('', ' |
2923
|
|
|
SELECT id_member, COUNT(*) AS num_deleted_messages, CASE WHEN is_read & 1 >= 1 THEN 1 ELSE 0 END AS is_read |
2924
|
|
|
FROM {db_prefix}pm_recipients |
2925
|
|
|
WHERE id_member IN ({array_int:member_list}) |
2926
|
|
|
AND deleted = {int:not_deleted}' . $where . ' |
2927
|
|
|
GROUP BY id_member, is_read', |
2928
|
|
|
array( |
2929
|
|
|
'member_list' => $owner, |
2930
|
|
|
'not_deleted' => 0, |
2931
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
2932
|
|
|
) |
2933
|
|
|
); |
2934
|
|
|
// ...And update the statistics accordingly - now including unread messages!. |
2935
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
2936
|
|
|
{ |
2937
|
|
|
if ($row['is_read']) |
2938
|
|
|
updateMemberData($row['id_member'], array('instant_messages' => $where == '' ? 0 : 'instant_messages - ' . $row['num_deleted_messages'])); |
2939
|
|
|
else |
2940
|
|
|
updateMemberData($row['id_member'], array('instant_messages' => $where == '' ? 0 : 'instant_messages - ' . $row['num_deleted_messages'], 'unread_messages' => $where == '' ? 0 : 'unread_messages - ' . $row['num_deleted_messages'])); |
2941
|
|
|
|
2942
|
|
|
// If this is the current member we need to make their message count correct. |
2943
|
|
|
if ($user_info['id'] == $row['id_member']) |
2944
|
|
|
{ |
2945
|
|
|
$user_info['messages'] -= $row['num_deleted_messages']; |
2946
|
|
|
if (!($row['is_read'])) |
2947
|
|
|
$user_info['unread_messages'] -= $row['num_deleted_messages']; |
2948
|
|
|
} |
2949
|
|
|
} |
2950
|
|
|
$smcFunc['db_free_result']($request); |
2951
|
|
|
|
2952
|
|
|
// Do the actual deletion. |
2953
|
|
|
$smcFunc['db_query']('', ' |
2954
|
|
|
UPDATE {db_prefix}pm_recipients |
2955
|
|
|
SET deleted = {int:is_deleted} |
2956
|
|
|
WHERE id_member IN ({array_int:member_list}) |
2957
|
|
|
AND deleted = {int:not_deleted}' . $where, |
2958
|
|
|
array( |
2959
|
|
|
'member_list' => $owner, |
2960
|
|
|
'is_deleted' => 1, |
2961
|
|
|
'not_deleted' => 0, |
2962
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
2963
|
|
|
) |
2964
|
|
|
); |
2965
|
|
|
|
2966
|
|
|
$labels = array(); |
2967
|
|
|
|
2968
|
|
|
// Get any labels that the owner may have applied to this PM |
2969
|
|
|
// The join is here to ensure we only get labels applied by the specified member(s) |
2970
|
|
|
$get_labels = $smcFunc['db_query']('', ' |
2971
|
|
|
SELECT pml.id_label |
2972
|
|
|
FROM {db_prefix}pm_labels AS l |
2973
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_label = l.id_label) |
2974
|
|
|
WHERE l.id_member IN ({array_int:member_list})' . $where, |
2975
|
|
|
array( |
2976
|
|
|
'member_list' => $owner, |
2977
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
2978
|
|
|
) |
2979
|
|
|
); |
2980
|
|
|
|
2981
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($get_labels)) |
2982
|
|
|
{ |
2983
|
|
|
$labels[] = $row['id_label']; |
2984
|
|
|
} |
2985
|
|
|
|
2986
|
|
|
$smcFunc['db_free_result']($get_labels); |
2987
|
|
|
|
2988
|
|
|
if (!empty($labels)) |
2989
|
|
|
{ |
2990
|
|
|
$smcFunc['db_query']('', ' |
2991
|
|
|
DELETE FROM {db_prefix}pm_labeled_messages |
2992
|
|
|
WHERE id_label IN ({array_int:labels})' . $where, |
2993
|
|
|
array( |
2994
|
|
|
'labels' => $labels, |
2995
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
2996
|
|
|
) |
2997
|
|
|
); |
2998
|
|
|
} |
2999
|
|
|
} |
3000
|
|
|
|
3001
|
|
|
// If sender and recipients all have deleted their message, it can be removed. |
3002
|
|
|
$request = $smcFunc['db_query']('', ' |
3003
|
|
|
SELECT pm.id_pm AS sender, pmr.id_pm |
3004
|
|
|
FROM {db_prefix}personal_messages AS pm |
3005
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm AND pmr.deleted = {int:not_deleted}) |
3006
|
|
|
WHERE pm.deleted_by_sender = {int:is_deleted} AND pmr.id_pm is null |
3007
|
|
|
' . str_replace('id_pm', 'pm.id_pm', $where), |
3008
|
|
|
array( |
3009
|
|
|
'not_deleted' => 0, |
3010
|
|
|
'is_deleted' => 1, |
3011
|
|
|
'pm_list' => $personal_messages !== null ? array_unique($personal_messages) : array(), |
3012
|
|
|
) |
3013
|
|
|
); |
3014
|
|
|
$remove_pms = array(); |
3015
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3016
|
|
|
$remove_pms[] = $row['sender']; |
3017
|
|
|
$smcFunc['db_free_result']($request); |
3018
|
|
|
|
3019
|
|
View Code Duplication |
if (!empty($remove_pms)) |
|
|
|
|
3020
|
|
|
{ |
3021
|
|
|
$smcFunc['db_query']('', ' |
3022
|
|
|
DELETE FROM {db_prefix}personal_messages |
3023
|
|
|
WHERE id_pm IN ({array_int:pm_list})', |
3024
|
|
|
array( |
3025
|
|
|
'pm_list' => $remove_pms, |
3026
|
|
|
) |
3027
|
|
|
); |
3028
|
|
|
|
3029
|
|
|
$smcFunc['db_query']('', ' |
3030
|
|
|
DELETE FROM {db_prefix}pm_recipients |
3031
|
|
|
WHERE id_pm IN ({array_int:pm_list})', |
3032
|
|
|
array( |
3033
|
|
|
'pm_list' => $remove_pms, |
3034
|
|
|
) |
3035
|
|
|
); |
3036
|
|
|
|
3037
|
|
|
$smcFunc['db_query']('', ' |
3038
|
|
|
DELETE FROM {db_prefix}pm_labeled_messages |
3039
|
|
|
WHERE id_pm IN ({array_int:pm_list})', |
3040
|
|
|
array( |
3041
|
|
|
'pm_list' => $remove_pms, |
3042
|
|
|
) |
3043
|
|
|
); |
3044
|
|
|
} |
3045
|
|
|
|
3046
|
|
|
// Any cached numbers may be wrong now. |
3047
|
|
|
cache_put_data('labelCounts:' . $user_info['id'], null, 720); |
3048
|
|
|
} |
3049
|
|
|
|
3050
|
|
|
/** |
3051
|
|
|
* Mark the specified personal messages read. |
3052
|
|
|
* |
3053
|
|
|
* @param array|null $personal_messages An array of PM IDs to mark or null to mark all |
3054
|
|
|
* @param int|null $label The ID of a label. If set, only messages with this label will be marked. |
3055
|
|
|
* @param int|null $owner If owner is set, marks messages owned by that member id |
3056
|
|
|
*/ |
3057
|
|
|
function markMessages($personal_messages = null, $label = null, $owner = null) |
3058
|
|
|
{ |
3059
|
|
|
global $user_info, $context, $smcFunc; |
3060
|
|
|
|
3061
|
|
|
if ($owner === null) |
3062
|
|
|
$owner = $user_info['id']; |
3063
|
|
|
|
3064
|
|
|
$in_inbox = ''; |
3065
|
|
|
|
3066
|
|
|
// Marking all messages with a specific label as read? |
3067
|
|
|
// If we know which PMs we're marking read, then we don't need label info |
3068
|
|
|
if ($personal_messages === null && $label !== null && $label != '-1') |
3069
|
|
|
{ |
3070
|
|
|
$personal_messages = array(); |
3071
|
|
|
$get_messages = $smcFunc['db_query']('', ' |
3072
|
|
|
SELECT id_pm |
3073
|
|
|
FROM {db_prefix}pm_labeled_messages |
3074
|
|
|
WHERE id_label = {int:current_label}', |
3075
|
|
|
array( |
3076
|
|
|
'current_label' => $label, |
3077
|
|
|
) |
3078
|
|
|
); |
3079
|
|
|
|
3080
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($get_messages)) |
3081
|
|
|
{ |
3082
|
|
|
$personal_messages[] = $row['id_pm']; |
3083
|
|
|
} |
3084
|
|
|
|
3085
|
|
|
$smcFunc['db_free_result']($get_messages); |
3086
|
|
|
} |
3087
|
|
|
elseif ($label = '-1') |
3088
|
|
|
{ |
3089
|
|
|
// Marking all PMs in your inbox read |
3090
|
|
|
$in_inbox = ' |
3091
|
|
|
AND in_inbox = {int:in_inbox}'; |
3092
|
|
|
} |
3093
|
|
|
|
3094
|
|
|
$smcFunc['db_query']('', ' |
3095
|
|
|
UPDATE {db_prefix}pm_recipients |
3096
|
|
|
SET is_read = is_read | 1 |
3097
|
|
|
WHERE id_member = {int:id_member} |
3098
|
|
|
AND NOT (is_read & 1 >= 1)' . ($personal_messages !== null ? ' |
3099
|
|
|
AND id_pm IN ({array_int:personal_messages})' : '') . $in_inbox, |
3100
|
|
|
array( |
3101
|
|
|
'personal_messages' => $personal_messages, |
3102
|
|
|
'id_member' => $owner, |
3103
|
|
|
'in_inbox' => 1, |
3104
|
|
|
) |
3105
|
|
|
); |
3106
|
|
|
|
3107
|
|
|
// If something wasn't marked as read, get the number of unread messages remaining. |
3108
|
|
|
if ($smcFunc['db_affected_rows']() > 0) |
3109
|
|
|
{ |
3110
|
|
|
if ($owner == $user_info['id']) |
3111
|
|
|
{ |
3112
|
|
|
foreach ($context['labels'] as $label) |
3113
|
|
|
$context['labels'][(int) $label['id']]['unread_messages'] = 0; |
3114
|
|
|
} |
3115
|
|
|
|
3116
|
|
|
$result = $smcFunc['db_query']('', ' |
3117
|
|
|
SELECT id_pm, in_inbox, COUNT(*) AS num |
3118
|
|
|
FROM {db_prefix}pm_recipients |
3119
|
|
|
WHERE id_member = {int:id_member} |
3120
|
|
|
AND NOT (is_read & 1 >= 1) |
3121
|
|
|
AND deleted = {int:is_not_deleted} |
3122
|
|
|
GROUP BY id_pm, in_inbox', |
3123
|
|
|
array( |
3124
|
|
|
'id_member' => $owner, |
3125
|
|
|
'is_not_deleted' => 0, |
3126
|
|
|
) |
3127
|
|
|
); |
3128
|
|
|
$total_unread = 0; |
3129
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
3130
|
|
|
{ |
3131
|
|
|
$total_unread += $row['num']; |
3132
|
|
|
|
3133
|
|
|
if ($owner != $user_info['id'] || empty($row['id_pm'])) |
3134
|
|
|
continue; |
3135
|
|
|
|
3136
|
|
|
$this_labels = array(); |
3137
|
|
|
|
3138
|
|
|
// Get all the labels |
3139
|
|
|
$result2 = $smcFunc['db_query']('', ' |
3140
|
|
|
SELECT pml.id_label |
3141
|
|
|
FROM {db_prefix}pm_labels AS l |
3142
|
|
|
INNER JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_label = l.id_label) |
3143
|
|
|
WHERE l.id_member = {int:id_member} |
3144
|
|
|
AND pml.id_pm = {int:current_pm}', |
3145
|
|
|
array( |
3146
|
|
|
'id_member' => $owner, |
3147
|
|
|
'current_pm' => $row['id_pm'], |
3148
|
|
|
) |
3149
|
|
|
); |
3150
|
|
|
|
3151
|
|
|
while ($row2 = $smcFunc['db_fetch_assoc']($result2)) |
3152
|
|
|
{ |
3153
|
|
|
$this_labels[] = $row2['id_label']; |
3154
|
|
|
} |
3155
|
|
|
|
3156
|
|
|
$smcFunc['db_free_result']($result2); |
3157
|
|
|
|
3158
|
|
|
foreach ($this_labels as $this_label) |
3159
|
|
|
$context['labels'][$this_label]['unread_messages'] += $row['num']; |
3160
|
|
|
|
3161
|
|
|
if ($row['in_inbox'] == 1) |
3162
|
|
|
$context['labels'][-1]['unread_messages'] += $row['num']; |
3163
|
|
|
} |
3164
|
|
|
$smcFunc['db_free_result']($result); |
3165
|
|
|
|
3166
|
|
|
// Need to store all this. |
3167
|
|
|
cache_put_data('labelCounts:' . $owner, $context['labels'], 720); |
3168
|
|
|
updateMemberData($owner, array('unread_messages' => $total_unread)); |
3169
|
|
|
|
3170
|
|
|
// If it was for the current member, reflect this in the $user_info array too. |
3171
|
|
|
if ($owner == $user_info['id']) |
3172
|
|
|
$user_info['unread_messages'] = $total_unread; |
3173
|
|
|
} |
3174
|
|
|
} |
3175
|
|
|
|
3176
|
|
|
/** |
3177
|
|
|
* This function handles adding, deleting and editing labels on messages. |
3178
|
|
|
*/ |
3179
|
|
|
function ManageLabels() |
3180
|
|
|
{ |
3181
|
|
|
global $txt, $context, $user_info, $scripturl, $smcFunc; |
3182
|
|
|
|
3183
|
|
|
// Build the link tree elements... |
3184
|
|
|
$context['linktree'][] = array( |
3185
|
|
|
'url' => $scripturl . '?action=pm;sa=manlabels', |
3186
|
|
|
'name' => $txt['pm_manage_labels'] |
3187
|
|
|
); |
3188
|
|
|
|
3189
|
|
|
$context['page_title'] = $txt['pm_manage_labels']; |
3190
|
|
|
$context['sub_template'] = 'labels'; |
3191
|
|
|
|
3192
|
|
|
$the_labels = array(); |
3193
|
|
|
$labels_to_add = array(); |
3194
|
|
|
$labels_to_remove = array(); |
3195
|
|
|
$label_updates = array(); |
3196
|
|
|
|
3197
|
|
|
// Add all existing labels to the array to save, slashing them as necessary... |
3198
|
|
|
foreach ($context['labels'] as $label) |
3199
|
|
|
{ |
3200
|
|
|
if ($label['id'] != -1) |
3201
|
|
|
$the_labels[$label['id']] = $label['name']; |
3202
|
|
|
} |
3203
|
|
|
|
3204
|
|
|
if (isset($_POST[$context['session_var']])) |
3205
|
|
|
{ |
3206
|
|
|
checkSession(); |
3207
|
|
|
|
3208
|
|
|
// This will be for updating messages. |
3209
|
|
|
$message_changes = array(); |
3210
|
|
|
$rule_changes = array(); |
3211
|
|
|
|
3212
|
|
|
// Will most likely need this. |
3213
|
|
|
LoadRules(); |
3214
|
|
|
|
3215
|
|
|
// Adding a new label? |
3216
|
|
|
if (isset($_POST['add'])) |
3217
|
|
|
{ |
3218
|
|
|
$_POST['label'] = strtr($smcFunc['htmlspecialchars'](trim($_POST['label'])), array(',' => ',')); |
3219
|
|
|
|
3220
|
|
View Code Duplication |
if ($smcFunc['strlen']($_POST['label']) > 30) |
|
|
|
|
3221
|
|
|
$_POST['label'] = $smcFunc['substr']($_POST['label'], 0, 30); |
3222
|
|
|
if ($_POST['label'] != '') |
3223
|
|
|
{ |
3224
|
|
|
$the_labels[] = $_POST['label']; |
3225
|
|
|
$labels_to_add[] = $_POST['label']; |
3226
|
|
|
} |
3227
|
|
|
} |
3228
|
|
|
// Deleting an existing label? |
3229
|
|
|
elseif (isset($_POST['delete'], $_POST['delete_label'])) |
3230
|
|
|
{ |
3231
|
|
|
foreach ($_POST['delete_label'] AS $label => $dummy) |
3232
|
|
|
{ |
3233
|
|
|
unset($the_labels[$label]); |
3234
|
|
|
$labels_to_remove[] = $label; |
3235
|
|
|
} |
3236
|
|
|
} |
3237
|
|
|
// The hardest one to deal with... changes. |
3238
|
|
|
elseif (isset($_POST['save']) && !empty($_POST['label_name'])) |
3239
|
|
|
{ |
3240
|
|
|
foreach ($the_labels as $id => $name) |
3241
|
|
|
{ |
3242
|
|
|
if ($id == -1) |
3243
|
|
|
continue; |
3244
|
|
|
elseif (isset($_POST['label_name'][$id])) |
3245
|
|
|
{ |
3246
|
|
|
$_POST['label_name'][$id] = trim(strtr($smcFunc['htmlspecialchars']($_POST['label_name'][$id]), array(',' => ','))); |
3247
|
|
|
|
3248
|
|
|
if ($smcFunc['strlen']($_POST['label_name'][$id]) > 30) |
3249
|
|
|
$_POST['label_name'][$id] = $smcFunc['substr']($_POST['label_name'][$id], 0, 30); |
3250
|
|
|
if ($_POST['label_name'][$id] != '') |
3251
|
|
|
{ |
3252
|
|
|
// Changing the name of this label? |
3253
|
|
|
if ($the_labels[$id] != $_POST['label_name'][$id]) |
3254
|
|
|
$label_updates[$id] = $_POST['label_name'][$id]; |
3255
|
|
|
|
3256
|
|
|
$the_labels[(int) $id] = $_POST['label_name'][$id]; |
3257
|
|
|
|
3258
|
|
|
} |
3259
|
|
|
else |
3260
|
|
|
{ |
3261
|
|
|
unset($the_labels[(int) $id]); |
3262
|
|
|
$labels_to_remove[] = $id; |
3263
|
|
|
$message_changes[(int) $id] = true; |
3264
|
|
|
} |
3265
|
|
|
} |
3266
|
|
|
} |
3267
|
|
|
} |
3268
|
|
|
|
3269
|
|
|
// Save any new labels |
3270
|
|
View Code Duplication |
if (!empty($labels_to_add)) |
|
|
|
|
3271
|
|
|
{ |
3272
|
|
|
$inserts = array(); |
3273
|
|
|
foreach ($labels_to_add AS $label) |
3274
|
|
|
$inserts[] = array($user_info['id'], $label); |
3275
|
|
|
|
3276
|
|
|
$smcFunc['db_insert']('', '{db_prefix}pm_labels', array('id_member' => 'int', 'name' => 'string-30'), $inserts, array()); |
3277
|
|
|
} |
3278
|
|
|
|
3279
|
|
|
// Update existing labels as needed |
3280
|
|
|
if (!empty($label_upates)) |
|
|
|
|
3281
|
|
|
{ |
3282
|
|
|
foreach ($label_updates AS $id => $name) |
3283
|
|
|
{ |
3284
|
|
|
$smcFunc['db_query']('', ' |
3285
|
|
|
UPDATE {db_prefix}labels |
3286
|
|
|
SET name = {string:name} |
3287
|
|
|
WHERE id_label = {int:id_label}', |
3288
|
|
|
array( |
3289
|
|
|
'name' => $name, |
3290
|
|
|
'id' => $id |
3291
|
|
|
) |
3292
|
|
|
); |
3293
|
|
|
} |
3294
|
|
|
} |
3295
|
|
|
|
3296
|
|
|
// Now the fun part... Deleting labels. |
3297
|
|
|
if (!empty($labels_to_remove)) |
3298
|
|
|
{ |
3299
|
|
|
// First delete the labels |
3300
|
|
|
$smcFunc['db_query']('', ' |
3301
|
|
|
DELETE FROM {db_prefix}pm_labels |
3302
|
|
|
WHERE id_label IN ({array_int:labels_to_delete})', |
3303
|
|
|
array( |
3304
|
|
|
'labels_to_delete' => $labels_to_remove, |
3305
|
|
|
) |
3306
|
|
|
); |
3307
|
|
|
|
3308
|
|
|
// Now remove the now-deleted labels from any PMs... |
3309
|
|
|
$smcFunc['db_query']('', ' |
3310
|
|
|
DELETE FROM {db_prefix}pm_labeled_messages |
3311
|
|
|
WHERE id_label IN ({array_int:labels_to_delete})', |
3312
|
|
|
array( |
3313
|
|
|
'labels_to_delete' => $labels_to_remove, |
3314
|
|
|
) |
3315
|
|
|
); |
3316
|
|
|
|
3317
|
|
|
// Get any PMs with no labels which aren't in the inbox |
3318
|
|
|
$get_stranded_pms = $smcFunc['db_query']('', ' |
3319
|
|
|
SELECT pmr.id_pm |
3320
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
3321
|
|
|
LEFT JOIN {db_prefix}pm_labeled_messages AS pml ON (pml.id_pm = pmr.id_pm) |
3322
|
|
|
WHERE pml.id_label IS NULL |
3323
|
|
|
AND pmr.in_inbox = {int:not_in_inbox} |
3324
|
|
|
AND pmr.deleted = {int:not_deleted} |
3325
|
|
|
AND pmr.id_member = {int:current_member}', |
3326
|
|
|
array( |
3327
|
|
|
'not_in_inbox' => 0, |
3328
|
|
|
'not_deleted' => 0, |
3329
|
|
|
'current_member' => $user_info['id'], |
3330
|
|
|
) |
3331
|
|
|
); |
3332
|
|
|
|
3333
|
|
|
$stranded_messages = array(); |
3334
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($get_stranded_pms)) |
3335
|
|
|
{ |
3336
|
|
|
$stranded_messages[] = $row['id_pm']; |
3337
|
|
|
} |
3338
|
|
|
|
3339
|
|
|
$smcFunc['db_free_result']($get_stranded_pms); |
3340
|
|
|
|
3341
|
|
|
// Move these back to the inbox if necessary |
3342
|
|
|
if (!empty($stranded_messages)) |
3343
|
|
|
{ |
3344
|
|
|
// We now have more messages in the inbox |
3345
|
|
|
$context['labels'][-1]['messages'] += count($stranded_messages); |
3346
|
|
|
$smcFunc['db_query']('', ' |
3347
|
|
|
UPDATE {db_prefix}pm_recipients |
3348
|
|
|
SET in_inbox = {int:in_inbox} |
3349
|
|
|
WHERE id_pm IN ({array_int:stranded_messages}) |
3350
|
|
|
AND id_member = {int:current_member}', |
3351
|
|
|
array( |
3352
|
|
|
'stranded_messages' => $stranded_messages, |
3353
|
|
|
'in_inbox' => 1, |
3354
|
|
|
) |
3355
|
|
|
); |
3356
|
|
|
} |
3357
|
|
|
|
3358
|
|
|
// Now do the same the rules - check through each rule. |
3359
|
|
|
foreach ($context['rules'] as $k => $rule) |
3360
|
|
|
{ |
3361
|
|
|
// Each action... |
3362
|
|
|
foreach ($rule['actions'] as $k2 => $action) |
3363
|
|
|
{ |
3364
|
|
|
if ($action['t'] != 'lab' || !in_array($action['v'], $labels_to_remove)) |
3365
|
|
|
continue; |
3366
|
|
|
|
3367
|
|
|
$rule_changes[] = $rule['id']; |
3368
|
|
|
|
3369
|
|
|
// Can't apply this label anymore if it doesn't exist |
3370
|
|
|
unset($context['rules'][$k]['actions'][$k2]); |
3371
|
|
|
} |
3372
|
|
|
} |
3373
|
|
|
} |
3374
|
|
|
|
3375
|
|
|
// If we have rules to change do so now. |
3376
|
|
|
if (!empty($rule_changes)) |
3377
|
|
|
{ |
3378
|
|
|
$rule_changes = array_unique($rule_changes); |
3379
|
|
|
// Update/delete as appropriate. |
3380
|
|
|
foreach ($rule_changes as $k => $id) |
3381
|
|
|
if (!empty($context['rules'][$id]['actions'])) |
3382
|
|
|
{ |
3383
|
|
|
$smcFunc['db_query']('', ' |
3384
|
|
|
UPDATE {db_prefix}pm_rules |
3385
|
|
|
SET actions = {string:actions} |
3386
|
|
|
WHERE id_rule = {int:id_rule} |
3387
|
|
|
AND id_member = {int:current_member}', |
3388
|
|
|
array( |
3389
|
|
|
'current_member' => $user_info['id'], |
3390
|
|
|
'id_rule' => $id, |
3391
|
|
|
'actions' => json_encode($context['rules'][$id]['actions']), |
3392
|
|
|
) |
3393
|
|
|
); |
3394
|
|
|
unset($rule_changes[$k]); |
3395
|
|
|
} |
3396
|
|
|
|
3397
|
|
|
// Anything left here means it's lost all actions... |
3398
|
|
|
if (!empty($rule_changes)) |
3399
|
|
|
$smcFunc['db_query']('', ' |
3400
|
|
|
DELETE FROM {db_prefix}pm_rules |
3401
|
|
|
WHERE id_rule IN ({array_int:rule_list}) |
3402
|
|
|
AND id_member = {int:current_member}', |
3403
|
|
|
array( |
3404
|
|
|
'current_member' => $user_info['id'], |
3405
|
|
|
'rule_list' => $rule_changes, |
3406
|
|
|
) |
3407
|
|
|
); |
3408
|
|
|
} |
3409
|
|
|
|
3410
|
|
|
// Make sure we're not caching this! |
3411
|
|
|
cache_put_data('labelCounts:' . $user_info['id'], null, 720); |
3412
|
|
|
|
3413
|
|
|
// To make the changes appear right away, redirect. |
3414
|
|
|
redirectexit('action=pm;sa=manlabels'); |
3415
|
|
|
} |
3416
|
|
|
} |
3417
|
|
|
|
3418
|
|
|
/** |
3419
|
|
|
* Allows to edit Personal Message Settings. |
3420
|
|
|
* |
3421
|
|
|
* @uses Profile.php |
3422
|
|
|
* @uses Profile-Modify.php |
3423
|
|
|
* @uses Profile template. |
3424
|
|
|
* @uses Profile language file. |
3425
|
|
|
*/ |
3426
|
|
|
function MessageSettings() |
3427
|
|
|
{ |
3428
|
|
|
global $txt, $user_info, $context, $sourcedir; |
3429
|
|
|
global $scripturl, $profile_vars, $cur_profile, $user_profile; |
3430
|
|
|
|
3431
|
|
|
// Need this for the display. |
3432
|
|
|
require_once($sourcedir . '/Profile.php'); |
3433
|
|
|
require_once($sourcedir . '/Profile-Modify.php'); |
3434
|
|
|
|
3435
|
|
|
// We want them to submit back to here. |
3436
|
|
|
$context['profile_custom_submit_url'] = $scripturl . '?action=pm;sa=settings;save'; |
3437
|
|
|
|
3438
|
|
|
loadMemberData($user_info['id'], false, 'profile'); |
3439
|
|
|
$cur_profile = $user_profile[$user_info['id']]; |
3440
|
|
|
|
3441
|
|
|
loadLanguage('Profile'); |
3442
|
|
|
loadTemplate('Profile'); |
3443
|
|
|
|
3444
|
|
|
// Since this is internally handled with the profile code because that's how it was done ages ago |
3445
|
|
|
// we have to set everything up for handling this... |
3446
|
|
|
$context['page_title'] = $txt['pm_settings']; |
3447
|
|
|
$context['user']['is_owner'] = true; |
3448
|
|
|
$context['id_member'] = $user_info['id']; |
3449
|
|
|
$context['require_password'] = false; |
3450
|
|
|
$context['menu_item_selected'] = 'settings'; |
3451
|
|
|
$context['submit_button_text'] = $txt['pm_settings']; |
3452
|
|
|
$context['profile_header_text'] = $txt['personal_messages']; |
3453
|
|
|
$context['sub_template'] = 'edit_options'; |
3454
|
|
|
$context['page_desc'] = $txt['pm_settings_desc']; |
3455
|
|
|
|
3456
|
|
|
loadThemeOptions($user_info['id']); |
3457
|
|
|
loadCustomFields($user_info['id'], 'pmprefs'); |
3458
|
|
|
|
3459
|
|
|
// Add our position to the linktree. |
3460
|
|
|
$context['linktree'][] = array( |
3461
|
|
|
'url' => $scripturl . '?action=pm;sa=settings', |
3462
|
|
|
'name' => $txt['pm_settings'] |
3463
|
|
|
); |
3464
|
|
|
|
3465
|
|
|
// Are they saving? |
3466
|
|
|
if (isset($_REQUEST['save'])) |
3467
|
|
|
{ |
3468
|
|
|
checkSession(); |
3469
|
|
|
|
3470
|
|
|
// Mimic what profile would do. |
3471
|
|
|
$_POST = htmltrim__recursive($_POST); |
3472
|
|
|
$_POST = htmlspecialchars__recursive($_POST); |
3473
|
|
|
|
3474
|
|
|
// Save the fields. |
3475
|
|
|
saveProfileFields(); |
3476
|
|
|
|
3477
|
|
|
if (!empty($profile_vars)) |
3478
|
|
|
updateMemberData($user_info['id'], $profile_vars); |
3479
|
|
|
} |
3480
|
|
|
|
3481
|
|
|
setupProfileContext( |
3482
|
|
|
array( |
3483
|
|
|
'pm_prefs', |
3484
|
|
|
) |
3485
|
|
|
); |
3486
|
|
|
} |
3487
|
|
|
|
3488
|
|
|
/** |
3489
|
|
|
* Allows the user to report a personal message to an administrator. |
3490
|
|
|
* |
3491
|
|
|
* - In the first instance requires that the ID of the message to report is passed through $_GET. |
3492
|
|
|
* - It allows the user to report to either a particular administrator - or the whole admin team. |
3493
|
|
|
* - It will forward on a copy of the original message without allowing the reporter to make changes. |
3494
|
|
|
* |
3495
|
|
|
* @uses report_message sub-template. |
3496
|
|
|
*/ |
3497
|
|
|
function ReportMessage() |
3498
|
|
|
{ |
3499
|
|
|
global $txt, $context, $scripturl; |
3500
|
|
|
global $user_info, $language, $modSettings, $smcFunc; |
3501
|
|
|
|
3502
|
|
|
// Check that this feature is even enabled! |
3503
|
|
|
if (empty($modSettings['enableReportPM']) || empty($_REQUEST['pmsg'])) |
3504
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
3505
|
|
|
|
3506
|
|
|
$pmsg = (int) $_REQUEST['pmsg']; |
3507
|
|
|
|
3508
|
|
|
if (!isAccessiblePM($pmsg, 'inbox')) |
3509
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
3510
|
|
|
|
3511
|
|
|
$context['pm_id'] = $pmsg; |
3512
|
|
|
$context['page_title'] = $txt['pm_report_title']; |
3513
|
|
|
|
3514
|
|
|
// If we're here, just send the user to the template, with a few useful context bits. |
3515
|
|
|
if (!isset($_POST['report'])) |
3516
|
|
|
{ |
3517
|
|
|
$context['sub_template'] = 'report_message'; |
3518
|
|
|
|
3519
|
|
|
// @todo I don't like being able to pick who to send it to. Favoritism, etc. sucks. |
3520
|
|
|
// Now, get all the administrators. |
3521
|
|
|
$request = $smcFunc['db_query']('', ' |
3522
|
|
|
SELECT id_member, real_name |
3523
|
|
|
FROM {db_prefix}members |
3524
|
|
|
WHERE id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0 |
3525
|
|
|
ORDER BY real_name', |
3526
|
|
|
array( |
3527
|
|
|
'admin_group' => 1, |
3528
|
|
|
) |
3529
|
|
|
); |
3530
|
|
|
$context['admins'] = array(); |
3531
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3532
|
|
|
$context['admins'][$row['id_member']] = $row['real_name']; |
3533
|
|
|
$smcFunc['db_free_result']($request); |
3534
|
|
|
|
3535
|
|
|
// How many admins in total? |
3536
|
|
|
$context['admin_count'] = count($context['admins']); |
3537
|
|
|
} |
3538
|
|
|
// Otherwise, let's get down to the sending stuff. |
3539
|
|
|
else |
3540
|
|
|
{ |
3541
|
|
|
// Check the session before proceeding any further! |
3542
|
|
|
checkSession(); |
3543
|
|
|
|
3544
|
|
|
// First, pull out the message contents, and verify it actually went to them! |
3545
|
|
|
$request = $smcFunc['db_query']('', ' |
3546
|
|
|
SELECT pm.subject, pm.body, pm.msgtime, pm.id_member_from, COALESCE(m.real_name, pm.from_name) AS sender_name |
3547
|
|
|
FROM {db_prefix}personal_messages AS pm |
3548
|
|
|
INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm) |
3549
|
|
|
LEFT JOIN {db_prefix}members AS m ON (m.id_member = pm.id_member_from) |
3550
|
|
|
WHERE pm.id_pm = {int:id_pm} |
3551
|
|
|
AND pmr.id_member = {int:current_member} |
3552
|
|
|
AND pmr.deleted = {int:not_deleted} |
3553
|
|
|
LIMIT 1', |
3554
|
|
|
array( |
3555
|
|
|
'current_member' => $user_info['id'], |
3556
|
|
|
'id_pm' => $context['pm_id'], |
3557
|
|
|
'not_deleted' => 0, |
3558
|
|
|
) |
3559
|
|
|
); |
3560
|
|
|
// Can only be a hacker here! |
3561
|
|
|
if ($smcFunc['db_num_rows']($request) == 0) |
3562
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
3563
|
|
|
list ($subject, $body, $time, $memberFromID, $memberFromName) = $smcFunc['db_fetch_row']($request); |
3564
|
|
|
$smcFunc['db_free_result']($request); |
3565
|
|
|
|
3566
|
|
|
// Remove the line breaks... |
3567
|
|
|
$body = preg_replace('~<br ?/?' . '>~i', "\n", $body); |
3568
|
|
|
|
3569
|
|
|
// Get any other recipients of the email. |
3570
|
|
|
$request = $smcFunc['db_query']('', ' |
3571
|
|
|
SELECT mem_to.id_member AS id_member_to, mem_to.real_name AS to_name, pmr.bcc |
3572
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
3573
|
|
|
LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member) |
3574
|
|
|
WHERE pmr.id_pm = {int:id_pm} |
3575
|
|
|
AND pmr.id_member != {int:current_member}', |
3576
|
|
|
array( |
3577
|
|
|
'current_member' => $user_info['id'], |
3578
|
|
|
'id_pm' => $context['pm_id'], |
3579
|
|
|
) |
3580
|
|
|
); |
3581
|
|
|
$recipients = array(); |
3582
|
|
|
$hidden_recipients = 0; |
3583
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3584
|
|
|
{ |
3585
|
|
|
// If it's hidden still don't reveal their names - privacy after all ;) |
3586
|
|
|
if ($row['bcc']) |
3587
|
|
|
$hidden_recipients++; |
3588
|
|
|
else |
3589
|
|
|
$recipients[] = '[url=' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . ']' . $row['to_name'] . '[/url]'; |
3590
|
|
|
} |
3591
|
|
|
$smcFunc['db_free_result']($request); |
3592
|
|
|
|
3593
|
|
|
if ($hidden_recipients) |
3594
|
|
|
$recipients[] = sprintf($txt['pm_report_pm_hidden'], $hidden_recipients); |
3595
|
|
|
|
3596
|
|
|
// Now let's get out and loop through the admins. |
3597
|
|
|
$request = $smcFunc['db_query']('', ' |
3598
|
|
|
SELECT id_member, real_name, lngfile |
3599
|
|
|
FROM {db_prefix}members |
3600
|
|
|
WHERE (id_group = {int:admin_id} OR FIND_IN_SET({int:admin_id}, additional_groups) != 0) |
3601
|
|
|
' . (empty($_POST['id_admin']) ? '' : 'AND id_member = {int:specific_admin}') . ' |
3602
|
|
|
ORDER BY lngfile', |
3603
|
|
|
array( |
3604
|
|
|
'admin_id' => 1, |
3605
|
|
|
'specific_admin' => isset($_POST['id_admin']) ? (int) $_POST['id_admin'] : 0, |
3606
|
|
|
) |
3607
|
|
|
); |
3608
|
|
|
|
3609
|
|
|
// Maybe we shouldn't advertise this? |
3610
|
|
|
if ($smcFunc['db_num_rows']($request) == 0) |
3611
|
|
|
fatal_lang_error('no_access', false); |
|
|
|
|
3612
|
|
|
|
3613
|
|
|
$memberFromName = un_htmlspecialchars($memberFromName); |
3614
|
|
|
|
3615
|
|
|
// Prepare the message storage array. |
3616
|
|
|
$messagesToSend = array(); |
3617
|
|
|
// Loop through each admin, and add them to the right language pile... |
3618
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3619
|
|
|
{ |
3620
|
|
|
// Need to send in the correct language! |
3621
|
|
|
$cur_language = empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']; |
3622
|
|
|
|
3623
|
|
|
if (!isset($messagesToSend[$cur_language])) |
3624
|
|
|
{ |
3625
|
|
|
loadLanguage('PersonalMessage', $cur_language, false); |
3626
|
|
|
|
3627
|
|
|
// Make the body. |
3628
|
|
|
$report_body = str_replace(array('{REPORTER}', '{SENDER}'), array(un_htmlspecialchars($user_info['name']), $memberFromName), $txt['pm_report_pm_user_sent']); |
3629
|
|
|
$report_body .= "\n" . '[b]' . $_POST['reason'] . '[/b]' . "\n\n"; |
3630
|
|
|
if (!empty($recipients)) |
3631
|
|
|
$report_body .= $txt['pm_report_pm_other_recipients'] . ' ' . implode(', ', $recipients) . "\n\n"; |
3632
|
|
|
$report_body .= $txt['pm_report_pm_unedited_below'] . "\n" . '[quote author=' . (empty($memberFromID) ? '"' . $memberFromName . '"' : $memberFromName . ' link=action=profile;u=' . $memberFromID . ' date=' . $time) . ']' . "\n" . un_htmlspecialchars($body) . '[/quote]'; |
3633
|
|
|
|
3634
|
|
|
// Plonk it in the array ;) |
3635
|
|
|
$messagesToSend[$cur_language] = array( |
3636
|
|
|
'subject' => ($smcFunc['strpos']($subject, $txt['pm_report_pm_subject']) === false ? $txt['pm_report_pm_subject'] : '') . un_htmlspecialchars($subject), |
3637
|
|
|
'body' => $report_body, |
3638
|
|
|
'recipients' => array( |
3639
|
|
|
'to' => array(), |
3640
|
|
|
'bcc' => array() |
3641
|
|
|
), |
3642
|
|
|
); |
3643
|
|
|
} |
3644
|
|
|
|
3645
|
|
|
// Add them to the list. |
3646
|
|
|
$messagesToSend[$cur_language]['recipients']['to'][$row['id_member']] = $row['id_member']; |
3647
|
|
|
} |
3648
|
|
|
$smcFunc['db_free_result']($request); |
3649
|
|
|
|
3650
|
|
|
// Send a different email for each language. |
3651
|
|
|
foreach ($messagesToSend as $lang => $message) |
3652
|
|
|
sendpm($message['recipients'], $message['subject'], $message['body']); |
3653
|
|
|
|
3654
|
|
|
// Give the user their own language back! |
3655
|
|
|
if (!empty($modSettings['userLanguage'])) |
3656
|
|
|
loadLanguage('PersonalMessage', '', false); |
3657
|
|
|
|
3658
|
|
|
// Leave them with a template. |
3659
|
|
|
$context['sub_template'] = 'report_message_complete'; |
3660
|
|
|
} |
3661
|
|
|
} |
3662
|
|
|
|
3663
|
|
|
/** |
3664
|
|
|
* List all rules, and allow adding/entering etc... |
3665
|
|
|
*/ |
3666
|
|
|
function ManageRules() |
3667
|
|
|
{ |
3668
|
|
|
global $txt, $context, $user_info, $scripturl, $smcFunc; |
3669
|
|
|
|
3670
|
|
|
// The link tree - gotta have this :o |
3671
|
|
|
$context['linktree'][] = array( |
3672
|
|
|
'url' => $scripturl . '?action=pm;sa=manrules', |
3673
|
|
|
'name' => $txt['pm_manage_rules'] |
3674
|
|
|
); |
3675
|
|
|
|
3676
|
|
|
$context['page_title'] = $txt['pm_manage_rules']; |
3677
|
|
|
$context['sub_template'] = 'rules'; |
3678
|
|
|
|
3679
|
|
|
// Load them... load them!! |
3680
|
|
|
LoadRules(); |
3681
|
|
|
|
3682
|
|
|
// Likely to need all the groups! |
3683
|
|
|
$request = $smcFunc['db_query']('', ' |
3684
|
|
|
SELECT mg.id_group, mg.group_name, COALESCE(gm.id_member, 0) AS can_moderate, mg.hidden |
3685
|
|
|
FROM {db_prefix}membergroups AS mg |
3686
|
|
|
LEFT JOIN {db_prefix}group_moderators AS gm ON (gm.id_group = mg.id_group AND gm.id_member = {int:current_member}) |
3687
|
|
|
WHERE mg.min_posts = {int:min_posts} |
3688
|
|
|
AND mg.id_group != {int:moderator_group} |
3689
|
|
|
AND mg.hidden = {int:not_hidden} |
3690
|
|
|
ORDER BY mg.group_name', |
3691
|
|
|
array( |
3692
|
|
|
'current_member' => $user_info['id'], |
3693
|
|
|
'min_posts' => -1, |
3694
|
|
|
'moderator_group' => 3, |
3695
|
|
|
'not_hidden' => 0, |
3696
|
|
|
) |
3697
|
|
|
); |
3698
|
|
|
$context['groups'] = array(); |
3699
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3700
|
|
|
{ |
3701
|
|
|
// Hide hidden groups! |
3702
|
|
|
if ($row['hidden'] && !$row['can_moderate'] && !allowedTo('manage_membergroups')) |
3703
|
|
|
continue; |
3704
|
|
|
|
3705
|
|
|
$context['groups'][$row['id_group']] = $row['group_name']; |
3706
|
|
|
} |
3707
|
|
|
$smcFunc['db_free_result']($request); |
3708
|
|
|
|
3709
|
|
|
// Applying all rules? |
3710
|
|
|
if (isset($_GET['apply'])) |
3711
|
|
|
{ |
3712
|
|
|
checkSession('get'); |
3713
|
|
|
|
3714
|
|
|
ApplyRules(true); |
3715
|
|
|
redirectexit('action=pm;sa=manrules'); |
3716
|
|
|
} |
3717
|
|
|
// Editing a specific one? |
3718
|
|
|
if (isset($_GET['add'])) |
3719
|
|
|
{ |
3720
|
|
|
$context['rid'] = isset($_GET['rid']) && isset($context['rules'][$_GET['rid']]) ? (int) $_GET['rid'] : 0; |
3721
|
|
|
$context['sub_template'] = 'add_rule'; |
3722
|
|
|
|
3723
|
|
|
// Current rule information... |
3724
|
|
|
if ($context['rid']) |
3725
|
|
|
{ |
3726
|
|
|
$context['rule'] = $context['rules'][$context['rid']]; |
3727
|
|
|
$members = array(); |
3728
|
|
|
// Need to get member names! |
3729
|
|
|
foreach ($context['rule']['criteria'] as $k => $criteria) |
3730
|
|
|
if ($criteria['t'] == 'mid' && !empty($criteria['v'])) |
3731
|
|
|
$members[(int) $criteria['v']] = $k; |
3732
|
|
|
|
3733
|
|
View Code Duplication |
if (!empty($members)) |
|
|
|
|
3734
|
|
|
{ |
3735
|
|
|
$request = $smcFunc['db_query']('', ' |
3736
|
|
|
SELECT id_member, member_name |
3737
|
|
|
FROM {db_prefix}members |
3738
|
|
|
WHERE id_member IN ({array_int:member_list})', |
3739
|
|
|
array( |
3740
|
|
|
'member_list' => array_keys($members), |
3741
|
|
|
) |
3742
|
|
|
); |
3743
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3744
|
|
|
$context['rule']['criteria'][$members[$row['id_member']]]['v'] = $row['member_name']; |
3745
|
|
|
$smcFunc['db_free_result']($request); |
3746
|
|
|
} |
3747
|
|
|
} |
3748
|
|
|
else |
3749
|
|
|
$context['rule'] = array( |
3750
|
|
|
'id' => '', |
3751
|
|
|
'name' => '', |
3752
|
|
|
'criteria' => array(), |
3753
|
|
|
'actions' => array(), |
3754
|
|
|
'logic' => 'and', |
3755
|
|
|
); |
3756
|
|
|
} |
3757
|
|
|
// Saving? |
3758
|
|
|
elseif (isset($_GET['save'])) |
3759
|
|
|
{ |
3760
|
|
|
checkSession(); |
3761
|
|
|
$context['rid'] = isset($_GET['rid']) && isset($context['rules'][$_GET['rid']]) ? (int) $_GET['rid'] : 0; |
3762
|
|
|
|
3763
|
|
|
// Name is easy! |
3764
|
|
|
$ruleName = $smcFunc['htmlspecialchars'](trim($_POST['rule_name'])); |
3765
|
|
|
if (empty($ruleName)) |
3766
|
|
|
fatal_lang_error('pm_rule_no_name', false); |
|
|
|
|
3767
|
|
|
|
3768
|
|
|
// Sanity check... |
3769
|
|
|
if (empty($_POST['ruletype']) || empty($_POST['acttype'])) |
3770
|
|
|
fatal_lang_error('pm_rule_no_criteria', false); |
|
|
|
|
3771
|
|
|
|
3772
|
|
|
// Let's do the criteria first - it's also hardest! |
3773
|
|
|
$criteria = array(); |
3774
|
|
|
foreach ($_POST['ruletype'] as $ind => $type) |
3775
|
|
|
{ |
3776
|
|
|
// Check everything is here... |
3777
|
|
|
if ($type == 'gid' && (!isset($_POST['ruledefgroup'][$ind]) || !isset($context['groups'][$_POST['ruledefgroup'][$ind]]))) |
3778
|
|
|
continue; |
3779
|
|
|
elseif ($type != 'bud' && !isset($_POST['ruledef'][$ind])) |
3780
|
|
|
continue; |
3781
|
|
|
|
3782
|
|
|
// Members need to be found. |
3783
|
|
|
if ($type == 'mid') |
3784
|
|
|
{ |
3785
|
|
|
$name = trim($_POST['ruledef'][$ind]); |
3786
|
|
|
$request = $smcFunc['db_query']('', ' |
3787
|
|
|
SELECT id_member |
3788
|
|
|
FROM {db_prefix}members |
3789
|
|
|
WHERE real_name = {string:member_name} |
3790
|
|
|
OR member_name = {string:member_name}', |
3791
|
|
|
array( |
3792
|
|
|
'member_name' => $name, |
3793
|
|
|
) |
3794
|
|
|
); |
3795
|
|
|
if ($smcFunc['db_num_rows']($request) == 0) |
3796
|
|
|
{ |
3797
|
|
|
loadLanguage('Errors'); |
3798
|
|
|
fatal_lang_error('invalid_username', false); |
|
|
|
|
3799
|
|
|
} |
3800
|
|
|
list ($memID) = $smcFunc['db_fetch_row']($request); |
3801
|
|
|
$smcFunc['db_free_result']($request); |
3802
|
|
|
|
3803
|
|
|
$criteria[] = array('t' => 'mid', 'v' => $memID); |
3804
|
|
|
} |
3805
|
|
|
elseif ($type == 'bud') |
3806
|
|
|
$criteria[] = array('t' => 'bud', 'v' => 1); |
3807
|
|
|
elseif ($type == 'gid') |
3808
|
|
|
$criteria[] = array('t' => 'gid', 'v' => (int) $_POST['ruledefgroup'][$ind]); |
3809
|
|
|
elseif (in_array($type, array('sub', 'msg')) && trim($_POST['ruledef'][$ind]) != '') |
3810
|
|
|
$criteria[] = array('t' => $type, 'v' => $smcFunc['htmlspecialchars'](trim($_POST['ruledef'][$ind]))); |
3811
|
|
|
} |
3812
|
|
|
|
3813
|
|
|
// Also do the actions! |
3814
|
|
|
$actions = array(); |
3815
|
|
|
$doDelete = 0; |
3816
|
|
|
$isOr = $_POST['rule_logic'] == 'or' ? 1 : 0; |
3817
|
|
|
foreach ($_POST['acttype'] as $ind => $type) |
3818
|
|
|
{ |
3819
|
|
|
// Picking a valid label? |
3820
|
|
|
if ($type == 'lab' && (!isset($_POST['labdef'][$ind]) || !isset($context['labels'][$_POST['labdef'][$ind]]))) |
3821
|
|
|
continue; |
3822
|
|
|
|
3823
|
|
|
// Record what we're doing. |
3824
|
|
|
if ($type == 'del') |
3825
|
|
|
$doDelete = 1; |
3826
|
|
|
elseif ($type == 'lab') |
3827
|
|
|
$actions[] = array('t' => 'lab', 'v' => (int) $_POST['labdef'][$ind]); |
3828
|
|
|
} |
3829
|
|
|
|
3830
|
|
|
if (empty($criteria) || (empty($actions) && !$doDelete)) |
3831
|
|
|
fatal_lang_error('pm_rule_no_criteria', false); |
|
|
|
|
3832
|
|
|
|
3833
|
|
|
// What are we storing? |
3834
|
|
|
$criteria = json_encode($criteria); |
3835
|
|
|
$actions = json_encode($actions); |
3836
|
|
|
|
3837
|
|
|
// Create the rule? |
3838
|
|
|
if (empty($context['rid'])) |
3839
|
|
|
$smcFunc['db_insert']('', |
3840
|
|
|
'{db_prefix}pm_rules', |
3841
|
|
|
array( |
3842
|
|
|
'id_member' => 'int', 'rule_name' => 'string', 'criteria' => 'string', 'actions' => 'string', |
3843
|
|
|
'delete_pm' => 'int', 'is_or' => 'int', |
3844
|
|
|
), |
3845
|
|
|
array( |
3846
|
|
|
$user_info['id'], $ruleName, $criteria, $actions, $doDelete, $isOr, |
3847
|
|
|
), |
3848
|
|
|
array('id_rule') |
3849
|
|
|
); |
3850
|
|
|
else |
3851
|
|
|
$smcFunc['db_query']('', ' |
3852
|
|
|
UPDATE {db_prefix}pm_rules |
3853
|
|
|
SET rule_name = {string:rule_name}, criteria = {string:criteria}, actions = {string:actions}, |
3854
|
|
|
delete_pm = {int:delete_pm}, is_or = {int:is_or} |
3855
|
|
|
WHERE id_rule = {int:id_rule} |
3856
|
|
|
AND id_member = {int:current_member}', |
3857
|
|
|
array( |
3858
|
|
|
'current_member' => $user_info['id'], |
3859
|
|
|
'delete_pm' => $doDelete, |
3860
|
|
|
'is_or' => $isOr, |
3861
|
|
|
'id_rule' => $context['rid'], |
3862
|
|
|
'rule_name' => $ruleName, |
3863
|
|
|
'criteria' => $criteria, |
3864
|
|
|
'actions' => $actions, |
3865
|
|
|
) |
3866
|
|
|
); |
3867
|
|
|
|
3868
|
|
|
redirectexit('action=pm;sa=manrules'); |
3869
|
|
|
} |
3870
|
|
|
// Deleting? |
3871
|
|
|
elseif (isset($_POST['delselected']) && !empty($_POST['delrule'])) |
3872
|
|
|
{ |
3873
|
|
|
checkSession(); |
3874
|
|
|
$toDelete = array(); |
3875
|
|
|
foreach ($_POST['delrule'] as $k => $v) |
3876
|
|
|
$toDelete[] = (int) $k; |
3877
|
|
|
|
3878
|
|
|
if (!empty($toDelete)) |
3879
|
|
|
$smcFunc['db_query']('', ' |
3880
|
|
|
DELETE FROM {db_prefix}pm_rules |
3881
|
|
|
WHERE id_rule IN ({array_int:delete_list}) |
3882
|
|
|
AND id_member = {int:current_member}', |
3883
|
|
|
array( |
3884
|
|
|
'current_member' => $user_info['id'], |
3885
|
|
|
'delete_list' => $toDelete, |
3886
|
|
|
) |
3887
|
|
|
); |
3888
|
|
|
|
3889
|
|
|
redirectexit('action=pm;sa=manrules'); |
3890
|
|
|
} |
3891
|
|
|
} |
3892
|
|
|
|
3893
|
|
|
/** |
3894
|
|
|
* This will apply rules to all unread messages. If all_messages is set will, clearly, do it to all! |
3895
|
|
|
* |
3896
|
|
|
* @param bool $all_messages Whether to apply this to all messages or just unread ones |
3897
|
|
|
*/ |
3898
|
|
|
function ApplyRules($all_messages = false) |
3899
|
|
|
{ |
3900
|
|
|
global $user_info, $smcFunc, $context, $options; |
3901
|
|
|
|
3902
|
|
|
// Want this - duh! |
3903
|
|
|
loadRules(); |
3904
|
|
|
|
3905
|
|
|
// No rules? |
3906
|
|
|
if (empty($context['rules'])) |
3907
|
|
|
return; |
3908
|
|
|
|
3909
|
|
|
// Just unread ones? |
3910
|
|
|
$ruleQuery = $all_messages ? '' : ' AND pmr.is_new = 1'; |
3911
|
|
|
|
3912
|
|
|
// @todo Apply all should have timeout protection! |
3913
|
|
|
// Get all the messages that match this. |
3914
|
|
|
$request = $smcFunc['db_query']('', ' |
3915
|
|
|
SELECT |
3916
|
|
|
pmr.id_pm, pm.id_member_from, pm.subject, pm.body, mem.id_group |
3917
|
|
|
FROM {db_prefix}pm_recipients AS pmr |
3918
|
|
|
INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) |
3919
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) |
3920
|
|
|
WHERE pmr.id_member = {int:current_member} |
3921
|
|
|
AND pmr.deleted = {int:not_deleted} |
3922
|
|
|
' . $ruleQuery, |
3923
|
|
|
array( |
3924
|
|
|
'current_member' => $user_info['id'], |
3925
|
|
|
'not_deleted' => 0, |
3926
|
|
|
) |
3927
|
|
|
); |
3928
|
|
|
$actions = array(); |
3929
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
3930
|
|
|
{ |
3931
|
|
|
foreach ($context['rules'] as $rule) |
3932
|
|
|
{ |
3933
|
|
|
$match = false; |
3934
|
|
|
// Loop through all the criteria hoping to make a match. |
3935
|
|
|
foreach ($rule['criteria'] as $criterium) |
3936
|
|
|
{ |
3937
|
|
|
if (($criterium['t'] == 'mid' && $criterium['v'] == $row['id_member_from']) || ($criterium['t'] == 'gid' && $criterium['v'] == $row['id_group']) || ($criterium['t'] == 'sub' && strpos($row['subject'], $criterium['v']) !== false) || ($criterium['t'] == 'msg' && strpos($row['body'], $criterium['v']) !== false)) |
3938
|
|
|
$match = true; |
3939
|
|
|
// If we're adding and one criteria don't match then we stop! |
3940
|
|
|
elseif ($rule['logic'] == 'and') |
3941
|
|
|
{ |
3942
|
|
|
$match = false; |
3943
|
|
|
break; |
3944
|
|
|
} |
3945
|
|
|
} |
3946
|
|
|
|
3947
|
|
|
// If we have a match the rule must be true - act! |
3948
|
|
|
if ($match) |
3949
|
|
|
{ |
3950
|
|
|
if ($rule['delete']) |
3951
|
|
|
$actions['deletes'][] = $row['id_pm']; |
3952
|
|
|
else |
3953
|
|
|
{ |
3954
|
|
|
foreach ($rule['actions'] as $ruleAction) |
3955
|
|
|
{ |
3956
|
|
|
if ($ruleAction['t'] == 'lab') |
3957
|
|
|
{ |
3958
|
|
|
// Get a basic pot started! |
3959
|
|
|
if (!isset($actions['labels'][$row['id_pm']])) |
3960
|
|
|
$actions['labels'][$row['id_pm']] = array(); |
3961
|
|
|
$actions['labels'][$row['id_pm']][] = $ruleAction['v']; |
3962
|
|
|
} |
3963
|
|
|
} |
3964
|
|
|
} |
3965
|
|
|
} |
3966
|
|
|
} |
3967
|
|
|
} |
3968
|
|
|
$smcFunc['db_free_result']($request); |
3969
|
|
|
|
3970
|
|
|
// Deletes are easy! |
3971
|
|
|
if (!empty($actions['deletes'])) |
3972
|
|
|
deleteMessages($actions['deletes']); |
3973
|
|
|
|
3974
|
|
|
// Relabel? |
3975
|
|
|
if (!empty($actions['labels'])) |
3976
|
|
|
{ |
3977
|
|
|
foreach ($actions['labels'] as $pm => $labels) |
3978
|
|
|
{ |
3979
|
|
|
// Quickly check each label is valid! |
3980
|
|
|
$realLabels = array(); |
3981
|
|
|
foreach ($context['labels'] as $label) |
3982
|
|
|
{ |
3983
|
|
|
if (in_array($label['id'], $labels) && $label['id'] != -1 || empty($options['pm_remove_inbox_label'])) |
3984
|
|
|
{ |
3985
|
|
|
// Make sure this stays in the inbox |
3986
|
|
|
if ($label['id'] == '-1') |
3987
|
|
|
{ |
3988
|
|
|
$smcFunc['db_query']('', ' |
3989
|
|
|
UPDATE {db_prefix}pm_recipients |
3990
|
|
|
SET in_inbox = {int:in_inbox} |
3991
|
|
|
WHERE id_pm = {int:id_pm} |
3992
|
|
|
AND id_member = {int:current_member}', |
3993
|
|
|
array( |
3994
|
|
|
'in_inbox' => 1, |
3995
|
|
|
'id_pm' => $pm, |
3996
|
|
|
'current_member' => $user_info['id'], |
3997
|
|
|
) |
3998
|
|
|
); |
3999
|
|
|
} |
4000
|
|
|
else |
4001
|
|
|
{ |
4002
|
|
|
$realLabels[] = $label['id']; |
4003
|
|
|
} |
4004
|
|
|
} |
4005
|
|
|
} |
4006
|
|
|
|
4007
|
|
|
$inserts = array(); |
4008
|
|
|
// Now we insert the label info |
4009
|
|
|
foreach ($realLabels as $a_label) |
4010
|
|
|
$inserts[] = array($pm, $a_label); |
4011
|
|
|
|
4012
|
|
|
$smcFunc['db_insert']('ignore', |
4013
|
|
|
'{db_prefix}pm_labeled_messages', |
4014
|
|
|
array('id_pm' => 'int', 'id_label' => 'int'), |
4015
|
|
|
$inserts, |
4016
|
|
|
array() |
4017
|
|
|
); |
4018
|
|
|
} |
4019
|
|
|
} |
4020
|
|
|
} |
4021
|
|
|
|
4022
|
|
|
/** |
4023
|
|
|
* Load up all the rules for the current user. |
4024
|
|
|
* |
4025
|
|
|
* @param bool $reload Whether or not to reload all the rules from the database if $context['rules'] is set |
4026
|
|
|
*/ |
4027
|
|
|
function LoadRules($reload = false) |
4028
|
|
|
{ |
4029
|
|
|
global $user_info, $context, $smcFunc; |
4030
|
|
|
|
4031
|
|
|
if (isset($context['rules']) && !$reload) |
4032
|
|
|
return; |
4033
|
|
|
|
4034
|
|
|
$request = $smcFunc['db_query']('', ' |
4035
|
|
|
SELECT |
4036
|
|
|
id_rule, rule_name, criteria, actions, delete_pm, is_or |
4037
|
|
|
FROM {db_prefix}pm_rules |
4038
|
|
|
WHERE id_member = {int:current_member}', |
4039
|
|
|
array( |
4040
|
|
|
'current_member' => $user_info['id'], |
4041
|
|
|
) |
4042
|
|
|
); |
4043
|
|
|
$context['rules'] = array(); |
4044
|
|
|
// Simply fill in the data! |
4045
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
4046
|
|
|
{ |
4047
|
|
|
$context['rules'][$row['id_rule']] = array( |
4048
|
|
|
'id' => $row['id_rule'], |
4049
|
|
|
'name' => $row['rule_name'], |
4050
|
|
|
'criteria' => smf_json_decode($row['criteria'], true), |
4051
|
|
|
'actions' => smf_json_decode($row['actions'], true), |
4052
|
|
|
'delete' => $row['delete_pm'], |
4053
|
|
|
'logic' => $row['is_or'] ? 'or' : 'and', |
4054
|
|
|
); |
4055
|
|
|
|
4056
|
|
|
if ($row['delete_pm']) |
4057
|
|
|
$context['rules'][$row['id_rule']]['actions'][] = array('t' => 'del', 'v' => 1); |
4058
|
|
|
} |
4059
|
|
|
$smcFunc['db_free_result']($request); |
4060
|
|
|
} |
4061
|
|
|
|
4062
|
|
|
/** |
4063
|
|
|
* Check if the PM is available to the current user. |
4064
|
|
|
* |
4065
|
|
|
* @param int $pmID The ID of the PM |
4066
|
|
|
* @param string $validFor Which folders this is valud for - can be 'inbox', 'outbox' or 'in_or_outbox' |
4067
|
|
|
* @return boolean Whether the PM is accessible in that folder for the current user |
4068
|
|
|
*/ |
4069
|
|
|
function isAccessiblePM($pmID, $validFor = 'in_or_outbox') |
4070
|
|
|
{ |
4071
|
|
|
global $user_info, $smcFunc; |
4072
|
|
|
|
4073
|
|
|
$request = $smcFunc['db_query']('', ' |
4074
|
|
|
SELECT |
4075
|
|
|
pm.id_member_from = {int:id_current_member} AND pm.deleted_by_sender = {int:not_deleted} AS valid_for_outbox, |
4076
|
|
|
pmr.id_pm IS NOT NULL AS valid_for_inbox |
4077
|
|
|
FROM {db_prefix}personal_messages AS pm |
4078
|
|
|
LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm AND pmr.id_member = {int:id_current_member} AND pmr.deleted = {int:not_deleted}) |
4079
|
|
|
WHERE pm.id_pm = {int:id_pm} |
4080
|
|
|
AND ((pm.id_member_from = {int:id_current_member} AND pm.deleted_by_sender = {int:not_deleted}) OR pmr.id_pm IS NOT NULL)', |
4081
|
|
|
array( |
4082
|
|
|
'id_pm' => $pmID, |
4083
|
|
|
'id_current_member' => $user_info['id'], |
4084
|
|
|
'not_deleted' => 0, |
4085
|
|
|
) |
4086
|
|
|
); |
4087
|
|
|
|
4088
|
|
View Code Duplication |
if ($smcFunc['db_num_rows']($request) === 0) |
|
|
|
|
4089
|
|
|
{ |
4090
|
|
|
$smcFunc['db_free_result']($request); |
4091
|
|
|
return false; |
4092
|
|
|
} |
4093
|
|
|
|
4094
|
|
|
$validationResult = $smcFunc['db_fetch_assoc']($request); |
4095
|
|
|
$smcFunc['db_free_result']($request); |
4096
|
|
|
|
4097
|
|
|
switch ($validFor) |
4098
|
|
|
{ |
4099
|
|
|
case 'inbox': |
4100
|
|
|
return !empty($validationResult['valid_for_inbox']); |
4101
|
|
|
break; |
|
|
|
|
4102
|
|
|
|
4103
|
|
|
case 'outbox': |
4104
|
|
|
return !empty($validationResult['valid_for_outbox']); |
4105
|
|
|
break; |
|
|
|
|
4106
|
|
|
|
4107
|
|
|
case 'in_or_outbox': |
4108
|
|
|
return !empty($validationResult['valid_for_inbox']) || !empty($validationResult['valid_for_outbox']); |
4109
|
|
|
break; |
|
|
|
|
4110
|
|
|
|
4111
|
|
|
default: |
4112
|
|
|
trigger_error('Undefined validation type given', E_USER_ERROR); |
4113
|
|
|
break; |
4114
|
|
|
} |
4115
|
|
|
} |
4116
|
|
|
|
4117
|
|
|
?> |
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.