phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / includes / functions_privmsgs.php

History | View | Annotate | Download (57.4 kB)

1
<?php
2
/**
3
*
4
* @package phpBB3
5
* @version $Id: functions_privmsgs.php 11530 2011-11-13 20:15:11Z git-gate $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
*
9
*/
10
11
/**
12
*/
13
if (!defined('IN_PHPBB'))
14
{
15
        exit;
16
}
17
18
/*
19
        Ability to simply add own rules by doing three things:
20
                1) Add an appropriate constant
21
                2) Add a new check array to the global_privmsgs_rules variable and the condition array (if one is required)
22
                3) Add a new language variable to ucp.php
23
24
                The user is then able to select the new rule. It will be checked against and handled as specified.
25
                To add new actions (yes, checks can be added here too) to the rule management, the core code has to be modified.
26
*/
27
28
define('RULE_IS_LIKE', 1);                // Is Like
29
define('RULE_IS_NOT_LIKE', 2);        // Is Not Like
30
define('RULE_IS', 3);                        // Is
31
define('RULE_IS_NOT', 4);                // Is Not
32
define('RULE_BEGINS_WITH', 5);        // Begins with
33
define('RULE_ENDS_WITH', 6);        // Ends with
34
define('RULE_IS_FRIEND', 7);        // Is Friend
35
define('RULE_IS_FOE', 8);                // Is Foe
36
define('RULE_IS_USER', 9);                // Is User
37
define('RULE_IS_GROUP', 10);        // Is In Usergroup
38
define('RULE_ANSWERED', 11);        // Answered
39
define('RULE_FORWARDED', 12);        // Forwarded
40
define('RULE_TO_GROUP', 14);        // Usergroup
41
define('RULE_TO_ME', 15);                // Me
42
43
define('ACTION_PLACE_INTO_FOLDER', 1);
44
define('ACTION_MARK_AS_READ', 2);
45
define('ACTION_MARK_AS_IMPORTANT', 3);
46
define('ACTION_DELETE_MESSAGE', 4);
47
48
define('CHECK_SUBJECT', 1);
49
define('CHECK_SENDER', 2);
50
define('CHECK_MESSAGE', 3);
51
define('CHECK_STATUS', 4);
52
define('CHECK_TO', 5);
53
54
/**
55
* Global private message rules
56
* These rules define what to do if a rule is hit
57
*/
58
$global_privmsgs_rules = array(
59
        CHECK_SUBJECT        => array(
60
                RULE_IS_LIKE                => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
61
                RULE_IS_NOT_LIKE        => array('check0' => 'message_subject', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
62
                RULE_IS                                => array('check0' => 'message_subject', 'function' => '{CHECK0} == {STRING}'),
63
                RULE_IS_NOT                        => array('check0' => 'message_subject', 'function' => '{CHECK0} != {STRING}'),
64
                RULE_BEGINS_WITH        => array('check0' => 'message_subject', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
65
                RULE_ENDS_WITH                => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
66
        ),
67
68
        CHECK_SENDER        => array(
69
                RULE_IS_LIKE                => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
70
                RULE_IS_NOT_LIKE        => array('check0' => 'username', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
71
                RULE_IS                                => array('check0' => 'username', 'function' => '{CHECK0} == {STRING}'),
72
                RULE_IS_NOT                        => array('check0' => 'username', 'function' => '{CHECK0} != {STRING}'),
73
                RULE_BEGINS_WITH        => array('check0' => 'username', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
74
                RULE_ENDS_WITH                => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
75
                RULE_IS_FRIEND                => array('check0' => 'friend', 'function' => '{CHECK0} == 1'),
76
                RULE_IS_FOE                        => array('check0' => 'foe', 'function' => '{CHECK0} == 1'),
77
                RULE_IS_USER                => array('check0' => 'author_id', 'function' => '{CHECK0} == {USER_ID}'),
78
                RULE_IS_GROUP                => array('check0' => 'author_in_group', 'function' => 'in_array({GROUP_ID}, {CHECK0})'),
79
        ),
80
81
        CHECK_MESSAGE        => array(
82
                RULE_IS_LIKE                => array('check0' => 'message_text', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
83
                RULE_IS_NOT_LIKE        => array('check0' => 'message_text', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
84
                RULE_IS                                => array('check0' => 'message_text', 'function' => '{CHECK0} == {STRING}'),
85
                RULE_IS_NOT                        => array('check0' => 'message_text', 'function' => '{CHECK0} != {STRING}'),
86
        ),
87
88
        CHECK_STATUS        => array(
89
                RULE_ANSWERED                => array('check0' => 'pm_replied', 'function' => '{CHECK0} == 1'),
90
                RULE_FORWARDED                => array('check0' => 'pm_forwarded', 'function' => '{CHECK0} == 1'),
91
        ),
92
93
        CHECK_TO                => array(
94
                RULE_TO_GROUP                => array('check0' => 'to', 'check1' => 'bcc', 'check2' => 'user_in_group', 'function' => 'in_array("g_" . {CHECK2}, {CHECK0}) || in_array("g_" . {CHECK2}, {CHECK1})'),
95
                RULE_TO_ME                        => array('check0' => 'to', 'check1' => 'bcc', 'function' => 'in_array("u_" . $user_id, {CHECK0}) || in_array("u_" . $user_id, {CHECK1})'),
96
        )
97
);
98
99
/**
100
* This is for defining which condition fields to show for which Rule
101
*/
102
$global_rule_conditions = array(
103
        RULE_IS_LIKE                => 'text',
104
        RULE_IS_NOT_LIKE        => 'text',
105
        RULE_IS                                => 'text',
106
        RULE_IS_NOT                        => 'text',
107
        RULE_BEGINS_WITH        => 'text',
108
        RULE_ENDS_WITH                => 'text',
109
        RULE_IS_USER                => 'user',
110
        RULE_IS_GROUP                => 'group'
111
);
112
113
/**
114
* Get all folder
115
*/
116
function get_folder($user_id, $folder_id = false)
117
{
118
        global $db, $user, $template;
119
        global $phpbb_root_path, $phpEx;
120
121
        $folder = array();
122
123
        // Get folder information
124
        $sql = 'SELECT folder_id, COUNT(msg_id) as num_messages, SUM(pm_unread) as num_unread
125
                FROM ' . PRIVMSGS_TO_TABLE . "
126
                WHERE user_id = $user_id
127
                        AND folder_id <> " . PRIVMSGS_NO_BOX . '
128
                GROUP BY folder_id';
129
        $result = $db->sql_query($sql);
130
131
        $num_messages = $num_unread = array();
132
        while ($row = $db->sql_fetchrow($result))
133
        {
134
                $num_messages[(int) $row['folder_id']] = $row['num_messages'];
135
                $num_unread[(int) $row['folder_id']] = $row['num_unread'];
136
        }
137
        $db->sql_freeresult($result);
138
139
        // Make sure the default boxes are defined
140
        $available_folder = array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX);
141
142
        foreach ($available_folder as $default_folder)
143
        {
144
                if (!isset($num_messages[$default_folder]))
145
                {
146
                        $num_messages[$default_folder] = 0;
147
                }
148
149
                if (!isset($num_unread[$default_folder]))
150
                {
151
                        $num_unread[$default_folder] = 0;
152
                }
153
        }
154
155
        // Adjust unread status for outbox
156
        $num_unread[PRIVMSGS_OUTBOX] = $num_messages[PRIVMSGS_OUTBOX];
157
158
        $folder[PRIVMSGS_INBOX] = array(
159
                'folder_name'                => $user->lang['PM_INBOX'],
160
                'num_messages'                => $num_messages[PRIVMSGS_INBOX],
161
                'unread_messages'        => $num_unread[PRIVMSGS_INBOX]
162
        );
163
164
        // Custom Folder
165
        $sql = 'SELECT folder_id, folder_name, pm_count
166
                FROM ' . PRIVMSGS_FOLDER_TABLE . "
167
                        WHERE user_id = $user_id";
168
        $result = $db->sql_query($sql);
169
170
        while ($row = $db->sql_fetchrow($result))
171
        {
172
                $folder[$row['folder_id']] = array(
173
                        'folder_name'                => $row['folder_name'],
174
                        'num_messages'                => $row['pm_count'],
175
                        'unread_messages'        => ((isset($num_unread[$row['folder_id']])) ? $num_unread[$row['folder_id']] : 0)
176
                );
177
        }
178
        $db->sql_freeresult($result);
179
180
        $folder[PRIVMSGS_OUTBOX] = array(
181
                'folder_name'                => $user->lang['PM_OUTBOX'],
182
                'num_messages'                => $num_messages[PRIVMSGS_OUTBOX],
183
                'unread_messages'        => $num_unread[PRIVMSGS_OUTBOX]
184
        );
185
186
        $folder[PRIVMSGS_SENTBOX] = array(
187
                'folder_name'                => $user->lang['PM_SENTBOX'],
188
                'num_messages'                => $num_messages[PRIVMSGS_SENTBOX],
189
                'unread_messages'        => $num_unread[PRIVMSGS_SENTBOX]
190
        );
191
192
        // Define Folder Array for template designers (and for making custom folders usable by the template too)
193
        foreach ($folder as $f_id => $folder_ary)
194
        {
195
                $folder_id_name = ($f_id == PRIVMSGS_INBOX) ? 'inbox' : (($f_id == PRIVMSGS_OUTBOX) ? 'outbox' : 'sentbox');
196
197
                $template->assign_block_vars('folder', array(
198
                        'FOLDER_ID'                        => $f_id,
199
                        'FOLDER_NAME'                => $folder_ary['folder_name'],
200
                        'NUM_MESSAGES'                => $folder_ary['num_messages'],
201
                        'UNREAD_MESSAGES'        => $folder_ary['unread_messages'],
202
203
                        'U_FOLDER'                        => ($f_id > 0) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $f_id) : append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $folder_id_name),
204
205
                        'S_CUR_FOLDER'                => ($f_id === $folder_id) ? true : false,
206
                        'S_UNREAD_MESSAGES'        => ($folder_ary['unread_messages']) ? true : false,
207
                        'S_CUSTOM_FOLDER'        => ($f_id > 0) ? true : false)
208
                );
209
        }
210
211
        if ($folder_id !== false && !isset($folder[$folder_id]))
212
        {
213
                trigger_error('UNKNOWN_FOLDER');
214
        }
215
216
        return $folder;
217
}
218
219
/**
220
* Delete Messages From Sentbox
221
* we are doing this here because this saves us a bunch of checks and queries
222
*/
223
function clean_sentbox($num_sentbox_messages)
224
{
225
        global $db, $user, $config;
226
227
        // Check Message Limit
228
        if ($user->data['message_limit'] && $num_sentbox_messages > $user->data['message_limit'])
229
        {
230
                // Delete old messages
231
                $sql = 'SELECT t.msg_id
232
                        FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
233
                        WHERE t.msg_id = p.msg_id
234
                                AND t.user_id = ' . $user->data['user_id'] . '
235
                                AND t.folder_id = ' . PRIVMSGS_SENTBOX . '
236
                        ORDER BY p.message_time ASC';
237
                $result = $db->sql_query_limit($sql, ($num_sentbox_messages - $user->data['message_limit']));
238
239
                $delete_ids = array();
240
                while ($row = $db->sql_fetchrow($result))
241
                {
242
                        $delete_ids[] = $row['msg_id'];
243
                }
244
                $db->sql_freeresult($result);
245
                delete_pm($user->data['user_id'], $delete_ids, PRIVMSGS_SENTBOX);
246
        }
247
}
248
249
/**
250
* Check Rule against Message Information
251
*/
252
function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
253
{
254
        global $user, $config;
255
256
        if (!isset($rules[$rule_row['rule_check']][$rule_row['rule_connection']]))
257
        {
258
                return false;
259
        }
260
261
        $check_ary = $rules[$rule_row['rule_check']][$rule_row['rule_connection']];
262
263
        // Replace Check Literals
264
        $evaluate = $check_ary['function'];
265
        $evaluate = preg_replace('/{(CHECK[0-9])}/', '$message_row[$check_ary[strtolower("\1")]]', $evaluate);
266
267
        // Replace Rule Literals
268
        $evaluate = preg_replace('/{(STRING|USER_ID|GROUP_ID)}/', '$rule_row["rule_" . strtolower("\1")]', $evaluate);
269
270
        // Evil Statement
271
        $result = false;
272
        eval('$result = (' . $evaluate . ') ? true : false;');
273
274
        if (!$result)
275
        {
276
                return false;
277
        }
278
279
        switch ($rule_row['rule_action'])
280
        {
281
                case ACTION_PLACE_INTO_FOLDER:
282
                        return array('action' => $rule_row['rule_action'], 'folder_id' => $rule_row['rule_folder_id']);
283
                break;
284
285
                case ACTION_MARK_AS_READ:
286
                case ACTION_MARK_AS_IMPORTANT:
287
                        return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
288
                break;
289
290
                case ACTION_DELETE_MESSAGE:
291
                        global $db, $auth;
292
293
                        // Check for admins/mods - users are not allowed to remove those messages...
294
                        // We do the check here to make sure the data we use is consistent
295
                        $sql = 'SELECT user_id, user_type, user_permissions
296
                                FROM ' . USERS_TABLE . '
297
                                WHERE user_id = ' . (int) $message_row['author_id'];
298
                        $result = $db->sql_query($sql);
299
                        $userdata = $db->sql_fetchrow($result);
300
                        $db->sql_freeresult($result);
301
302
                        $auth2 = new auth();
303
                        $auth2->acl($userdata);
304
305
                        if (!$auth2->acl_get('a_') && !$auth2->acl_get('m_') && !$auth2->acl_getf_global('m_'))
306
                        {
307
                                return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
308
                        }
309
310
                        return false;
311
                break;
312
313
                default:
314
                        return false;
315
        }
316
317
        return false;
318
}
319
320
/**
321
* Update user PM count
322
*/
323
function update_pm_counts()
324
{
325
        global $user, $db;
326
327
        // Update unread count
328
        $sql = 'SELECT COUNT(msg_id) as num_messages
329
                FROM ' . PRIVMSGS_TO_TABLE . '
330
                WHERE pm_unread = 1
331
                        AND folder_id <> ' . PRIVMSGS_OUTBOX . '
332
                        AND user_id = ' . $user->data['user_id'];
333
        $result = $db->sql_query($sql);
334
        $user->data['user_unread_privmsg'] = (int) $db->sql_fetchfield('num_messages');
335
        $db->sql_freeresult($result);
336
337
        // Update new pm count
338
        $sql = 'SELECT COUNT(msg_id) as num_messages
339
                FROM ' . PRIVMSGS_TO_TABLE . '
340
                WHERE pm_new = 1
341
                        AND folder_id IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
342
                        AND user_id = ' . $user->data['user_id'];
343
        $result = $db->sql_query($sql);
344
        $user->data['user_new_privmsg'] = (int) $db->sql_fetchfield('num_messages');
345
        $db->sql_freeresult($result);
346
347
        $db->sql_query('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
348
                'user_unread_privmsg'        => (int) $user->data['user_unread_privmsg'],
349
                'user_new_privmsg'                => (int) $user->data['user_new_privmsg'],
350
        )) . ' WHERE user_id = ' . $user->data['user_id']);
351
352
        // Ok, here we need to repair something, other boxes than privmsgs_no_box and privmsgs_hold_box should not carry the pm_new flag.
353
        if (!$user->data['user_new_privmsg'])
354
        {
355
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
356
                        SET pm_new = 0
357
                        WHERE pm_new = 1
358
                                AND folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
359
                                AND user_id = ' . $user->data['user_id'];
360
                $db->sql_query($sql);
361
        }
362
}
363
364
/**
365
* Place new messages into appropriate folder
366
*/
367
function place_pm_into_folder(&$global_privmsgs_rules, $release = false)
368
{
369
        global $db, $user, $config;
370
371
        if (!$user->data['user_new_privmsg'])
372
        {
373
                return array('not_moved' => 0, 'removed' => 0);
374
        }
375
376
        $user_message_rules = (int) $user->data['user_message_rules'];
377
        $user_id = (int) $user->data['user_id'];
378
379
        $action_ary = $move_into_folder = array();
380
        $num_removed = 0;
381
382
        // Newly processing on-hold messages
383
        if ($release)
384
        {
385
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
386
                        SET folder_id = ' . PRIVMSGS_NO_BOX . '
387
                        WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . "
388
                                AND user_id = $user_id";
389
                $db->sql_query($sql);
390
        }
391
392
        // Get those messages not yet placed into any box
393
        $retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.group_id
394
                FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u
395
                WHERE t.user_id = $user_id
396
                        AND p.author_id = u.user_id
397
                        AND t.folder_id = " . PRIVMSGS_NO_BOX . '
398
                        AND t.msg_id = p.msg_id';
399
400
        // Just place into the appropriate arrays if no rules need to be checked
401
        if (!$user_message_rules)
402
        {
403
                $result = $db->sql_query($retrieve_sql);
404
405
                while ($row = $db->sql_fetchrow($result))
406
                {
407
                        $action_ary[$row['msg_id']][] = array('action' => false);
408
                }
409
                $db->sql_freeresult($result);
410
        }
411
        else
412
        {
413
                $user_rules = $zebra = $check_rows = array();
414
                $user_ids = $memberships = array();
415
416
                // First of all, grab all rules and retrieve friends/foes
417
                $sql = 'SELECT *
418
                        FROM ' . PRIVMSGS_RULES_TABLE . "
419
                        WHERE user_id = $user_id";
420
                $result = $db->sql_query($sql);
421
                $user_rules = $db->sql_fetchrowset($result);
422
                $db->sql_freeresult($result);
423
424
                if (sizeof($user_rules))
425
                {
426
                        $sql = 'SELECT zebra_id, friend, foe
427
                                FROM ' . ZEBRA_TABLE . "
428
                                WHERE user_id = $user_id";
429
                        $result = $db->sql_query($sql);
430
431
                        while ($row = $db->sql_fetchrow($result))
432
                        {
433
                                $zebra[$row['zebra_id']] = $row;
434
                        }
435
                        $db->sql_freeresult($result);
436
                }
437
438
                // Now build a bare-bone check_row array
439
                $result = $db->sql_query($retrieve_sql);
440
441
                while ($row = $db->sql_fetchrow($result))
442
                {
443
                        $check_rows[] = array_merge($row, array(
444
                                'to'                                => explode(':', $row['to_address']),
445
                                'bcc'                                => explode(':', $row['bcc_address']),
446
                                'friend'                        => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['friend'] : 0,
447
                                'foe'                                => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['foe'] : 0,
448
                                'user_in_group'                => array($user->data['group_id']),
449
                                'author_in_group'        => array())
450
                        );
451
452
                        $user_ids[] = $row['user_id'];
453
                }
454
                $db->sql_freeresult($result);
455
456
                // Retrieve user memberships
457
                if (sizeof($user_ids))
458
                {
459
                        $sql = 'SELECT *
460
                                FROM ' . USER_GROUP_TABLE . '
461
                                WHERE ' . $db->sql_in_set('user_id', $user_ids) . '
462
                                        AND user_pending = 0';
463
                        $result = $db->sql_query($sql);
464
465
                        while ($row = $db->sql_fetchrow($result))
466
                        {
467
                                $memberships[$row['user_id']][] = $row['group_id'];
468
                        }
469
                        $db->sql_freeresult($result);
470
                }
471
472
                // Now place into the appropriate folder
473
                foreach ($check_rows as $row)
474
                {
475
                        // Add membership if set
476
                        if (isset($memberships[$row['author_id']]))
477
                        {
478
                                $row['author_in_group'] = $memberships[$row['user_id']];
479
                        }
480
481
                        // Check Rule - this should be very quick since we have all information we need
482
                        $is_match = false;
483
                        foreach ($user_rules as $rule_row)
484
                        {
485
                                if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false)
486
                                {
487
                                        $is_match = true;
488
                                        $action_ary[$row['msg_id']][] = $action;
489
                                }
490
                        }
491
492
                        if (!$is_match)
493
                        {
494
                                $action_ary[$row['msg_id']][] = array('action' => false);
495
                        }
496
                }
497
498
                unset($user_rules, $zebra, $check_rows, $user_ids, $memberships);
499
        }
500
501
        // We place actions into arrays, to save queries.
502
        $sql = $unread_ids = $delete_ids = $important_ids = array();
503
504
        foreach ($action_ary as $msg_id => $msg_ary)
505
        {
506
                // It is allowed to execute actions more than once, except placing messages into folder
507
                $folder_action = $message_removed = false;
508
509
                foreach ($msg_ary as $pos => $rule_ary)
510
                {
511
                        if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER)
512
                        {
513
                                continue;
514
                        }
515
516
                        switch ($rule_ary['action'])
517
                        {
518
                                case ACTION_PLACE_INTO_FOLDER:
519
                                        // Folder actions have precedence, so we will remove any other ones
520
                                        $folder_action = true;
521
                                        $move_into_folder[(int) $rule_ary['folder_id']][] = $msg_id;
522
                                break;
523
524
                                case ACTION_MARK_AS_READ:
525
                                        if ($rule_ary['pm_unread'])
526
                                        {
527
                                                $unread_ids[] = $msg_id;
528
                                        }
529
                                break;
530
531
                                case ACTION_DELETE_MESSAGE:
532
                                        $delete_ids[] = $msg_id;
533
                                        $message_removed = true;
534
                                break;
535
536
                                case ACTION_MARK_AS_IMPORTANT:
537
                                        if (!$rule_ary['pm_marked'])
538
                                        {
539
                                                $important_ids[] = $msg_id;
540
                                        }
541
                                break;
542
                        }
543
                }
544
545
                // We place this here because it could happen that the messages are doubled if a rule marks a message and then moves it into a specific
546
                // folder. Here we simply move the message into the INBOX if it gets not removed and also not put into a custom folder.
547
                if (!$folder_action && !$message_removed)
548
                {
549
                        $move_into_folder[PRIVMSGS_INBOX][] = $msg_id;
550
                }
551
        }
