~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/php/phpBB3/includes/functions_admin.php

  • Committer: dcoles
  • Date: 2008-02-13 04:10:55 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:443
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
*
 
4
* @package acp
 
5
* @version $Id: functions_admin.php,v 1.254 2007/11/17 12:14:27 acydburn Exp $
 
6
* @copyright (c) 2005 phpBB Group
 
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
 
8
*
 
9
*/
 
10
 
 
11
/**
 
12
* @ignore
 
13
*/
 
14
if (!defined('IN_PHPBB'))
 
15
{
 
16
        exit;
 
17
}
 
18
 
 
19
/**
 
20
* Recalculate Binary Tree
 
21
function recalc_btree($sql_id, $sql_table, $module_class = '')
 
22
{
 
23
        global $db;
 
24
 
 
25
        if (!$sql_id || !$sql_table)
 
26
        {
 
27
                return;
 
28
        }
 
29
 
 
30
        $sql_where = ($module_class) ? " WHERE module_class = '" . $db->sql_escape($module_class) . "'" : '';
 
31
 
 
32
        // Reset to minimum possible left and right id
 
33
        $sql = "SELECT MIN(left_id) as min_left_id, MIN(right_id) as min_right_id
 
34
                FROM $sql_table
 
35
                $sql_where";
 
36
        $result = $db->sql_query($sql);
 
37
        $row = $db->sql_fetchrow($result);
 
38
        $db->sql_freeresult($result);
 
39
 
 
40
        $substract = (int) (min($row['min_left_id'], $row['min_right_id']) - 1);
 
41
 
 
42
        if ($substract > 0)
 
43
        {
 
44
                $sql = "UPDATE $sql_table
 
45
                        SET left_id = left_id - $substract, right_id = right_id - $substract
 
46
                        $sql_where";
 
47
                $db->sql_query($sql);
 
48
        }
 
49
 
 
50
        $sql = "SELECT $sql_id, parent_id, left_id, right_id
 
51
                FROM $sql_table
 
52
                $sql_where
 
53
                ORDER BY left_id ASC, parent_id ASC, $sql_id ASC";
 
54
        $f_result = $db->sql_query($sql);
 
55
 
 
56
        while ($item_data = $db->sql_fetchrow($f_result))
 
57
        {
 
58
                if ($item_data['parent_id'])
 
59
                {
 
60
                        $sql = "SELECT left_id, right_id
 
61
                                FROM $sql_table
 
62
                                $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
 
63
                                        $sql_id = {$item_data['parent_id']}";
 
64
                        $result = $db->sql_query($sql);
 
65
 
 
66
                        if (!$row = $db->sql_fetchrow($result))
 
67
                        {
 
68
                                $sql = "UPDATE $sql_table SET parent_id = 0 WHERE $sql_id = " . $item_data[$sql_id];
 
69
                                $db->sql_query($sql);
 
70
                        }
 
71
                        $db->sql_freeresult($result);
 
72
 
 
73
                        $sql = "UPDATE $sql_table
 
74
                                SET left_id = left_id + 2, right_id = right_id + 2
 
75
                                $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
 
76
                                        left_id > {$row['right_id']}";
 
77
                        $db->sql_query($sql);
 
78
 
 
79
                        $sql = "UPDATE $sql_table
 
80
                                SET right_id = right_id + 2
 
81
                                $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
 
82
                                        {$row['left_id']} BETWEEN left_id AND right_id";
 
83
                        $db->sql_query($sql);
 
84
 
 
85
                        $item_data['left_id'] = $row['right_id'];
 
86
                        $item_data['right_id'] = $row['right_id'] + 1;
 
87
                }
 
88
                else
 
89
                {
 
90
                        $sql = "SELECT MAX(right_id) AS right_id
 
91
                                FROM $sql_table
 
92
                                $sql_where";
 
93
                        $result = $db->sql_query($sql);
 
94
                        $row = $db->sql_fetchrow($result);
 
95
                        $db->sql_freeresult($result);
 
96
 
 
97
                        $item_data['left_id'] = $row['right_id'] + 1;
 
98
                        $item_data['right_id'] = $row['right_id'] + 2;
 
99
                }
 
100
        
 
101
                $sql = "UPDATE $sql_table
 
102
                        SET left_id = {$item_data['left_id']}, right_id = {$item_data['right_id']}
 
103
                        WHERE $sql_id = " . $item_data[$sql_id];
 
104
                $db->sql_query($sql);
 
105
        }
 
106
        $db->sql_freeresult($f_result);
 
107
}
 
108
*/
 
109
 
 
110
/**
 
111
* Simple version of jumpbox, just lists authed forums
 
112
*/
 
113
function make_forum_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $only_acl_post = false, $return_array = false)
 
114
{
 
115
        global $db, $user, $auth;
 
116
 
 
117
        $acl = ($ignore_acl) ? '' : (($only_acl_post) ? 'f_post' : array('f_list', 'a_forum', 'a_forumadd', 'a_forumdel'));
 
118
 
 
119
        // This query is identical to the jumpbox one
 
120
        $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
 
121
                FROM ' . FORUMS_TABLE . '
 
122
                ORDER BY left_id ASC';
 
123
        $result = $db->sql_query($sql, 600);
 
124
 
 
125
        $right = 0;
 
126
        $padding_store = array('0' => '');
 
127
        $padding = '';
 
128
        $forum_list = ($return_array) ? array() : '';
 
129
 
 
130
        // Sometimes it could happen that forums will be displayed here not be displayed within the index page
 
131
        // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions.
 
132
        // If this happens, the padding could be "broken"
 
133
 
 
134
        while ($row = $db->sql_fetchrow($result))
 
135
        {
 
136
                if ($row['left_id'] < $right)
 
137
                {
 
138
                        $padding .= '&nbsp; &nbsp;';
 
139
                        $padding_store[$row['parent_id']] = $padding;
 
140
                }
 
141
                else if ($row['left_id'] > $right + 1)
 
142
                {
 
143
                        $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
 
144
                }
 
145
 
 
146
                $right = $row['right_id'];
 
147
                $disabled = false;
 
148
 
 
149
                if ($acl && !$auth->acl_gets($acl, $row['forum_id']))
 
150
                {
 
151
                        // List permission?
 
152
                        if ($auth->acl_get('f_list', $row['forum_id']))
 
153
                        {
 
154
                                $disabled = true;
 
155
                        }
 
156
                        else
 
157
                        {
 
158
                                continue;
 
159
                        }
 
160
                }
 
161
 
 
162
                if (
 
163
                        ((is_array($ignore_id) && in_array($row['forum_id'], $ignore_id)) || $row['forum_id'] == $ignore_id)
 
164
                        ||
 
165
                        // Non-postable forum with no subforums, don't display
 
166
                        ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
 
167
                        ||
 
168
                        ($row['forum_type'] != FORUM_POST && $ignore_nonpost)
 
169
                        )
 
170
                {
 
171
                        $disabled = true;
 
172
                }
 
173
 
 
174
                if ($return_array)
 
175
                {
 
176
                        // Include some more information...
 
177
                        $selected = (is_array($select_id)) ? ((in_array($row['forum_id'], $select_id)) ? true : false) : (($row['forum_id'] == $select_id) ? true : false);
 
178
                        $forum_list[$row['forum_id']] = array_merge(array('padding' => $padding, 'selected' => ($selected && !$disabled), 'disabled' => $disabled), $row);
 
179
                }
 
180
                else
 
181
                {
 
182
                        $selected = (is_array($select_id)) ? ((in_array($row['forum_id'], $select_id)) ? ' selected="selected"' : '') : (($row['forum_id'] == $select_id) ? ' selected="selected"' : '');
 
183
                        $forum_list .= '<option value="' . $row['forum_id'] . '"' . (($disabled) ? ' disabled="disabled" class="disabled-option"' : $selected) . '>' . $padding . $row['forum_name'] . '</option>';
 
184
                }
 
185
        }
 
186
        $db->sql_freeresult($result);
 
187
        unset($padding_store);
 
188
 
 
189
        return $forum_list;
 
190
}
 
191
 
 
192
/**
 
193
* Generate size select options
 
194
*/
 
195
function size_select_options($size_compare)
 
196
{
 
197
        global $user;
 
198
 
 
199
        $size_types_text = array($user->lang['BYTES'], $user->lang['KB'], $user->lang['MB']);
 
200
        $size_types = array('b', 'kb', 'mb');
 
201
 
 
202
        $s_size_options = '';
 
203
 
 
204
        for ($i = 0, $size = sizeof($size_types_text); $i < $size; $i++)
 
205
        {
 
206
                $selected = ($size_compare == $size_types[$i]) ? ' selected="selected"' : '';
 
207
                $s_size_options .= '<option value="' . $size_types[$i] . '"' . $selected . '>' . $size_types_text[$i] . '</option>';
 
208
        }
 
209
 
 
210
        return $s_size_options;
 
211
}
 
212
 
 
213
/**
 
214
* Generate list of groups (option fields without select)
 
215
*
 
216
* @param int $group_id The default group id to mark as selected
 
217
* @param array $exclude_ids The group ids to exclude from the list, false (default) if you whish to exclude no id
 
218
* @param int $manage_founder If set to false (default) all groups are returned, if 0 only those groups returned not being managed by founders only, if 1 only those groups returned managed by founders only.
 
219
*
 
220
* @return string The list of options.
 
221
*/
 
222
function group_select_options($group_id, $exclude_ids = false, $manage_founder = false)
 
223
{
 
224
        global $db, $user, $config;
 
225
 
 
226
        $exclude_sql = ($exclude_ids !== false && sizeof($exclude_ids)) ? 'WHERE ' . $db->sql_in_set('group_id', array_map('intval', $exclude_ids), true) : '';
 
227
        $sql_and = (!$config['coppa_enable']) ? (($exclude_sql) ? ' AND ' : ' WHERE ') . "group_name <> 'REGISTERED_COPPA'" : '';
 
228
        $sql_founder = ($manage_founder !== false) ? (($exclude_sql || $sql_and) ? ' AND ' : ' WHERE ') . 'group_founder_manage = ' . (int) $manage_founder : '';
 
229
 
 
230
        $sql = 'SELECT group_id, group_name, group_type
 
231
                FROM ' . GROUPS_TABLE . "
 
232
                $exclude_sql
 
233
                $sql_and
 
234
                $sql_founder
 
235
                ORDER BY group_type DESC, group_name ASC";
 
236
        $result = $db->sql_query($sql);
 
237
 
 
238
        $s_group_options = '';
 
239
        while ($row = $db->sql_fetchrow($result))
 
240
        {
 
241
                $selected = ($row['group_id'] == $group_id) ? ' selected="selected"' : '';
 
242
                $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . $selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
 
243
        }
 
244
        $db->sql_freeresult($result);
 
245
 
 
246
        return $s_group_options;
 
247
}
 
248
 
 
249
/**
 
250
* Obtain authed forums list
 
251
*/
 
252
function get_forum_list($acl_list = 'f_list', $id_only = true, $postable_only = false, $no_cache = false)
 
253
{
 
254
        global $db, $auth;
 
255
        static $forum_rows;
 
256
 
 
257
        if (!isset($forum_rows))
 
258
        {
 
259
                // This query is identical to the jumpbox one
 
260
                $expire_time = ($no_cache) ? 0 : 600;
 
261
 
 
262
                $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
 
263
                        FROM ' . FORUMS_TABLE . '
 
264
                        ORDER BY left_id ASC';
 
265
                $result = $db->sql_query($sql, $expire_time);
 
266
 
 
267
                $forum_rows = array();
 
268
 
 
269
                $right = $padding = 0;
 
270
                $padding_store = array('0' => 0);
 
271
 
 
272
                while ($row = $db->sql_fetchrow($result))
 
273
                {
 
274
                        if ($row['left_id'] < $right)
 
275
                        {
 
276
                                $padding++;
 
277
                                $padding_store[$row['parent_id']] = $padding;
 
278
                        }
 
279
                        else if ($row['left_id'] > $right + 1)
 
280
                        {
 
281
                                // Ok, if the $padding_store for this parent is empty there is something wrong. For now we will skip over it.
 
282
                                // @todo digging deep to find out "how" this can happen.
 
283
                                $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding;
 
284
                        }
 
285
 
 
286
                        $right = $row['right_id'];
 
287
                        $row['padding'] = $padding;
 
288
 
 
289
                        $forum_rows[] = $row;
 
290
                }
 
291
                $db->sql_freeresult($result);
 
292
                unset($padding_store);
 
293
        }
 
294
 
 
295
        $rowset = array();
 
296
        foreach ($forum_rows as $row)
 
297
        {
 
298
                if ($postable_only && $row['forum_type'] != FORUM_POST)
 
299
                {
 
300
                        continue;
 
301
                }
 
302
 
 
303
                if ($acl_list == '' || ($acl_list != '' && $auth->acl_gets($acl_list, $row['forum_id'])))
 
304
                {
 
305
                        $rowset[] = ($id_only) ? $row['forum_id'] : $row;
 
306
                }
 
307
        }
 
308
 
 
309
        return $rowset;
 
310
}
 
311
 
 
312
/**
 
313
* Get forum branch
 
314
*/
 
315
function get_forum_branch($forum_id, $type = 'all', $order = 'descending', $include_forum = true)
 
316
{
 
317
        global $db;
 
318
 
 
319
        switch ($type)
 
320
        {
 
321
                case 'parents':
 
322
                        $condition = 'f1.left_id BETWEEN f2.left_id AND f2.right_id';
 
323
                break;
 
324
 
 
325
                case 'children':
 
326
                        $condition = 'f2.left_id BETWEEN f1.left_id AND f1.right_id';
 
327
                break;
 
328
 
 
329
                default:
 
330
                        $condition = 'f2.left_id BETWEEN f1.left_id AND f1.right_id OR f1.left_id BETWEEN f2.left_id AND f2.right_id';
 
331
                break;
 
332
        }
 
333
 
 
334
        $rows = array();
 
335
 
 
336
        $sql = 'SELECT f2.*
 
337
                FROM ' . FORUMS_TABLE . ' f1
 
338
                LEFT JOIN ' . FORUMS_TABLE . " f2 ON ($condition)
 
339
                WHERE f1.forum_id = $forum_id
 
340
                ORDER BY f2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
 
341
        $result = $db->sql_query($sql);
 
342
 
 
343
        while ($row = $db->sql_fetchrow($result))
 
344
        {
 
345
                if (!$include_forum && $row['forum_id'] == $forum_id)
 
346
                {
 
347
                        continue;
 
348
                }
 
349
 
 
350
                $rows[] = $row;
 
351
        }
 
352
        $db->sql_freeresult($result);
 
353
 
 
354
        return $rows;
 
355
}
 
356
 
 
357
/**
 
358
* Get physical file listing
 
359
*/
 
360
function filelist($rootdir, $dir = '', $type = 'gif|jpg|jpeg|png')
 
361
{
 
362
        $matches = array();
 
363
 
 
364
        // Remove initial / if present
 
365
        $rootdir = (substr($rootdir, 0, 1) == '/') ? substr($rootdir, 1) : $rootdir;
 
366
        // Add closing / if not present
 
367
        $rootdir = ($rootdir && substr($rootdir, -1) != '/') ? $rootdir . '/' : $rootdir;
 
368
 
 
369
        // Remove initial / if present
 
370
        $dir = (substr($dir, 0, 1) == '/') ? substr($dir, 1) : $dir;
 
371
        // Add closing / if not present
 
372
        $dir = ($dir && substr($dir, -1) != '/') ? $dir . '/' : $dir;
 
373
 
 
374
        if (!is_dir($rootdir . $dir))
 
375
        {
 
376
                return $matches;
 
377
        }
 
378
 
 
379
        $dh = @opendir($rootdir . $dir);
 
380
 
 
381
        if (!$dh)
 
382
        {
 
383
                return $matches;
 
384
        }
 
385
 
 
386
        while (($fname = readdir($dh)) !== false)
 
387
        {
 
388
                if (is_file("$rootdir$dir$fname"))
 
389
                {
 
390
                        if (filesize("$rootdir$dir$fname") && preg_match('#\.' . $type . '$#i', $fname))
 
391
                        {
 
392
                                $matches[$dir][] = $fname;
 
393
                        }
 
394
                }
 
395
                else if ($fname[0] != '.' && is_dir("$rootdir$dir$fname"))
 
396
                {
 
397
                        $matches += filelist($rootdir, "$dir$fname", $type);
 
398
                }
 
399
        }
 
400
        closedir($dh);
 
401
 
 
402
        return $matches;
 
403
}
 
