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

« back to all changes in this revision

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

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

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'