552
553
        // Do not change the order of processing
554
        // The number of queries needed to be executed here highly depends on the defined rules and are
555
        // only gone through if new messages arrive.
556
557
        // Delete messages
558
        if (sizeof($delete_ids))
559
        {
560
                $num_removed += sizeof($delete_ids);
561
                delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX);
562
        }
563
564
        // Set messages to Unread
565
        if (sizeof($unread_ids))
566
        {
567
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
568
                        SET pm_unread = 0
569
                        WHERE ' . $db->sql_in_set('msg_id', $unread_ids) . "
570
                                AND user_id = $user_id
571
                                AND folder_id = " . PRIVMSGS_NO_BOX;
572
                $db->sql_query($sql);
573
        }
574
575
        // mark messages as important
576
        if (sizeof($important_ids))
577
        {
578
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
579
                        SET pm_marked = 1 - pm_marked
580
                        WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
581
                                AND user_id = $user_id
582
                                AND " . $db->sql_in_set('msg_id', $important_ids);
583
                $db->sql_query($sql);
584
        }
585
586
        // Move into folder
587
        $folder = array();
588
589
        if (sizeof($move_into_folder))
590
        {
591
                // Determine Full Folder Action - we need the move to folder id later eventually
592
                $full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
593
594
                $sql_folder = array_keys($move_into_folder);
595
                if ($full_folder_action >= 0)
596
                {
597
                        $sql_folder[] = $full_folder_action;
598
                }
599
600
                $sql = 'SELECT folder_id, pm_count
601
                        FROM ' . PRIVMSGS_FOLDER_TABLE . '
602
                        WHERE ' . $db->sql_in_set('folder_id', $sql_folder) . "
603
                                AND user_id = $user_id";
604
                $result = $db->sql_query($sql);
605
606
                while ($row = $db->sql_fetchrow($result))
607
                {
608
                        $folder[(int) $row['folder_id']] = (int) $row['pm_count'];
609
                }
610
                $db->sql_freeresult($result);
611
612
                unset($sql_folder);
613
614
                if (isset($move_into_folder[PRIVMSGS_INBOX]))
615
                {
616
                        $sql = 'SELECT COUNT(msg_id) as num_messages
617
                                FROM ' . PRIVMSGS_TO_TABLE . "
618
                                WHERE user_id = $user_id
619
                                        AND folder_id = " . PRIVMSGS_INBOX;
620
                        $result = $db->sql_query($sql);
621
                        $folder[PRIVMSGS_INBOX] = (int) $db->sql_fetchfield('num_messages');
622
                        $db->sql_freeresult($result);
623
                }
624
        }