404
 
 
405
/**
 
406
* Move topic(s)
 
407
*/
 
408
function move_topics($topic_ids, $forum_id, $auto_sync = true)
 
409
{
 
410
        global $db;
 
411
 
 
412
        if (empty($topic_ids))
 
413
        {
 
414
                return;
 
415
        }
 
416
 
 
417
        $forum_ids = array($forum_id);
 
418
 
 
419
        if (!is_array($topic_ids))
 
420
        {
 
421
                $topic_ids = array($topic_ids);
 
422
        }
 
423
 
 
424
        $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 
425
                WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids) . '
 
426
                        AND forum_id = ' . $forum_id;
 
427
        $db->sql_query($sql);
 
428
 
 
429
        if ($auto_sync)
 
430
        {
 
431
                $sql = 'SELECT DISTINCT forum_id
 
432
                        FROM ' . TOPICS_TABLE . '
 
433
                        WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
434
                $result = $db->sql_query($sql);
 
435
 
 
436
                while ($row = $db->sql_fetchrow($result))
 
437
                {
 
438
                        $forum_ids[] = $row['forum_id'];
 
439
                }
 
440
                $db->sql_freeresult($result);
 
441
        }
 
442
 
 
443
        $table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE);
 
444
        foreach ($table_ary as $table)
 
445
        {
 
446
                $sql = "UPDATE $table
 
447
                        SET forum_id = $forum_id
 
448
                        WHERE " . $db->sql_in_set('topic_id', $topic_ids);
 
449
                $db->sql_query($sql);
 
450
        }
 
451
        unset($table_ary);
 
452
 
 
453
        if ($auto_sync)
 
454
        {
 
455
                sync('forum', 'forum_id', $forum_ids, true, true);
 
456
                unset($forum_ids);
 
457
        }
 
458
}
 
459
 
 
460
/**
 
461
* Move post(s)
 
462
*/
 
463
function move_posts($post_ids, $topic_id, $auto_sync = true)
 
464
{
 
465
        global $db;
 
466
 
 
467
        if (!is_array($post_ids))
 
468
        {
 
469
                $post_ids = array($post_ids);
 
470
        }
 
471
 
 
472
        $forum_ids = array();
 
473
        $topic_ids = array($topic_id);
 
474
 
 
475
        $sql = 'SELECT DISTINCT topic_id, forum_id
 
476
                FROM ' . POSTS_TABLE . '
 
477
                WHERE ' . $db->sql_in_set('post_id', $post_ids);
 
478
        $result = $db->sql_query($sql);
 
479
 
 
480
        while ($row = $db->sql_fetchrow($result))
 
481
        {
 
482
                $forum_ids[] = $row['forum_id'];
 
483
                $topic_ids[] = $row['topic_id'];
 
484
        }
 
485
        $db->sql_freeresult($result);
 
486
 
 
487
        $sql = 'SELECT forum_id
 
488
                FROM ' . TOPICS_TABLE . '
 
489
                WHERE topic_id = ' . $topic_id;
 
490
        $result = $db->sql_query($sql);
 
491
        $forum_row = $db->sql_fetchrow($result);
 
492
        $db->sql_freeresult($result);
 
493
 
 
494
        if (!$forum_row)
 
495
        {
 
496
                trigger_error('NO_TOPIC');
 
497
        }
 
498
 
 
499
        $sql = 'UPDATE ' . POSTS_TABLE . '
 
500
                SET forum_id = ' . $forum_row['forum_id'] . ", topic_id = $topic_id
 
501
                WHERE " . $db->sql_in_set('post_id', $post_ids);
 
502
        $db->sql_query($sql);
 
503
 
 
504
        $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
 
505
                SET topic_id = $topic_id, in_message = 0
 
506
                WHERE " . $db->sql_in_set('post_msg_id', $post_ids);
 
507
        $db->sql_query($sql);
 
508
 
 
509
        if ($auto_sync)
 
510
        {
 
511
                $forum_ids[] = $forum_row['forum_id'];
 
512
 
 
513
                sync('topic_reported', 'topic_id', $topic_ids);
 
514
                sync('topic_attachment', 'topic_id', $topic_ids);
 
515
                sync('topic', 'topic_id', $topic_ids, true);
 
516
                sync('forum', 'forum_id', $forum_ids, true, true);
 
517
        }
 
518
 
 
519
        // Update posted information
 
520
        update_posted_info($topic_ids);
 
521
}
 
522
 
 
523
/**
 
524
* Remove topic(s)
 
525
*/
 
526
function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_sync = true, $call_delete_posts = true)
 
527
{
 
528
        global $db, $config;
 
529
 
 
530
        $approved_topics = 0;
 
531
        $forum_ids = $topic_ids = array();
 
532
 
 
533
        if ($where_type === 'range')
 
534
        {
 
535
                $where_clause = $where_ids;
 
536
        }
 
537
        else
 
538
        {
 
539
                $where_ids = (is_array($where_ids)) ? array_unique($where_ids) : array($where_ids);
 
540
 
 
541
                if (!sizeof($where_ids))
 
542
                {
 
543
                        return array('topics' => 0, 'posts' => 0);
 
544
                }
 
545
 
 
546
                $where_clause = $db->sql_in_set($where_type, $where_ids);
 
547
        }
 
548
 
 
549
        // Making sure that delete_posts does not call delete_topics again...
 
550
        $return = array(
 
551
                'posts' => ($call_delete_posts) ? delete_posts($where_type, $where_ids, false, true, $post_count_sync, false) : 0,
 
552
        );
 
553
 
 
554
        $sql = 'SELECT topic_id, forum_id, topic_approved
 
555
                FROM ' . TOPICS_TABLE . '
 
556
                WHERE ' . $where_clause;
 
557
        $result = $db->sql_query($sql);
 
558
 
 
559
        while ($row = $db->sql_fetchrow($result))
 
560
        {
 
561
                $forum_ids[] = $row['forum_id'];
 
562
                $topic_ids[] = $row['topic_id'];
 
563
 
 
564
                if ($row['topic_approved'])
 
565
                {
 
566
                        $approved_topics++;
 
567
                }
 
568
        }
 
569
        $db->sql_freeresult($result);
 
570
 
 
571
        $return['topics'] = sizeof($topic_ids);
 
572
 
 
573
        if (!sizeof($topic_ids))
 
574
        {
 
575
                return $return;
 
576
        }
 
577
 
 
578
        $db->sql_transaction('begin');
 
579
 
 
580
        $table_ary = array(TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, POLL_VOTES_TABLE, POLL_OPTIONS_TABLE, TOPICS_WATCH_TABLE, TOPICS_TABLE);
 
581
 
 
582
        foreach ($table_ary as $table)
 
583
        {
 
584
                $sql = "DELETE FROM $table
 
585
                        WHERE " . $db->sql_in_set('topic_id', $topic_ids);
 
586
                $db->sql_query($sql);
 
587
        }
 
588
        unset($table_ary);
 
589
 
 
590
        $moved_topic_ids = array();
 
591
 
 
592
        // update the other forums
 
593
        $sql = 'SELECT topic_id, forum_id
 
594
                FROM ' . TOPICS_TABLE . '
 
595
                WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids);
 
596
        $result = $db->sql_query($sql);
 
597
 
 
598
        while ($row = $db->sql_fetchrow($result))
 
599
        {
 
600
                $forum_ids[] = $row['forum_id'];
 
601
                $moved_topic_ids[] = $row['topic_id'];
 
602
        }
 
603
        $db->sql_freeresult($result);
 
604
 
 
605
        if (sizeof($moved_topic_ids))
 
606
        {
 
607
                $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 
608
                        WHERE ' . $db->sql_in_set('topic_id', $moved_topic_ids);
 
609
                $db->sql_query($sql);
 
610
        }
 
611
 
 
612
        $db->sql_transaction('commit');
 
613
 
 
614
        if ($auto_sync)
 
615
        {
 
616
                sync('forum', 'forum_id', array_unique($forum_ids), true, true);
 
617
                sync('topic_reported', $where_type, $where_ids);
 
618
        }
 
619
 
 
620
        if ($approved_topics)
 
621
        {
 
622
                set_config('num_topics', $config['num_topics'] - $approved_topics, true);
 
623
        }
 
624
 
 
625
        return $return;
 
626
}
 
627
 
 
628
/**
 
629
* Remove post(s)
 
630
*/
 
631
function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true, $post_count_sync = true, $call_delete_topics = true)
 
632
{
 
633
        global $db, $config, $phpbb_root_path, $phpEx;
 
634
 
 
635
        if ($where_type === 'range')
 
636
        {
 
637
                $where_clause = $where_ids;
 
638
        }
 
639
        else
 
640
        {
 
641
                if (is_array($where_ids))
 
642
                {
 
643
                        $where_ids = array_unique($where_ids);
 
644
                }
 
645
                else
 
646
                {
 
647
                        $where_ids = array($where_ids);
 
648
                }
 
649
 
 
650
                if (!sizeof($where_ids))
 
651
                {
 
652
                        return false;
 
653
                }
 
654
 
 
655
                $where_clause = $db->sql_in_set($where_type, array_map('intval', $where_ids));
 
656
        }
 
657
 
 
658
        $approved_posts = 0;
 
659
        $post_ids = $topic_ids = $forum_ids = $post_counts = $remove_topics = array();
 
660
 
 
661
        $sql = 'SELECT post_id, poster_id, post_approved, post_postcount, topic_id, forum_id
 
662
                FROM ' . POSTS_TABLE . '
 
663
                WHERE ' . $where_clause;
 
664
        $result = $db->sql_query($sql);
 
665
 
 
666
        while ($row = $db->sql_fetchrow($result))
 
667
        {
 
668
                $post_ids[] = $row['post_id'];
 
669
                $poster_ids[] = $row['poster_id'];
 
670
                $topic_ids[] = $row['topic_id'];
 
671
                $forum_ids[] = $row['forum_id'];
 
672
 
 
673
                if ($row['post_postcount'] && $post_count_sync)
 
674
                {
 
675
                        $post_counts[$row['poster_id']] = (!empty($post_counts[$row['poster_id']])) ? $post_counts[$row['poster_id']] + 1 : 1;
 
676
                }
 
677
 
 
678
                if ($row['post_approved'])
 
679
                {
 
680
                        $approved_posts++;
 
681
                }
 
682
        }
 
683
        $db->sql_freeresult($result);
 
684
 
 
685
        if (!sizeof($post_ids))
 
686
        {
 
687
                return false;
 
688
        }
 
689
 
 
690
        $db->sql_transaction('begin');
 
691
 
 
692
        $table_ary = array(POSTS_TABLE, REPORTS_TABLE);
 
693
 
 
694
        foreach ($table_ary as $table)
 
695
        {
 
696
                $sql = "DELETE FROM $table
 
697
                        WHERE " . $db->sql_in_set('post_id', $post_ids);
 
698
                $db->sql_query($sql);
 
699
        }
 
700
        unset($table_ary);
 
701
 
 
702
        // Adjust users post counts
 
703
        if (sizeof($post_counts) && $post_count_sync)
 
704
        {
 
705
                foreach ($post_counts as $poster_id => $substract)
 
706
                {
 
707
                        $sql = 'UPDATE ' . USERS_TABLE . '
 
708
                                SET user_posts = 0
 
709
                                WHERE user_id = ' . $poster_id . '
 
710
                                AND user_posts < ' . $substract;
 
711
                        $db->sql_query($sql);
 
712
                        $sql = 'UPDATE ' . USERS_TABLE . '
 
713
                                SET user_posts = user_posts - ' . $substract . '
 
714
                                WHERE user_id = ' . $poster_id . '
 
715
                                AND user_posts >= ' . $substract;
 
716
                        $db->sql_query($sql);
 
717
                }
 
718
        }
 
719
 
 
720
        // Remove topics now having no posts?
 
721
        if (sizeof($topic_ids))
 
722
        {
 
723
                $sql = 'SELECT topic_id
 
724
                        FROM ' . POSTS_TABLE . '
 
725
                        WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
 
726
                        GROUP BY topic_id';
 
727
                $result = $db->sql_query($sql);
 
728
 
 
729
                while ($row = $db->sql_fetchrow($result))
 
730
                {
 
731
                        $remove_topics[] = $row['topic_id'];
 
732
                }
 
733
                $db->sql_freeresult($result);
 
734
 
 
735
                // Actually, those not within remove_topics should be removed. ;)
 
736
                $remove_topics = array_diff($topic_ids, $remove_topics);
 
737
        }
 
738
 
 
739
        // Remove the message from the search index
 
740
        $search_type = basename($config['search_type']);
 
741
 
 
742
        if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
 
743
        {
 
744
                trigger_error('NO_SUCH_SEARCH_MODULE');
 
745
        }
 
746
 
 
747
        include_once("{$phpbb_root_path}includes/search/$search_type.$phpEx");
 
748
 
 
749
        $error = false;
 
750
        $search = new $search_type($error);
 
751
 
 
752
        if ($error)
 
753
        {
 
754
                trigger_error($error);
 
755
        }
 
756
 
 
757
        $search->index_remove($post_ids, $poster_ids, $forum_ids);
 
758
 
 
759
        delete_attachments('post', $post_ids, false);
 
760
 
 
761
        $db->sql_transaction('commit');
 
762
 
 
763
        // Resync topics_posted table
 
764
        if ($posted_sync)
 
765
        {
 
766
                update_posted_info($topic_ids);
 
767
        }
 
768
 
 
769
        if ($auto_sync)
 
770
        {
 
771
                sync('topic_reported', 'topic_id', $topic_ids);
 
772
                sync('topic', 'topic_id', $topic_ids, true);
 
773
                sync('forum', 'forum_id', $forum_ids, true, true);
 
774
        }
 
775
 
 
776
        if ($approved_posts)
 
777
        {
 
778
                set_config('num_posts', $config['num_posts'] - $approved_posts, true);
 
779
        }
 
780
 
 
781
        // We actually remove topics now to not be inconsistent (the delete_topics function calls this function too)
 
782
        if (sizeof($remove_topics) && $call_delete_topics)
 
783
        {
 
784
                delete_topics('topic_id', $remove_topics, $auto_sync, $post_count_sync, false);
 
785
        }
 
786
 
 
787
        return sizeof($post_ids);
 
788
}
 
789
 
 
790
/**
 
791
* Delete Attachments
 
792
*
 
793
* @param string $mode can be: post|topic|attach|user
 
794
* @param mixed $ids can be: post_ids, topic_ids, attach_ids, user_ids
 
795
* @param bool $resync set this to false if you are deleting posts or topics
 
796
*/
 
797
function delete_attachments($mode, $ids, $resync = true)
 
