annotate forum/Sources/PersonalMessage.php @ 76:e3e11437ecea website

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