625
626
        // Here we have ideally only one folder to move into
627
        foreach ($move_into_folder as $folder_id => $msg_ary)
628
        {
629
                $dest_folder = $folder_id;
630
                $full_folder_action = FULL_FOLDER_NONE;
631
632
                // Check Message Limit - we calculate with the complete array, most of the time it is one message
633
                // But we are making sure that the other way around works too (more messages in queue than allowed to be stored)
634
                if ($user->data['message_limit'] && $folder[$folder_id] && ($folder[$folder_id] + sizeof($msg_ary)) > $user->data['message_limit'])
635
                {
636
                        $full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
637
638
                        // If destination folder itself is full...
639
                        if ($full_folder_action >= 0 && ($folder[$full_folder_action] + sizeof($msg_ary)) > $user->data['message_limit'])
640
                        {
641
                                $full_folder_action = $config['full_folder_action'] - (FULL_FOLDER_NONE*(-1));
642
                        }
643
644
                        // If Full Folder Action is to move to another folder, we simply adjust the destination folder
645
                        if ($full_folder_action >= 0)
646
                        {
647
                                $dest_folder = $full_folder_action;
648
                        }
649
                        else if ($full_folder_action == FULL_FOLDER_DELETE)
650
                        {
651
                                // Delete some messages. NOTE: Ordered by msg_id here instead of message_time!
652
                                $sql = 'SELECT msg_id
653
                                        FROM ' . PRIVMSGS_TO_TABLE . "
654
                                        WHERE user_id = $user_id
655
                                                AND folder_id = $dest_folder
656
                                        ORDER BY msg_id ASC";
657
                                $result = $db->sql_query_limit($sql, (($folder[$dest_folder] + sizeof($msg_ary)) - $user->data['message_limit']));
658
659
                                $delete_ids = array();
660
                                while ($row = $db->sql_fetchrow($result))
661
                                {
662
                                        $delete_ids[] = $row['msg_id'];
663
                                }
664
                                $db->sql_freeresult($result);
665
666
                                $num_removed += sizeof($delete_ids);
667
                                delete_pm($user_id, $delete_ids, $dest_folder);
668
                        }
669
                }
670
671
                //
672
                if ($full_folder_action == FULL_FOLDER_HOLD)
673
                {
674
                        $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
675
                                SET folder_id = ' . PRIVMSGS_HOLD_BOX . '
676
                                WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
677
                                        AND user_id = $user_id
678
                                        AND " . $db->sql_in_set('msg_id', $msg_ary);
679
                        $db->sql_query($sql);
680
                }
681
                else
682
                {
683
                        $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
684
                                SET folder_id = $dest_folder, pm_new = 0
685
                                WHERE folder_id = " . PRIVMSGS_NO_BOX . "
686
                                        AND user_id = $user_id
687
                                        AND pm_new = 1
688
                                        AND " . $db->sql_in_set('msg_id', $msg_ary);
689
                        $db->sql_query($sql);
690
691
                        if ($dest_folder != PRIVMSGS_INBOX)
692
                        {
693
                                $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . '
694
                                        SET pm_count = pm_count + ' . (int) $db->sql_affectedrows() . "
695
                                        WHERE folder_id = $dest_folder
696
                                                AND user_id = $user_id";
697
                                $db->sql_query($sql);
698
                        }
699
                }
700
        }
701
702
        if (sizeof($action_ary))