798
{
 
799
        global $db, $config;
 
800
 
 
801
        if (is_array($ids) && sizeof($ids))
 
802
        {
 
803
                $ids = array_unique($ids);
 
804
                $ids = array_map('intval', $ids);
 
805
        }
 
806
        else
 
807
        {
 
808
                $ids = array((int) $ids);
 
809
        }
 
810
 
 
811
        if (!sizeof($ids))
 
812
        {
 
813
                return false;
 
814
        }
 
815
 
 
816
        $sql_id = ($mode == 'user') ? 'poster_id' : (($mode == 'post') ? 'post_msg_id' : (($mode == 'topic') ? 'topic_id' : 'attach_id'));
 
817
 
 
818
        $post_ids = $topic_ids = $physical = array();
 
819
 
 
820
        // Collect post and topics ids for later use
 
821
        if ($mode == 'attach' || $mode == 'user' || ($mode == 'topic' && $resync))
 
822
        {
 
823
                $sql = 'SELECT post_msg_id as post_id, topic_id, physical_filename, thumbnail, filesize
 
824
                        FROM ' . ATTACHMENTS_TABLE . '
 
825
                        WHERE ' . $db->sql_in_set($sql_id, $ids);
 
826
                $result = $db->sql_query($sql);
 
827
 
 
828
                while ($row = $db->sql_fetchrow($result))
 
829
                {
 
830
                        $post_ids[] = $row['post_id'];
 
831
                        $topic_ids[] = $row['topic_id'];
 
832
                        $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']);
 
833
                }
 
834
                $db->sql_freeresult($result);
 
835
        }
 
836
 
 
837
        if ($mode == 'post')
 
838
        {
 
839
                $sql = 'SELECT topic_id, physical_filename, thumbnail, filesize
 
840
                        FROM ' . ATTACHMENTS_TABLE . '
 
841
                        WHERE ' . $db->sql_in_set('post_msg_id', $ids) . '
 
842
                                AND in_message = 0';
 
843
                $result = $db->sql_query($sql);
 
844
 
 
845
                while ($row = $db->sql_fetchrow($result))
 
846
                {
 
847
                        $topic_ids[] = $row['topic_id'];
 
848
                        $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']);
 
849
                }
 
850
                $db->sql_freeresult($result);
 
851
        }
 
852
 
 
853
        // Delete attachments
 
854
        $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
 
855
                WHERE ' . $db->sql_in_set($sql_id, $ids);
 
856
        $db->sql_query($sql);
 
857
        $num_deleted = $db->sql_affectedrows();
 
858
 
 
859
        if (!$num_deleted)
 
860
        {
 
861
                return 0;
 
862
        }
 
863
 
 
864
        // Delete attachments from filesystem
 
865
        $space_removed = $files_removed = 0;
 
866
        foreach ($physical as $file_ary)
 
867
        {
 
868
                if (phpbb_unlink($file_ary['filename'], 'file', true))
 
869
                {
 
870
                        $space_removed += $file_ary['filesize'];
 
871
                        $files_removed++;
 
872
                }
 
873
 
 
874
                if ($file_ary['thumbnail'])
 
875
                {
 
876
                        phpbb_unlink($file_ary['filename'], 'thumbnail', true);
 
877
                }
 
878
        }
 
879
        set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true);
 
880
        set_config('num_files', $config['num_files'] - $files_removed, true);
 
881
 
 
882
        if ($mode == 'topic' && !$resync)
 
883
        {
 
884
                return $num_deleted;
 
885
        }
 
886
 
 
887
        if ($mode == 'post')
 
888
        {
 
889
                $post_ids = $ids;
 
890
        }
 
891
        unset($ids);
 
892
 
 
893
        $post_ids = array_unique($post_ids);
 
894
        $topic_ids = array_unique($topic_ids);
 
895
 
 
896
        // Update post indicators
 
897
        if (sizeof($post_ids))
 
898
        {
 
899
                if ($mode == 'post' || $mode == 'topic')
 
900
                {
 
901
                        $sql = 'UPDATE ' . POSTS_TABLE . '
 
902
                                SET post_attachment = 0
 
903
                                WHERE ' . $db->sql_in_set('post_id', $post_ids);
 
904
                        $db->sql_query($sql);
 
905
                }
 
906
 
 
907
                if ($mode == 'user' || $mode == 'attach')
 
908
                {
 
909
                        $remaining = array();
 
910
 
 
911
                        $sql = 'SELECT post_msg_id
 
912
                                FROM ' . ATTACHMENTS_TABLE . '
 
913
                                WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
 
914
                                        AND in_message = 0';
 
915
                        $result = $db->sql_query($sql);
 
916
 
 
917
                        while ($row = $db->sql_fetchrow($result))
 
918
                        {
 
919
                                $remaining[] = $row['post_msg_id'];             
 
920
                        }
 
921
                        $db->sql_freeresult($result);
 
922
 
 
923
                        $unset_ids = array_diff($post_ids, $remaining);
 
924
 
 
925
                        if (sizeof($unset_ids))
 
926
                        {
 
927
                                $sql = 'UPDATE ' . POSTS_TABLE . '
 
928
                                        SET post_attachment = 0
 
929
                                        WHERE ' . $db->sql_in_set('post_id', $unset_ids);
 
930
                                $db->sql_query($sql);
 
931
                        }
 
932
 
 
933
                        $remaining = array();
 
934
 
 
935
                        $sql = 'SELECT post_msg_id
 
936
                                FROM ' . ATTACHMENTS_TABLE . '
 
937
                                WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
 
938
                                        AND in_message = 1';
 
939
                        $result = $db->sql_query($sql);
 
940
 
 
941
                        while ($row = $db->sql_fetchrow($result))
 
942
                        {
 
943
                                $remaining[] = $row['post_msg_id'];             
 
944
                        }
 
945
                        $db->sql_freeresult($result);
 
946
 
 
947
                        $unset_ids = array_diff($post_ids, $remaining);
 
948
 
 
949
                        if (sizeof($unset_ids))
 
950
                        {
 
951
                                $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
 
952
                                        SET message_attachment = 0
 
953
                                        WHERE ' . $db->sql_in_set('msg_id', $unset_ids);
 
954
                                $db->sql_query($sql);
 
955
                        }
 
956
                }
 
957
        }
 
958
 
 
959
        if (sizeof($topic_ids))
 
960
        {
 
961
                // Update topic indicator
 
962
                if ($mode == 'topic')
 
963
                {
 
964
                        $sql = 'UPDATE ' . TOPICS_TABLE . '
 
965
                                SET topic_attachment = 0
 
966
                                WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
967
                        $db->sql_query($sql);
 
968
                }
 
969
 
 
970
                if ($mode == 'post' || $mode == 'user' || $mode == 'attach')
 
971
                {
 
972
                        $remaining = array();
 
973
 
 
974
                        $sql = 'SELECT topic_id
 
975
                                FROM ' . ATTACHMENTS_TABLE . '
 
976
                                WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
977
                        $result = $db->sql_query($sql);
 
978
 
 
979
                        while ($row = $db->sql_fetchrow($result))
 
980
                        {
 
981
                                $remaining[] = $row['topic_id'];                
 
982
                        }
 
983
                        $db->sql_freeresult($result);
 
984
 
 
985
                        $unset_ids = array_diff($topic_ids, $remaining);
 
986
 
 
987
                        if (sizeof($unset_ids))
 
988
                        {
 
989
                                $sql = 'UPDATE ' . TOPICS_TABLE . '
 
990
                                        SET topic_attachment = 0
 
991
                                        WHERE ' . $db->sql_in_set('topic_id', $unset_ids);
 
992
                                $db->sql_query($sql);
 
993
                        }
 
994
                }
 
995
        }
 
996
 
 
997
        return $num_deleted;
 
998
}
 
999
 
 
1000
/**
 
1001
* Remove topic shadows
 
1002
*/
 
1003
function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true)
 
1004
{
 
1005
        $where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : '');
 
1006
 
 
1007
        switch ($db->sql_layer)
 
1008
        {
 
1009
                case 'mysql4':
 
1010
                case 'mysqli':
 
1011
                        $sql = 'DELETE t.*
 
1012
                                FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
 
1013
                                WHERE t.topic_moved_id = t2.topic_id
 
1014
                                        AND t.topic_time < ' . (time() - $max_age)
 
1015
                                . $where;
 
1016
                        $db->sql_query($sql);
 
1017
                break;
 
1018
        
 
1019
                default:
 
1020
                        $sql = 'SELECT t.topic_id
 
1021
                                FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
 
1022
                                WHERE t.topic_moved_id = t2.topic_id
 
1023
                                        AND t.topic_time < ' . (time() - $max_age)
 
1024
                                . $where;
 
1025
                        $result = $db->sql_query($sql);
 
1026
 
 
1027
                        $topic_ids = array();
 
1028
                        while ($row = $db->sql_fetchrow($result))
 
1029
                        {
 
1030
                                $topic_ids[] = $row['topic_id'];
 
1031
                        }
 
1032
                        $db->sql_freeresult($result);
 
1033
 
 
1034
                        if (sizeof($topic_ids))
 
1035
                        {
 
1036
                                $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 
1037
                                        WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
1038
                                $db->sql_query($sql);
 
1039
                        }
 
1040
                break;
 
1041
        }
 
1042
 
 
1043
        if ($auto_sync)
 
1044
        {
 
1045
                $where_type = ($forum_id) ? 'forum_id' : '';
 
1046
                sync('forum', $where_type, $forum_id, true, true);
 
1047
        }
 
1048
}
 
1049
 
 
1050
/**
 
1051
* Update/Sync posted information for topics
 
1052
*/
 
1053
function update_posted_info(&$topic_ids)
 
1054
{
 
1055
        global $db, $config;
 
1056
 
 
1057
        if (empty($topic_ids) || !$config['load_db_track'])
 
1058
        {
 
1059
                return;
 
1060
        }
 
1061
 
 
1062
        // First of all, let us remove any posted information for these topics
 
1063
        $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
 
1064
                WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
1065
        $db->sql_query($sql);
 
1066
 
 
1067
        // Now, let us collect the user/topic combos for rebuilding the information
 
1068
        $sql = 'SELECT poster_id, topic_id
 
1069
                FROM ' . POSTS_TABLE . '
 
1070
                WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
 
1071
                        AND poster_id <> ' . ANONYMOUS . '
 
1072
                GROUP BY poster_id, topic_id';
 
1073
        $result = $db->sql_query($sql);
 
1074
 
 
1075
        $posted = array();
 
1076
        while ($row = $db->sql_fetchrow($result))
 
1077
        {
 
1078
                // Add as key to make them unique (grouping by) and circumvent empty keys on array_unique
 
1079
                $posted[$row['poster_id']][] = $row['topic_id'];
 
1080
        }
 
1081
        $db->sql_freeresult($result);
 
1082
 
 
1083
        // Now add the information...
 
1084
        $sql_ary = array();
 
1085
        foreach ($posted as $user_id => $topic_row)
 
1086
        {
 
1087
                foreach ($topic_row as $topic_id)
 
1088
                {
 
1089
                        $sql_ary[] = array(
 
1090
                                'user_id'               => (int) $user_id,
 
1091
                                'topic_id'              => (int) $topic_id,
 
1092
                                'topic_posted'  => 1,
 
1093
                        );
 
1094
                }
 
1095
        }
 
1096
        unset($posted);
 
1097
 
 
1098
        $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
 
1099
}
 
1100
 
 
1101
/**
 
1102
* Delete attached file
 
1103
*/
 
1104
function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
 
1105
{
 
1106
        global $db, $phpbb_root_path, $config;
 
1107
 
 
1108
        // Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
 
1109
        $sql = 'SELECT COUNT(attach_id) AS num_entries
 
1110
                FROM ' . ATTACHMENTS_TABLE . "
 
1111
                WHERE physical_filename = '" . $db->sql_escape(basename($filename)) . "'";
 
1112
        $result = $db->sql_query($sql);
 
1113
        $num_entries = (int) $db->sql_fetchfield('num_entries');
 
1114
        $db->sql_freeresult($result);
 
1115
 
 
1116
        // Do not remove file if at least one additional entry with the same name exist.
 
1117
        if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
 
1118
        {
 
1119
                return false;
 
1120
        }
 
1121
 
 
1122
        $filename = ($mode == 'thumbnail') ? 'thumb_' . basename($filename) : basename($filename);
 
1123
        return @unlink($phpbb_root_path . $config['upload_path'] . '/' . $filename);
 
1124
}
 
1125
 
 
1126
/**
 
1127
* All-encompasing sync function
 
1128
*
 
1129
* Exaples:
 
1130
* <code>
 
1131
* sync('topic', 'topic_id', 123);                       // resync topic #123
 
1132
* sync('topic', 'forum_id', array(2, 3));       // resync topics from forum #2 and #3
 
1133
* sync('topic');                                                        // resync all topics
 
1134
* sync('topic', 'range', 'topic_id BETWEEN 1 AND 60');  // resync a range of topics/forums (only available for 'topic' and 'forum' modes)
 
1135
* </code>
 
1136
*
 
1137
* Modes:
 
1138
* - forum                               Resync complete forum
 
1139
* - topic                               Resync topics
 
1140
* - topic_moved                 Removes topic shadows that would be in the same forum as the topic they link to
 
1141
* - topic_approved              Resyncs the topic_approved flag according to the status of the first post
 
1142
* - post_reported               Resyncs the post_reported flag, relying on actual reports
 
1143
* - topic_reported              Resyncs the topic_reported flag, relying on post_reported flags
 
1144
* - post_attachement    Same as post_reported, but with attachment flags
 
1145
* - topic_attachement   Same as topic_reported, but with attachment flags
 
1146
*/
 
1147
function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $sync_extra = false)
 
