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