703
        {
704
                // Move from OUTBOX to SENTBOX
705
                // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted)
706
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
707
                        SET folder_id = ' . PRIVMSGS_SENTBOX . '
708
                        WHERE folder_id = ' . PRIVMSGS_OUTBOX . '
709
                                AND ' . $db->sql_in_set('msg_id', array_keys($action_ary));
710
                $db->sql_query($sql);
711
        }
712
713
        // Update new/unread count
714
        update_pm_counts();
715
716
        // Now check how many messages got not moved...
717
        $sql = 'SELECT COUNT(msg_id) as num_messages
718
                FROM ' . PRIVMSGS_TO_TABLE . "
719
                WHERE user_id = $user_id
720
                        AND folder_id = " . PRIVMSGS_HOLD_BOX;
721
        $result = $db->sql_query($sql);
722
        $num_not_moved = (int) $db->sql_fetchfield('num_messages');
723
        $db->sql_freeresult($result);
724
725
        return array('not_moved' => $num_not_moved, 'removed' => $num_removed);
726
}
727
728
/**
729
* Move PM from one to another folder
730
*/
731
function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_folder_id)
732
{
733
        global $db, $user;
734
        global $phpbb_root_path, $phpEx;
735
736
        $num_moved = 0;
737
738
        if (!is_array($move_msg_ids))
739
        {
740
                $move_msg_ids = array($move_msg_ids);
741
        }
742
743
        if (sizeof($move_msg_ids) && !in_array($dest_folder, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)) &&
744
                !in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)) && $cur_folder_id != $dest_folder)
745
        {
746
                // We have to check the destination folder ;)
747
                if ($dest_folder != PRIVMSGS_INBOX)
748
                {
749
                        $sql = 'SELECT folder_id, folder_name, pm_count
750
                                FROM ' . PRIVMSGS_FOLDER_TABLE . "
751
                                WHERE folder_id = $dest_folder
752
                                        AND user_id = $user_id";
753
                        $result = $db->sql_query($sql);
754
                        $row = $db->sql_fetchrow($result);
755
                        $db->sql_freeresult($result);
756
757
                        if (!$row)
758
                        {
759
                                trigger_error('NOT_AUTHORISED');
760
                        }
761
762
                        if ($message_limit && $row['pm_count'] + sizeof($move_msg_ids) > $message_limit)
763
                        {
764
                                $message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $row['folder_name']) . '<br /><br />';
765
                                $message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $row['folder_id']) . '">', '</a>', $row['folder_name']);
766
                                trigger_error($message);
767
                        }
768
                }
769
                else
770
                {
771
                        $sql = 'SELECT COUNT(msg_id) as num_messages
772
                                FROM ' . PRIVMSGS_TO_TABLE . '
773
                                WHERE folder_id = ' . PRIVMSGS_INBOX . "
774
                                        AND user_id = $user_id";
775
                        $result = $db->sql_query($sql);
776
                        $num_messages = (int) $db->sql_fetchfield('num_messages');
777
                        $db->sql_freeresult($result);
778
779
                        if ($message_limit && $num_messages + sizeof($move_msg_ids) > $message_limit)
780
                        {
781
                                $message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $user->lang['PM_INBOX']) . '<br /><br />';
782
                                $message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=inbox') . '">', '</a>', $user->lang['PM_INBOX']);
783
                                trigger_error($message);
784
                        }
785
                }
786
787
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
788
                        SET folder_id = $dest_folder
789
                        WHERE folder_id = $cur_folder_id
790
                                AND user_id = $user_id
791
                                AND " . $db->sql_in_set('msg_id', $move_msg_ids);
792
                $db->sql_query($sql);
793
                $num_moved = $db->sql_affectedrows();
794
795
                // Update pm counts
796
                if ($num_moved)
797
                {
798
                        if (!in_array($cur_folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)))
799
                        {
800
                                $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
801
                                        SET pm_count = pm_count - $num_moved
802
                                        WHERE folder_id = $cur_folder_id
803
                                                AND user_id = $user_id";
804
                                $db->sql_query($sql);
805
                        }
806
807
                        if ($dest_folder != PRIVMSGS_INBOX)
808
                        {
809
                                $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
810
                                        SET pm_count = pm_count + $num_moved
811
                                        WHERE folder_id = $dest_folder
812
                                                AND user_id = $user_id";
813
                                $db->sql_query($sql);
814
                        }
815
                }
816
        }
817
        else if (in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)))
818
        {
819
                trigger_error('CANNOT_MOVE_SPECIAL');
820
        }
821
822
        return $num_moved;
823
}
824
825
/**
826
* Update unread message status
827
*/
828
function update_unread_status($unread, $msg_id, $user_id, $folder_id)
829
{
830
        if (!$unread)
831
        {
832
                return;
833
        }
834
835
        global $db, $user;
836
837
        $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
838
                SET pm_unread = 0
839
                WHERE msg_id = $msg_id
840
                        AND user_id = $user_id
841
                        AND folder_id = $folder_id";
842
        $db->sql_query($sql);
843
844
        $sql = 'UPDATE ' . USERS_TABLE . "
845
                SET user_unread_privmsg = user_unread_privmsg - 1
846
                WHERE user_id = $user_id";
847
        $db->sql_query($sql);
848
849
        if ($user->data['user_id'] == $user_id)
850
        {
851
                $user->data['user_unread_privmsg']--;
852
853
                // Try to cope with previous wrong conversions...
854
                if ($user->data['user_unread_privmsg'] < 0)
855
                {
856
                        $sql = 'UPDATE ' . USERS_TABLE . "
857
                                SET user_unread_privmsg = 0
858
                                WHERE user_id = $user_id";
859
                        $db->sql_query($sql);
860
861
                        $user->data['user_unread_privmsg'] = 0;
862
                }
863
        }
864
}
865
866
/**
867
* Handle all actions possible with marked messages
868
*/
869
function handle_mark_actions($user_id, $mark_action)
870
{
871
        global $db, $user, $phpbb_root_path, $phpEx;
872
873
        $msg_ids                = request_var('marked_msg_id', array(0));
874
        $cur_folder_id        = request_var('cur_folder_id', PRIVMSGS_NO_BOX);
875
        $confirm                = (isset($_POST['confirm'])) ? true : false;
876
877
        if (!sizeof($msg_ids))
878
        {
879
                return false;
880
        }
881
882
        switch ($mark_action)
883
        {
884
                case 'mark_important':
885
886
                        $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
887
                                SET pm_marked = 1 - pm_marked
888
                                WHERE folder_id = $cur_folder_id
889
                                        AND user_id = $user_id
890
                                        AND " . $db->sql_in_set('msg_id', $msg_ids);
891
                        $db->sql_query($sql);
892
893
                break;
894
895
                case 'delete_marked':
896
897
                        global $auth;
898
899
                        if (!$auth->acl_get('u_pm_delete'))
900
                        {
901
                                trigger_error('NO_AUTH_DELETE_MESSAGE');
902
                        }
903
904
                        if (confirm_box(true))
905
                        {
906
                                delete_pm($user_id, $msg_ids, $cur_folder_id);
907
908
                                $success_msg = (sizeof($msg_ids) == 1) ? 'MESSAGE_DELETED' : 'MESSAGES_DELETED';
909
                                $redirect = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $cur_folder_id);
910
911
                                meta_refresh(3, $redirect);
912
                                trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_FOLDER'], '<a href="' . $redirect . '">', '</a>'));
913
                        }
914
                        else
915
                        {
916
                                $s_hidden_fields = array(
917
                                        'cur_folder_id'        => $cur_folder_id,
918
                                        'mark_option'        => 'delete_marked',
919
                                        'submit_mark'        => true,
920
                                        'marked_msg_id'        => $msg_ids
921
                                );
922
923
                                confirm_box(false, 'DELETE_MARKED_PM', build_hidden_fields($s_hidden_fields));
924
                        }
925
926
                break;
927
928
                default:
929
                        return false;
930
        }
931
932
        return true;
933
}
934
935
/**
936
* Delete PM(s)
937
*/
938
function delete_pm($user_id, $msg_ids, $folder_id)
939
{
940
        global $db, $user, $phpbb_root_path, $phpEx;
941
942
        $user_id        = (int) $user_id;
943
        $folder_id        = (int) $folder_id;
944
945
        if (!$user_id)
946
        {
947
                return false;
948
        }
949
950
        if (!is_array($msg_ids))
951
        {
952
                if (!$msg_ids)
953
                {
954
                        return false;
955
                }
956
                $msg_ids = array($msg_ids);
957
        }
958
959
        if (!sizeof($msg_ids))
960
        {
961
                return false;
962
        }
963
964
        // Get PM Information for later deleting
965
        $sql = 'SELECT msg_id, pm_unread, pm_new
966
                FROM ' . PRIVMSGS_TO_TABLE . '
967
                WHERE ' . $db->sql_in_set('msg_id', array_map('intval', $msg_ids)) . "
968
                        AND folder_id = $folder_id
969
                        AND user_id = $user_id";
970
        $result = $db->sql_query($sql);
971
972
        $delete_rows = array();
973
        $num_unread = $num_new = $num_deleted = 0;
974
        while ($row = $db->sql_fetchrow($result))
975
        {
976
                $num_unread += (int) $row['pm_unread'];
977
                $num_new += (int) $row['pm_new'];
978
979
                $delete_rows[$row['msg_id']] = 1;
980
        }
981
        $db->sql_freeresult($result);
982
        unset($msg_ids);
983
984
        if (!sizeof($delete_rows))
985
        {
986
                return false;
987
        }
988
989
        $db->sql_transaction('begin');
990
991
        // if no one has read the message yet (meaning it is in users outbox)
992
        // then mark the message as deleted...
993
        if ($folder_id == PRIVMSGS_OUTBOX)
994
        {
995
                // Remove PM from Outbox
996
                $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
997
                        WHERE user_id = $user_id AND folder_id = " . PRIVMSGS_OUTBOX . '
998
                                AND ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
999
                $db->sql_query($sql);
1000
1001
                // Update PM Information for safety
1002
                $sql = 'UPDATE ' . PRIVMSGS_TABLE . " SET message_text = ''
1003
                        WHERE " . $db->sql_in_set('msg_id', array_keys($delete_rows));
1004
                $db->sql_query($sql);
1005
1006
                // Set delete flag for those intended to receive the PM
1007
                // We do not remove the message actually, to retain some basic information (sent time for example)
1008
                $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
1009
                        SET pm_deleted = 1
1010
                        WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
1011
                $db->sql_query($sql);
1012
1013
                $num_deleted = $db->sql_affectedrows();
1014
        }
1015
        else
1016
        {
1017
                // Delete private message data
1018
                $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
1019
                        WHERE user_id = $user_id
1020
                                AND folder_id = $folder_id
1021
                                AND " . $db->sql_in_set('msg_id', array_keys($delete_rows));
1022
                $db->sql_query($sql);
1023
                $num_deleted = $db->sql_affectedrows();
1024
        }
1025
1026
        // if folder id is user defined folder then decrease pm_count
1027
        if (!in_array($folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX, PRIVMSGS_NO_BOX)))