1148
{
 
1149
        global $db;
 
1150
 
 
1151
        if (is_array($where_ids))
 
1152
        {
 
1153
                $where_ids = array_unique($where_ids);
 
1154
                $where_ids = array_map('intval', $where_ids);
 
1155
        }
 
1156
        else if ($where_type != 'range')
 
1157
        {
 
1158
                $where_ids = ($where_ids) ? array((int) $where_ids) : array();
 
1159
        }
 
1160
 
 
1161
        if ($mode == 'forum' || $mode == 'topic' || $mode == 'topic_approved' || $mode == 'topic_reported' || $mode == 'post_reported')
 
1162
        {
 
1163
                if (!$where_type)
 
1164
                {
 
1165
                        $where_sql = '';
 
1166
                        $where_sql_and = 'WHERE';
 
1167
                }
 
1168
                else if ($where_type == 'range')
 
1169
                {
 
1170
                        // Only check a range of topics/forums. For instance: 'topic_id BETWEEN 1 AND 60'
 
1171
                        $where_sql = 'WHERE (' . $mode[0] . ".$where_ids)";
 
1172
                        $where_sql_and = $where_sql . "\n\tAND";
 
1173
                }
 
1174
                else
 
1175
                {
 
1176
                        // Do not sync the "global forum"
 
1177
                        $where_ids = array_diff($where_ids, array(0));
 
1178
 
 
1179
                        if (!sizeof($where_ids))
 
1180
                        {
 
1181
                                // Empty array with IDs. This means that we don't have any work to do. Just return.
 
1182
                                return;
 
1183
                        }
 
1184
 
 
1185
                        // Limit the topics/forums we are syncing, use specific topic/forum IDs.
 
1186
                        // $where_type contains the field for the where clause (forum_id, topic_id)
 
1187
                        $where_sql = 'WHERE ' . $db->sql_in_set($mode[0] . '.' . $where_type, $where_ids);
 
1188
                        $where_sql_and = $where_sql . "\n\tAND";
 
1189
                }
 
1190
        }
 
1191
        else
 
1192
        {
 
1193
                if (!sizeof($where_ids))
 
1194
                {
 
1195
                        return;
 
1196
                }
 
1197
 
 
1198
                // $where_type contains the field for the where clause (forum_id, topic_id)
 
1199
                $where_sql = 'WHERE ' . $db->sql_in_set($mode[0] . '.' . $where_type, $where_ids);
 
1200
                $where_sql_and = $where_sql . "\n\tAND";
 
1201
        }
 
1202
 
 
1203
        switch ($mode)
 
1204
        {
 
1205
                case 'topic_moved':
 
1206
                        switch ($db->sql_layer)
 
1207
                        {
 
1208
                                case 'mysql4':
 
1209
                                case 'mysqli':
 
1210
                                        $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 
1211
                                                USING ' . TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
 
1212
                                                WHERE t1.topic_moved_id = t2.topic_id
 
1213
                                                        AND t1.forum_id = t2.forum_id";
 
1214
                                        $db->sql_query($sql);
 
1215
                                break;
 
1216
                        
 
1217
                                default:
 
1218
                                        $sql = 'SELECT t1.topic_id
 
1219
                                                FROM ' .TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
 
1220
                                                WHERE t1.topic_moved_id = t2.topic_id
 
1221
                                                        AND t1.forum_id = t2.forum_id";
 
1222
                                        $result = $db->sql_query($sql);
 
1223
 
 
1224
                                        $topic_id_ary = array();
 
1225
                                        while ($row = $db->sql_fetchrow($result))
 
1226
                                        {
 
1227
                                                $topic_id_ary[] = $row['topic_id'];
 
1228
                                        }
 
1229
                                        $db->sql_freeresult($result);
 
1230
 
 
1231
                                        if (!sizeof($topic_id_ary))
 
1232
                                        {
 
1233
                                                return;
 
1234
                                        }
 
1235
 
 
1236
                                        $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 
1237
                                                WHERE ' . $db->sql_in_set('topic_id', $topic_id_ary);
 
1238
                                        $db->sql_query($sql);
 
1239
 
 
1240
                                break;
 
1241
                        }
 
1242
                break;
 
1243
 
 
1244
                case 'topic_approved':
 
1245
                        switch ($db->sql_layer)
 
1246
                        {
 
1247
                                case 'mysql4':
 
1248
                                case 'mysqli':
 
1249
                                        $sql = 'UPDATE ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
 
1250
                                                SET t.topic_approved = p.post_approved
 
1251
                                                $where_sql_and t.topic_first_post_id = p.post_id";
 
1252
                                        $db->sql_query($sql);
 
1253
                                break;
 
1254
 
 
1255
                                default:
 
1256
                                        $sql = 'SELECT t.topic_id, p.post_approved
 
1257
                                                FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
 
1258
                                                $where_sql_and p.post_id = t.topic_first_post_id
 
1259
                                                        AND p.post_approved <> t.topic_approved";
 
1260
                                        $result = $db->sql_query($sql);
 
1261
 
 
1262
                                        $topic_ids = array();
 
1263
                                        while ($row = $db->sql_fetchrow($result))
 
1264
                                        {
 
1265
                                                $topic_ids[] = $row['topic_id'];
 
1266
                                        }
 
1267
                                        $db->sql_freeresult($result);
 
1268
 
 
1269
                                        if (!sizeof($topic_ids))
 
1270
                                        {
 
1271
                                                return;
 
1272
                                        }
 
1273
 
 
1274
                                        $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1275
                                                SET topic_approved = 1 - topic_approved
 
1276
                                                WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
1277
                                        $db->sql_query($sql);
 
1278
                                break;
 
1279
                        }
 
1280
                break;
 
1281
 
 
1282
                case 'post_reported':
 
1283
                        $post_ids = $post_reported = array();
 
1284
 
 
1285
                        $sql = 'SELECT p.post_id, p.post_reported
 
1286
                                FROM ' . POSTS_TABLE . " p
 
1287
                                $where_sql
 
1288
                                GROUP BY p.post_id, p.post_reported";
 
1289
                        $result = $db->sql_query($sql);
 
1290
 
 
1291
                        while ($row = $db->sql_fetchrow($result))
 
1292
                        {
 
1293
                                $post_ids[$row['post_id']] = $row['post_id'];
 
1294
                                if ($row['post_reported'])
 
1295
                                {
 
1296
                                        $post_reported[$row['post_id']] = 1;
 
1297
                                }
 
1298
                        }
 
1299
                        $db->sql_freeresult($result);
 
1300
 
 
1301
                        $sql = 'SELECT DISTINCT(post_id)
 
1302
                                FROM ' . REPORTS_TABLE . '
 
1303
                                WHERE ' . $db->sql_in_set('post_id', $post_ids) . '
 
1304
                                        AND report_closed = 0';
 
1305
                        $result = $db->sql_query($sql);
 
1306
 
 
1307
                        $post_ids = array();
 
1308
                        while ($row = $db->sql_fetchrow($result))
 
1309
                        {
 
1310
                                if (!isset($post_reported[$row['post_id']]))
 
1311
                                {
 
1312
                                        $post_ids[] = $row['post_id'];
 
1313
                                }
 
1314
                                else
 
1315
                                {
 
1316
                                        unset($post_reported[$row['post_id']]);
 
1317
                                }
 
1318
                        }
 
1319
                        $db->sql_freeresult($result);
 
1320
 
 
1321
                        // $post_reported should be empty by now, if it's not it contains
 
1322
                        // posts that are falsely flagged as reported
 
1323
                        foreach ($post_reported as $post_id => $void)
 
1324
                        {
 
1325
                                $post_ids[] = $post_id;
 
1326
                        }
 
1327
 
 
1328
                        if (sizeof($post_ids))
 
1329
                        {
 
1330
                                $sql = 'UPDATE ' . POSTS_TABLE . '
 
1331
                                        SET post_reported = 1 - post_reported
 
1332
                                        WHERE ' . $db->sql_in_set('post_id', $post_ids);
 
1333
                                $db->sql_query($sql);
 
1334
                        }
 
1335
                break;
 
1336
 
 
1337
                case 'topic_reported':
 
1338
                        if ($sync_extra)
 
1339
                        {
 
1340
                                sync('post_reported', $where_type, $where_ids);
 
1341
                        }
 
1342
 
 
1343
                        $topic_ids = $topic_reported = array();
 
1344
 
 
1345
                        $sql = 'SELECT DISTINCT(t.topic_id)
 
1346
                                FROM ' . POSTS_TABLE . " t
 
1347
                                $where_sql_and t.post_reported = 1";
 
1348
                        $result = $db->sql_query($sql);
 
1349
 
 
1350
                        while ($row = $db->sql_fetchrow($result))
 
1351
                        {
 
1352
                                $topic_reported[$row['topic_id']] = 1;
 
1353
                        }
 
1354
                        $db->sql_freeresult($result);
 
1355
 
 
1356
                        $sql = 'SELECT t.topic_id, t.topic_reported
 
1357
                                FROM ' . TOPICS_TABLE . " t
 
1358
                                $where_sql";
 
1359
                        $result = $db->sql_query($sql);
 
1360
 
 
1361
                        while ($row = $db->sql_fetchrow($result))
 
1362
                        {
 
1363
                                if ($row['topic_reported'] ^ isset($topic_reported[$row['topic_id']]))
 
1364
                                {
 
1365
                                        $topic_ids[] = $row['topic_id'];
 
1366
                                }
 
1367
                        }
 
1368
                        $db->sql_freeresult($result);
 
1369
 
 
1370
                        if (sizeof($topic_ids))
 
1371
                        {
 
1372
                                $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1373
                                        SET topic_reported = 1 - topic_reported
 
1374
                                        WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
1375
                                $db->sql_query($sql);
 
1376
                        }
 
1377
                break;
 
1378
 
 
1379
                case 'post_attachment':
 
1380
                        $post_ids = $post_attachment = array();
 
1381
 
 
1382
                        $sql = 'SELECT p.post_id, p.post_attachment
 
1383
                                FROM ' . POSTS_TABLE . " p
 
1384
                                $where_sql
 
1385
                                GROUP BY p.post_id, p.post_attachment";
 
1386
                        $result = $db->sql_query($sql);
 
1387
 
 
1388
                        while ($row = $db->sql_fetchrow($result))
 
1389
                        {
 
1390
                                $post_ids[$row['post_id']] = $row['post_id'];
 
1391
                                if ($row['post_attachment'])
 
1392
                                {
 
1393
                                        $post_attachment[$row['post_id']] = 1;
 
1394
                                }
 
1395
                        }
 
1396
                        $db->sql_freeresult($result);
 
1397
 
 
1398
                        $sql = 'SELECT DISTINCT(post_msg_id)
 
1399
                                FROM ' . ATTACHMENTS_TABLE . '
 
1400
                                WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
 
1401
                                        AND in_message = 0';
 
1402
                        $result = $db->sql_query($sql);
 
1403
 
 
1404
                        $post_ids = array();
 
1405
                        while ($row = $db->sql_fetchrow($result))
 
1406
                        {
 
1407
                                if (!isset($post_attachment[$row['post_msg_id']]))
 
1408
                                {
 
1409
                                        $post_ids[] = $row['post_msg_id'];
 
1410
                                }
 
1411
                                else
 
1412
                                {
 
1413
                                        unset($post_attachment[$row['post_msg_id']]);
 
1414
                                }
 
1415
                        }
 
1416
                        $db->sql_freeresult($result);
 
1417
 
 
1418
                        // $post_attachment should be empty by now, if it's not it contains
 
1419
                        // posts that are falsely flagged as having attachments
 
1420
                        foreach ($post_attachment as $post_id => $void)
 
1421
                        {
 
1422
                                $post_ids[] = $post_id;
 
1423
                        }
 
1424
 
 
1425
                        if (sizeof($post_ids))
 
1426
                        {
 
1427
                                $sql = 'UPDATE ' . POSTS_TABLE . '
 
1428
                                        SET post_attachment = 1 - post_attachment
 
1429
                                        WHERE ' . $db->sql_in_set('post_id', $post_ids);
 
1430
                                $db->sql_query($sql);
 
1431
                        }
 
1432
                break;
 
1433
 
 
1434
                case 'topic_attachment':
 
1435
                        if ($sync_extra)
 
1436
                        {
 
1437
                                sync('post_attachment', $where_type, $where_ids);
 
1438
                        }
 
1439
 
 
1440
                        $topic_ids = $topic_attachment = array();
 
1441
 
 
1442
                        $sql = 'SELECT DISTINCT(t.topic_id)
 
1443
                                FROM ' . POSTS_TABLE . " t
 
1444
                                $where_sql_and t.post_attachment = 1";
 
1445
                        $result = $db->sql_query($sql);
 
1446
 
 
1447
                        while ($row = $db->sql_fetchrow($result))
 
1448
                        {
 
1449
                                $topic_attachment[$row['topic_id']] = 1;
 
1450
                        }
 
1451
                        $db->sql_freeresult($result);
 
1452
 
 
1453
                        $sql = 'SELECT t.topic_id, t.topic_attachment
 
1454
                                FROM ' . TOPICS_TABLE . " t
 
1455
                                $where_sql";
 
1456
                        $result = $db->sql_query($sql);
 
1457
 
 
1458
                        while ($row = $db->sql_fetchrow($result))
 
1459
                        {
 
1460
                                if ($row['topic_attachment'] ^ isset($topic_attachment[$row['topic_id']]))
 
1461
                                {
 
1462
                                        $topic_ids[] = $row['topic_id'];
 
1463
                                }
 
1464
                        }
 
1465
                        $db->sql_freeresult($result);
 
1466
 
 
1467
                        if (sizeof($topic_ids))
 
1468
                        {
 
1469
                                $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1470
                                        SET topic_attachment = 1 - topic_attachment
 
1471
                                        WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 
1472
                                $db->sql_query($sql);
 
1473
                        }
 
1474
                break;
 
1475
 
 
1476
                case 'forum':
 
1477
 
 
1478
                        // 1: Get the list of all forums
 
1479
                        $sql = 'SELECT f.*
 
1480
                                FROM ' . FORUMS_TABLE . " f
 
1481
                                $where_sql";
 
1482
                        $result = $db->sql_query($sql);
 
1483
 
 
1484
                        $forum_data = $forum_ids = $post_ids = $last_post_id = $post_info = array();
 
1485
                        while ($row = $db->sql_fetchrow($result))
 
1486
                        {
 
1487
                                if ($row['forum_type'] == FORUM_LINK)
 
1488
                                {
 
1489
                                        continue;
 
1490
                                }
 
1491
 
 
1492
                                $forum_id = (int) $row['forum_id'];
 
1493
                                $forum_ids[$forum_id] = $forum_id;
 
1494
 
 
1495
                                $forum_data[$forum_id] = $row;
 
1496
                                if ($sync_extra)
 
1497
                                {
 
1498
                                        $forum_data[$forum_id]['posts'] = 0;
 
1499
                                        $forum_data[$forum_id]['topics'] = 0;
 
1500
                                        $forum_data[$forum_id]['topics_real'] = 0;
 
1501
                                }
 
1502
                                $forum_data[$forum_id]['last_post_id'] = 0;
 
1503
                                $forum_data[$forum_id]['last_post_subject'] = '';
 
1504
                                $forum_data[$forum_id]['last_post_time'] = 0;
 
1505
                                $forum_data[$forum_id]['last_poster_id'] = 0;
 
1506
                                $forum_data[$forum_id]['last_poster_name'] = '';
 
1507
                                $forum_data[$forum_id]['last_poster_colour'] = '';
 
1508
                        }
 
1509
                        $db->sql_freeresult($result);
 
1510
 
 
1511
                        if (!sizeof($forum_ids))
 
1512
                        {
 
1513
                                break;
 
1514
                        }
 
1515
 
 
1516
                        $forum_ids = array_values($forum_ids);
 
1517
 
 
1518
                        // 2: Get topic counts for each forum (optional)
 
1519
                        if ($sync_extra)
 
1520
                        {
 
1521
                                $sql = 'SELECT forum_id, topic_approved, COUNT(topic_id) AS forum_topics
 
1522
                                        FROM ' . TOPICS_TABLE . '
 
1523
                                        WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
 
1524
                                        GROUP BY forum_id, topic_approved';
 
1525
                                $result = $db->sql_query($sql);
 
1526
 
 
1527
                                while ($row = $db->sql_fetchrow($result))
 
1528
                                {
 
1529
                                        $forum_id = (int) $row['forum_id'];
 
1530
                                        $forum_data[$forum_id]['topics_real'] += $row['forum_topics'];
 
1531
 
 
1532
                                        if ($row['topic_approved'])
 
1533
                                        {
 
1534
                                                $forum_data[$forum_id]['topics'] = $row['forum_topics'];
 
1535
                                        }
 
1536
                                }
 
1537
                                $db->sql_freeresult($result);
 
1538
                        }
 
1539
 
 
1540
                        // 3: Get post count for each forum (optional)
 
1541
                        if ($sync_extra)
 
1542
                        {
 
1543
                                if (sizeof($forum_ids) == 1)
 
1544
                                {
 
1545
                                        $sql = 'SELECT SUM(t.topic_replies + 1) AS forum_posts
 
1546
                                                FROM ' . TOPICS_TABLE . ' t
 
1547
                                                WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . '
 
1548
                                                        AND t.topic_approved = 1';
 
1549
                                }
 
1550
                                else
 
1551
                                {
 
1552
                                        $sql = 'SELECT t.forum_id, SUM(t.topic_replies + 1) AS forum_posts
 
1553
                                                FROM ' . TOPICS_TABLE . ' t
 
1554
                                                WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . '
 
1555
                                                        AND t.topic_approved = 1
 
1556
                                                GROUP BY t.forum_id';
 
1557
                                }
 
1558
 
 
1559
                                $result = $db->sql_query($sql);
 
1560
 
 
1561
                                while ($row = $db->sql_fetchrow($result))
 
1562
                                {
 
1563
                                        $forum_id = (sizeof($forum_ids) == 1) ? (int) $forum_ids[0] : (int) $row['forum_id'];
 
1564
 
 
1565
                                        $forum_data[$forum_id]['posts'] = (int) $row['forum_posts'];
 
1566
                                }
 
1567
                                $db->sql_freeresult($result);
 
1568
                        }
 
1569
 
 
1570
                        // 4: Get last_post_id for each forum
 
1571
                        if (sizeof($forum_ids) == 1)
 
1572
                        {
 
1573
                                $sql = 'SELECT MAX(t.topic_last_post_id) as last_post_id
 
1574
                                        FROM ' . TOPICS_TABLE . ' t
 
1575
                                        WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . '
 
1576
                                                AND t.topic_approved = 1';
 
1577
                        }
 
1578
                        else
 
1579
                        {
 
1580
                                $sql = 'SELECT t.forum_id, MAX(t.topic_last_post_id) as last_post_id
 
1581
                                        FROM ' . TOPICS_TABLE . ' t
 
1582
                                        WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . '
 
1583
                                                AND t.topic_approved = 1
 
1584
                                        GROUP BY t.forum_id';
 
1585
                        }
 
1586
 
 
1587
                        $result = $db->sql_query($sql);
 
1588
 
 
1589
                        while ($row = $db->sql_fetchrow($result))
 
1590
                        {
 
1591
                                $forum_id = (sizeof($forum_ids) == 1) ? (int) $forum_ids[0] : (int) $row['forum_id'];
 
1592
 
 
1593
                                $forum_data[$forum_id]['last_post_id'] = (int) $row['last_post_id'];
 
1594
 
 
1595
                                $post_ids[] = $row['last_post_id'];
 
1596
                        }
 
1597
                        $db->sql_freeresult($result);
 
1598
 
 
1599
                        // 5: Retrieve last_post infos
 
1600
                        if (sizeof($post_ids))
 
1601
                        {
 
1602
                                $sql = 'SELECT p.post_id, p.poster_id, p.post_subject, p.post_time, p.post_username, u.username, u.user_colour
 
1603
                                        FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 
1604
                                        WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
 
1605
                                                AND p.poster_id = u.user_id';
 
1606
                                $result = $db->sql_query($sql);
 
1607
 
 
1608
                                while ($row = $db->sql_fetchrow($result))
 
1609
                                {
 
1610
                                        $post_info[$row['post_id']] = $row;
 
1611
                                }
 
1612
                                $db->sql_freeresult($result);
 
1613
 
 
1614
                                foreach ($forum_data as $forum_id => $data)
 
1615
                                {
 
1616
                                        if ($data['last_post_id'])
 
1617
                                        {
 
1618
                                                if (isset($post_info[$data['last_post_id']]))
 
1619
                                                {
 
1620
                                                        $forum_data[$forum_id]['last_post_subject'] = $post_info[$data['last_post_id']]['post_subject'];
 
1621
                                                        $forum_data[$forum_id]['last_post_time'] = $post_info[$data['last_post_id']]['post_time'];
 
1622
                                                        $forum_data[$forum_id]['last_poster_id'] = $post_info[$data['last_post_id']]['poster_id'];
 
1623
                                                        $forum_data[$forum_id]['last_poster_name'] = ($post_info[$data['last_post_id']]['poster_id'] != ANONYMOUS) ? $post_info[$data['last_post_id']]['username'] : $post_info[$data['last_post_id']]['post_username'];
 
1624
                                                        $forum_data[$forum_id]['last_poster_colour'] = $post_info[$data['last_post_id']]['user_colour'];
 
1625
                                                }
 
1626
                                                else
 
1627
                                                {
 
1628
                                                        // For some reason we did not find the post in the db
 
1629
                                                        $forum_data[$forum_id]['last_post_id'] = 0;
 
1630
                                                        $forum_data[$forum_id]['last_post_subject'] = '';
 
1631
                                                        $forum_data[$forum_id]['last_post_time'] = 0;
 
1632
                                                        $forum_data[$forum_id]['last_poster_id'] = 0;
 
1633
                                                        $forum_data[$forum_id]['last_poster_name'] = '';
 
1634
                                                        $forum_data[$forum_id]['last_poster_colour'] = '';
 
1635
                                                }
 
1636
                                        }
 
1637
                                }
 
1638
                                unset($post_info);
 
1639
                        }
 
1640
 
 
1641
                        // 6: Now do that thing
 
1642
                        $fieldnames = array('last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour');
 
1643
 
 
1644
                        if ($sync_extra)
 
1645
                        {
 
1646
                                array_push($fieldnames, 'posts', 'topics', 'topics_real');
 
1647
                        }
 
1648
 
 
1649
                        foreach ($forum_data as $forum_id => $row)
 
1650
                        {
 
1651
                                $sql_ary = array();
 
1652
 
 
1653
                                foreach ($fieldnames as $fieldname)
 
1654
                                {
 
1655
                                        if ($row['forum_' . $fieldname] != $row[$fieldname])
 
1656
                                        {
 
1657
                                                if (preg_match('#(name|colour|subject)$#', $fieldname))
 
1658
                                                {
 
1659
                                                        $sql_ary['forum_' . $fieldname] = (string) $row[$fieldname];
 
1660
                                                }
 
1661
                                                else
 
1662
                                                {
 
1663
                                                        $sql_ary['forum_' . $fieldname] = (int) $row[$fieldname];
 
1664
                                                }
 
1665
                                        }
 
1666
                                }
 
1667
 
 
1668
                                if (sizeof($sql_ary))
 
1669
                                {
 
1670
                                        $sql = 'UPDATE ' . FORUMS_TABLE . '
 
1671
                                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
 
1672
                                                WHERE forum_id = ' . $forum_id;
 
1673
                                        $db->sql_query($sql);
 
1674
                                }
 
1675
                        }
 
1676
                break;
 
1677
 
 
1678
                case 'topic':
 
1679
                        $topic_data = $post_ids = $approved_unapproved_ids = $resync_forums = $delete_topics = $delete_posts = $moved_topics = array();
 
1680
 
 
1681
                        $sql = 'SELECT t.topic_id, t.forum_id, t.topic_moved_id, t.topic_approved, ' . (($sync_extra) ? 't.topic_attachment, t.topic_reported, ' : '') . 't.topic_poster, t.topic_time, t.topic_replies, t.topic_replies_real, t.topic_first_post_id, t.topic_first_poster_name, t.topic_first_poster_colour, t.topic_last_post_id, t.topic_last_post_subject, t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_poster_colour, t.topic_last_post_time
 
1682
                                FROM ' . TOPICS_TABLE . " t
 
1683
                                $where_sql";
 
1684
                        $result = $db->sql_query($sql);
 
1685
 
 
1686
                        while ($row = $db->sql_fetchrow($result))
 
1687
                        {
 
1688
                                if ($row['topic_moved_id'])
 
1689
                                {
 
1690
                                        $moved_topics[] = $row['topic_id'];
 
1691
                                        continue;
 
1692
                                }
 
1693
 
 
1694
                                $topic_id = (int) $row['topic_id'];
 
1695
                                $topic_data[$topic_id] = $row;
 
1696
                                $topic_data[$topic_id]['replies_real'] = -1;
 
1697
                                $topic_data[$topic_id]['replies'] = 0;
 
1698
                                $topic_data[$topic_id]['first_post_id'] = 0;
 
1699
                                $topic_data[$topic_id]['last_post_id'] = 0;
 
1700
                                unset($topic_data[$topic_id]['topic_id']);
 
1701
 
 
1702
                                // This array holds all topic_ids
 
1703
                                $delete_topics[$topic_id] = '';
 
1704
 
 
1705
                                if ($sync_extra)
 
1706
                                {
 
1707
                                        $topic_data[$topic_id]['reported'] = 0;
 
1708
                                        $topic_data[$topic_id]['attachment'] = 0;
 
1709
                                }
 
1710
                        }
 
1711
                        $db->sql_freeresult($result);
 
1712
 
 
1713
                        // Use "t" as table alias because of the $where_sql clause
 
1714
                        // NOTE: 't.post_approved' in the GROUP BY is causing a major slowdown.
 
1715
                        $sql = 'SELECT t.topic_id, t.post_approved, COUNT(t.post_id) AS total_posts, MIN(t.post_id) AS first_post_id, MAX(t.post_id) AS last_post_id
 
1716
                                FROM ' . POSTS_TABLE . " t
 
1717
                                $where_sql
 
1718
                                GROUP BY t.topic_id, t.post_approved";
 
1719
                        $result = $db->sql_query($sql);
 
1720
 
 
1721
                        while ($row = $db->sql_fetchrow($result))
 
1722
                        {
 
1723
                                $topic_id = (int) $row['topic_id'];
 
1724
 
 
1725
                                $row['first_post_id'] = (int) $row['first_post_id'];
 
1726
                                $row['last_post_id'] = (int) $row['last_post_id'];
 
1727
 
 
1728
                                if (!isset($topic_data[$topic_id]))
 
1729
                                {
 
1730
                                        // Hey, these posts come from a topic that does not exist
 
1731
                                        $delete_posts[$topic_id] = '';
 
1732
                                }
 
1733
                                else
 
1734
                                {
 
1735
                                        // Unset the corresponding entry in $delete_topics
 
1736
                                        // When we'll be done, only topics with no posts will remain
 
1737
                                        unset($delete_topics[$topic_id]);
 
1738
 
 
1739
                                        $topic_data[$topic_id]['replies_real'] += $row['total_posts'];
 
1740
                                        $topic_data[$topic_id]['first_post_id'] = (!$topic_data[$topic_id]['first_post_id']) ? $row['first_post_id'] : min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']);
 
1741
 
 
1742
                                        if ($row['post_approved'] || !$topic_data[$topic_id]['last_post_id'])
 
1743
                                        {
 
1744
                                                $topic_data[$topic_id]['replies'] = $row['total_posts'] - 1;
 
1745
                                                $topic_data[$topic_id]['last_post_id'] = $row['last_post_id'];
 
1746
                                        }
 
1747
                                }
 
1748
                        }
 
1749
                        $db->sql_freeresult($result);
 
1750
 
 
1751
                        foreach ($topic_data as $topic_id => $row)
 
1752
                        {
 
1753
                                $post_ids[] = $row['first_post_id'];
 
1754
                                if ($row['first_post_id'] != $row['last_post_id'])
 
1755
                                {
 
1756
                                        $post_ids[] = $row['last_post_id'];
 
1757
                                }
 
1758
                        }
 
1759
 
 
1760
                        // Now we delete empty topics and orphan posts
 
1761
                        if (sizeof($delete_posts))
 
1762
                        {
 
1763
                                delete_posts('topic_id', array_keys($delete_posts), false);
 
1764
                                unset($delete_posts);
 
1765
                        }
 
1766
 
 
1767
                        if (!sizeof($topic_data))
 
1768
                        {
 
1769
                                // If we get there, topic ids were invalid or topics did not contain any posts
 
1770
                                delete_topics($where_type, $where_ids, true);
 
1771
                                return;
 
1772
                        }
 
1773
 
 
1774
                        if (sizeof($delete_topics))
 
1775
                        {
 
1776
                                $delete_topic_ids = array();
 
1777
                                foreach ($delete_topics as $topic_id => $void)
 
1778
                                {
 
1779
                                        unset($topic_data[$topic_id]);
 
1780
                                        $delete_topic_ids[] = $topic_id;
 
1781
                                }
 
1782
 
 
1783
                                delete_topics('topic_id', $delete_topic_ids, false);
 
1784
                                unset($delete_topics, $delete_topic_ids);
 
1785
                        }
 
1786
 
 
1787
                        $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour
 
1788
                                FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 
1789
                                WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
 
1790
                                        AND u.user_id = p.poster_id';
 
1791
                        $result = $db->sql_query($sql);
 
1792
 
 
1793
                        $post_ids = array();
 
1794
                        while ($row = $db->sql_fetchrow($result))
 
1795
                        {
 
1796
                                $topic_id = intval($row['topic_id']);
 
1797
 
 
1798
                                if ($row['post_id'] == $topic_data[$topic_id]['first_post_id'])
 
1799
                                {
 
1800
                                        if ($topic_data[$topic_id]['topic_approved'] != $row['post_approved'])
 
1801
                                        {
 
1802
                                                $approved_unapproved_ids[] = $topic_id;
 
1803
                                        }
 
1804
                                        $topic_data[$topic_id]['time'] = $row['post_time'];
 
1805
                                        $topic_data[$topic_id]['poster'] = $row['poster_id'];
 
1806
                                        $topic_data[$topic_id]['first_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
 
1807
                                        $topic_data[$topic_id]['first_poster_colour'] = $row['user_colour'];
 
1808
                                }
 
1809
 
 
1810
                                if ($row['post_id'] == $topic_data[$topic_id]['last_post_id'])
 
1811
                                {
 
1812
                                        $topic_data[$topic_id]['last_poster_id'] = $row['poster_id'];
 
1813
                                        $topic_data[$topic_id]['last_post_subject'] = $row['post_subject'];
 
1814
                                        $topic_data[$topic_id]['last_post_time'] = $row['post_time'];
 
1815
                                        $topic_data[$topic_id]['last_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
 
1816
                                        $topic_data[$topic_id]['last_poster_colour'] = $row['user_colour'];
 
1817
                                }
 
1818
                        }
 
1819
                        $db->sql_freeresult($result);
 
1820
 
 
1821
                        // Make sure shadow topics do link to existing topics
 
1822
                        if (sizeof($moved_topics))
 
1823
                        {
 
1824
                                $delete_topics = array();
 
1825
 
 
1826
                                $sql = 'SELECT t1.topic_id, t1.topic_moved_id
 
1827
                                        FROM ' . TOPICS_TABLE . ' t1
 
1828
                                        LEFT JOIN ' . TOPICS_TABLE . ' t2 ON (t2.topic_id = t1.topic_moved_id)
 
1829
                                        WHERE ' . $db->sql_in_set('t1.topic_id', $moved_topics) . '
 
1830
                                                AND t2.topic_id IS NULL';
 
1831
                                $result = $db->sql_query($sql);
 
1832
 
 
1833
                                while ($row = $db->sql_fetchrow($result))
 
1834
                                {
 
1835
                                        $delete_topics[] = $row['topic_id'];
 
1836
                                }
 
1837
                                $db->sql_freeresult($result);
 
1838
 
 
1839
                                if (sizeof($delete_topics))
 
1840
                                {
 
1841
                                        delete_topics('topic_id', $delete_topics, false);
 
1842
                                }
 
1843
                                unset($delete_topics);
 
1844
 
 
1845
                                // Make sure shadow topics having no last post data being updated (this only rarely happens...)
 
1846
                                $sql = 'SELECT topic_id, topic_moved_id, topic_last_post_id, topic_first_post_id
 
1847
                                        FROM ' . TOPICS_TABLE . '
 
1848
                                        WHERE ' . $db->sql_in_set('topic_id', $moved_topics) . '
 
1849
                                                AND topic_last_post_time = 0';
 
1850
                                $result = $db->sql_query($sql);
 
1851
 
 
1852
                                $shadow_topic_data = $post_ids = array();
 
1853
                                while ($row = $db->sql_fetchrow($result))
 
1854
                                {
 
1855
                                        $shadow_topic_data[$row['topic_moved_id']] = $row;
 
1856
                                        $post_ids[] = $row['topic_last_post_id'];
 
1857
                                        $post_ids[] = $row['topic_first_post_id'];
 
1858
                                }
 
1859
                                $db->sql_freeresult($result);
 
1860
 
 
1861
                                $sync_shadow_topics = array();
 
1862
                                if (sizeof($post_ids))
 
1863
                                {
 
1864
                                        $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour
 
1865
                                                FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 
1866
                                                WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
 
1867
                                                        AND u.user_id = p.poster_id';
 
1868
                                        $result = $db->sql_query($sql);
 
1869
 
 
1870
                                        $post_ids = array();
 
1871
                                        while ($row = $db->sql_fetchrow($result))
 
1872
                                        {
 
1873
                                                $topic_id = (int) $row['topic_id'];
 
1874
 
 
1875
                                                // Ok, there should be a shadow topic. If there isn't, then there's something wrong with the db.
 
1876
                                                // However, there's not much we can do about it.
 
1877
                                                if (!empty($shadow_topic_data[$topic_id]))
 
1878
                                                {
 
1879
                                                        if ($row['post_id'] == $shadow_topic_data[$topic_id]['topic_first_post_id'])
 
1880
                                                        {
 
1881
                                                                $orig_topic_id = $shadow_topic_data[$topic_id]['topic_id'];
 
1882
 
 
1883
                                                                if (!isset($sync_shadow_topics[$orig_topic_id]))
 
1884
                                                                {
 
1885
                                                                        $sync_shadow_topics[$orig_topic_id] = array();
 
1886
                                                                }
 
1887
 
 
1888
                                                                $sync_shadow_topics[$orig_topic_id]['topic_time'] = $row['post_time'];
 
1889
                                                                $sync_shadow_topics[$orig_topic_id]['topic_poster'] = $row['poster_id'];
 
1890
                                                                $sync_shadow_topics[$orig_topic_id]['topic_first_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
 
1891
                                                                $sync_shadow_topics[$orig_topic_id]['topic_first_poster_colour'] = $row['user_colour'];
 
1892
                                                        }
 
1893
 
 
1894
                                                        if ($row['post_id'] == $shadow_topic_data[$topic_id]['topic_last_post_id'])
 
1895
                                                        {
 
1896
                                                                $orig_topic_id = $shadow_topic_data[$topic_id]['topic_id'];
 
1897
 
 
1898
                                                                if (!isset($sync_shadow_topics[$orig_topic_id]))
 
1899
                                                                {
 
1900
                                                                        $sync_shadow_topics[$orig_topic_id] = array();
 
1901
                                                                }
 
1902
 
 
1903
                                                                $sync_shadow_topics[$orig_topic_id]['topic_last_poster_id'] = $row['poster_id'];
 
1904
                                                                $sync_shadow_topics[$orig_topic_id]['topic_last_post_subject'] = $row['post_subject'];
 
1905
                                                                $sync_shadow_topics[$orig_topic_id]['topic_last_post_time'] = $row['post_time'];
 
1906
                                                                $sync_shadow_topics[$orig_topic_id]['topic_last_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
 
1907
                                                                $sync_shadow_topics[$orig_topic_id]['topic_last_poster_colour'] = $row['user_colour'];
 
1908
                                                        }
 
1909
                                                }
 
1910
                                        }
 
1911
                                        $db->sql_freeresult($result);
 
1912
 
 
1913
                                        $shadow_topic_data = array();
 
1914
 
 
1915
                                        // Update the information we collected
 
1916
                                        if (sizeof($sync_shadow_topics))
 
1917
                                        {
 
1918
                                                foreach ($sync_shadow_topics as $sync_topic_id => $sql_ary)
 
1919
                                                {
 
1920
                                                        $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1921
                                                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
 
1922
                                                                WHERE topic_id = ' . $sync_topic_id;
 
1923
                                                        $db->sql_query($sql);
 
1924
                                                }
 
1925
                                        }
 
1926
                                }
 
1927
 
 
1928
                                unset($sync_shadow_topics, $shadow_topic_data);
 
1929
                        }
 
1930
 
 
1931
                        // approved becomes unapproved, and vice-versa
 
1932
                        if (sizeof($approved_unapproved_ids))
 
1933
                        {
 
1934
                                $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1935
                                        SET topic_approved = 1 - topic_approved
 
1936
                                        WHERE ' . $db->sql_in_set('topic_id', $approved_unapproved_ids);
 
1937
                                $db->sql_query($sql);
 
1938
                        }
 
1939
                        unset($approved_unapproved_ids);
 
1940
 
 
1941
                        // These are fields that will be synchronised
 
1942
                        $fieldnames = array('time', 'replies', 'replies_real', 'poster', 'first_post_id', 'first_poster_name', 'first_poster_colour', 'last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour');
 
1943
 
 
1944
                        if ($sync_extra)
 
1945
                        {
 
1946
                                // This routine assumes that post_reported values are correct
 
1947
                                // if they are not, use sync('post_reported') first
 
1948
                                $sql = 'SELECT t.topic_id, p.post_id
 
1949
                                        FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
 
1950
                                        $where_sql_and p.topic_id = t.topic_id
 
1951
                                                AND p.post_reported = 1
 
1952
                                        GROUP BY t.topic_id, p.post_id";
 
1953
                                $result = $db->sql_query($sql);
 
1954
 
 
1955
                                $fieldnames[] = 'reported';
 
1956
                                while ($row = $db->sql_fetchrow($result))
 
1957
                                {
 
1958
                                        $topic_data[intval($row['topic_id'])]['reported'] = 1;
 
1959
                                }
 
1960
                                $db->sql_freeresult($result);
 
1961
 
 
1962
                                // This routine assumes that post_attachment values are correct
 
1963
                                // if they are not, use sync('post_attachment') first
 
1964
                                $sql = 'SELECT t.topic_id, p.post_id
 
1965
                                        FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
 
1966
                                        $where_sql_and p.topic_id = t.topic_id
 
1967
                                                AND p.post_attachment = 1
 
1968
                                        GROUP BY t.topic_id, p.post_id";
 
1969
                                $result = $db->sql_query($sql);
 
1970
 
 
1971
                                $fieldnames[] = 'attachment';
 
1972
                                while ($row = $db->sql_fetchrow($result))
 
1973
                                {
 
1974
                                        $topic_data[intval($row['topic_id'])]['attachment'] = 1;
 
1975
                                }
 
1976
                                $db->sql_freeresult($result);
 
1977
                        }
 
1978
 
 
1979
                        foreach ($topic_data as $topic_id => $row)
 
1980
                        {
 
1981
                                $sql_ary = array();
 
1982
 
 
1983
                                foreach ($fieldnames as $fieldname)
 
1984
                                {
 
1985
                                        if (isset($row[$fieldname]) && isset($row['topic_' . $fieldname]) && $row['topic_' . $fieldname] != $row[$fieldname])
 
1986
                                        {
 
1987
                                                $sql_ary['topic_' . $fieldname] = $row[$fieldname];
 
1988
                                        }
 
1989
                                }
 
1990
 
 
1991
                                if (sizeof($sql_ary))
 
1992
                                {
 
1993
                                        $sql = 'UPDATE ' . TOPICS_TABLE . '
 
1994
                                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
 
1995
                                                WHERE topic_id = ' . $topic_id;
 
1996
                                        $db->sql_query($sql);
 
1997
 
 
1998
                                        $resync_forums[$row['forum_id']] = $row['forum_id'];
 
1999
                                }
 
2000
                        }
 
2001
                        unset($topic_data);
 
2002
 
 
2003
                        // if some topics have been resync'ed then resync parent forums
 
2004
                        // except when we're only syncing a range, we don't want to sync forums during
 
2005
                        // batch processing.
 
2006
                        if ($resync_parents && sizeof($resync_forums) && $where_type != 'range')
 
2007
                        {
 
2008
                                sync('forum', 'forum_id', array_values($resync_forums), true, true);
 
2009
                        }
 
2010
                break;
 
2011
        }
 
2012
 
 
2013
        return;
 
2014
}
 
2015
 
 
2016
/**
 
2017
* Prune function
 
2018
*/
 
2019
function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync = true)
 
2020
{
 
2021
        global $db;
 
2022
 
 
2023
        if (!is_array($forum_id))
 
2024
        {
 
2025
                $forum_id = array($forum_id);
 
2026
        }
 
2027
 
 
2028
        if (!sizeof($forum_id))
 
2029
        {
 
2030
                return;
 
2031
        }
 
2032
 
 
2033
        $sql_and = '';
 
2034
 
 
2035
        if (!($prune_flags & FORUM_FLAG_PRUNE_ANNOUNCE))
 
2036
        {
 
2037
                $sql_and .= ' AND topic_type <> ' . POST_ANNOUNCE;
 
2038
        }
 
2039
 
 
2040
        if (!($prune_flags & FORUM_FLAG_PRUNE_STICKY))
 
2041
        {
 
2042
                $sql_and .= ' AND topic_type <> ' . POST_STICKY;
 
2043
        }
 
2044
 
 
2045
        if ($prune_mode == 'posted')
 
2046
        {
 
2047
                $sql_and .= " AND topic_last_post_time < $prune_date";
 
2048
        }
 
2049
 
 
2050
        if ($prune_mode == 'viewed')
 
2051
        {
 
2052
                $sql_and .= " AND topic_last_view_time < $prune_date";
 
2053
        }
 
2054
 
 
2055
        $sql = 'SELECT topic_id
 
2056
                FROM ' . TOPICS_TABLE . '
 
2057
                WHERE ' . $db->sql_in_set('forum_id', $forum_id) . "
 
2058
                        AND poll_start = 0
 
2059
                        $sql_and";
 
2060
        $result = $db->sql_query($sql);
 
2061
 
 
2062
        $topic_list = array();
 
2063
        while ($row = $db->sql_fetchrow($result))
 
2064
        {
 
2065
                $topic_list[] = $row['topic_id'];
 
2066
        }
 
2067
        $db->sql_freeresult($result);
 
2068
 
 
2069
        if ($prune_flags & FORUM_FLAG_PRUNE_POLL)
 
2070
        {
 
2071
                $sql = 'SELECT topic_id
 
2072
                        FROM ' . TOPICS_TABLE . '
 
2073
                        WHERE ' . $db->sql_in_set('forum_id', $forum_id) . "
 
2074
                                AND poll_start > 0
 
2075
                                AND poll_last_vote < $prune_date
 
2076
                                $sql_and";
 
2077
                $result = $db->sql_query($sql);
 
2078
 
 
2079
                while ($row = $db->sql_fetchrow($result))
 
2080
                {
 
2081
                        $topic_list[] = $row['topic_id'];
 
2082
                }
 
2083
                $db->sql_freeresult($result);
 
2084
 
 
2085
                $topic_list = array_unique($topic_list);
 
2086
        }
 
2087
 
 
2088
        return delete_topics('topic_id', $topic_list, $auto_sync, false);
 
2089
}
 
2090
 
 
2091
/**
 
2092
* Function auto_prune(), this function now relies on passed vars
 
2093
*/
 
2094
function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq)
 
2095
{
 
2096
        global $db;
 
2097
 
 
2098
        $sql = 'SELECT forum_name
 
2099
                FROM ' . FORUMS_TABLE . "
 
2100
                WHERE forum_id = $forum_id";
 
2101
        $result = $db->sql_query($sql, 3600);
 
2102
        $row = $db->sql_fetchrow($result);
 
2103
        $db->sql_freeresult($result);
 
2104
 
 
2105
        if ($row)
 
2106
        {
 
2107
                $prune_date = time() - ($prune_days * 86400);
 
2108
                $next_prune = time() + ($prune_freq * 86400);
 
2109
 
 
2110
                prune($forum_id, $prune_mode, $prune_date, $prune_flags, true);
 
2111
 
 
2112
                $sql = 'UPDATE ' . FORUMS_TABLE . "
 
2113
                        SET prune_next = $next_prune
 
2114
                        WHERE forum_id = $forum_id";
 
2115
                $db->sql_query($sql);
 
2116
 
 
2117
                add_log('admin', 'LOG_AUTO_PRUNE', $row['forum_name']);
 
2118
        }
 
2119
 
 
2120
        return;
 
2121
}
 
2122
 
 
2123
/**
 
2124
* remove_comments will strip the sql comment lines out of an uploaded sql file
 
2125
* specifically for mssql and postgres type files in the install....
 
2126
*/
 
2127
function remove_comments(&$output)
 
2128
{
 
2129
        $lines = explode("\n", $output);
 
2130
        $output = '';
 
2131
 
 
2132
        // try to keep mem. use down
 
2133
        $linecount = sizeof($lines);
 
2134
 
 
2135
        $in_comment = false;
 
2136
        for ($i = 0; $i < $linecount; $i++)
 
2137
        {
 
2138
                if (trim($lines[$i]) == '/*')
 
2139
                {
 
2140
                        $in_comment = true;
 
2141
                }
 
2142
 
 
2143
                if (!$in_comment)
 
2144
                {
 
2145
                        $output .= $lines[$i] . "\n";
 
2146
                }
 
2147
 
 
2148
                if (trim($lines[$i]) == '*/')
 
2149
                {
 
2150
                        $in_comment = false;
 
2151
                }
 
2152
        }
 
2153
 
 
2154
        unset($lines);
 
2155
        return $output;
 
2156
}
 
2157
 
 
2158
/**
 
2159
* Cache moderators, called whenever permissions are changed via admin_permissions. Changes of username
 
2160
* and group names must be carried through for the moderators table
 
2161
*/
 
2162
function cache_moderators()
 
2163
{
 
2164
        global $db, $cache, $auth, $phpbb_root_path, $phpEx;
 
2165
 
 
2166
        // Remove cached sql results
 
2167
        $cache->destroy('sql', MODERATOR_CACHE_TABLE);
 
2168
 
 
2169
        // Clear table
 
2170
        switch ($db->sql_layer)
 
2171
        {
 
2172
                case 'sqlite':
 
2173
                case 'firebird':
 
2174
                        $db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
 
2175
                break;
 
2176
 
 
2177
                default:
 
2178
                        $db->sql_query('TRUNCATE TABLE ' . MODERATOR_CACHE_TABLE);
 
2179
                break;
 
2180
        }
 
2181
 
 
2182
        // We add moderators who have forum moderator permissions without an explicit ACL_NEVER setting
 
2183
        $hold_ary = $ug_id_ary = $sql_ary = array();
 
2184
 
 
2185
        // Grab all users having moderative options...
 
2186
        $hold_ary = $auth->acl_user_raw_data(false, 'm_%', false);
 
2187
 
 
2188
        // Add users?
 
2189
        if (sizeof($hold_ary))
 
2190
        {
 
2191
                // At least one moderative option warrants a display
 
2192
                $ug_id_ary = array_keys($hold_ary);
 
2193
 
 
2194
                // Remove users who have group memberships with DENY moderator permissions
 
2195
                $sql = $db->sql_build_query('SELECT', array(
 
2196
                        'SELECT'        => 'a.forum_id, ug.user_id',
 
2197
 
 
2198
                        'FROM'          => array(
 
2199
                                ACL_OPTIONS_TABLE       => 'o',
 
2200
                                USER_GROUP_TABLE        => 'ug',
 
2201
                                ACL_GROUPS_TABLE        => 'a'
 
2202
                        ),
 
2203
 
 
2204
                        'LEFT_JOIN'     => array(
 
2205
                                array(
 
2206
                                        'FROM'  => array(ACL_ROLES_DATA_TABLE => 'r'),
 
2207
                                        'ON'    => 'a.auth_role_id = r.role_id'
 
2208
                                )
 
2209
                        ),
 
2210
 
 
2211
                        'WHERE'         => '(o.auth_option_id = a.auth_option_id OR o.auth_option_id = r.auth_option_id)
 
2212
                                AND ((a.auth_setting = ' . ACL_NEVER . ' AND r.auth_setting IS NULL)
 
2213
                                        OR r.auth_setting = ' . ACL_NEVER . ')
 
2214
                                AND a.group_id = ug.group_id
 
2215
                                AND ' . $db->sql_in_set('ug.user_id', $ug_id_ary) . "
 
2216
                                AND ug.user_pending = 0
 
2217
                                AND o.auth_option " . $db->sql_like_expression('m_' . $db->any_char),
 
2218
                ));
 
2219
                $result = $db->sql_query($sql);
 
2220
 
 
2221
                while ($row = $db->sql_fetchrow($result))
 
2222
                {
 
2223
                        if (isset($hold_ary[$row['user_id']][$row['forum_id']]))
 
2224
                        {
 
2225
                                unset($hold_ary[$row['user_id']][$row['forum_id']]);
 
2226
                        }
 
2227
                }
 
2228
                $db->sql_freeresult($result);
 
2229
 
 
2230
                if (sizeof($hold_ary))
 
2231
                {
 
2232
                        // Get usernames...
 
2233
                        $sql = 'SELECT user_id, username
 
2234
                                FROM ' . USERS_TABLE . '
 
2235
                                WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary));
 
2236
                        $result = $db->sql_query($sql);
 
2237
 
 
2238
                        $usernames_ary = array();
 
2239
                        while ($row = $db->sql_fetchrow($result))
 
2240
                        {
 
2241
                                $usernames_ary[$row['user_id']] = $row['username'];
 
2242
                        }
 
2243
 
 
2244
                        foreach ($hold_ary as $user_id => $forum_id_ary)
 
2245
                        {
 
2246
                                // Do not continue if user does not exist
 
2247
                                if (!isset($usernames_ary[$user_id]))
 
2248
                                {
 
2249
                                        continue;
 
2250
                                }
 
2251
 
 
2252
                                foreach ($forum_id_ary as $forum_id => $auth_ary)
 
2253
                                {
 
2254
                                        $sql_ary[] = array(
 
2255
                                                'forum_id'              => (int) $forum_id,
 
2256
                                                'user_id'               => (int) $user_id,
 
2257
                                                'username'              => (string) $usernames_ary[$user_id],
 
2258
                                                'group_id'              => 0,
 
2259
                                                'group_name'    => ''
 
2260
                                        );
 
2261
                                }
 
2262
                        }
 
2263
                }
 
2264
        }
 
2265
 
 
2266
        // Now to the groups...
 
2267
        $hold_ary = $auth->acl_group_raw_data(false, 'm_%', false);
 
2268
 
 
2269
        if (sizeof($hold_ary))
 
2270
        {
 
2271
                $ug_id_ary = array_keys($hold_ary);
 
2272
 
 
2273
                // Make sure not hidden or special groups are involved...
 
2274
                $sql = 'SELECT group_name, group_id, group_type
 
2275
                        FROM ' . GROUPS_TABLE . '
 
2276
                        WHERE ' . $db->sql_in_set('group_id', $ug_id_ary);
 
2277
                $result = $db->sql_query($sql);
 
2278
 
 
2279
                $groupnames_ary = array();
 
2280
                while ($row = $db->sql_fetchrow($result))
 
2281
                {
 
2282
                        if ($row['group_type'] == GROUP_HIDDEN || $row['group_type'] == GROUP_SPECIAL)
 
2283
                        {
 
2284
                                unset($hold_ary[$row['group_id']]);
 
2285
                        }
 
2286
 
 
2287
                        $groupnames_ary[$row['group_id']] = $row['group_name'];
 
2288
                }
 
2289
                $db->sql_freeresult($result);
 
2290
 
 
2291
                foreach ($hold_ary as $group_id => $forum_id_ary)
 
2292
                {
 
2293
                        // If there is no group, we do not assign it...
 
2294
                        if (!isset($groupnames_ary[$group_id]))
 
2295
                        {
 
2296
                                continue;
 
2297
                        }
 
2298
 
 
2299
                        foreach ($forum_id_ary as $forum_id => $auth_ary)
 
2300
                        {
 
2301
                                $flag = false;
 
2302
                                foreach ($auth_ary as $auth_option => $setting)
 
2303
                                {
 
2304
                                        // Make sure at least one ACL_YES option is set...
 
2305
                                        if ($setting == ACL_YES)
 
2306
                                        {
 
2307
                                                $flag = true;
 
2308
                                                break;
 
2309
                                        }
 
2310
                                }
 
2311
 
 
2312
                                if (!$flag)
 
2313
                                {
 
2314
                                        continue;
 
2315
                                }
 
2316
 
 
2317
                                $sql_ary[] = array(
 
2318
                                        'forum_id'              => (int) $forum_id,
 
2319
                                        'user_id'               => 0,
 
2320
                                        'username'              => '',
 
2321
                                        'group_id'              => (int) $group_id,
 
2322
                                        'group_name'    => (string) $groupnames_ary[$group_id]
 
2323
                                );
 
2324
                        }
 
2325
                }
 
2326
        }
 
2327
 
 
2328
        $db->sql_multi_insert(MODERATOR_CACHE_TABLE, $sql_ary);
 
2329
}
 