1028
        {
1029
                $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
1030
                        SET pm_count = pm_count - $num_deleted
1031
                        WHERE folder_id = $folder_id";
1032
                $db->sql_query($sql);
1033
        }
1034
1035
        // Update unread and new status field
1036
        if ($num_unread || $num_new)
1037
        {
1038
                $set_sql = ($num_unread) ? 'user_unread_privmsg = user_unread_privmsg - ' . $num_unread : '';
1039
1040
                if ($num_new)
1041
                {
1042
                        $set_sql .= ($set_sql != '') ? ', ' : '';
1043
                        $set_sql .= 'user_new_privmsg = user_new_privmsg - ' . $num_new;
1044
                }
1045
1046
                $db->sql_query('UPDATE ' . USERS_TABLE . " SET $set_sql WHERE user_id = $user_id");
1047
1048
                $user->data['user_new_privmsg'] -= $num_new;
1049
                $user->data['user_unread_privmsg'] -= $num_unread;
1050
        }
1051
1052
        // Now we have to check which messages we can delete completely
1053
        $sql = 'SELECT msg_id
1054
                FROM ' . PRIVMSGS_TO_TABLE . '
1055
                WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
1056
        $result = $db->sql_query($sql);
1057
1058
        while ($row = $db->sql_fetchrow($result))
1059
        {
1060
                unset($delete_rows[$row['msg_id']]);
1061
        }
1062
        $db->sql_freeresult($result);
1063
1064
        $delete_ids = array_keys($delete_rows);
1065
1066
        if (sizeof($delete_ids))
1067
        {
1068
                // Check if there are any attachments we need to remove
1069
                if (!function_exists('delete_attachments'))
1070
                {
1071
                        include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1072
                }
1073
1074
                delete_attachments('message', $delete_ids, false);
1075
1076
                $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
1077
                        WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
1078
                $db->sql_query($sql);
1079
        }
1080
1081
        $db->sql_transaction('commit');
1082
1083
        return true;
1084
}
1085
1086
/**
1087
* Rebuild message header
1088
*/
1089
function rebuild_header($check_ary)
1090
{
1091
        global $db;
1092
1093
        $address = array();
1094
1095
        foreach ($check_ary as $check_type => $address_field)
1096
        {
1097
                // Split Addresses into users and groups
1098
                preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
1099
1100
                $u = $g = array();
1101
                foreach ($match[1] as $id => $type)
1102
                {
1103
                        ${$type}[] = (int) $match[2][$id];
1104
                }
1105
1106
                $_types = array('u', 'g');
1107
                foreach ($_types as $type)
1108
                {
1109
                        if (sizeof($$type))
1110
                        {
1111
                                foreach ($$type as $id)
1112
                                {
1113
                                        $address[$type][$id] = $check_type;
1114
                                }
1115
                        }
1116
                }
1117
        }
1118
1119
        return $address;
1120
}
1121
1122
/**
1123
* Print out/assign recipient information
1124
*/
1125
function write_pm_addresses($check_ary, $author_id, $plaintext = false)
1126
{
1127
        global $db, $user, $template, $phpbb_root_path, $phpEx;
1128
1129
        $addresses = array();
1130
1131
        foreach ($check_ary as $check_type => $address_field)
1132
        {
1133
                if (!is_array($address_field))
1134
                {
1135
                        // Split Addresses into users and groups
1136
                        preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
1137
1138
                        $u = $g = array();
1139
                        foreach ($match[1] as $id => $type)
1140
                        {
1141
                                ${$type}[] = (int) $match[2][$id];
1142
                        }
1143
                }
1144
                else
1145
                {
1146
                        $u = $address_field['u'];
1147
                        $g = $address_field['g'];
1148
                }
1149
1150
                $address = array();
1151
                if (sizeof($u))
1152
                {
1153
                        $sql = 'SELECT user_id, username, user_colour
1154
                                FROM ' . USERS_TABLE . '
1155
                                WHERE ' . $db->sql_in_set('user_id', $u);
1156
                        $result = $db->sql_query($sql);
1157
1158
                        while ($row = $db->sql_fetchrow($result))
1159
                        {
1160
                                if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
1161
                                {
1162
                                        if ($plaintext)
1163
                                        {
1164
                                                $address[] = $row['username'];
1165
                                        }
1166
                                        else
1167
                                        {
1168
                                                $address['user'][$row['user_id']] = array('name' => $row['username'], 'colour' => $row['user_colour']);
1169
                                        }
1170
                                }
1171
                        }
1172
                        $db->sql_freeresult($result);
1173
                }
1174
1175
                if (sizeof($g))
1176
                {
1177
                        if ($plaintext)
1178
                        {
1179
                                $sql = 'SELECT group_name, group_type
1180
                                        FROM ' . GROUPS_TABLE . '
1181
                                                WHERE ' . $db->sql_in_set('group_id', $g);
1182
                                $result = $db->sql_query($sql);
1183
1184
                                while ($row = $db->sql_fetchrow($result))
1185
                                {
1186
                                        if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
1187
                                        {
1188
                                                $address[] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
1189
                                        }
1190
                                }
1191
                                $db->sql_freeresult($result);
1192
                        }
1193
                        else
1194
                        {
1195
                                $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type, ug.user_id
1196
                                        FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
1197
                                                WHERE ' . $db->sql_in_set('g.group_id', $g) . '
1198
                                                AND g.group_id = ug.group_id
1199
                                                AND ug.user_pending = 0';
1200
                                $result = $db->sql_query($sql);
1201
1202
                                while ($row = $db->sql_fetchrow($result))
1203
                                {
1204
                                        if (!isset($address['group'][$row['group_id']]))
1205
                                        {
1206
                                                if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
1207
                                                {
1208
                                                        $row['group_name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
1209
                                                        $address['group'][$row['group_id']] = array('name' => $row['group_name'], 'colour' => $row['group_colour']);
1210
                                                }
1211
                                        }
1212
1213
                                        if (isset($address['user'][$row['user_id']]))
1214
                                        {
1215
                                                $address['user'][$row['user_id']]['in_group'] = $row['group_id'];
1216
                                        }
1217
                                }
1218
                                $db->sql_freeresult($result);
1219
                        }
1220
                }
1221
1222
                if (sizeof($address) && !$plaintext)
1223
                {
1224
                        $template->assign_var('S_' . strtoupper($check_type) . '_RECIPIENT', true);
1225
1226
                        foreach ($address as $type => $adr_ary)
1227
                        {
1228
                                foreach ($adr_ary as $id => $row)
1229
                                {
1230
                                        $tpl_ary = array(
1231
                                                'IS_GROUP'        => ($type == 'group') ? true : false,
1232
                                                'IS_USER'        => ($type == 'user') ? true : false,
1233
                                                'UG_ID'                => $id,
1234
                                                'NAME'                => $row['name'],
1235
                                                'COLOUR'        => ($row['colour']) ? '#' . $row['colour'] : '',
1236
                                                'TYPE'                => $type,
1237
                                        );
1238
1239
                                        if ($type == 'user')
1240
                                        {
1241
                                                $tpl_ary = array_merge($tpl_ary, array(
1242
                                                        'U_VIEW'                => get_username_string('profile', $id, $row['name'], $row['colour']),
1243
                                                        'NAME_FULL'                => get_username_string('full', $id, $row['name'], $row['colour']),
1244
                                                ));
1245
                                        }
1246
                                        else
1247
                                        {
1248
                                                $tpl_ary = array_merge($tpl_ary, array(
1249
                                                        'U_VIEW'                => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $id),
1250
                                                ));
1251
                                        }
1252
1253
                                        $template->assign_block_vars($check_type . '_recipient', $tpl_ary);
1254
                                }
1255
                        }
1256
                }
1257
1258
                $addresses[$check_type] = $address;
1259
        }
1260
1261
        return $addresses;
1262
}
1263
1264
/**
1265
* Get folder status
1266
*/
1267
function get_folder_status($folder_id, $folder)
1268
{
1269
        global $db, $user, $config;
1270
1271
        if (isset($folder[$folder_id]))
1272
        {
1273
                $folder = $folder[$folder_id];
1274
        }
1275
        else
1276
        {
1277
                return false;
1278
        }
1279
1280
        $return = array(
1281
                'folder_name'        => $folder['folder_name'],
1282
                'cur'                        => $folder['num_messages'],
1283
                'remaining'                => ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0,
1284
                'max'                        => $user->data['message_limit'],
1285
                'percent'                => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
1286
        );
1287
1288
        $return['message']        = sprintf($user->lang['FOLDER_STATUS_MSG'], $return['percent'], $return['cur'], $return['max']);
1289
1290
        return $return;
1291
}
1292
1293
//
1294
// COMPOSE MESSAGES
1295
//
1296
1297
/**
1298
* Submit PM
1299
*/
1300
function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
1301
{
1302
        global $db, $auth, $config, $phpEx, $template, $user, $phpbb_root_path;
1303
1304
        // We do not handle erasing pms here
1305
        if ($mode == 'delete')
1306
        {
1307
                return false;
1308
        }
1309
1310
        $current_time = time();
1311
1312
        // Collect some basic information about which tables and which rows to update/insert
1313
        $sql_data = array();
1314
        $root_level = 0;
1315
1316
        // Recipient Information
1317
        $recipients = $to = $bcc = array();
1318
1319
        if ($mode != 'edit')
1320
        {
1321
                // Build Recipient List
1322
                // u|g => array($user_id => 'to'|'bcc')
1323
                $_types = array('u', 'g');
1324
                foreach ($_types as $ug_type)
1325
                {
1326
                        if (isset($data['address_list'][$ug_type]) && sizeof($data['address_list'][$ug_type]))
1327
                        {
1328
                                foreach ($data['address_list'][$ug_type] as $id => $field)
1329
                                {
1330
                                        $id = (int) $id;
1331
1332
                                        // Do not rely on the address list being "valid"
1333
                                        if (!$id || ($ug_type == 'u' && $id == ANONYMOUS))
1334
                                        {
1335
                                                continue;
1336
                                        }
1337
1338
                                        $field = ($field == 'to') ? 'to' : 'bcc';
1339
                                        if ($ug_type == 'u')
1340
                                        {
1341
                                                $recipients[$id] = $field;
1342
                                        }
1343
                                        ${$field}[] = $ug_type . '_' . $id;
1344
                                }
1345
                        }
1346
                }
1347
1348
                if (isset($data['address_list']['g']) && sizeof($data['address_list']['g']))
1349
                {
1350
                        // We need to check the PM status of group members (do they want to receive PM's?)
1351
                        // Only check if not a moderator or admin, since they are allowed to override this user setting
1352
                        $sql_allow_pm = (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND u.user_allow_pm = 1' : '';
1353
1354
                        $sql = 'SELECT u.user_type, ug.group_id, ug.user_id
1355
                                FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
1356
                                WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . '
1357
                                        AND ug.user_pending = 0
1358
                                        AND u.user_id = ug.user_id
1359
                                        AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' .
1360
                                        $sql_allow_pm;
1361
                        $result = $db->sql_query($sql);
1362
1363
                        while ($row = $db->sql_fetchrow($result))
1364
                        {
1365
                                // Additionally, do not include the sender if he is in the group he wants to send to. ;)
1366
                                if ($row['user_id'] === $user->data['user_id'])
1367
                                {
1368
                                        continue;
1369
                                }
1370
1371
                                $field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc';
1372
                                $recipients[$row['user_id']] = $field;
1373
                        }
1374
                        $db->sql_freeresult($result);
1375
                }
1376
1377
                if (!sizeof($recipients))
1378
                {
1379
                        trigger_error('NO_RECIPIENT');
1380
                }
1381
        }
1382
1383
        // First of all make sure the subject are having the correct length.
1384
        $subject = truncate_string($subject);
1385
1386
        $db->sql_transaction('begin');
1387
1388
        $sql = '';
1389
1390
        switch ($mode)
1391
        {
1392
                case 'reply':
1393
                case 'quote':
1394
                        $root_level = ($data['reply_from_root_level']) ? $data['reply_from_root_level'] : $data['reply_from_msg_id'];
1395
1396
                        // Set message_replied switch for this user
1397
                        $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
1398
                                SET pm_replied = 1
1399
                                WHERE user_id = ' . $data['from_user_id'] . '
1400
                                        AND msg_id = ' . $data['reply_from_msg_id'];
1401
1402
                // no break
1403
1404
                case 'forward':
1405
                case 'post':
1406
                case 'quotepost':
1407
                        $sql_data = array(
1408
                                'root_level'                => $root_level,
1409
                                'author_id'                        => $data['from_user_id'],
1410
                                'icon_id'                        => $data['icon_id'],
1411
                                'author_ip'                        => $data['from_user_ip'],
1412
                                'message_time'                => $current_time,
1413
                                'enable_bbcode'                => $data['enable_bbcode'],
1414
                                'enable_smilies'        => $data['enable_smilies'],
1415
                                'enable_magic_url'        => $data['enable_urls'],
1416
                                'enable_sig'                => $data['enable_sig'],
1417
                                'message_subject'        => $subject,
1418
                                'message_text'                => $data['message'],
1419
                                'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
1420
                                'bbcode_bitfield'        => $data['bbcode_bitfield'],
1421
                                'bbcode_uid'                => $data['bbcode_uid'],
1422
                                'to_address'                => implode(':', $to),
1423
                                'bcc_address'                => implode(':', $bcc),
1424
                                'message_reported'        => 0,
1425
                        );
1426
                break;
1427
1428
                case 'edit':
1429
                        $sql_data = array(
1430
                                'icon_id'                        => $data['icon_id'],
1431
                                'message_edit_time'        => $current_time,
1432
                                'enable_bbcode'                => $data['enable_bbcode'],
1433
                                'enable_smilies'        => $data['enable_smilies'],
1434
                                'enable_magic_url'        => $data['enable_urls'],
1435
                                'enable_sig'                => $data['enable_sig'],
1436
                                'message_subject'        => $subject,
1437
                                'message_text'                => $data['message'],
1438
                                'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
1439
                                'bbcode_bitfield'        => $data['bbcode_bitfield'],
1440
                                'bbcode_uid'                => $data['bbcode_uid']
1441
                        );
1442
                break;
1443
        }
1444
1445
        if (sizeof($sql_data))
1446
        {
1447
                $query = '';
1448
1449
                if ($mode == 'post' || $mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward')
1450
                {
1451
                        $db->sql_query('INSERT INTO ' . PRIVMSGS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data));
1452
                        $data['msg_id'] = $db->sql_nextid();
1453
                }
1454
                else if ($mode == 'edit')
1455
                {
1456
                        $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
1457
                                SET message_edit_count = message_edit_count + 1, ' . $db->sql_build_array('UPDATE', $sql_data) . '
1458
                                WHERE msg_id = ' . $data['msg_id'];
1459
                        $db->sql_query($sql);
1460
                }
1461
        }
1462
1463
        if ($mode != 'edit')
1464
        {
1465
                if ($sql)
1466
                {
1467
                        $db->sql_query($sql);
1468
                }
1469
                unset($sql);
1470
1471
                $sql_ary = array();
1472
                foreach ($recipients as $user_id => $type)
1473
                {
1474
                        $sql_ary[] = array(
1475
                                'msg_id'                => (int) $data['msg_id'],
1476
                                'user_id'                => (int) $user_id,
1477
                                'author_id'                => (int) $data['from_user_id'],
1478
                                'folder_id'                => PRIVMSGS_NO_BOX,
1479
                                'pm_new'                => 1,
1480
                                'pm_unread'                => 1,
1481
                                'pm_forwarded'        => ($mode == 'forward') ? 1 : 0
1482
                        );
1483
                }
1484
1485
                $db->sql_multi_insert(PRIVMSGS_TO_TABLE, $sql_ary);
1486
1487
                $sql = 'UPDATE ' . USERS_TABLE . '
1488
                        SET user_new_privmsg = user_new_privmsg + 1, user_unread_privmsg = user_unread_privmsg + 1, user_last_privmsg = ' . time() . '
1489
                        WHERE ' . $db->sql_in_set('user_id', array_keys($recipients));
1490
                $db->sql_query($sql);
1491
1492
                // Put PM into outbox
1493
                if ($put_in_outbox)
1494
                {
1495
                        $db->sql_query('INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1496
                                'msg_id'                => (int) $data['msg_id'],
1497
                                'user_id'                => (int) $data['from_user_id'],
1498
                                'author_id'                => (int) $data['from_user_id'],
1499
                                'folder_id'                => PRIVMSGS_OUTBOX,
1500
                                'pm_new'                => 0,
1501
                                'pm_unread'                => 0,
1502
                                'pm_forwarded'        => ($mode == 'forward') ? 1 : 0))
1503
                        );
1504
                }
1505
        }
1506
1507
        // Set user last post time