2330
 
 
2331
/**
 
2332
* View log
 
2333
*/
 
2334
function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $limit_days = 0, $sort_by = 'l.log_time DESC')
 
2335
{
 
2336
        global $db, $user, $auth, $phpEx, $phpbb_root_path, $phpbb_admin_path;
 
2337
 
 
2338
        $topic_id_list = $reportee_id_list = $is_auth = $is_mod = array();
 
2339
 
 
2340
        $profile_url = (defined('IN_ADMIN')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview') : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile');
 
2341
 
 
2342
        switch ($mode)
 
2343
        {
 
2344
                case 'admin':
 
2345
                        $log_type = LOG_ADMIN;
 
2346
                        $sql_forum = '';
 
2347
                break;
 
2348
 
 
2349
                case 'mod':
 
2350
                        $log_type = LOG_MOD;
 
2351
 
 
2352
                        if ($topic_id)
 
2353
                        {
 
2354
                                $sql_forum = 'AND l.topic_id = ' . intval($topic_id);
 
2355
                        }
 
2356
                        else if (is_array($forum_id))
 
2357
                        {
 
2358
                                $sql_forum = 'AND ' . $db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
 
2359
                        }
 
2360
                        else
 
2361
                        {
 
2362
                                $sql_forum = ($forum_id) ? 'AND l.forum_id = ' . intval($forum_id) : '';
 
2363
                        }
 
2364
                break;
 
2365
 
 
2366
                case 'user':
 
2367
                        $log_type = LOG_USERS;
 
2368
                        $sql_forum = 'AND l.reportee_id = ' . (int) $user_id;
 
2369
                break;
 
2370
                
 
2371
                case 'users':
 
2372
                        $log_type = LOG_USERS;
 
2373
                        $sql_forum = '';
 
2374
                break;
 
2375
 
 
2376
                case 'critical':
 
2377
                        $log_type = LOG_CRITICAL;
 
2378
                        $sql_forum = '';
 
2379
                break;
 
2380
                
 
2381
                default:
 
2382
                        return;
 
2383
        }
 
2384
 
 
2385
        $sql = "SELECT l.*, u.username, u.username_clean, u.user_colour
 
2386
                FROM " . LOG_TABLE . " l, " . USERS_TABLE . " u
 
2387
                WHERE l.log_type = $log_type
 
2388
                        AND u.user_id = l.user_id
 
2389
                        " . (($limit_days) ? "AND l.log_time >= $limit_days" : '') . "
 
2390
                        $sql_forum
 
2391
                ORDER BY $sort_by";
 
2392
        $result = $db->sql_query_limit($sql, $limit, $offset);
 
2393
 
 
2394
        $i = 0;
 
2395
        $log = array();
 
2396
        while ($row = $db->sql_fetchrow($result))
 
2397
        {
 
2398
                if ($row['topic_id'])
 
2399
                {
 
2400
                        $topic_id_list[] = $row['topic_id'];
 
2401
                }
 
2402
 
 
2403
                if ($row['reportee_id'])
 
2404
                {
 
2405
                        $reportee_id_list[] = $row['reportee_id'];
 
2406
                }
 
2407
 
 
2408
                $log[$i] = array(
 
2409
                        'id'                            => $row['log_id'],
 
2410
 
 
2411
                        'reportee_id'                   => $row['reportee_id'],
 
2412
                        'reportee_username'             => '',
 
2413
                        'reportee_username_full'=> '',
 
2414
 
 
2415
                        'user_id'                       => $row['user_id'],
 
2416
                        'username'                      => $row['username'],
 
2417
                        'username_full'         => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
 
2418
 
 
2419
                        'ip'                            => $row['log_ip'],
 
2420
                        'time'                          => $row['log_time'],
 
2421
                        'forum_id'                      => $row['forum_id'],
 
2422
                        'topic_id'                      => $row['topic_id'],
 
2423
 
 
2424
                        'viewforum'                     => ($row['forum_id'] && $auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']) : false,
 
2425
                        'action'                        => (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
 
2426
                );
 
2427
 
 
2428
                if (!empty($row['log_data']))
 
2429
                {
 
2430
                        $log_data_ary = unserialize($row['log_data']);
 
2431
 
 
2432
                        if (isset($user->lang[$row['log_operation']]))
 
2433
                        {
 
2434
                                // We supress the warning about inappropriate number of passed parameters here due to possible changes within LOG strings from one version to another.
 
2435
                                $log[$i]['action'] = @vsprintf($log[$i]['action'], $log_data_ary);
 
2436
 
 
2437
                                // If within the admin panel we do not censor text out
 
2438
                                if (defined('IN_ADMIN'))
 
2439
                                {
 
2440
                                        $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
 
2441
                                }
 
2442
                                else
 
2443
                                {
 
2444
                                        $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
 
2445
                                }
 
2446
                        }
 
2447
                        else
 
2448
                        {
 
2449
                                $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
 
2450
                        }
 
2451
 
 
2452
                        /* Apply make_clickable... has to be seen if it is for good. :/
 
2453
                        // Seems to be not for the moment, reconsider later...
 
2454
                        $log[$i]['action'] = make_clickable($log[$i]['action']);
 
2455
                        */
 
2456
                }
 
2457
 
 
2458
                $i++;
 
2459
        }
 
2460
        $db->sql_freeresult($result);
 
2461
 
 
2462
        if (sizeof($topic_id_list))
 
2463
        {
 
2464
                $topic_id_list = array_unique($topic_id_list);
 
2465
 
 
2466
                // This query is not really needed if move_topics() updates the forum_id field,
 
2467
                // although it's also used to determine if the topic still exists in the database
 
2468
                $sql = 'SELECT topic_id, forum_id
 
2469
                        FROM ' . TOPICS_TABLE . '
 
2470
                        WHERE ' . $db->sql_in_set('topic_id', array_map('intval', $topic_id_list));
 
2471
                $result = $db->sql_query($sql);
 
2472
 
 
2473
                $default_forum_id = 0;
 
2474
 
 
2475
                while ($row = $db->sql_fetchrow($result))
 
2476
                {
 
2477
                        if (!$row['forum_id'])
 
2478
                        {
 
2479
                                if ($auth->acl_getf_global('f_read'))
 
2480
                                {
 
2481
                                        if (!$default_forum_id)
 
2482
                                        {
 
2483
                                                $sql = 'SELECT forum_id
 
2484
                                                        FROM ' . FORUMS_TABLE . '
 
2485
                                                        WHERE forum_type = ' . FORUM_POST;
 
2486
                                                $f_result = $db->sql_query_limit($sql, 1);
 
2487
                                                $default_forum_id = (int) $db->sql_fetchfield('forum_id', false, $f_result);
 
2488
                                                $db->sql_freeresult($f_result);
 
2489
                                        }
 
2490
 
 
2491
                                        $is_auth[$row['topic_id']] = $default_forum_id;
 
2492
                                }
 
2493
                        }
 
2494
                        else
 
2495
                        {
 
2496
                                if ($auth->acl_get('f_read', $row['forum_id']))
 
2497
                                {
 
2498
                                        $is_auth[$row['topic_id']] = $row['forum_id'];
 
2499
                                }
 
2500
                        }
 
2501
 
 
2502
                        if ($auth->acl_gets('a_', 'm_', $row['forum_id']))
 
2503
                        {
 
2504
                                $is_mod[$row['topic_id']] = $row['forum_id'];
 
2505
                        }
 
2506
                }
 
2507
                $db->sql_freeresult($result);
 
2508
 
 
2509
                foreach ($log as $key => $row)
 
2510
                {
 
2511
                        $log[$key]['viewtopic'] = (isset($is_auth[$row['topic_id']])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $is_auth[$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
 
2512
                        $log[$key]['viewlogs'] = (isset($is_mod[$row['topic_id']])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $user->session_id) : false;
 
2513
                }
 
2514
        }
 
2515
 
 
2516
        if (sizeof($reportee_id_list))
 
2517
        {
 
2518
                $reportee_id_list = array_unique($reportee_id_list);
 
2519
                $reportee_names_list = array();
 
2520
 
 
2521
                $sql = 'SELECT user_id, username, user_colour
 
2522
                        FROM ' . USERS_TABLE . '
 
2523
                        WHERE ' . $db->sql_in_set('user_id', $reportee_id_list);
 
2524
                $result = $db->sql_query($sql);
 
2525
 
 
2526
                while ($row = $db->sql_fetchrow($result))
 
2527
                {
 
2528
                        $reportee_names_list[$row['user_id']] = $row;
 
2529
                }
 
2530
                $db->sql_freeresult($result);
 
2531
 
 
2532
                foreach ($log as $key => $row)
 
2533
                {
 
2534
                        if (!isset($reportee_names_list[$row['reportee_id']]))
 
2535
                        {
 
2536
                                continue;
 
2537
                        }
 
2538
 
 
2539
                        $log[$key]['reportee_username'] = $reportee_names_list[$row['reportee_id']]['username'];
 
2540
                        $log[$key]['reportee_username_full'] = get_username_string('full', $row['reportee_id'], $reportee_names_list[$row['reportee_id']]['username'], $reportee_names_list[$row['reportee_id']]['user_colour'], false, $profile_url);
 
2541
                }
 
2542
        }
 
2543
 
 
2544
        $sql = 'SELECT COUNT(l.log_id) AS total_entries
 
2545
                FROM ' . LOG_TABLE . " l
 
2546
                WHERE l.log_type = $log_type
 
2547
                        AND l.log_time >= $limit_days
 
2548
                        $sql_forum";
 
2549
        $result = $db->sql_query($sql);
 
2550
        $log_count = (int) $db->sql_fetchfield('total_entries');
 
2551
        $db->sql_freeresult($result);
 
2552
 
 
2553
        return;
 
2554
}
 
2555
 
 
2556
/**
 
2557
* Update foes - remove moderators and administrators from foe lists...
 
2558
*/
 
2559
function update_foes($group_id = false, $user_id = false)
 
2560
{
 
2561
        global $db, $auth;
 
2562
 
 
2563
        // update foes for some user
 
2564
        if (is_array($user_id) && sizeof($user_id))
 
2565
        {
 
2566
                $sql = 'DELETE FROM ' . ZEBRA_TABLE . '
 
2567
                        WHERE ' . $db->sql_in_set('zebra_id', $user_id) . '
 
2568
                                AND foe = 1';
 
2569
                $db->sql_query($sql);
 
2570
                return;
 
2571
        }
 
2572
 
 
2573
        // update foes for some group
 
2574
        if (is_array($group_id) && sizeof($group_id))
 
2575
        {
 
2576
                // Grab group settings...
 
2577
                $sql = $db->sql_build_query('SELECT', array(
 
2578
                        'SELECT'        => 'a.group_id',
 
2579
 
 
2580
                        'FROM'          => array(
 
2581
                                ACL_OPTIONS_TABLE       => 'ao',
 
2582
                                ACL_GROUPS_TABLE        => 'a'
 
2583
                        ),
 
2584
 
 
2585
                        'LEFT_JOIN'     => array(
 
2586
                                array(
 
2587
                                        'FROM'  => array(ACL_ROLES_DATA_TABLE => 'r'),
 
2588
                                        'ON'    => 'a.auth_role_id = r.role_id'
 
2589
                                ),
 
2590
                        ),
 
2591
 
 
2592
                        'WHERE'         => '(ao.auth_option_id = a.auth_option_id OR ao.auth_option_id = r.auth_option_id)
 
2593
                                AND ' . $db->sql_in_set('a.group_id', $group_id) . "
 
2594
                                AND ao.auth_option IN ('a_', 'm_')",
 
2595
 
 
2596
                        'GROUP_BY'      => 'a.group_id'
 
2597
                ));
 
2598
                $result = $db->sql_query($sql);
 
2599
 
 
2600
                $groups = array();
 
2601
                while ($row = $db->sql_fetchrow($result))
 
2602
                {
 
2603
                        $groups[] = (int) $row['group_id'];
 
2604
                }
 
2605
                $db->sql_freeresult($result);
 
2606
 
 
2607
                if (!sizeof($groups))
 
2608
                {
 
2609
                        return;
 
2610
                }
 
2611
 
 
2612
                switch ($db->sql_layer)
 
2613
                {
 
2614
                        case 'mysqli':
 
2615
                        case 'mysql4':
 
2616
                                $sql = 'DELETE ' . (($db->sql_layer === 'mysqli' || version_compare($db->mysql_version, '4.1', '>=')) ? 'z.*' : ZEBRA_TABLE) . '
 
2617
                                        FROM ' . ZEBRA_TABLE . ' z, ' . USER_GROUP_TABLE . ' ug
 
2618
                                        WHERE z.zebra_id = ug.user_id
 
2619
                                                AND z.foe = 1
 
2620
                                                AND ' . $db->sql_in_set('ug.group_id', $groups);
 
2621
                                $db->sql_query($sql);
 
2622
                        break;
 
2623
 
 
2624
                        default:
 
2625
                                $sql = 'SELECT user_id
 
2626
                                        FROM ' . USER_GROUP_TABLE . '
 
2627
                                        WHERE ' . $db->sql_in_set('group_id', $groups);
 
2628
                                $result = $db->sql_query($sql);
 
2629
 
 
2630
                                $users = array();
 
2631
                                while ($row = $db->sql_fetchrow($result))
 
2632
                                {
 
2633
                                        $users[] = (int) $row['user_id'];
 
2634
                                }
 
2635
                                $db->sql_freeresult($result);
 
2636
 
 
2637
                                if (sizeof($users))
 
2638
                                {                               
 
2639
                                        $sql = 'DELETE FROM ' . ZEBRA_TABLE . '
 
2640
                                                WHERE ' . $db->sql_in_set('zebra_id', $users) . '
 
2641
                                                        AND foe = 1';
 
2642
                                        $db->sql_query($sql);
 
2643
                                }
 
2644
                        break;
 
2645
                }
 
2646
 
 
2647
                return;
 
2648
        }
 
2649
 
 
2650
        // update foes for everyone
 
2651
        $perms = array();
 
2652
        foreach ($auth->acl_get_list(false, array('a_', 'm_'), false) as $forum_id => $forum_ary)
 
2653
        {
 
2654
                foreach ($forum_ary as $auth_option => $user_ary)
 
2655
                {
 
2656
                        $perms = array_merge($perms, $user_ary);
 
2657
                }
 
2658
        }
 
2659
 
 
2660
        if (sizeof($perms))
 
2661
        {
 
2662
                $sql = 'DELETE FROM ' . ZEBRA_TABLE . '
 
2663
                        WHERE ' . $db->sql_in_set('zebra_id', array_unique($perms)) . '
 
2664
                                AND foe = 1';
 
2665
                $db->sql_query($sql);
 
2666
        }
 
2667
        unset($perms);
 
2668
}
 
2669
 
 
2670
/**
 
2671
* Lists inactive users
 
2672
*/
 
2673
function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_inactive_time DESC')
 
2674
{
 
2675
        global $db, $user;
 
2676
 
 
2677
        $sql = 'SELECT COUNT(user_id) AS user_count
 
2678
                FROM ' . USERS_TABLE . '
 
2679
                WHERE user_type = ' . USER_INACTIVE .
 
2680
                (($limit_days) ? " AND user_inactive_time >= $limit_days" : '');
 
2681
        $result = $db->sql_query($sql);
 
2682
        $user_count = (int) $db->sql_fetchfield('user_count');
 
2683
        $db->sql_freeresult($result);
 
2684
 
 
2685
        if ($offset >= $user_count)
 
2686
        {
 
2687
                $offset = ($offset - $limit < 0) ? 0 : $offset - $limit;
 
2688
        }
 
2689
 
 
2690
        $sql = 'SELECT user_id, username, user_regdate, user_lastvisit, user_inactive_time, user_inactive_reason
 
2691
                FROM ' . USERS_TABLE . '
 
2692
                WHERE user_type = ' . USER_INACTIVE .
 
2693
                (($limit_days) ? " AND user_inactive_time >= $limit_days" : '') . "
 
2694
                ORDER BY $sort_by";
 
2695
        $result = $db->sql_query_limit($sql, $limit, $offset);
 
2696
 
 
2697
        while ($row = $db->sql_fetchrow($result))
 
2698
        {
 
2699
                $row['inactive_reason'] = $user->lang['INACTIVE_REASON_UNKNOWN'];
 
2700
                switch ($row['user_inactive_reason'])
 
2701
                {
 
2702
                        case INACTIVE_REGISTER:
 
2703
                                $row['inactive_reason'] = $user->lang['INACTIVE_REASON_REGISTER'];
 
2704
                        break;
 
2705
 
 
2706
                        case INACTIVE_PROFILE:
 
2707
                                $row['inactive_reason'] = $user->lang['INACTIVE_REASON_PROFILE'];
 
2708
                        break;
 
2709
 
 
2710
                        case INACTIVE_MANUAL:
 
2711
                                $row['inactive_reason'] = $user->lang['INACTIVE_REASON_MANUAL'];
 
2712
                        break;
 
2713
 
 
2714
                        case INACTIVE_REMIND:
 
2715
                                $row['inactive_reason'] = $user->lang['INACTIVE_REASON_REMIND'];
 
2716
                        break;
 
2717
                }
 
2718
        
 
2719
                $users[] = $row;
 
2720
        }
 
2721
 
 
2722
        return $offset;
 
2723
}
 
2724
 
 
2725
/**
 
2726
* Lists warned users
 
2727
*/
 
2728
function view_warned_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_warnings DESC')
 
2729
{
 
2730
        global $db;
 
2731
 
 
2732
        $sql = 'SELECT user_id, username, user_colour, user_warnings, user_last_warning
 
2733
                FROM ' . USERS_TABLE . '
 
2734
                WHERE user_warnings > 0
 
2735
                ' . (($limit_days) ? "AND user_last_warning >= $limit_days" : '') . "
 
2736
                ORDER BY $sort_by";
 
2737
        $result = $db->sql_query_limit($sql, $limit, $offset);
 
2738
        $users = $db->sql_fetchrowset($result);
 
2739
        $db->sql_freeresult($result);
 
2740
 
 
2741
        $sql = 'SELECT count(user_id) AS user_count
 
2742
                FROM ' . USERS_TABLE . '
 
2743
                WHERE user_warnings > 0
 
2744
                ' . (($limit_days) ? "AND user_last_warning >= $limit_days" : '');
 
2745
        $result = $db->sql_query($sql);
 
2746
        $user_count = (int) $db->sql_fetchfield('user_count');
 
2747
        $db->sql_freeresult($result);
 
2748
 
 
2749
        return;
 
2750
}
 
2751
 
 
2752
/**
 
2753
* Get database size
 
2754
* Currently only mysql and mssql are supported
 
2755
*/
 
2756
function get_database_size()
 
2757
{
 
2758
        global $db, $user, $table_prefix;
 
2759
 
 
2760
        $database_size = false;
 
2761
 
 
2762
        // This code is heavily influenced by a similar routine in phpMyAdmin 2.2.0
 
2763
        switch ($db->sql_layer)
 
2764
        {
 
2765
                case 'mysql':
 
2766
                case 'mysql4':
 
2767
                case 'mysqli':
 
2768
                        $sql = 'SELECT VERSION() AS mysql_version';
 
2769
                        $result = $db->sql_query($sql);
 
2770
                        $row = $db->sql_fetchrow($result);
 
2771
                        $db->sql_freeresult($result);
 
2772
 
 
2773
                        if ($row)
 
2774
                        {
 
2775
                                $version = $row['mysql_version'];
 
2776
 
 
2777
                                if (preg_match('#(3\.23|[45]\.)#', $version))
 
2778
                                {
 
2779
                                        $db_name = (preg_match('#^(?:3\.23\.(?:[6-9]|[1-9]{2}))|[45]\.#', $version)) ? "`{$db->dbname}`" : $db->dbname;
 
2780
 
 
2781
                                        $sql = 'SHOW TABLE STATUS
 
2782
                                                FROM ' . $db_name;
 
2783
                                        $result = $db->sql_query($sql, 7200);
 
2784
 
 
2785
                                        $database_size = 0;
 
2786
                                        while ($row = $db->sql_fetchrow($result))
 
2787
                                        {
 
2788
                                                if ((isset($row['Type']) && $row['Type'] != 'MRG_MyISAM') || (isset($row['Engine']) && ($row['Engine'] == 'MyISAM' || $row['Engine'] == 'InnoDB')))
 
2789
                                                {
 
2790
                                                        if ($table_prefix != '')
 
2791
                                                        {
 
2792
                                                                if (strpos($row['Name'], $table_prefix) !== false)
 
2793
                                                                {
 
2794
                                                                        $database_size += $row['Data_length'] + $row['Index_length'];
 
2795
                                                                }
 
2796
                                                        }
 
2797
                                                        else
 
2798
                                                        {
 
2799
                                                                $database_size += $row['Data_length'] + $row['Index_length'];
 
2800
                                                        }
 
2801
                                                }
 
2802
                                        }
 
2803
                                        $db->sql_freeresult($result);
 
2804
                                }
 
2805
                        }
 
2806
                break;
 
2807
 
 
2808
                case 'firebird':
 
2809
                        global $dbname;
 
2810
 
 
2811
                        // if it on the local machine, we can get lucky
 
2812
                        if (file_exists($dbname))
 
2813
                        {
 
2814
                                $database_size = filesize($dbname);
 
2815
                        }
 
2816
 
 
2817
                break;
 
2818
 
 
2819
                case 'sqlite':
 
2820
                        global $dbhost;
 
2821
 
 
2822
                        if (file_exists($dbhost))
 
2823
                        {
 
2824
                                $database_size = filesize($dbhost);
 
2825
                        }
 
2826
 
 
2827
                break;
 
2828
 
 
2829
                case 'mssql':
 
2830
                case 'mssql_odbc':
 
2831
                        $sql = 'SELECT ((SUM(size) * 8.0) * 1024.0) as dbsize
 
2832
                                FROM sysfiles';
 
2833
                        $result = $db->sql_query($sql, 7200);
 
2834
                        $database_size = ($row = $db->sql_fetchrow($result)) ? $row['dbsize'] : false;
 
2835
                        $db->sql_freeresult($result);
 
2836
                break;
 
2837
 
 
2838
                case 'postgres':
 
2839
                        $sql = "SELECT proname
 
2840
                                FROM pg_proc
 
2841
                                WHERE proname = 'pg_database_size'";
 
2842
                        $result = $db->sql_query($sql);
 
2843
                        $row = $db->sql_fetchrow($result);
 
2844
                        $db->sql_freeresult($result);
 
2845
 
 
2846
                        if ($row['proname'] == 'pg_database_size')
 
2847
                        {
 
2848
                                $database = $db->dbname;
 
2849
                                if (strpos($database, '.') !== false)
 
2850
                                {
 
2851
                                        list($database, ) = explode('.', $database);
 
2852
                                }
 
2853
 
 
2854
                                $sql = "SELECT oid
 
2855
                                        FROM pg_database
 
2856
                                        WHERE datname = '$database'";
 
2857
                                $result = $db->sql_query($sql);
 
2858
                                $row = $db->sql_fetchrow($result);
 
2859
                                $db->sql_freeresult($result);
 
2860
 
 
2861
                                $oid = $row['oid'];
 
2862
 
 
2863
                                $sql = 'SELECT pg_database_size(' . $oid . ') as size';
 
2864
                                $result = $db->sql_query($sql);
 
2865
                                $row = $db->sql_fetchrow($result);
 
2866
                                $db->sql_freeresult($result);
 
2867
 
 
2868
                                $database_size = $row['size'];
 
2869
                        }
 
2870
                break;
 
2871
 
 
2872
                case 'oracle':
 
2873
                        $sql = 'SELECT SUM(bytes) as dbsize
 
2874
                                FROM user_segments';
 
2875
                        $result = $db->sql_query($sql, 7200);
 
2876
                        $database_size = ($row = $db->sql_fetchrow($result)) ? $row['dbsize'] : false;
 
2877
                        $db->sql_freeresult($result);
 
2878
                break;
 
2879
        }
 
2880
 
 
2881
        if ($database_size !== false)
 
2882
        {
 
2883
                $database_size = ($database_size >= 1048576) ? sprintf('%.2f ' . $user->lang['MB'], ($database_size / 1048576)) : (($database_size >= 1024) ? sprintf('%.2f ' . $user->lang['KB'], ($database_size / 1024)) : sprintf('%.2f ' . $user->lang['BYTES'], $database_size));
 
2884
        }
 
2885
        else
 
2886
        {
 
2887
                $database_size = $user->lang['NOT_AVAILABLE'];
 
2888
        }
 
2889
 
 
2890
        return $database_size;
 
2891
}
 
2892
 
 
2893
/**
 
2894
* Retrieve contents from remotely stored file
 
2895
*/
 
2896
function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 10)
 
2897
{
 
2898
        global $user;
 
2899
 
 
2900
        if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout))
 
2901
        {
 
2902
                @fputs($fsock, "GET $directory/$filename HTTP/1.1\r\n");
 
2903
                @fputs($fsock, "HOST: $host\r\n");
 
2904
                @fputs($fsock, "Connection: close\r\n\r\n");
 
2905
        
 
2906
                $file_info = '';
 
2907
                $get_info = false;
 
2908
 
 
2909
                while (!@feof($fsock))
 
2910
                {
 
2911
                        if ($get_info)
 
2912
                        {
 
2913
                                $file_info .= @fread($fsock, 1024);
 
2914
                        }
 
2915
                        else
 
2916
                        {
 
2917
                                $line = @fgets($fsock, 1024);
 
2918
                                if ($line == "\r\n")
 
2919
                                {
 
2920
                                        $get_info = true;
 
2921
                                }
 
2922
                                else if (stripos($line, '404 not found') !== false)
 
2923
                                {
 
2924
                                        $errstr = $user->lang['FILE_NOT_FOUND'] . ': ' . $filename;
 
2925
                                        return false;
 
2926
                                }
 
2927
                        }
 
2928
                }
 
2929
                @fclose($fsock);
 
2930
        }
 
2931
        else
 
2932
        {
 
2933
                if ($errstr)
 
2934
                {
 
2935
                        $errstr = utf8_convert_message($errstr);
 
2936
                        return false;
 
2937
                }
 
2938
                else
 
2939
                {
 
2940
                        $errstr = $user->lang['FSOCK_DISABLED'];
 
2941
                        return false;
 
2942
                }
 
2943
        }
 
2944
        
 
2945
        return $file_info;
 
2946
}
 
2947
 
 
2948
/**
 
2949
* Tidy Warnings
 
2950
* Remove all warnings which have now expired from the database
 
2951
* The duration of a warning can be defined by the administrator
 
2952
* This only removes the warning and reduces the associated count,
 
2953
* it does not remove the user note recording the contents of the warning
 
2954
*/
 
2955
function tidy_warnings()
 
2956
{
 
2957
        global $db, $config;
 
2958
 
 
2959
        $expire_date = time() - ($config['warnings_expire_days'] * 86400);
 
2960
        $warning_list = $user_list = array();
 
2961
 
 
2962
        $sql = 'SELECT * FROM ' . WARNINGS_TABLE . "
 
2963
                WHERE warning_time < $expire_date";
 
2964
        $result = $db->sql_query($sql);
 
2965
 
 
2966
        while ($row = $db->sql_fetchrow($result))
 
2967
        {
 
2968
                $warning_list[] = $row['warning_id'];
 
2969
                $user_list[$row['user_id']] = isset($user_list[$row['user_id']]) ? ++$user_list[$row['user_id']] : 1;
 
2970
        }
 
2971
        $db->sql_freeresult($result);
 
2972
 
 
2973
        if (sizeof($warning_list))
 
2974
        {
 
2975
                $db->sql_transaction('begin');
 
2976
 
 
2977
                $sql = 'DELETE FROM ' . WARNINGS_TABLE . '
 
2978
                        WHERE ' . $db->sql_in_set('warning_id', $warning_list);
 
2979
                $db->sql_query($sql);
 
2980
        
 
2981
                foreach ($user_list as $user_id => $value)
 
2982
                {
 
2983
                        $sql = 'UPDATE ' . USERS_TABLE . " SET user_warnings = user_warnings - $value
 
2984
                                WHERE user_id = $user_id";
 
2985
                        $db->sql_query($sql);
 
2986
                }
 
2987
 
 
2988
                $db->sql_transaction('commit');
 
2989
        }
 
2990
 
 
2991
        set_config('warnings_last_gc', time(), true);
 
2992
}
 
2993
 
 
2994
/**
 
2995
* Tidy database, doing some maintanance tasks
 
2996
*/
 
2997
function tidy_database()
 
2998
{
 
2999
        global $db;
 
3000
 
 
3001
        set_config('database_last_gc', time(), true);
 
3002
}
 
3003
 
 
3004
/**
 
3005
* Add permission language - this will make sure custom files will be included
 
3006
*/
 
3007
function add_permission_language()
 
3008
{
 
3009
        global $user, $phpEx;
 
3010
 
 
3011
        // First of all, our own file. We need to include it as the first file because it presets all relevant variables.
 
3012
        $user->add_lang('acp/permissions_phpbb');
 
3013
 
 
3014
        $files_to_add = array();
 
3015
 
 
3016
        // Now search in acp and mods folder for permissions_ files.
 
3017
        foreach (array('acp/', 'mods/') as $path)
 
3018
        {
 
3019
                $dh = @opendir($user->lang_path . $path);
 
3020
 
 
3021
                if ($dh)
 
3022
                {
 
3023
                        while (($file = readdir($dh)) !== false)
 
3024
                        {
 
3025
                                if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx)
 
3026
                                {
 
3027
                                        $files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1));
 
3028
                                }
 
3029
                        }
 
3030
                        closedir($dh);
 
3031
                }
 
3032
        }
 
3033
 
 
3034
        if (!sizeof($files_to_add))
 
3035
        {
 
3036
                return false;
 
3037
        }
 
3038
 
 
3039
        $user->add_lang($files_to_add);
 
3040
        return true;
 
3041
}
 
3042
 
 
3043
?>
 
 
b'\\ No newline at end of file'