1508
        if ($mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward' || $mode == 'post')
1509
        {
1510
                $sql = 'UPDATE ' . USERS_TABLE . "
1511
                        SET user_lastpost_time = $current_time
1512
                        WHERE user_id = " . $data['from_user_id'];
1513
                $db->sql_query($sql);
1514
        }
1515
1516
        // Submit Attachments
1517
        if (!empty($data['attachment_data']) && $data['msg_id'] && in_array($mode, array('post', 'reply', 'quote', 'quotepost', 'edit', 'forward')))
1518
        {
1519
                $space_taken = $files_added = 0;
1520
                $orphan_rows = array();
1521
1522
                foreach ($data['attachment_data'] as $pos => $attach_row)
1523
                {
1524
                        $orphan_rows[(int) $attach_row['attach_id']] = array();
1525
                }
1526
1527
                if (sizeof($orphan_rows))
1528
                {
1529
                        $sql = 'SELECT attach_id, filesize, physical_filename
1530
                                FROM ' . ATTACHMENTS_TABLE . '
1531
                                WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
1532
                                        AND in_message = 1
1533
                                        AND is_orphan = 1
1534
                                        AND poster_id = ' . $user->data['user_id'];
1535
                        $result = $db->sql_query($sql);
1536
1537
                        $orphan_rows = array();
1538
                        while ($row = $db->sql_fetchrow($result))
1539
                        {
1540
                                $orphan_rows[$row['attach_id']] = $row;
1541
                        }
1542
                        $db->sql_freeresult($result);
1543
                }
1544
1545
                foreach ($data['attachment_data'] as $pos => $attach_row)
1546
                {
1547
                        if ($attach_row['is_orphan'] && !isset($orphan_rows[$attach_row['attach_id']]))
1548
                        {
1549
                                continue;
1550
                        }
1551
1552
                        if (!$attach_row['is_orphan'])
1553
                        {
1554
                                // update entry in db if attachment already stored in db and filespace
1555
                                $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
1556
                                        SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
1557
                                        WHERE attach_id = " . (int) $attach_row['attach_id'] . '
1558
                                                AND is_orphan = 0';
1559
                                $db->sql_query($sql);
1560
                        }
1561
                        else
1562
                        {
1563
                                // insert attachment into db
1564
                                if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
1565
                                {
1566
                                        continue;
1567
                                }
1568
1569
                                $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
1570
                                $files_added++;
1571
1572
                                $attach_sql = array(
1573
                                        'post_msg_id'                => $data['msg_id'],
1574
                                        'topic_id'                        => 0,
1575
                                        'is_orphan'                        => 0,
1576
                                        'poster_id'                        => $data['from_user_id'],
1577
                                        'attach_comment'        => $attach_row['attach_comment'],
1578
                                );
1579
1580
                                $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
1581
                                        WHERE attach_id = ' . $attach_row['attach_id'] . '
1582
                                                AND is_orphan = 1
1583
                                                AND poster_id = ' . $user->data['user_id'];
1584
                                $db->sql_query($sql);
1585
                        }
1586
                }
1587
1588
                if ($space_taken && $files_added)
1589
                {
1590
                        set_config_count('upload_dir_size', $space_taken, true);
1591
                        set_config_count('num_files', $files_added, true);
1592
                }
1593
        }
1594
1595
        // Delete draft if post was loaded...
1596
        $draft_id = request_var('draft_loaded', 0);
1597
        if ($draft_id)
1598
        {
1599
                $sql = 'DELETE FROM ' . DRAFTS_TABLE . "
1600
                        WHERE draft_id = $draft_id
1601
                                AND user_id = " . $data['from_user_id'];
1602
                $db->sql_query($sql);
1603
        }
1604
1605
        $db->sql_transaction('commit');
1606
1607
        // Send Notifications
1608
        if ($mode != 'edit')
1609
        {
1610
                pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message'], $data['msg_id']);
1611
        }
1612
1613
        return $data['msg_id'];
1614
}
1615
1616
/**
1617
* PM Notification
1618
*/
1619
function pm_notification($mode, $author, $recipients, $subject, $message, $msg_id)
1620
{
1621
        global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
1622
1623
        $subject = censor_text($subject);
1624
1625
        unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]);
1626
1627
        if (!sizeof($recipients))
1628
        {
1629
                return;
1630
        }
1631
1632
        // Get banned User ID's
1633
        $sql = 'SELECT ban_userid
1634
                FROM ' . BANLIST_TABLE . '
1635
                WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . '
1636
                        AND ban_exclude = 0';
1637
        $result = $db->sql_query($sql);
1638
1639
        while ($row = $db->sql_fetchrow($result))
1640
        {
1641
                unset($recipients[$row['ban_userid']]);
1642
        }
1643
        $db->sql_freeresult($result);
1644
1645
        if (!sizeof($recipients))
1646
        {
1647
                return;
1648
        }
1649
1650
        $sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber
1651
                FROM ' . USERS_TABLE . '
1652
                WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients)));
1653
        $result = $db->sql_query($sql);
1654
1655
        $msg_list_ary = array();
1656
        while ($row = $db->sql_fetchrow($result))
1657
        {
1658
                if ($row['user_notify_pm'] == 1 && trim($row['user_email']))
1659
                {
1660
                        $msg_list_ary[] = array(
1661
                                'method'        => $row['user_notify_type'],
1662
                                'email'                => $row['user_email'],
1663
                                'jabber'        => $row['user_jabber'],
1664
                                'name'                => $row['username'],
1665
                                'lang'                => $row['user_lang']
1666
                        );
1667
                }
1668
        }
1669
        $db->sql_freeresult($result);
1670
1671
        if (!sizeof($msg_list_ary))
1672
        {
1673
                return;
1674
        }
1675
1676
        include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1677
        $messenger = new messenger();
1678
1679
        foreach ($msg_list_ary as $pos => $addr)
1680
        {
1681
                $messenger->template('privmsg_notify', $addr['lang']);
1682
1683
                $messenger->to($addr['email'], $addr['name']);
1684
                $messenger->im($addr['jabber'], $addr['name']);
1685
1686
                $messenger->assign_vars(array(
1687
                        'SUBJECT'                => htmlspecialchars_decode($subject),
1688
                        'AUTHOR_NAME'        => htmlspecialchars_decode($author),
1689
                        'USERNAME'                => htmlspecialchars_decode($addr['name']),
1690
1691
                        'U_INBOX'                        => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox",
1692
                        'U_VIEW_MESSAGE'        => generate_board_url() . "/ucp.$phpEx?i=pm&mode=view&p=$msg_id",
1693
                ));
1694
1695
                $messenger->send($addr['method']);
1696
        }
1697
        unset($msg_list_ary);
1698
1699
        $messenger->save_queue();
1700
1701
        unset($messenger);
1702
}
1703
1704
/**
1705
* Display Message History
1706
*/
1707
function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode = false)
1708
{
1709
        global $db, $user, $config, $template, $phpbb_root_path, $phpEx, $auth, $bbcode;
1710
1711
        // Select all receipts and the author from the pm we currently view, to only display their pm-history
1712
        $sql = 'SELECT author_id, user_id
1713
                FROM ' . PRIVMSGS_TO_TABLE . "
1714
                WHERE msg_id = $msg_id
1715
                        AND folder_id <> " . PRIVMSGS_HOLD_BOX;
1716
        $result = $db->sql_query($sql);
1717
1718
        $recipients = array();
1719
        while ($row = $db->sql_fetchrow($result))
1720
        {
1721
                $recipients[] = (int) $row['user_id'];
1722
                $recipients[] = (int) $row['author_id'];
1723
        }
1724
        $db->sql_freeresult($result);
1725
        $recipients = array_unique($recipients);
1726
1727
        // Get History Messages (could be newer)
1728
        $sql = 'SELECT t.*, p.*, u.*
1729
                FROM ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TO_TABLE . ' t, ' . USERS_TABLE . ' u
1730
                WHERE t.msg_id = p.msg_id
1731
                        AND p.author_id = u.user_id
1732
                        AND t.folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
1733
                        AND ' . $db->sql_in_set('t.author_id', $recipients, false, true) . "
1734
                        AND t.user_id = $user_id";
1735
1736
        // We no longer need those.
1737
        unset($recipients);
1738
1739
        if (!$message_row['root_level'])
1740
        {
1741
                $sql .= " AND (p.root_level = $msg_id OR (p.root_level = 0 AND p.msg_id = $msg_id))";
1742
        }
1743
        else
1744
        {
1745
                $sql .= " AND (p.root_level = " . $message_row['root_level'] . ' OR p.msg_id = ' . $message_row['root_level'] . ')';
1746
        }
1747
        $sql .= ' ORDER BY p.message_time DESC';
1748
1749
        $result = $db->sql_query($sql);
1750
        $row = $db->sql_fetchrow($result);
1751
1752
        if (!$row)
1753
        {
1754
                $db->sql_freeresult($result);
1755
                return false;
1756
        }
1757
1758
        $title = $row['message_subject'];
1759
1760
        $rowset = array();
1761
        $bbcode_bitfield = '';
1762
        $folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm') . '&amp;folder=';
1763
1764
        do
1765
        {
1766
                $folder_id = (int) $row['folder_id'];
1767
1768
                $row['folder'][] = (isset($folder[$folder_id])) ? '<a href="' . $folder_url . $folder_id . '">' . $folder[$folder_id]['folder_name'] . '</a>' : $user->lang['UNKNOWN_FOLDER'];
1769
1770
                if (isset($rowset[$row['msg_id']]))
1771
                {
1772
                        $rowset[$row['msg_id']]['folder'][] = (isset($folder[$folder_id])) ? '<a href="' . $folder_url . $folder_id . '">' . $folder[$folder_id]['folder_name'] . '</a>' : $user->lang['UNKNOWN_FOLDER'];
1773
                }
1774
                else
1775
                {
1776
                        $rowset[$row['msg_id']] = $row;
1777
                        $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
1778
                }
1779
        }
1780
        while ($row = $db->sql_fetchrow($result));
1781
        $db->sql_freeresult($result);
1782
1783
        if (sizeof($rowset) == 1 && !$in_post_mode)
1784
        {
1785
                return false;
1786
        }
1787
1788
        // Instantiate BBCode class
1789
        if ((empty($bbcode) || $bbcode === false) && $bbcode_bitfield !== '')
1790
        {
1791
                if (!class_exists('bbcode'))
1792
                {
1793
                        include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
1794
                }
1795
                $bbcode = new bbcode(base64_encode($bbcode_bitfield));
1796
        }
1797
1798
        $title = censor_text($title);
1799
1800
        $url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm');
1801
        $next_history_pm = $previous_history_pm = $prev_id = 0;
1802
1803
        // Re-order rowset to be able to get the next/prev message rows...
1804
        $rowset = array_values($rowset);
1805
1806
        for ($i = 0, $size = sizeof($rowset); $i < $size; $i++)
1807
        {
1808
                $row = &$rowset[$i];
1809
                $id = (int) $row['msg_id'];
1810
1811
                $author_id        = $row['author_id'];
1812
                $folder_id        = (int) $row['folder_id'];
1813
1814
                $subject        = $row['message_subject'];
1815
                $message        = $row['message_text'];
1816
1817
                $message = censor_text($message);
1818
1819
                $decoded_message = false;
1820
1821
                if ($in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS)
1822
                {
1823
                        $decoded_message = $message;
1824
                        decode_message($decoded_message, $row['bbcode_uid']);
1825
1826
                        $decoded_message = bbcode_nl2br($decoded_message);
1827
                }
1828
1829
                if ($row['bbcode_bitfield'])
1830
                {
1831
                        $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
1832
                }
1833
1834
                $message = bbcode_nl2br($message);
1835
                $message = smiley_text($message, !$row['enable_smilies']);
1836
1837
                $subject = censor_text($subject);
1838
1839
                if ($id == $msg_id)
1840
                {
1841
                        $next_history_pm = (isset($rowset[$i + 1])) ? (int) $rowset[$i + 1]['msg_id'] : 0;
1842
                        $previous_history_pm = $prev_id;
1843
                }
1844
1845
                $template->assign_block_vars('history_row', array(
1846
                        'MESSAGE_AUTHOR_QUOTE'                => (($decoded_message) ? addslashes(get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username'])) : ''),
1847
                        'MESSAGE_AUTHOR_FULL'                => get_username_string('full', $author_id, $row['username'], $row['user_colour'], $row['username']),
1848
                        'MESSAGE_AUTHOR_COLOUR'                => get_username_string('colour', $author_id, $row['username'], $row['user_colour'], $row['username']),
1849
                        'MESSAGE_AUTHOR'                        => get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username']),
1850
                        'U_MESSAGE_AUTHOR'                        => get_username_string('profile', $author_id, $row['username'], $row['user_colour'], $row['username']),
1851
1852
                        'SUBJECT'                        => $subject,
1853
                        'SENT_DATE'                        => $user->format_date($row['message_time']),
1854
                        'MESSAGE'                        => $message,
1855
                        'FOLDER'                        => implode(', ', $row['folder']),
1856
                        'DECODED_MESSAGE'        => $decoded_message,
1857
1858
                        'S_CURRENT_MSG'                => ($row['msg_id'] == $msg_id),
1859
                        'S_AUTHOR_DELETED'        => ($author_id == ANONYMOUS) ? true : false,
1860
                        'S_IN_POST_MODE'        => $in_post_mode,
1861
1862
                        'MSG_ID'                        => $row['msg_id'],
1863
                        'U_VIEW_MESSAGE'        => "$url&amp;f=$folder_id&amp;p=" . $row['msg_id'],
1864
                        'U_QUOTE'                        => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&amp;mode=compose&amp;action=quote&amp;f=" . $folder_id . "&amp;p=" . $row['msg_id'] : '',
1865
                        'U_POST_REPLY_PM'        => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $row['msg_id'] : '')
1866
                );
1867
                unset($rowset[$i]);
1868
                $prev_id = $id;
1869
        }
1870
1871
        $template->assign_vars(array(
1872
                'QUOTE_IMG'                        => $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']),
1873
                'HISTORY_TITLE'                => $title,
1874
1875
                'U_VIEW_NEXT_HISTORY'                => ($next_history_pm) ? "$url&amp;p=" . $next_history_pm : '',
1876
                'U_VIEW_PREVIOUS_HISTORY'        => ($previous_history_pm) ? "$url&amp;p=" . $previous_history_pm : '',
1877
        ));
1878
1879
        return true;
1880
}
1881
1882
/**
1883
* Set correct users max messages in PM folder.
1884
* If several group memberships define different amount of messages, the highest will be chosen.
1885
*/
1886
function set_user_message_limit()
1887
{
1888
        global $user, $db, $config;
1889
1890
        // Get maximum about from user memberships - if it is 0, there is no limit set and we use the maximum value within the config.
1891
        $sql = 'SELECT MAX(g.group_message_limit) as max_message_limit
1892
                FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
1893
                WHERE ug.user_id = ' . $user->data['user_id'] . '
1894
                        AND ug.user_pending = 0
1895
                        AND ug.group_id = g.group_id';
1896
        $result = $db->sql_query($sql);
1897
        $message_limit = (int) $db->sql_fetchfield('max_message_limit');
1898
        $db->sql_freeresult($result);
1899
1900
        $user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
1901
}
1902
1903
/**
1904
* Generates an array of coloured recipient names from a list of PMs - (groups & users)
1905
*
1906
* @param        array        $pm_by_id        An array of rows from PRIVMSGS_TABLE, keys are the msg_ids.
1907
*
1908
* @return        array                                2D Array: array(msg_id => array('username or group string', ...), ...)
1909
*                                                                Usernames are generated with {@link get_username_string get_username_string}
1910
*                                                                Groups are coloured and have a link to the membership page
1911
*/
1912
function get_recipient_strings($pm_by_id)
1913
{
1914
        global $db, $phpbb_root_path, $phpEx, $user;
1915
1916
        $address_list = $recipient_list = $address = array();
1917
1918
        $_types = array('u', 'g');
1919
1920
        foreach ($pm_by_id as $message_id => $row)
1921
        {
1922
                $address[$message_id] = rebuild_header(array('to' => $row['to_address'], 'bcc' => $row['bcc_address']));
1923
1924
                foreach ($_types as $ug_type)
1925
                {
1926
                        if (isset($address[$message_id][$ug_type]) && sizeof($address[$message_id][$ug_type]))
1927
                        {
1928
                                foreach ($address[$message_id][$ug_type] as $ug_id => $in_to)
1929
                                {
1930
                                        $recipient_list[$ug_type][$ug_id] = array('name' => $user->lang['NA'], 'colour' => '');
1931
                                }
1932
                        }
1933
                }
1934
        }
1935
1936
        foreach ($_types as $ug_type)
1937
        {
1938
                if (!empty($recipient_list[$ug_type]))
1939
                {
1940
                        if ($ug_type == 'u')
1941
                        {
1942
                                $sql = 'SELECT user_id as id, username as name, user_colour as colour
1943
                                        FROM ' . USERS_TABLE . '
1944
                                        WHERE ';
1945
                        }
1946
                        else
1947
                        {
1948
                                $sql = 'SELECT group_id as id, group_name as name, group_colour as colour, group_type
1949
                                        FROM ' . GROUPS_TABLE . '
1950
                                        WHERE ';
1951
                        }
1952
                        $sql .= $db->sql_in_set(($ug_type == 'u') ? 'user_id' : 'group_id', array_map('intval', array_keys($recipient_list[$ug_type])));
1953
1954
                        $result = $db->sql_query($sql);
1955
1956
                        while ($row = $db->sql_fetchrow($result))
1957
                        {
1958
                                if ($ug_type == 'g')
1959
                                {
1960
                                        $row['name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['name']] : $row['name'];
1961
                                }
1962
1963
                                $recipient_list[$ug_type][$row['id']] = array('name' => $row['name'], 'colour' => $row['colour']);
1964
                        }
1965
                        $db->sql_freeresult($result);
1966
                }
1967
        }
1968
1969
        foreach ($address as $message_id => $adr_ary)
1970
        {
1971
                foreach ($adr_ary as $type => $id_ary)
1972
                {
1973
                        foreach ($id_ary as $ug_id => $_id)
1974
                        {
1975
                                if ($type == 'u')
1976
                                {
1977
                                        $address_list[$message_id][] = get_username_string('full', $ug_id, $recipient_list[$type][$ug_id]['name'], $recipient_list[$type][$ug_id]['colour']);
1978
                                }
1979
                                else
1980
                                {
1981
                                        $user_colour = ($recipient_list[$type][$ug_id]['colour']) ? ' style="font-weight: bold; color:#' . $recipient_list[$type][$ug_id]['colour'] . '"' : '';
1982
                                        $link = '<a href="' . append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $ug_id) . '"' . $user_colour . '>';
1983
                                        $address_list[$message_id][] = $link . $recipient_list[$type][$ug_id]['name'] . (($link) ? '</a>' : '');
1984
                                }
1985
                        }
1986
                }
1987
        }
1988
1989
        return $address_list;
1990
}
1991
1992
?>