Subversion Repositories Applications.papyrus

Rev

Rev 1087 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
831 florian 1
<?php
2
 
3
////////////////////////////////////////////////////////////////////////////////
4
//                                                                            //
5
//   Copyright (C) 2006  Phorum Development Team                              //
6
//   http://www.phorum.org                                                    //
7
//                                                                            //
8
//   This program is free software. You can redistribute it and/or modify     //
9
//   it under the terms of either the current Phorum License (viewable at     //
10
//   phorum.org) or the Phorum License that was distributed with this file    //
11
//                                                                            //
12
//   This program is distributed in the hope that it will be useful,          //
13
//   but WITHOUT ANY WARRANTY, without even the implied warranty of           //
14
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     //
15
//                                                                            //
16
//   You should have received a copy of the Phorum License                    //
17
//   along with this program.                                                 //
18
////////////////////////////////////////////////////////////////////////////////
19
 
20
// cvs-info: $Id$
21
 
22
if (!defined("PHORUM")) return;
23
 
24
/**
25
 * The other Phorum code does not care how the messages are stored.
26
 *    The only requirement is that they are returned from these functions
27
 *    in the right way.  This means each database can use as many or as
28
 *    few tables as it likes.  It can store the fields anyway it wants.
29
 *    The only thing to worry about is the table_prefix for the tables.
30
 *    all tables for a Phorum install should be prefixed with the
31
 *    table_prefix that will be entered in include/db/config.php.  This
32
 *    will allow multiple Phorum installations to use the same database.
33
 */
34
 
35
/**
36
 * These are the table names used for this database system.
37
 */
38
 
39
// tables needed to be "partitioned"
40
$PHORUM["message_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_messages";
41
$PHORUM["user_newflags_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_newflags";
42
$PHORUM["subscribers_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_subscribers";
43
$PHORUM["files_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_files";
44
$PHORUM["search_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_search";
45
 
46
// tables common to all "partitions"
47
$PHORUM["settings_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_settings";
48
$PHORUM["forums_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_forums";
49
$PHORUM["user_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_users";
50
$PHORUM["user_permissions_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_permissions";
51
$PHORUM["groups_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_groups";
52
$PHORUM["forum_group_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_forum_group_xref";
53
$PHORUM["user_group_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_group_xref";
54
$PHORUM['user_custom_fields_table'] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_custom_fields";
55
$PHORUM["banlist_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_banlists";
56
$PHORUM["pm_messages_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_messages";
57
$PHORUM["pm_folders_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_folders";
58
$PHORUM["pm_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_xref";
59
$PHORUM["pm_buddies_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_buddies";
60
/*
61
* fields which are always strings, even if they contain only numbers
62
* used in post-message and update-message, otherwise strange things happen
63
*/
64
$PHORUM['string_fields']= array('author', 'subject', 'body', 'email');
65
 
66
/* A piece of SQL code that can be used for identifying moved messages. */
67
define('PHORUM_SQL_MOVEDMESSAGES', '(parent_id = 0 and thread != message_id)');
68
 
69
/**
70
 * This function executes a query to select the visible messages from
71
 * the database for a given page offset. The main Phorum code handles
72
 * actually sorting the threads into a threaded list if needed.
73
 *
74
 * By default, the message body is not included in the fetch queries.
75
 * If the body is needed in the thread list, $PHORUM['TMP']['bodies_in_list']
76
 * must be set to "1" (for example using setting.tpl).
77
 *
78
 * NOTE: ALL dates should be returned as Unix timestamps
79
 *
80
 * @param offset - the index of the page to return, starting with 0
81
 * @param messages - an array containing forum messages
82
 */
83
 
84
function phorum_db_get_thread_list($offset)
85
{
86
    $PHORUM = $GLOBALS["PHORUM"];
87
 
88
    settype($offset, "int");
89
 
90
    $conn = phorum_db_mysql_connect();
91
 
92
    $table = $PHORUM["message_table"];
93
 
94
    // The messagefields that we want to fetch from the database.
95
    $messagefields =
96
       "$table.author,
97
        $table.datestamp,
98
        $table.email,
99
        $table.message_id,
100
        $table.meta,
101
        $table.moderator_post,
102
        $table.modifystamp,
103
        $table.parent_id,
104
        $table.sort,
105
        $table.status,
106
        $table.subject,
107
        $table.thread,
108
        $table.thread_count,
109
        $table.user_id,
110
        $table.viewcount,
111
        $table.closed";
112
    if(isset($PHORUM['TMP']['bodies_in_list']) && $PHORUM['TMP']['bodies_in_list'] == 1) {
113
        $messagefields .= "\n,$table.body\n,$table.ip";
114
    }
115
 
116
    // The sort mechanism to use.
117
    if($PHORUM["float_to_top"]){
118
            $sortfield = "modifystamp";
119
            $index = "list_page_float";
120
    } else{
121
            $sortfield = "thread";
122
            $index = "list_page_flat";
123
    }
124
 
125
    // Initialize the return array.
126
    $messages = array();
127
 
128
    // The groups of messages we want to fetch from the database.
129
    $groups = array();
130
    if ($offset == 0) $groups[] = "specials";
131
    $groups[] = "threads";
132
    if ($PHORUM["threaded_list"]) $groups[] = "replies";
133
 
134
    // for remembering message ids for which we want to fetch the replies.
135
    $replymsgids = array();
136
 
137
    // Process all groups.
138
    foreach ($groups as $group) {
139
 
140
 
141
        $sql = NULL;
142
 
143
        switch ($group) {
144
 
145
            // Announcements and stickies.
146
            case "specials":
147
 
148
                $sql = "select $messagefields
149
                       from $table
150
                       where
151
                         status=".PHORUM_STATUS_APPROVED." and
152
                         ((parent_id=0 and sort=".PHORUM_SORT_ANNOUNCEMENT."
153
                           and forum_id={$PHORUM['vroot']})
154
                         or
155
                         (parent_id=0 and sort=".PHORUM_SORT_STICKY."
156
                          and forum_id={$PHORUM['forum_id']}))
157
                       order by
158
                         sort, $sortfield desc";
159
                break;
160
 
161
            // Threads.
162
            case "threads":
163
 
164
                if ($PHORUM["threaded_list"]) {
165
                    $limit = $PHORUM['list_length_threaded'];
166
                    $extrasql = '';
167
                } else {
168
                    $limit = $PHORUM['list_length_flat'];
169
                }
170
                $start = $offset * $limit;
171
 
172
                $sql = "select $messagefields
173
                        from $table use index ($index)
174
                        where
175
                          $sortfield > 0 and
176
                          forum_id = {$PHORUM["forum_id"]} and
177
                          status = ".PHORUM_STATUS_APPROVED." and
178
                          parent_id = 0 and
179
                          sort > 1
180
                        order by
181
                          $sortfield desc
182
                        limit $start, $limit";
183
                break;
184
 
185
            // Reply messages.
186
            case "replies":
187
 
188
                // We're done if we did not collect any messages with replies.
189
                if (! count($replymsgids)) break;
190
 
191
                $sortorder = "sort, $sortfield desc, message_id";
192
                if(isset($PHORUM["reverse_threading"]) && $PHORUM["reverse_threading"])
193
                    $sortorder.=" desc";
194
 
195
                $sql = "select $messagefields
196
                        from $table
197
                        where
198
                          status = ".PHORUM_STATUS_APPROVED." and
199
                          thread in (" . implode(",",$replymsgids) .")
200
                        order by $sortorder";
201
                break;
202
 
203
        } // End of switch ($group)
204
 
205
        // Continue with the next group if no SQL query was formulated.
206
        if (is_null($sql)) continue;
207
 
208
        // Fetch the messages for the current group.
209
        $res = mysql_query($sql, $conn);
210
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
211
        $rows = mysql_num_rows($res);
212
        if($rows > 0){
213
            while ($rec = mysql_fetch_assoc($res)){
214
                $messages[$rec["message_id"]] = $rec;
215
                $messages[$rec["message_id"]]["meta"] = array();
216
                if(!empty($rec["meta"])){
217
                    $messages[$rec["message_id"]]["meta"] = unserialize($rec["meta"]);
218
                }
219
 
220
                // We need the message ids for fetching reply messages.
221
                if ($group == 'threads' && $rec["thread_count"] > 1) {
222
                    $replymsgids[] = $rec["message_id"];
223
                }
224
            }
225
        }
226
    }
227
 
228
    return $messages;
229
}
230
 
231
/**
232
 * This function executes a query to get the recent messages for
233
 * all forums the user can read, a particular forum, or a particular
234
 * thread, and and returns an array of the messages order by message_id.
235
 * You can optionally retrieve only new threads.
236
 *
237
 * The original version of this function came from Jim Winstead of mysql.com
238
 */
239
function phorum_db_get_recent_messages($count, $forum_id = 0, $thread = 0, $threads_only = 0)
240
{
241
    $PHORUM = $GLOBALS["PHORUM"];
242
    settype($count, "int");
243
    settype($thread, "int");
244
    $arr = array();
245
    $allowed_forums = array();
246
 
247
    $conn = phorum_db_mysql_connect();
248
 
249
    // we need to differentiate on which key to use
250
    if($thread) {
251
        $use_key='thread_message';
252
    } else {
253
        $use_key='forum_max_message';
254
    }
255
 
256
    $sql = "SELECT {$PHORUM['message_table']}.* FROM {$PHORUM['message_table']} USE KEY($use_key) WHERE status=".PHORUM_STATUS_APPROVED;
257
 
258
    // have to check what forums they can read first.
259
    // even if $thread is passed, we have to make sure
260
    // the user can read the forum
261
    if($forum_id <= 0) {
262
        $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
263
 
264
        // if they are not allowed to see any forums, return the emtpy $arr;
265
        if(empty($allowed_forums))
266
            return $arr;
267
    } elseif(is_array($forum_id)) {
268
        // for an array, check each one and return if none are allowed
269
        foreach($forum_id as $id){
270
            if(phorum_user_access_allowed(PHORUM_USER_ALLOW_READ,$id)) {
271
                $allowed_forums[]=$id;
272
            }
273
        }
274
 
275
        // if they are not allowed to see any forums, return the emtpy $arr;
276
        if(empty($allowed_forums))
277
            return $arr;
278
    } else {
279
        // only single forum, *much* fast this way
280
        if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_READ,$forum_id)) {
281
            return $arr;
282
        }
283
        settype($forum_id, "int");
284
    }
285
 
286
    if(count($allowed_forums)){
287
        $sql.=" and forum_id in (".implode(",", $allowed_forums).")";
288
    } else {
289
        $sql.=" and forum_id=$forum_id";
290
    }
291
 
292
    if($thread){
293
        $sql.=" and thread=$thread";
294
    }
295
 
296
    if($threads_only) {
297
        $sql.= " and parent_id = 0";
298
        $sql.= " ORDER BY thread DESC";
299
    } else {
300
        $sql.= " ORDER BY message_id DESC";
301
    }
302
 
303
    if($count){
304
        $sql.= " LIMIT $count";
305
    }
306
 
307
    $res = mysql_query($sql, $conn);
308
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
309
 
310
    while ($rec = mysql_fetch_assoc($res)){
311
        $arr[$rec["message_id"]] = $rec;
312
 
313
        // convert meta field
314
        if(empty($rec["meta"])){
315
            $arr[$rec["message_id"]]["meta"]=array();
316
        } else {
317
            $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
318
        }
319
        if(empty($arr['users'])) $arr['users']=array();
320
        if($rec["user_id"]){
321
            $arr['users'][]=$rec["user_id"];
322
        }
323
 
324
    }
325
 
326
    return $arr;
327
}
328
 
329
 
330
/**
331
 * This function executes a query to select messages from the database
332
 * and returns an array.  The main Phorum code handles actually sorting
333
 * the threads into a threaded list if needed.
334
 *
335
 * NOTE: ALL dates should be returned as Unix timestamps
336
 * @param forum - the forum id to work with. Omit or NULL for all forums.
337
 *                You can also pass an array of forum_id's.
338
 * @param waiting_only - only take into account messages which have to
339
 *                be approved directly after posting. Do not include
340
 *                messages which are hidden by a moderator.
341
 */
342
 
343
function phorum_db_get_unapproved_list($forum = NULL, $waiting_only=false,$moddays=0)
344
{
345
    $PHORUM = $GLOBALS["PHORUM"];
346
 
347
    $conn = phorum_db_mysql_connect();
348
 
349
    $table = $PHORUM["message_table"];
350
 
351
    $arr = array();
352
 
353
    $sql = "select
354
            $table.*
355
          from
356
            $table ";
357
 
358
    if (is_array($forum)){
359
        $sql .= "where forum_id in (" . implode(",", $forum) . ") and ";
360
    } elseif (! is_null($forum)){
361
        settype($forum, "int");
362
        $sql .= "where forum_id = $forum and ";
363
    } else {
364
        $sql .= "where ";
365
    }
366
 
367
    if($moddays > 0) {
368
        $checktime=time()-(86400*$moddays);
369
        $sql .=" datestamp > $checktime AND";
370
    }
371
 
372
    if($waiting_only){
373
        $sql.=" status=".PHORUM_STATUS_HOLD;
374
    } else {
375
        $sql="($sql status=".PHORUM_STATUS_HOLD.") " .
376
             "union ($sql status=".PHORUM_STATUS_HIDDEN.")";
377
    }
378
 
379
 
380
    $sql .=" order by thread, message_id";
381
 
382
    $res = mysql_query($sql, $conn);
383
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
384
 
385
    while ($rec = mysql_fetch_assoc($res)){
386
        $arr[$rec["message_id"]] = $rec;
387
        $arr[$rec["message_id"]]["meta"] = array();
388
        if(!empty($rec["meta"])){
389
            $arr[$rec["message_id"]]["meta"] = unserialize($rec["meta"]);
390
        }
391
    }
392
 
393
    return $arr;
394
}
395
 
396
 
397
/**
398
 * This function posts a message to the tables.
399
 * The message is passed by reference and message_id and thread are filled
400
 */
401
 
402
function phorum_db_post_message(&$message,$convert=false){
403
    $PHORUM = $GLOBALS["PHORUM"];
404
    $table = $PHORUM["message_table"];
405
 
406
    $conn = phorum_db_mysql_connect();
407
 
408
    $success = false;
409
 
410
    foreach($message as $key => $value){
411
        if (is_numeric($value) && !in_array($key,$PHORUM['string_fields'])){
412
            $message[$key] = (int)$value;
413
        } elseif(is_array($value)) {
414
            $message[$key] = mysql_escape_string(serialize($value));
415
        } else{
416
            $message[$key] = mysql_escape_string($value);
417
        }
418
    }
419
 
420
    if(!$convert) {
421
        $NOW = time();
422
    } else {
423
        $NOW = $message['datestamp'];
424
    }
425
 
426
    // duplicate-check
427
    if(isset($PHORUM['check_duplicate']) && $PHORUM['check_duplicate'] && !$convert) {
428
        // we check for dupes in that number of minutes
429
        $check_minutes=60;
430
        $check_timestamp =$NOW - ($check_minutes*60);
431
        // check_query
432
        $chk_query="SELECT message_id FROM $table WHERE forum_id = {$message['forum_id']} AND author='{$message['author']}' AND subject='{$message['subject']}' AND body='{$message['body']}' AND datestamp > $check_timestamp";
433
        $res = mysql_query($chk_query, $conn);
434
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $chk_query");
435
        if(mysql_num_rows($res))
436
            return 0;
437
    }
438
 
439
    if(isset($message['meta'])){
440
        $metaval=",meta='{$message['meta']}'";
441
    } else {
442
        $metaval="";
443
    }
444
 
445
    $sql = "Insert into $table set
446
            forum_id = {$message['forum_id']},
447
            datestamp=$NOW,
448
            thread={$message['thread']},
449
            parent_id={$message['parent_id']},
450
            author='{$message['author']}',
451
            subject='{$message['subject']}',
452
            email='{$message['email']}',
453
            ip='{$message['ip']}',
454
            user_id={$message['user_id']},
455
            moderator_post={$message['moderator_post']},
456
            status={$message['status']},
457
            sort={$message['sort']},
458
            msgid='{$message['msgid']}',
459
            body='{$message['body']}',
460
            closed={$message['closed']}
461
            $metaval";
462
 
463
    // if in conversion we need the message-id too
464
    if($convert && isset($message['message_id'])) {
465
        $sql.=",message_id=".$message['message_id'];
466
    }
467
 
468
    if(isset($message['modifystamp'])) {
469
        $sql.=",modifystamp=".$message['modifystamp'];
470
    }
471
 
472
    if(isset($message['viewcount'])) {
473
        $sql.=",viewcount=".$message['viewcount'];
474
    }
475
 
476
 
477
    $res = mysql_query($sql, $conn);
478
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
479
 
480
    if ($res){
481
        $message["message_id"] = mysql_insert_id($conn);
482
 
483
        if(!empty($message["message_id"])){
484
 
485
            $message["datestamp"]=$NOW;
486
 
487
            if ($message["thread"] == 0){
488
                $message["thread"] = $message["message_id"];
489
                $sql = "update $table set thread={$message['message_id']} where message_id={$message['message_id']}";
490
                $res = mysql_query($sql, $conn);
491
                if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
492
            }
493
 
494
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
495
 
496
            // start ft-search stuff
497
            $search_text="$message[author] | $message[subject] | $message[body]";
498
 
499
            $sql="insert delayed into {$PHORUM['search_table']} set message_id={$message['message_id']}, forum_id={$message['forum_id']}, search_text='$search_text'";
500
            $res = mysql_query($sql, $conn);
501
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
502
 
503
            // end ft-search stuff
504
 
505
            $success = true;
506
            // some data for later use, i.e. email-notification
507
            $GLOBALS['PHORUM']['post_returns']['message_id']=$message["message_id"];
508
            $GLOBALS['PHORUM']['post_returns']['thread_id']=$message["thread"];
509
        }
510
    }
511
 
512
    return $success;
513
}
514
 
515
/**
516
 * This function deletes messages from the messages table.
517
 *
518
 * @param message $ _id the id of the message which should be deleted
519
 * mode the mode of deletion, PHORUM_DELETE_MESSAGE for reconnecting the children, PHORUM_DELETE_TREE for deleting the children
520
 */
521
 
522
function phorum_db_delete_message($message_id, $mode = PHORUM_DELETE_MESSAGE)
523
{
524
    $PHORUM = $GLOBALS["PHORUM"];
525
 
526
    $conn = phorum_db_mysql_connect();
527
 
528
    settype($message_id, "int");
529
 
530
    $threadset = 0;
531
    // get the parents of the message to delete.
532
    $sql = "select forum_id, message_id, thread, parent_id from {$PHORUM['message_table']} where message_id = $message_id ";
533
    $res = mysql_query($sql, $conn);
534
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
535
 
536
    $rec = mysql_fetch_assoc($res);
537
 
538
    if($mode == PHORUM_DELETE_TREE){
539
        $mids = phorum_db_get_messagetree($message_id, $rec['forum_id']);
540
    }else{
541
        $mids = $message_id;
542
    }
543
 
544
    // unapprove the messages first so replies will not get posted
545
    $sql = "update {$PHORUM['message_table']} set status=".PHORUM_STATUS_HOLD." where message_id in ($mids)";
546
    $res = mysql_query($sql, $conn);
547
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
548
 
549
    $thread = $rec['thread'];
550
    if($thread == $message_id && $mode == PHORUM_DELETE_TREE){
551
        $threadset = 1;
552
    }else{
553
        $threadset = 0;
554
    }
555
 
556
    if($mode == PHORUM_DELETE_MESSAGE){
557
        $count = 1;
558
        // change the children to point to their parent's parent
559
        // forum_id is in here for speed by using a key only
560
        $sql = "update {$PHORUM['message_table']} set parent_id=$rec[parent_id] where forum_id=$rec[forum_id] and parent_id=$rec[message_id]";
561
        mysql_query($sql, $conn);
562
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
563
    }else{
564
        $count = count(explode(",", $mids));
565
    }
566
 
567
    // delete the messages
568
    $sql = "delete from {$PHORUM['message_table']} where message_id in ($mids)";
569
    mysql_query($sql, $conn);
570
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
571
 
572
    // start ft-search stuff
573
    $sql="delete from {$PHORUM['search_table']} where message_id in ($mids)";
574
    $res = mysql_query($sql, $conn);
575
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
576
    // end ft-search stuff
577
 
578
    // it kind of sucks to have this here, but it is the best way
579
    // to ensure that it gets done if stuff is deleted.
580
    // leave this include here, it needs to be conditional
581
    include_once("./include/thread_info.php");
582
    phorum_update_thread_info($thread);
583
 
584
    // we need to delete the subscriptions for that thread too
585
    $sql = "DELETE FROM {$PHORUM['subscribers_table']} WHERE forum_id > 0 AND thread=$thread";
586
    $res = mysql_query($sql, $conn);
587
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
588
 
589
    // this function will be slow with a lot of messages.
590
    phorum_db_update_forum_stats(true);
591
 
592
    return explode(",", $mids);
593
}
594
 
595
/**
596
 * gets all attached messages to a message
597
 *
598
 * @param id $ id of the message
599
 */
600
function phorum_db_get_messagetree($parent_id, $forum_id){
601
    $PHORUM = $GLOBALS["PHORUM"];
602
 
603
    settype($parent_id, "int");
604
    settype($forum_id, "int");
605
 
606
    $conn = phorum_db_mysql_connect();
607
 
608
    $sql = "Select message_id from {$PHORUM['message_table']} where forum_id=$forum_id and parent_id=$parent_id";
609
 
610
    $res = mysql_query($sql, $conn);
611
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
612
 
613
    $tree = "$parent_id";
614
 
615
    while($rec = mysql_fetch_row($res)){
616
        $tree .= "," . phorum_db_get_messagetree($rec[0],$forum_id);
617
    }
618
 
619
    return $tree;
620
}
621
 
622
/**
623
 * This function updates the message given in the $message array for
624
 * the row with the given message id.  It returns non 0 on success.
625
 */
626
 
627
function phorum_db_update_message($message_id, $message)
628
{
629
    $PHORUM = $GLOBALS["PHORUM"];
630
 
631
    settype($message_id, "int");
632
 
633
    if (count($message) > 0){
634
        $conn = phorum_db_mysql_connect();
635
 
636
        foreach($message as $field => $value){
637
            if (is_numeric($value) && !in_array($field,$PHORUM['string_fields'])){
638
                $fields[] = "$field=$value";
639
            }elseif (is_array($value)){
640
                $value = mysql_escape_string(serialize($value));
641
                $message[$field] = $value;
642
                $fields[] = "$field='$value'";
643
            }else{
644
                $value = mysql_escape_string($value);
645
                $message[$field] = $value;
646
                $fields[] = "$field='$value'";
647
            }
648
        }
649
 
650
        $sql = "update {$PHORUM['message_table']} set " . implode(", ", $fields) . " where message_id=$message_id";
651
        $res = mysql_query($sql, $conn);
652
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
653
 
654
        if($res){
655
            // start ft-search stuff
656
            if(isset($message["author"]) && isset($message["subject"]) && isset($message["body"])){
657
                $search_text="$message[author] | $message[subject] | $message[body]";
658
                $sql="replace delayed into {$PHORUM['search_table']} set message_id={$message_id}, forum_id={$message['forum_id']}, search_text='$search_text'";
659
                $res = mysql_query($sql, $conn);
660
                if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
661
            }
662
            // end ft-search stuff
663
        }
664
 
665
        return ($res > 0) ? true : false;
666
 
667
    }else{
668
        trigger_error("\$message cannot be empty in phorum_update_message()", E_USER_ERROR);
669
    }
670
}
671
 
672
 
673
/**
674
 * This function executes a query to get the row with the given value
675
 * in the given field and returns the message in an array.
676
 */
677
 
678
function phorum_db_get_message($value, $field="message_id", $ignore_forum_id=false)
679
{
680
    $PHORUM = $GLOBALS["PHORUM"];
681
    $field=mysql_escape_string($field);
682
    $multiple=false;
683
 
684
    $conn = phorum_db_mysql_connect();
685
 
686
 
687
    $forum_id_check = "";
688
    if (!$ignore_forum_id && !empty($PHORUM["forum_id"])){
689
        $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
690
    }
691
 
692
    if(is_array($value)) {
693
        $checkvar="$field IN('".implode("','",$value)."')";
694
        $multiple=true;
695
    } else {
696
        $value=mysql_escape_string($value);
697
        $checkvar="$field='$value'";
698
    }
699
 
700
 
701
    $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check $checkvar";
702
    $res = mysql_query($sql, $conn);
703
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
704
 
705
    $ret = $multiple ? array() : NULL;
706
 
707
    if(mysql_num_rows($res)){
708
        if($multiple) {
709
            while($rec=mysql_fetch_assoc($res)) {
710
                // convert meta field
711
                if(empty($rec["meta"])){
712
                    $rec["meta"]=array();
713
                } else {
714
                    $rec["meta"]=unserialize($rec["meta"]);
715
                }
716
                $ret[$rec['message_id']]=$rec;
717
            }
718
        } else {
719
            $rec = mysql_fetch_assoc($res);
720
 
721
            // convert meta field
722
            if(empty($rec["meta"])){
723
                $rec["meta"]=array();
724
            } else {
725
                $rec["meta"]=unserialize($rec["meta"]);
726
            }
727
            $ret=$rec;
728
        }
729
    }
730
 
731
    return $ret;
732
}
733
 
734
/**
735
 * This function executes a query to get the rows with the given thread
736
 * id and returns an array of the message.
737
 */
738
function phorum_db_get_messages($thread,$page=0)
739
{
740
    $PHORUM = $GLOBALS["PHORUM"];
741
 
742
    settype($thread, "int");
743
 
744
    $conn = phorum_db_mysql_connect();
745
 
746
    $forum_id_check = "";
747
    if (!empty($PHORUM["forum_id"])){
748
        $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
749
    }
750
 
751
    // are we really allowed to show this thread/message?
752
    $approvedval = "";
753
    if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
754
        $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
755
    }
756
 
757
    if($page > 0) {
758
           $start=$PHORUM["read_length"]*($page-1);
759
           $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval order by message_id LIMIT $start,".$PHORUM["read_length"];
760
    } else {
761
           $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval order by message_id";
762
           if(isset($PHORUM["reverse_threading"]) && $PHORUM["reverse_threading"]) $sql.=" desc";
763
    }
764
 
765
    $res = mysql_query($sql, $conn);
766
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
767
 
768
    $arr = array();
769
 
770
    while ($rec = mysql_fetch_assoc($res)){
771
        $arr[$rec["message_id"]] = $rec;
772
 
773
        // convert meta field
774
        if(empty($rec["meta"])){
775
            $arr[$rec["message_id"]]["meta"]=array();
776
        } else {
777
            $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
778
        }
779
        if(empty($arr['users'])) $arr['users']=array();
780
        if($rec["user_id"]){
781
            $arr['users'][]=$rec["user_id"];
782
        }
783
 
784
    }
785
 
786
    if(count($arr) && $page != 0) {
787
        // selecting the thread-starter
788
        $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check message_id=$thread $approvedval";
789
        $res = mysql_query($sql, $conn);
790
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
791
        if(mysql_num_rows($res) > 0) {
792
            $rec = mysql_fetch_assoc($res);
793
            $arr[$rec["message_id"]] = $rec;
794
            $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
795
        }
796
    }
797
    return $arr;
798
}
799
 
800
/**
801
 * this function returns the index of a message in a thread
802
 */
803
function phorum_db_get_message_index($thread=0,$message_id=0) {
804
    $PHORUM = $GLOBALS["PHORUM"];
805
 
806
    // check for valid values
807
    if(empty($message_id) || empty($message_id)) {
808
        return 0;
809
    }
810
 
811
    settype($thread, "int");
812
    settype($message_id, "int");
813
 
814
    $approvedval="";
815
    $forum_id_check="";
816
 
817
    $conn = phorum_db_mysql_connect();
818
 
819
    if (!empty($PHORUM["forum_id"])){
820
        $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) AND";
821
    }
822
 
823
    if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
824
        $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
825
    }
826
 
827
    $sql = "select count(*) as msg_index from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval AND message_id <= $message_id order by message_id";
828
 
829
    $res = mysql_query($sql, $conn);
830
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
831
 
832
    $rec = mysql_fetch_assoc($res);
833
 
834
    return $rec['msg_index'];
835
}
836
 
837
/**
838
 * This function searches the database for the supplied search
839
 * criteria and returns an array with two elements.  One is the count
840
 * of total messages that matched, the second is an array of the
841
 * messages from the results based on the $start (0 base) given and
842
 * the $length given.
843
 */
844
 
845
function phorum_db_search($search, $offset, $length, $match_type, $match_date, $match_forum)
846
{
847
    $PHORUM = $GLOBALS["PHORUM"];
848
 
849
    $start = $offset * $PHORUM["list_length"];
850
 
851
    $arr = array("count" => 0, "rows" => array());
852
 
853
    $conn = phorum_db_mysql_connect();
854
 
855
    // have to check what forums they can read first.
856
    $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
857
    // if they are not allowed to search any forums, return the emtpy $arr;
858
    if(empty($allowed_forums) || ($PHORUM['forum_id']>0 && !in_array($PHORUM['forum_id'], $allowed_forums)) ) return $arr;
859
 
860
    // Add forum 0 (for announcements) to the allowed forums.
861
    $allowed_forums[] = 0;
862
 
863
    if($PHORUM['forum_id']!=0 && $match_forum!="ALL"){
864
        $forum_where=" and forum_id={$PHORUM['forum_id']}";
865
    } else {
866
        $forum_where=" and forum_id in (".implode(",", $allowed_forums).")";
867
    }
868
 
869
    if($match_type=="AUTHOR"){
870
 
871
        $id_table=$PHORUM['search_table']."_auth_".md5(microtime());
872
 
873
        $search=mysql_escape_string($search);
874
 
875
        $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['message_table']} where author='$search' $forum_where";
876
        if($match_date>0){
877
            $ts=time()-86400*$match_date;
878
            $sql.=" and datestamp>=$ts";
879
        }
880
 
881
        $res = mysql_query($sql, $conn);
882
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
883
 
884
    } else {
885
 
886
        if($match_type=="PHRASE"){
887
            $terms = array('"'.$search.'"');
888
        } else {
889
            $quote_terms=array();
890
            if ( strstr( $search, '"' ) ){
891
                //first pull out all the double quoted strings (e.g. '"iMac DV" or -"iMac DV"')
892
                preg_match_all( '/-*"(.*?)"/', $search, $match );
893
                $search = preg_replace( '/-*".*?"/', '', $search );
894
                $quote_terms = $match[0];
895
            }
896
 
897
            //finally pull out the rest words in the string
898
            $terms = preg_split( "/\s+/", $search, 0, PREG_SPLIT_NO_EMPTY );
899
 
900
            //merge them all together and return
901
            $terms = array_merge($terms, $quote_terms);
902
 
903
        }
904
 
905
        if(count($terms)){
906
 
907
            $use_key="";
908
            $extra_where="";
909
 
910
            /* using this code on larger forums has shown to make the search faster.
911
               However, on smaller forums, it does not appear to help and in fact
912
               appears to slow down searches.
913
 
914
            if($match_date){
915
                $min_time=time()-86400*$match_date;
916
                $sql="select min(message_id) as min_id from {$PHORUM['message_table']} where datestamp>=$min_time";
917
                $res=mysql_query($sql, $conn);
918
                if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
919
                $min_id=mysql_result($res, 0, "min_id");
920
                $use_key=" use key (primary)";
921
                $extra_where="and message_id>=$min_id";
922
            }
923
            */
924
 
925
            $id_table=$PHORUM['search_table']."_ft_".md5(microtime());
926
 
927
            if($PHORUM["DBCONFIG"]["mysql_use_ft"]){
928
 
929
                if($match_type=="ALL" && count($terms)>1){
930
                    $against="+".mysql_escape_string(implode(" +", $terms));
931
                } else {
932
                    $against=mysql_escape_string(implode(" ", $terms));
933
                }
934
 
935
                $clause="MATCH (search_text) AGAINST ('$against' IN BOOLEAN MODE)";
936
 
937
            } else {
938
 
939
                if($match_type=="ALL"){
940
                    $conj="and";
941
                } else {
942
                    $conj="or";
943
                }
944
 
945
                // quote strings correctly
946
                foreach ($terms as $id => $term) {
947
                    $terms[$id] = mysql_escape_string($term);
948
                }
949
 
950
                $clause = "( search_text like '%".implode("%' $conj search_text like '%", $terms)."%' )";
951
 
952
            }
953
 
954
            $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['search_table']} $use_key where $clause $extra_where";
955
            $res = mysql_unbuffered_query($sql, $conn);
956
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
957
 
958
        }
959
    }
960
 
961
 
962
    if(isset($id_table)){
963
 
964
        // create a temporary table of the messages we want
965
        $table=$PHORUM['search_table']."_".md5(microtime());
966
        $sql="create temporary table $table (key (forum_id, status, datestamp)) ENGINE=HEAP select {$PHORUM['message_table']}.message_id, {$PHORUM['message_table']}.datestamp, status, forum_id from {$PHORUM['message_table']} inner join $id_table using (message_id) where status=".PHORUM_STATUS_APPROVED." $forum_where";
967
 
968
        if($match_date>0){
969
            $ts=time()-86400*$match_date;
970
            $sql.=" and datestamp>=$ts";
971
        }
972
 
973
        $res=mysql_query($sql, $conn);
974
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
975
 
976
        $sql="select count(*) as count from $table";
977
        $res = mysql_query($sql, $conn);
978
 
979
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
980
        $total_count=mysql_result($res, 0, 0);
981
 
982
        $sql="select message_id from $table order by datestamp desc limit $start, $length";
983
        $res = mysql_unbuffered_query($sql, $conn);
984
 
985
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
986
 
987
        $idstring="";
988
        while ($rec = mysql_fetch_row($res)){
989
            $idstring.="$rec[0],";
990
        }
991
        $idstring=substr($idstring, 0, -1);
992
 
993
        if($idstring){
994
            $sql="select * from {$PHORUM['message_table']} where message_id in ($idstring) order by datestamp desc";
995
            $res = mysql_unbuffered_query($sql, $conn);
996
 
997
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
998
 
999
            $rows = array();
1000
 
1001
            while ($rec = mysql_fetch_assoc($res)){
1002
                $rows[$rec["message_id"]] = $rec;
1003
            }
1004
 
1005
            $arr = array("count" => $total_count, "rows" => $rows);
1006
        }
1007
    }
1008
 
1009
    return $arr;
1010
}
1011
 
1012
/**
1013
 * This function returns the closest thread that is greater than $thread
1014
 */
1015
 
1016
function phorum_db_get_newer_thread($key){
1017
    $PHORUM = $GLOBALS["PHORUM"];
1018
 
1019
    settype($key, "int");
1020
 
1021
    $conn = phorum_db_mysql_connect();
1022
 
1023
    $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
1024
 
1025
    // are we really allowed to show this thread/message?
1026
    $approvedval = "";
1027
    if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
1028
        $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
1029
    } else {
1030
        $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
1031
    }
1032
 
1033
    $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} $approvedval and $keyfield>$key order by $keyfield limit 1";
1034
 
1035
    $res = mysql_query($sql, $conn);
1036
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1037
 
1038
    return (mysql_num_rows($res)) ? mysql_result($res, 0, "thread") : 0;
1039
}
1040
 
1041
/**
1042
 * This function returns the closest thread that is less than $thread
1043
 */
1044
 
1045
function phorum_db_get_older_thread($key){
1046
    $PHORUM = $GLOBALS["PHORUM"];
1047
 
1048
    settype($key, "int");
1049
 
1050
    $conn = phorum_db_mysql_connect();
1051
 
1052
    $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
1053
    // are we really allowed to show this thread/message?
1054
    $approvedval = "";
1055
    if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
1056
        $approvedval="AND {$PHORUM['message_table']}.status=".PHORUM_STATUS_APPROVED;
1057
    } else {
1058
        $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
1059
    }
1060
 
1061
    $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']}  $approvedval and $keyfield<$key order by $keyfield desc limit 1";
1062
 
1063
    $res = mysql_query($sql, $conn);
1064
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1065
 
1066
    return (mysql_num_rows($res)) ? mysql_result($res, 0, "thread") : 0;
1067
}
1068
 
1069
/**
1070
 * This function executes a query to get bad items of type $type and
1071
 * returns an array of the results.
1072
 */
1073
 
1074
function phorum_db_load_settings(){
1075
    global $PHORUM;
1076
 
1077
 
1078
    $conn = phorum_db_mysql_connect();
1079
 
1080
    $sql = "select * from {$PHORUM['settings_table']}";
1081
 
1082
    $res = mysql_query($sql, $conn);
1083
    if(!$res && !defined("PHORUM_ADMIN")){
1084
        if (mysql_errno($conn)==1146){
1085
            // settings table does not exist
1086
            return;
1087
        } elseif(($err = mysql_error())){
1088
            phorum_db_mysql_error("$err: $sql");
1089
        }
1090
    }
1091
 
1092
    if (empty($err) && $res){
1093
        while ($rec = mysql_fetch_assoc($res)){
1094
 
1095
            // only load the default forum options in the admin
1096
            if($rec["name"]=="default_forum_options" && !defined("PHORUM_ADMIN")) continue;
1097
 
1098
            if ($rec["type"] == "V"){
1099
                if ($rec["data"] == 'true'){
1100
                    $val = true;
1101
                }elseif ($rec["data"] == 'false'){
1102
                    $val = false;
1103
                }elseif (is_numeric($rec["data"])){
1104
                    $val = $rec["data"];
1105
                }else{
1106
                    $val = "$rec[data]";
1107
                }
1108
            }else{
1109
                $val = unserialize($rec["data"]);
1110
            }
1111
 
1112
            $PHORUM[$rec['name']]=$val;
1113
            $PHORUM['SETTINGS'][$rec['name']]=$val;
1114
        }
1115
    }
1116
}
1117
 
1118
/**
1119
 * This function executes a query to get bad items of type $type and
1120
 * returns an array of the results.
1121
 */
1122
 
1123
function phorum_db_update_settings($settings){
1124
    global $PHORUM;
1125
 
1126
    if (count($settings) > 0){
1127
        $conn = phorum_db_mysql_connect();
1128
 
1129
        foreach($settings as $field => $value){
1130
            if (is_numeric($value)){
1131
                $type = 'V';
1132
            }elseif (is_string($value)){
1133
                $value = mysql_escape_string($value);
1134
                $type = 'V';
1135
            }else{
1136
                $value = mysql_escape_string(serialize($value));
1137
                $type = 'S';
1138
            }
1139
 
1140
            $sql = "replace into {$PHORUM['settings_table']} set data='$value', type='$type', name='$field'";
1141
            $res = mysql_query($sql, $conn);
1142
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1143
        }
1144
 
1145
        return ($res > 0) ? true : false;
1146
    }else{
1147
        trigger_error("\$settings cannot be empty in phorum_db_update_settings()", E_USER_ERROR);
1148
    }
1149
}
1150
 
1151
/**
1152
 * This function executes a query to select all forum data from
1153
 * the database for a flat/collapsed display and returns the data in
1154
 * an array.
1155
 */
1156
 
1157
 
1158
function phorum_db_get_forums($forum_ids = 0, $parent_id = -1, $vroot = null, $inherit_id = null){
1159
    $PHORUM = $GLOBALS["PHORUM"];
1160
 
1161
    settype($parent_id, "int");
1162
 
1163
    $conn = phorum_db_mysql_connect();
1164
 
1165
    if (is_array($forum_ids)) {
1166
        $int_ids = array();
1167
        foreach ($forum_ids as $id) {
1168
            settype($id, "int");
1169
            $int_ids[] = $id;
1170
        }
1171
        $forum_ids = implode(",", $int_ids);
1172
    } else {
1173
        settype($forum_ids, "int");
1174
    }
1175
 
1176
    $sql = "select * from {$PHORUM['forums_table']} ";
1177
    if ($forum_ids){
1178
        $sql .= " where forum_id in ($forum_ids)";
1179
    } elseif ($inherit_id !== null) {
1180
        $sql .= " where inherit_id = $inherit_id";
1181
        if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
1182
    } elseif ($parent_id >= 0) {
1183
        $sql .= " where parent_id = $parent_id";
1184
        if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
1185
    }  elseif($vroot !== null) {
1186
        $sql .= " where vroot = $vroot";
1187
    } else {
1188
        $sql .= " where forum_id <> 0";
1189
    }
1190
 
1191
    $sql .= " order by display_order ASC, name";
1192
 
1193
    $res = mysql_query($sql, $conn);
1194
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1195
 
1196
    $forums = array();
1197
 
1198
    while ($row = mysql_fetch_assoc($res)){
1199
        $forums[$row["forum_id"]] = $row;
1200
    }
1201
 
1202
    return $forums;
1203
}
1204
 
1205
/**
1206
 * This function updates the forums stats.  If refresh is true, it pulls the
1207
 * numbers from the table.
1208
 */
1209
 
1210
function phorum_db_update_forum_stats($refresh=false, $msg_count_change=0, $timestamp=0, $thread_count_change=0, $sticky_count_change=0)
1211
{
1212
    $PHORUM = $GLOBALS["PHORUM"];
1213
 
1214
    $conn = phorum_db_mysql_connect();
1215
 
1216
    // always refresh on small forums
1217
    if (isset($PHORUM["message_count"]) && $PHORUM["message_count"]<1000) {
1218
        $refresh=true;
1219
    }
1220
 
1221
    if($refresh || empty($msg_count_change)){
1222
        $sql = "select count(*) as message_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and status=".PHORUM_STATUS_APPROVED;
1223
 
1224
        $res = mysql_query($sql, $conn);
1225
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1226
 
1227
        $message_count = (int)mysql_result($res, 0, "message_count");
1228
    } else {
1229
        $message_count="message_count+$msg_count_change";
1230
    }
1231
 
1232
    if($refresh || empty($timestamp)){
1233
 
1234
        $sql = "select max(modifystamp) as last_post_time from {$PHORUM['message_table']} where status=".PHORUM_STATUS_APPROVED." and forum_id={$PHORUM['forum_id']}";
1235
 
1236
        $res = mysql_query($sql, $conn);
1237
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1238
 
1239
        $last_post_time = (int)mysql_result($res, 0, "last_post_time");
1240
    } else {
1241
 
1242
        $last_post_time = $timestamp;
1243
    }
1244
 
1245
    if($refresh || empty($thread_count_change)){
1246
 
1247
        $sql = "select count(*) as thread_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and parent_id=0 and status=".PHORUM_STATUS_APPROVED;
1248
        $res = mysql_query($sql, $conn);
1249
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1250
        $thread_count = (int)mysql_result($res, 0, "thread_count");
1251
 
1252
    } else {
1253
 
1254
        $thread_count="thread_count+$thread_count_change";
1255
    }
1256
 
1257
    if($refresh || empty($sticky_count_change)){
1258
 
1259
        $sql = "select count(*) as sticky_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and sort=".PHORUM_SORT_STICKY." and parent_id=0 and status=".PHORUM_STATUS_APPROVED;
1260
        $res = mysql_query($sql, $conn);
1261
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1262
        $sticky_count = (int)mysql_result($res, 0, "sticky_count");
1263
 
1264
    } else {
1265
 
1266
        $sticky_count="sticky_count+$sticky_count_change";
1267
    }
1268
 
1269
    $sql = "update {$PHORUM['forums_table']} set thread_count=$thread_count, message_count=$message_count, sticky_count=$sticky_count, last_post_time=$last_post_time where forum_id={$PHORUM['forum_id']}";
1270
    mysql_query($sql, $conn);
1271
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1272
 
1273
}
1274
 
1275
/**
1276
 * actually moves a thread to the given forum
1277
 */
1278
function phorum_db_move_thread($thread_id, $toforum)
1279
{
1280
    $PHORUM = $GLOBALS["PHORUM"];
1281
 
1282
    settype($thread_id, "int");
1283
    settype($toforum, "int");
1284
 
1285
    if($toforum > 0 && $thread_id > 0){
1286
        $conn = phorum_db_mysql_connect();
1287
        // retrieving the messages for the newflags and search updates below
1288
        $thread_messages=phorum_db_get_messages($thread_id);
1289
 
1290
        // just changing the forum-id, simple isn't it?
1291
        $sql = "UPDATE {$PHORUM['message_table']} SET forum_id=$toforum where thread=$thread_id";
1292
 
1293
        $res = mysql_query($sql, $conn);
1294
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1295
 
1296
        // we need to update the number of posts in the current forum
1297
        phorum_db_update_forum_stats(true);
1298
 
1299
        // and of the new forum
1300
        $old_id=$GLOBALS["PHORUM"]["forum_id"];
1301
        $GLOBALS["PHORUM"]["forum_id"]=$toforum;
1302
        phorum_db_update_forum_stats(true);
1303
        $GLOBALS["PHORUM"]["forum_id"]=$old_id;
1304
 
1305
        // move the new-flags and the search records for this thread
1306
        // to the new forum too
1307
        unset($thread_messages['users']);
1308
 
1309
        $new_newflags=phorum_db_newflag_get_flags($toforum);
1310
        $message_ids = array();
1311
        $delete_ids = array();
1312
        $search_ids = array();
1313
        foreach($thread_messages as $mid => $data) {
1314
            // gather information for updating the newflags
1315
            if($mid > $new_newflags['min_id']) { // only using it if its higher than min_id
1316
                $message_ids[]=$mid;
1317
            } else { // newflags to delete
1318
                $delete_ids[]=$mid;
1319
            }
1320
 
1321
            // gather the information for updating the search table
1322
            $search_ids[] = $mid;
1323
        }
1324
 
1325
        if(count($message_ids)) { // we only go in if there are messages ... otherwise an error occured
1326
 
1327
            $ids_str=implode(",",$message_ids);
1328
 
1329
            // then doing the update to newflags
1330
            $sql="UPDATE IGNORE {$PHORUM['user_newflags_table']} SET forum_id = $toforum where message_id IN($ids_str)";
1331
            $res = mysql_query($sql, $conn);
1332
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1333
 
1334
            // then doing the update to subscriptions
1335
            $sql="UPDATE {$PHORUM['subscribers_table']} SET forum_id = $toforum where thread IN($ids_str)";
1336
            $res = mysql_query($sql, $conn);
1337
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1338
 
1339
        }
1340
 
1341
        if(count($delete_ids)) {
1342
            $ids_str=implode(",",$delete_ids);
1343
            // then doing the delete
1344
            $sql="DELETE FROM {$PHORUM['user_newflags_table']} where message_id IN($ids_str)";
1345
            mysql_query($sql, $conn);
1346
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1347
        }
1348
 
1349
        if (count($search_ids)) {
1350
            $ids_str = implode(",",$search_ids);
1351
            // then doing the search table update
1352
            $sql = "UPDATE {$PHORUM['search_table']} set forum_id = $toforum where message_id in ($ids_str)";
1353
            mysql_query($sql, $conn);
1354
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1355
        }
1356
 
1357
    }
1358
}
1359
 
1360
/**
1361
 * closes the given thread
1362
 */
1363
function phorum_db_close_thread($thread_id){
1364
    $PHORUM = $GLOBALS["PHORUM"];
1365
 
1366
    settype($thread_id, "int");
1367
 
1368
    if($thread_id > 0){
1369
        $conn = phorum_db_mysql_connect();
1370
 
1371
        $sql = "UPDATE {$PHORUM['message_table']} SET closed=1 where thread=$thread_id";
1372
 
1373
        $res = mysql_query($sql, $conn);
1374
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1375
    }
1376
}
1377
 
1378
/**
1379
 * (re)opens the given thread
1380
 */
1381
function phorum_db_reopen_thread($thread_id){
1382
    $PHORUM = $GLOBALS["PHORUM"];
1383
 
1384
    settype($thread_id, "int");
1385
 
1386
    if($thread_id > 0){
1387
        $conn = phorum_db_mysql_connect();
1388
 
1389
        $sql = "UPDATE {$PHORUM['message_table']} SET closed=0 where thread=$thread_id";
1390
 
1391
        $res = mysql_query($sql, $conn);
1392
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1393
    }
1394
}
1395
 
1396
/**
1397
 * This function executes a query to insert a forum into the forums
1398
 * table and returns the forums id on success or 0 on failure.
1399
 */
1400
 
1401
function phorum_db_add_forum($forum)
1402
{
1403
    $PHORUM = $GLOBALS["PHORUM"];
1404
 
1405
    $conn = phorum_db_mysql_connect();
1406
 
1407
    foreach($forum as $key => $value){
1408
        if (is_numeric($value)){
1409
            $value = (int)$value;
1410
            $fields[] = "$key=$value";
1411
        } elseif($value=="NULL") {
1412
            $fields[] = "$key=$value";
1413
        }else{
1414
            $value = mysql_escape_string($value);
1415
            $fields[] = "$key='$value'";
1416
        }
1417
    }
1418
 
1419
    $sql = "insert into {$PHORUM['forums_table']} set " . implode(", ", $fields);
1420
 
1421
    $res = mysql_query($sql, $conn);
1422
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1423
 
1424
    $forum_id = 0;
1425
 
1426
    if ($res){
1427
        $forum_id = mysql_insert_id($conn);
1428
    }
1429
 
1430
    return $forum_id;
1431
}
1432
 
1433
/**
1434
 * This function executes a query to remove a forum from the forums
1435
 * table and its messages.
1436
 */
1437
 
1438
function phorum_db_drop_forum($forum_id)
1439
{
1440
    $PHORUM = $GLOBALS["PHORUM"];
1441
 
1442
    settype($forum_id, "int");
1443
 
1444
    $conn = phorum_db_mysql_connect();
1445
 
1446
    $tables = array (
1447
        $PHORUM['message_table'],
1448
        $PHORUM['user_permissions_table'],
1449
        $PHORUM['user_newflags_table'],
1450
        $PHORUM['subscribers_table'],
1451
        $PHORUM['forum_group_xref_table'],
1452
        $PHORUM['forums_table'],
1453
        $PHORUM['banlist_table'],
1454
        $PHORUM['search_table']
1455
    );
1456
 
1457
    foreach($tables as $table){
1458
        $sql = "delete from $table where forum_id=$forum_id";
1459
        $res = mysql_query($sql, $conn);
1460
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1461
    }
1462
 
1463
$sql = "select file_id from {$PHORUM['files_table']} left join {$PHORUM['message_table']} using (message_id) where {$PHORUM['files_table']}.message_id > 0 AND link='" . PHORUM_LINK_MESSAGE . "' AND {$PHORUM['message_table']}.message_id is NULL";
1464
    $res = mysql_query($sql, $conn);
1465
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1466
    while($rec=mysql_fetch_assoc($res)){
1467
        $files[]=$rec["file_id"];
1468
    }
1469
    if(isset($files)){
1470
        $sql = "delete from {$PHORUM['files_table']} where file_id in (".implode(",", $files).")";
1471
        $res = mysql_query($sql, $conn);
1472
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1473
    }
1474
 
1475
 
1476
}
1477
 
1478
/**
1479
 * This function executes a query to remove a folder from the forums
1480
 * table and change the parent of its children.
1481
 */
1482
 
1483
function phorum_db_drop_folder($forum_id)
1484
{
1485
    $PHORUM = $GLOBALS["PHORUM"];
1486
 
1487
    settype($forum_id, "int");
1488
 
1489
    $conn = phorum_db_mysql_connect();
1490
 
1491
    $sql = "select parent_id from {$PHORUM['forums_table']} where forum_id=$forum_id";
1492
 
1493
    $res = mysql_query($sql, $conn);
1494
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1495
 
1496
    $new_parent_id = mysql_result($res, 0, "parent_id");
1497
 
1498
    $sql = "update {$PHORUM['forums_table']} set parent_id=$new_parent_id where parent_id=$forum_id";
1499
 
1500
    $res = mysql_query($sql, $conn);
1501
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1502
 
1503
    $sql = "delete from {$PHORUM['forums_table']} where forum_id=$forum_id";
1504
 
1505
    $res = mysql_query($sql, $conn);
1506
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1507
}
1508
 
1509
/**
1510
 * This function executes a query to update a forum in the forums
1511
 * table and returns non zero on success or 0 on failure.
1512
 */
1513
 
1514
function phorum_db_update_forum($forum){
1515
    $PHORUM = $GLOBALS["PHORUM"];
1516
 
1517
    $res = 0;
1518
 
1519
    if (!empty($forum["forum_id"])){
1520
 
1521
        // this way we can also update multiple forums at once
1522
        if(is_array($forum["forum_id"])) {
1523
            $forumwhere="forum_id IN (".implode(",",$forum["forum_id"]).")";
1524
        } else {
1525
            $forumwhere="forum_id=".$forum["forum_id"];
1526
        }
1527
 
1528
        unset($forum["forum_id"]);
1529
 
1530
        $conn = phorum_db_mysql_connect();
1531
 
1532
        foreach($forum as $key => $value){
1533
            if (is_numeric($value)){
1534
                $value = (int)$value;
1535
                $fields[] = "$key=$value";
1536
            } elseif($value=="NULL") {
1537
                $fields[] = "$key=$value";
1538
            } else {
1539
                $value = mysql_escape_string($value);
1540
                $fields[] = "$key='$value'";
1541
            }
1542
        }
1543
 
1544
        $sql = "update {$PHORUM['forums_table']} set " . implode(", ", $fields) . " where $forumwhere";
1545
 
1546
        $res = mysql_query($sql, $conn);
1547
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1548
    }else{
1549
        trigger_error("\$forum[forum_id] cannot be empty in phorum_update_forum()", E_USER_ERROR);
1550
    }
1551
 
1552
    return $res;
1553
}
1554
 
1555
/**
1556
*
1557
*/
1558
 
1559
function phorum_db_get_groups($group_id=0)
1560
{
1561
    $PHORUM = $GLOBALS["PHORUM"];
1562
    $conn = phorum_db_mysql_connect();
1563
 
1564
    settype($group_id, "integer");
1565
 
1566
    $sql="select * from {$PHORUM['groups_table']}";
1567
    if($group_id!=0) $sql.=" where group_id=$group_id";
1568
 
1569
    $res = mysql_query($sql, $conn);
1570
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1571
 
1572
    $groups=array();
1573
    while($rec=mysql_fetch_assoc($res)){
1574
 
1575
        $groups[$rec["group_id"]]=$rec;
1576
        $groups[$rec["group_id"]]["permissions"]=array();
1577
    }
1578
 
1579
    $sql="select * from {$PHORUM['forum_group_xref_table']}";
1580
    if($group_id!=0) $sql.=" where group_id=$group_id";
1581
 
1582
    $res = mysql_query($sql, $conn);
1583
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1584
 
1585
    while($rec=mysql_fetch_assoc($res)){
1586
 
1587
        $groups[$rec["group_id"]]["permissions"][$rec["forum_id"]]=$rec["permission"];
1588
 
1589
    }
1590
 
1591
    return $groups;
1592
 
1593
}
1594
 
1595
/**
1596
* Get the members of a group.
1597
* @param group_id - can be an integer (single group), or an array of groups
1598
* @param status - a specific status to look for, defaults to all
1599
* @return array - users (key is userid, value is group membership status)
1600
*/
1601
 
1602
function phorum_db_get_group_members($group_id, $status = PHORUM_USER_GROUP_REMOVE)
1603
{
1604
    $PHORUM = $GLOBALS["PHORUM"];
1605
    $conn = phorum_db_mysql_connect();
1606
 
1607
    if(is_array($group_id)){
1608
        $group_id=implode(",", $group_id);
1609
    } else {
1610
        settype($group_id, "int");
1611
    }
1612
 
1613
    // this join is only here so that the list of users comes out sorted
1614
    // if phorum_db_user_get() sorts results itself, this join can go away
1615
    $sql="select {$PHORUM['user_group_xref_table']}.user_id, {$PHORUM['user_group_xref_table']}.status from {$PHORUM['user_table']}, {$PHORUM['user_group_xref_table']} where {$PHORUM['user_table']}.user_id = {$PHORUM['user_group_xref_table']}.user_id and group_id in ($group_id)";
1616
    if ($status != PHORUM_USER_GROUP_REMOVE) $sql.=" and {$PHORUM['user_group_xref_table']}.status = $status";
1617
    $sql .=" order by username asc";
1618
 
1619
    $res = mysql_query($sql, $conn);
1620
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1621
    $users=array();
1622
    while($rec=mysql_fetch_assoc($res)){
1623
        $users[$rec["user_id"]]=$rec["status"];
1624
    }
1625
 
1626
    return $users;
1627
 
1628
}
1629
 
1630
/**
1631
*
1632
*/
1633
 
1634
function phorum_db_save_group($group)
1635
{
1636
    $PHORUM = $GLOBALS["PHORUM"];
1637
    $conn = phorum_db_mysql_connect();
1638
 
1639
    $ret=false;
1640
 
1641
    if(isset($group["name"])){
1642
        $sql="update {$PHORUM['groups_table']} set name='{$group['name']}', open={$group['open']} where group_id={$group['group_id']}";
1643
 
1644
        $res=mysql_query($sql, $conn);
1645
 
1646
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1647
 
1648
    }
1649
 
1650
    if(!$err){
1651
 
1652
        if(isset($group["permissions"])){
1653
            $sql="delete from {$PHORUM['forum_group_xref_table']} where group_id={$group['group_id']}";
1654
 
1655
            $res=mysql_query($sql, $conn);
1656
 
1657
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1658
 
1659
            foreach($group["permissions"] as $forum_id=>$permission){
1660
                $sql="insert into {$PHORUM['forum_group_xref_table']} set group_id={$group['group_id']}, permission=$permission, forum_id=$forum_id";
1661
                $res=mysql_query($sql, $conn);
1662
                if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1663
                if(!$res) break;
1664
            }
1665
        }
1666
    }
1667
 
1668
    if($res>0) $ret=true;
1669
 
1670
    return $ret;
1671
 
1672
}
1673
 
1674
function phorum_db_delete_group($group_id)
1675
{
1676
    $PHORUM = $GLOBALS["PHORUM"];
1677
    $conn = phorum_db_mysql_connect();
1678
 
1679
    settype($group_id, "int");
1680
 
1681
    $sql = "delete from {$PHORUM['groups_table']} where group_id = $group_id";
1682
    $res = mysql_query($sql, $conn);
1683
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1684
 
1685
    // delete things associated with groups
1686
    $sql = "delete from {$PHORUM['user_group_xref_table']} where group_id = $group_id";
1687
    $res = mysql_query($sql, $conn);
1688
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1689
 
1690
    $sql = "delete from {$PHORUM['forum_group_xref_table']} where group_id = $group_id";
1691
    $res = mysql_query($sql, $conn);
1692
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1693
}
1694
 
1695
/**
1696
 * phorum_db_add_group()
1697
 *
1698
 * @param $group_name $group_id
1699
 * @return
1700
 **/
1701
function phorum_db_add_group($group_name,$group_id=0)
1702
{
1703
    $PHORUM = $GLOBALS["PHORUM"];
1704
    $conn = phorum_db_mysql_connect();
1705
 
1706
    settype($group_id, "int");
1707
 
1708
    if($group_id > 0) { // only used in conversion
1709
        $sql="insert into {$PHORUM['groups_table']} (group_id,name) values ($group_id,'$group_name')";
1710
    } else {
1711
        $sql="insert into {$PHORUM['groups_table']} (name) values ('$group_name')";
1712
    }
1713
 
1714
    $res = mysql_query($sql, $conn);
1715
 
1716
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1717
 
1718
    $group_id = 0;
1719
 
1720
    if ($res) {
1721
        $group_id = mysql_insert_id($conn);
1722
    }
1723
 
1724
    return $group_id;
1725
}
1726
 
1727
/**
1728
* This function returns all moderators for a particular forum
1729
*/
1730
function phorum_db_user_get_moderators($forum_id,$ignore_user_perms=false,$for_email=false) {
1731
 
1732
   $PHORUM = $GLOBALS["PHORUM"];
1733
   $userinfo=array();
1734
 
1735
   $conn = phorum_db_mysql_connect();
1736
 
1737
   settype($forum_id, "int");
1738
 
1739
   if(!$ignore_user_perms) { // sometimes we just don't need them
1740
       if(!$PHORUM['email_ignore_admin']) {
1741
            $admincheck=" OR user.admin=1";
1742
       } else {
1743
            $admincheck="";
1744
       }
1745
 
1746
 
1747
       $sql="SELECT DISTINCT user.user_id, user.email, user.moderation_email FROM {$PHORUM['user_table']} as user LEFT JOIN {$PHORUM['user_permissions_table']} as perm ON perm.user_id=user.user_id WHERE (perm.permission >= ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." AND (perm.permission & ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." > 0) AND perm.forum_id=$forum_id)$admincheck";
1748
 
1749
 
1750
       $res = mysql_query($sql, $conn);
1751
 
1752
       if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1753
 
1754
       while ($row = mysql_fetch_row($res)){
1755
           if(!$for_email || $row[2] == 1)
1756
                $userinfo[$row[0]]=$row[1];
1757
       }
1758
 
1759
   }
1760
 
1761
   // get users who belong to groups that have moderator access
1762
   $sql = "SELECT DISTINCT user.user_id, user.email, user.moderation_email FROM {$PHORUM['user_table']} AS user, {$PHORUM['groups_table']} AS groups, {$PHORUM['user_group_xref_table']} AS usergroup, {$PHORUM['forum_group_xref_table']} AS forumgroup WHERE user.user_id = usergroup.user_id AND usergroup.group_id = groups.group_id AND groups.group_id = forumgroup.group_id AND forum_id = $forum_id AND permission & ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." > 0 AND usergroup.status >= ".PHORUM_USER_GROUP_APPROVED;
1763
 
1764
   $res = mysql_query($sql, $conn);
1765
 
1766
   if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1767
 
1768
   while ($row = mysql_fetch_row($res)){
1769
       if(!$for_email || $row[2] == 1)
1770
           $userinfo[$row[0]]=$row[1];
1771
   }
1772
   return $userinfo;
1773
}
1774
 
1775
/**
1776
 * This function executes a query to select data about a user including
1777
 * his permission data and returns that in an array.
1778
 */
1779
 
1780
function phorum_db_user_get($user_id, $detailed)
1781
{
1782
    $PHORUM = $GLOBALS["PHORUM"];
1783
 
1784
    $conn = phorum_db_mysql_connect();
1785
 
1786
    if(is_array($user_id)){
1787
        $user_ids=implode(",", $user_id);
1788
    } else {
1789
        $user_ids=(int)$user_id;
1790
    }
1791
 
1792
    $users = array();
1793
 
1794
    $sql = "select * from {$PHORUM['user_table']} where user_id in ($user_ids)";
1795
    $res = mysql_query($sql, $conn);
1796
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1797
 
1798
    if (mysql_num_rows($res)){
1799
        while($rec=mysql_fetch_assoc($res)){
1800
            $users[$rec["user_id"]] = $rec;
1801
        }
1802
 
1803
        if ($detailed){
1804
            // get the users' permissions
1805
            $sql = "select * from {$PHORUM['user_permissions_table']} where user_id in ($user_ids)";
1806
 
1807
            $res = mysql_query($sql, $conn);
1808
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1809
 
1810
            while ($row = mysql_fetch_assoc($res)){
1811
                $users[$row["user_id"]]["forum_permissions"][$row["forum_id"]] = $row["permission"];
1812
            }
1813
 
1814
            // get the users' groups and forum permissions through those groups
1815
            $sql = "select user_id, {$PHORUM['user_group_xref_table']}.group_id, forum_id, permission from {$PHORUM['user_group_xref_table']} left join {$PHORUM['forum_group_xref_table']} using (group_id) where user_id in ($user_ids) AND {$PHORUM['user_group_xref_table']}.status >= ".PHORUM_USER_GROUP_APPROVED;
1816
 
1817
            $res = mysql_query($sql, $conn);
1818
            if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1819
 
1820
            while ($row = mysql_fetch_assoc($res)){
1821
                $users[$row["user_id"]]["groups"][$row["group_id"]] = $row["group_id"];
1822
                if(!empty($row["forum_id"])){
1823
                    if(!isset($users[$row["user_id"]]["group_permissions"][$row["forum_id"]])) {
1824
                         $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] = 0;
1825
                    }
1826
                    $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] = $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] | $row["permission"];
1827
                }
1828
            }
1829
 
1830
        }
1831
        $sql = "select * from {$PHORUM['user_custom_fields_table']} where user_id in ($user_ids)";
1832
        $res = mysql_query($sql, $conn);
1833
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1834
 
1835
        while ($row = mysql_fetch_assoc($res)){
1836
            if(isset($PHORUM["PROFILE_FIELDS"][$row['type']])) {
1837
                if($PHORUM["PROFILE_FIELDS"][$row['type']]['html_disabled']) {
1838
                    $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = htmlspecialchars($row["data"]);
1839
                } else { // not html-disabled
1840
                    if(substr($row["data"],0,6) == 'P_SER:') {
1841
                        // P_SER (PHORUM_SERIALIZED) is our marker telling this field is serialized
1842
                        $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = unserialize(substr($row["data"],6));
1843
                    } else {
1844
                        $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = $row["data"];
1845
                    }
1846
                }
1847
            }
1848
        }
1849
 
1850
    }
1851
 
1852
    if(is_array($user_id)){
1853
        return $users;
1854
    } else {
1855
        return isset($users[$user_id]) ? $users[$user_id] : NULL;
1856
    }
1857
 
1858
}
1859
 
1860
/*
1861
 * Generic function to retrieve a couple of fields from the user-table
1862
 * for a couple of users or only one of them
1863
 *
1864
 * result is always an array with one or more users in it
1865
 */
1866
 
1867
function phorum_db_user_get_fields($user_id, $fields)
1868
{
1869
    $PHORUM = $GLOBALS["PHORUM"];
1870
 
1871
    $conn = phorum_db_mysql_connect();
1872
 
1873
    // input could be either array or string
1874
    if(is_array($user_id)){
1875
        $user_ids=implode(",", $user_id);
1876
    } else {
1877
        $user_ids=(int)$user_id;
1878
    }
1879
 
1880
 
1881
    if(is_array($fields)) {
1882
        $fields_str=implode(",",$fields);
1883
    } else {
1884
        $fields_str=$fields;
1885
    }
1886
 
1887
    $users = array();
1888
 
1889
 
1890
 
1891
    $sql = "select user_id,$fields_str from {$PHORUM['user_table']} where user_id in ($user_ids)";
1892
 
1893
    $res = mysql_query($sql, $conn);
1894
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1895
 
1896
    if (mysql_num_rows($res)){
1897
        while($rec=mysql_fetch_assoc($res)){
1898
            $users[$rec["user_id"]] = $rec;
1899
        }
1900
    }
1901
 
1902
    return $users;
1903
 
1904
}
1905
 
1906
/**
1907
 * This function gets a list of all the active users.
1908
 * @return array - (key: userid, value: array (username, displayname)
1909
 */
1910
function phorum_db_user_get_list(){
1911
   $PHORUM = $GLOBALS["PHORUM"];
1912
 
1913
   $conn = phorum_db_mysql_connect();
1914
 
1915
   $users = array();
1916
   $sql = "select user_id, username from {$PHORUM['user_table']} order by username asc";
1917
   $res = mysql_query($sql, $conn);
1918
   if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1919
 
1920
   while ($row = mysql_fetch_assoc($res)){
1921
       $users[$row["user_id"]] = array("username" => $row["username"], "displayname" => $row["username"]);
1922
   }
1923
 
1924
   return $users;
1925
}
1926
 
1927
/**
1928
 * This function executes a query to select data about a user including
1929
 * his permission data and returns that in an array.
1930
 */
1931
 
1932
function phorum_db_user_check_pass($username, $password, $temp_password=false){
1933
    $PHORUM = $GLOBALS["PHORUM"];
1934
 
1935
    $conn = phorum_db_mysql_connect();
1936
 
1937
    $username = mysql_escape_string($username);
1938
 
1939
    $password = mysql_escape_string($password);
1940
 
1941
    $pass_field = ($temp_password) ? "password_temp" : "password";
1942
 
1943
    $sql = "select user_id from {$PHORUM['user_table']} where username='$username' and $pass_field='$password'";
1944
 
1945
    $res = mysql_query($sql, $conn);
1946
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1947
 
1948
    return ($res && mysql_num_rows($res)) ? mysql_result($res, 0, "user_id") : 0;
1949
}
1950
 
1951
/**
1952
 * This function executes a query to check for the given field in the
1953
 * user tableusername and return the user_id of the user it matches or 0
1954
 * if no match is found.
1955
 *
1956
 * The parameters can be arrays.  If they are, all must be passed and all
1957
 * must have the same number of values.
1958
 *
1959
 * If $return_array is true, an array of all matching rows will be returned.
1960
 * Otherwise, only the first user_id from the results will be returned.
1961
 */
1962
 
1963
function phorum_db_user_check_field($field, $value, $operator="=", $return_array=false){
1964
    $PHORUM = $GLOBALS["PHORUM"];
1965
 
1966
    $ret = 0;
1967
 
1968
    $conn = phorum_db_mysql_connect();
1969
 
1970
    if(!is_array($field)){
1971
        $field=array($field);
1972
    }
1973
 
1974
    if(!is_array($value)){
1975
        $value=array($value);
1976
    }
1977
 
1978
    if(!is_array($operator)){
1979
        $operator=array($operator);
1980
    }
1981
 
1982
    foreach($field as $key=>$name){
1983
        $value[$key] = mysql_escape_string($value[$key]);
1984
        $clauses[]="$name $operator[$key] '$value[$key]'";
1985
    }
1986
 
1987
    $sql = "select user_id from {$PHORUM['user_table']} where ".implode(" and ", $clauses);
1988
 
1989
    $res = mysql_query($sql, $conn);
1990
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
1991
 
1992
    if ($res && mysql_num_rows($res)){
1993
        if($return_array){
1994
            $ret=array();
1995
            while($row=mysql_fetch_assoc($res)){
1996
                $ret[$row["user_id"]]=$row["user_id"];
1997
            }
1998
        } else {
1999
            $ret = mysql_result($res, 0, "user_id");
2000
        }
2001
    }
2002
 
2003
    return $ret;
2004
}
2005
 
2006
 
2007
/**
2008
 * This function executes a query to add the given user data to the
2009
 * database and returns the userid or 0
2010
 */
2011
 
2012
function phorum_db_user_add($userdata){
2013
    $PHORUM = $GLOBALS["PHORUM"];
2014
 
2015
    $conn = phorum_db_mysql_connect();
2016
 
2017
    if (isset($userdata["forum_permissions"]) && !empty($userdata["forum_permissions"])){
2018
        $forum_perms = $userdata["forum_permissions"];
2019
        unset($userdata["forum_permissions"]);
2020
    }
2021
 
2022
    if (isset($userdata["user_data"]) && !empty($userdata["user_data"])){
2023
        $user_data = $userdata["user_data"];
2024
        unset($userdata["user_data"]);
2025
    }
2026
 
2027
 
2028
    $sql = "insert into {$PHORUM['user_table']} set ";
2029
 
2030
    $values = array();
2031
 
2032
    foreach($userdata as $key => $value){
2033
        if (!is_numeric($value)){
2034
            $value = mysql_escape_string($value);
2035
            $values[] = "$key='$value'";
2036
        }else{
2037
            $values[] = "$key=$value";
2038
        }
2039
    }
2040
 
2041
    $sql .= implode(", ", $values);
2042
 
2043
    $res = mysql_query($sql, $conn);
2044
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2045
 
2046
    $user_id = 0;
2047
    if ($res){
2048
        $user_id = mysql_insert_id($conn);
2049
    }
2050
 
2051
    if ($res){
2052
        if(isset($forum_perms)) {
2053
            // storing forum-permissions
2054
            foreach($forum_perms as $fid => $p){
2055
                $sql = "insert into {$PHORUM['user_permissions_table']} set user_id=$user_id, forum_id=$fid, permission=$p";
2056
                $res = mysql_query($sql, $conn);
2057
                if ($err = mysql_error()){
2058
                    phorum_db_mysql_error("$err: $sql");
2059
                    break;
2060
                }
2061
            }
2062
        }
2063
        if(isset($user_data)) {
2064
            /* storing custom-fields */
2065
            foreach($user_data as $key => $val){
2066
                if(is_array($val)) { /* arrays need to be serialized */
2067
                    $val = 'P_SER:'.serialize($val);
2068
                    /* P_SER: (PHORUM_SERIALIZED is our marker telling this Field is serialized */
2069
                } else { /* other vars need to be escaped */
2070
                    $val = mysql_escape_string($val);
2071
                }
2072
                $sql = "insert into {$PHORUM['user_custom_fields_table']} (user_id,type,data) VALUES($user_id,$key,'$val')";
2073
                $res = mysql_query($sql, $conn);
2074
                if ($err = mysql_error()){
2075
                    phorum_db_mysql_error("$err: $sql");
2076
                    break;
2077
                }
2078
            }
2079
        }
2080
    }
2081
 
2082
    return $user_id;
2083
}
2084
 
2085
 
2086
/**
2087
 * This function executes a query to update the given user data in the
2088
 * database and returns the true or false
2089
 */
2090
function phorum_db_user_save($userdata){
2091
    $PHORUM = $GLOBALS["PHORUM"];
2092
 
2093
    $conn = phorum_db_mysql_connect();
2094
 
2095
    if(isset($userdata["permissions"])){
2096
        unset($userdata["permissions"]);
2097
    }
2098
 
2099
    if (isset($userdata["forum_permissions"])){
2100
        $forum_perms = $userdata["forum_permissions"];
2101
        unset($userdata["forum_permissions"]);
2102
    }
2103
 
2104
    if (isset($userdata["groups"])){
2105
        $groups = $userdata["groups"];
2106
        unset($userdata["groups"]);
2107
        unset($userdata["group_permissions"]);
2108
    }
2109
    if (isset($userdata["user_data"])){
2110
        $user_data = $userdata["user_data"];
2111
        unset($userdata["user_data"]);
2112
    }
2113
 
2114
    $user_id = $userdata["user_id"];
2115
    unset($userdata["user_id"]);
2116
 
2117
    if(count($userdata)){
2118
 
2119
        $sql = "update {$PHORUM['user_table']} set ";
2120
 
2121
        $values = array();
2122
 
2123
        foreach($userdata as $key => $value){
2124
            $values[] = "$key='".mysql_escape_string($value)."'";
2125
        }
2126
 
2127
        $sql .= implode(", ", $values);
2128
 
2129
        $sql .= " where user_id=$user_id";
2130
 
2131
        $res = mysql_query($sql, $conn);
2132
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2133
    }
2134
 
2135
    if (isset($forum_perms)){
2136
 
2137
        $sql = "delete from {$PHORUM['user_permissions_table']} where user_id = $user_id";
2138
        $res=mysql_query($sql, $conn);
2139
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2140
 
2141
        foreach($forum_perms as $fid=>$perms){
2142
            $sql = "insert into {$PHORUM['user_permissions_table']} set user_id=$user_id, forum_id=$fid, permission=$perms";
2143
            $res = mysql_query($sql, $conn);
2144
            if ($err = mysql_error()){
2145
                phorum_db_mysql_error("$err: $sql");
2146
            }
2147
        }
2148
    }
2149
    if(isset($user_data)) {
2150
        // storing custom-fields
2151
        $sql = "delete from {$PHORUM['user_custom_fields_table']} where user_id = $user_id";
2152
        $res=mysql_query($sql, $conn);
2153
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2154
 
2155
        if(is_array($user_data)) {
2156
            foreach($user_data as $key => $val){
2157
                if(is_array($val)) { /* arrays need to be serialized */
2158
                    $val = 'P_SER:'.serialize($val);
2159
                    /* P_SER: (PHORUM_SERIALIZED is our marker telling this Field is serialized */
2160
                } else { /* other vars need to be escaped */
2161
                    $val = mysql_escape_string($val);
2162
                }
2163
 
2164
                $sql = "insert into {$PHORUM['user_custom_fields_table']} (user_id,type,data) VALUES($user_id,$key,'$val')";
2165
                $res = mysql_query($sql, $conn);
2166
                if ($err = mysql_error()){
2167
                    phorum_db_mysql_error("$err: $sql");
2168
                    break;
2169
                }
2170
            }
2171
        }
2172
    }
2173
 
2174
    return (bool)$res;
2175
}
2176
 
2177
/**
2178
 * This function saves a users group permissions.
2179
 */
2180
function phorum_db_user_save_groups($user_id, $groups)
2181
{
2182
    $PHORUM = $GLOBALS["PHORUM"];
2183
    if (!$user_id > 0){
2184
        return false;
2185
    }
2186
 
2187
    settype($user_id, "int");
2188
 
2189
    // erase the group memberships they have now
2190
    $conn = phorum_db_mysql_connect();
2191
    $sql = "delete from {$PHORUM['user_group_xref_table']} where user_id = $user_id";
2192
    $res=mysql_query($sql, $conn);
2193
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2194
 
2195
    foreach($groups as $group_id => $group_perm){
2196
        $sql = "insert into {$PHORUM['user_group_xref_table']} set user_id=$user_id, group_id=$group_id, status=$group_perm";
2197
        mysql_query($sql, $conn);
2198
        if ($err = mysql_error()){
2199
            phorum_db_mysql_error("$err: $sql");
2200
            break;
2201
        }
2202
    }
2203
    return (bool)$res;
2204
}
2205
 
2206
/**
2207
 * This function executes a query to subscribe a user to a forum/thread.
2208
 */
2209
 
2210
function phorum_db_user_subscribe($user_id, $forum_id, $thread, $type)
2211
{
2212
    $PHORUM = $GLOBALS["PHORUM"];
2213
 
2214
    settype($user_id, "int");
2215
    settype($forum_id, "int");
2216
    settype($thread, "int");
2217
    settype($type, "int");
2218
 
2219
    $conn = phorum_db_mysql_connect();
2220
 
2221
    $sql = "replace into {$PHORUM['subscribers_table']} set user_id=$user_id, forum_id=$forum_id, sub_type=$type, thread=$thread";
2222
 
2223
    $res = mysql_query($sql, $conn);
2224
 
2225
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2226
 
2227
    return (bool)$res;
2228
}
2229
 
2230
/**
2231
  * This function increases the post-counter for a user by one
2232
  */
2233
function phorum_db_user_addpost() {
2234
 
2235
        $conn = phorum_db_mysql_connect();
2236
 
2237
        $sql="UPDATE ".$GLOBALS['PHORUM']['user_table']." SET posts=posts+1 WHERE user_id = ".$GLOBALS['PHORUM']['user']['user_id'];
2238
        $res=mysql_query($sql,$conn);
2239
 
2240
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2241
 
2242
        return (bool)$res;
2243
}
2244
 
2245
/**
2246
 * This function executes a query to unsubscribe a user to a forum/thread.
2247
 */
2248
 
2249
function phorum_db_user_unsubscribe($user_id, $thread, $forum_id=0)
2250
{
2251
    $PHORUM = $GLOBALS["PHORUM"];
2252
 
2253
    settype($user_id, "int");
2254
    settype($forum_id, "int");
2255
    settype($thread, "int");
2256
 
2257
    $conn = phorum_db_mysql_connect();
2258
 
2259
    $sql = "DELETE FROM {$PHORUM['subscribers_table']} WHERE user_id=$user_id AND thread=$thread";
2260
    if($forum_id) $sql.=" and forum_id=$forum_id";
2261
 
2262
    $res = mysql_query($sql, $conn);
2263
 
2264
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2265
 
2266
    return (bool)$res;
2267
}
2268
 
2269
/**
2270
 * This function will return a list of groups the user
2271
 * is a member of, as well as the users permissions.
2272
 */
2273
function phorum_db_user_get_groups($user_id)
2274
{
2275
    $PHORUM = $GLOBALS["PHORUM"];
2276
    $groups = array();
2277
 
2278
    if (!$user_id > 0){
2279
           return $groups;
2280
    }
2281
 
2282
    settype($user_id, "int");
2283
 
2284
    $conn = phorum_db_mysql_connect();
2285
    $sql = "SELECT group_id, status FROM {$PHORUM['user_group_xref_table']} WHERE user_id = $user_id ORDER BY status DESC";
2286
 
2287
    $res = mysql_query($sql, $conn);
2288
 
2289
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2290
 
2291
    while($row = mysql_fetch_assoc($res)){
2292
        $groups[$row["group_id"]] = $row["status"];
2293
    }
2294
 
2295
    return $groups;
2296
}
2297
 
2298
/**
2299
 * This function executes a query to select data about a user including
2300
 * his permission data and returns that in an array.
2301
 * If $search is empty, all users should be returned.
2302
 */
2303
 
2304
function phorum_db_search_users($search)
2305
{
2306
    $PHORUM = $GLOBALS["PHORUM"];
2307
 
2308
    $conn = phorum_db_mysql_connect();
2309
 
2310
    $users = array();
2311
 
2312
    $search = trim($search);
2313
 
2314
    $sql = "select user_id, username, email, active, posts, date_last_active from {$PHORUM['user_table']} where username like '%$search%' or email like '%$search%'order by username";
2315
 
2316
    $res = mysql_query($sql, $conn);
2317
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2318
 
2319
    if (mysql_num_rows($res)){
2320
        while ($user = mysql_fetch_assoc($res)){
2321
            $users[$user["user_id"]] = $user;
2322
        }
2323
    }
2324
 
2325
    return $users;
2326
}
2327
 
2328
 
2329
/**
2330
 * This function gets the users that await approval
2331
 */
2332
 
2333
function phorum_db_user_get_unapproved()
2334
{
2335
    $PHORUM = $GLOBALS["PHORUM"];
2336
 
2337
    $conn = phorum_db_mysql_connect();
2338
 
2339
    $sql="select user_id, username, email from {$PHORUM['user_table']} where active in(".PHORUM_USER_PENDING_BOTH.", ".PHORUM_USER_PENDING_MOD.") order by username";
2340
    $res=mysql_query($sql, $conn);
2341
 
2342
    if ($err = mysql_error()){
2343
        phorum_db_mysql_error("$err: $sql");
2344
    }
2345
 
2346
    $users=array();
2347
    if($res){
2348
        while($rec=mysql_fetch_assoc($res)){
2349
            $users[$rec["user_id"]]=$rec;
2350
        }
2351
    }
2352
 
2353
    return $users;
2354
 
2355
}
2356
/**
2357
 * This function deletes a user completely
2358
 * - entry in the users-table
2359
 * - entries in the permissions-table
2360
 * - entries in the newflags-table
2361
 * - entries in the subscribers-table
2362
 * - entries in the group_xref-table
2363
 * - entries in the private-messages-table
2364
 * - entries in the files-table
2365
 * - sets entries in the messages-table to anonymous
2366
 *
2367
 */
2368
function phorum_db_user_delete($user_id) {
2369
    $PHORUM = $GLOBALS["PHORUM"];
2370
 
2371
    // how would we check success???
2372
    $ret = true;
2373
 
2374
    settype($user_id, "int");
2375
 
2376
    $conn = phorum_db_mysql_connect();
2377
    // user-table
2378
    $sql = "delete from {$PHORUM['user_table']} where user_id=$user_id";
2379
    $res = mysql_query($sql, $conn);
2380
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2381
 
2382
    // permissions-table
2383
    $sql = "delete from {$PHORUM['user_permissions_table']} where user_id=$user_id";
2384
    $res = mysql_query($sql, $conn);
2385
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2386
 
2387
    // newflags-table
2388
    $sql = "delete from {$PHORUM['user_newflags_table']} where user_id=$user_id";
2389
    $res = mysql_query($sql, $conn);
2390
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2391
 
2392
    // subscribers-table
2393
    $sql = "delete from {$PHORUM['subscribers_table']} where user_id=$user_id";
2394
    $res = mysql_query($sql, $conn);
2395
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2396
 
2397
    // group-xref-table
2398
    $sql = "delete from {$PHORUM['user_group_xref_table']} where user_id=$user_id";
2399
    $res = mysql_query($sql, $conn);
2400
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2401
 
2402
    // private messages
2403
    $sql = "select * from {$PHORUM["pm_xref_table"]} where user_id=$user_id";
2404
    $res = mysql_query($sql, $conn);
2405
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2406
    while ($row = mysql_fetch_assoc($res)) {
2407
        $folder = $row["pm_folder_id"] == 0 ? $row["special_folder"] : $row["pm_folder_id"];
2408
        phorum_db_pm_delete($row["pm_message_id"], $folder, $user_id);
2409
    }
2410
 
2411
    // pm_buddies
2412
    $sql = "delete from {$PHORUM["pm_buddies_table"]} where user_id=$user_id or buddy_user_id=$user_id";
2413
    $res = mysql_query($sql, $conn);
2414
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2415
 
2416
    // private message folders
2417
    $sql = "delete from {$PHORUM["pm_folders_table"]} where user_id=$user_id";
2418
    $res = mysql_query($sql, $conn);
2419
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2420
 
2421
    // files-table
2422
    $sql = "delete from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
2423
    $res = mysql_query($sql, $conn);
2424
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2425
 
2426
    // custom-fields-table
2427
    $sql = "delete from {$PHORUM['user_custom_fields_table']} where user_id=$user_id";
2428
    $res = mysql_query($sql, $conn);
2429
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2430
 
2431
    // messages-table
2432
    if(PHORUM_DELETE_CHANGE_AUTHOR) {
2433
      $sql = "update {$PHORUM['message_table']} set user_id=0,email='',author='".mysql_escape_string($PHORUM['DATA']['LANG']['AnonymousUser'])."' where user_id=$user_id";
2434
    } else {
2435
      $sql = "update {$PHORUM['message_table']} set user_id=0,email='' where user_id=$user_id";
2436
    }
2437
    $res = mysql_query($sql, $conn);
2438
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2439
 
2440
    return $ret;
2441
}
2442
 
2443
 
2444
/**
2445
 * This function gets the users file list
2446
 */
2447
 
2448
function phorum_db_get_user_file_list($user_id)
2449
{
2450
    $PHORUM = $GLOBALS["PHORUM"];
2451
 
2452
    $conn = phorum_db_mysql_connect();
2453
 
2454
    settype($user_id, "int");
2455
 
2456
    $files=array();
2457
 
2458
    $sql="select file_id, filename, filesize, add_datetime from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
2459
 
2460
    $res = mysql_query($sql, $conn);
2461
 
2462
    if ($err = mysql_error()){
2463
        phorum_db_mysql_error("$err: $sql");
2464
    }
2465
 
2466
    if($res){
2467
        while($rec=mysql_fetch_assoc($res)){
2468
            $files[$rec["file_id"]]=$rec;
2469
        }
2470
    }
2471
 
2472
    return $files;
2473
}
2474
 
2475
 
2476
/**
2477
 * This function gets the message's file list
2478
 */
2479
 
2480
function phorum_db_get_message_file_list($message_id)
2481
{
2482
    $PHORUM = $GLOBALS["PHORUM"];
2483
 
2484
    $conn = phorum_db_mysql_connect();
2485
 
2486
    $files=array();
2487
 
2488
    $sql="select file_id, filename, filesize, add_datetime from {$PHORUM['files_table']} where message_id=$message_id and link='" . PHORUM_LINK_MESSAGE . "'";
2489
 
2490
    $res = mysql_query($sql, $conn);
2491
 
2492
    if ($err = mysql_error()){
2493
        phorum_db_mysql_error("$err: $sql");
2494
    }
2495
 
2496
    if($res){
2497
        while($rec=mysql_fetch_assoc($res)){
2498
            $files[$rec["file_id"]]=$rec;
2499
        }
2500
    }
2501
 
2502
    return $files;
2503
}
2504
 
2505
 
2506
/**
2507
 * This function retrieves a file from the db
2508
 */
2509
 
2510
function phorum_db_file_get($file_id)
2511
{
2512
    $PHORUM = $GLOBALS["PHORUM"];
2513
 
2514
    $conn = phorum_db_mysql_connect();
2515
 
2516
    settype($file_id, "int");
2517
 
2518
    $file=array();
2519
 
2520
    $sql="select * from {$PHORUM['files_table']} where file_id=$file_id";
2521
 
2522
    $res = mysql_query($sql, $conn);
2523
 
2524
    if ($err = mysql_error()){
2525
        phorum_db_mysql_error("$err: $sql");
2526
    }
2527
 
2528
    if($res){
2529
        $file=mysql_fetch_assoc($res);
2530
    }
2531
 
2532
    return $file;
2533
}
2534
 
2535
 
2536
/**
2537
 * This function saves a file to the db
2538
 */
2539
 
2540
function phorum_db_file_save($user_id, $filename, $filesize, $buffer, $message_id=0, $link=null)
2541
{
2542
    $PHORUM = $GLOBALS["PHORUM"];
2543
 
2544
    if (is_null($link)) {
2545
        $link = $message_id ? PHORUM_LINK_MESSAGE : PHORUM_LINK_USER;
2546
    } else {
2547
        $link = addslashes($link);
2548
    }
2549
 
2550
    $conn = phorum_db_mysql_connect();
2551
 
2552
    $file_id=0;
2553
 
2554
    settype($user_id, "int");
2555
    settype($message_id, "int");
2556
    settype($filesize, "int");
2557
 
2558
    $filename=addslashes($filename);
2559
 
2560
    $sql="insert into {$PHORUM['files_table']} set user_id=$user_id, message_id=$message_id, link='$link', filename='$filename', filesize=$filesize, file_data='$buffer', add_datetime=".time();
2561
 
2562
    $res = mysql_query($sql, $conn);
2563
 
2564
    if ($err = mysql_error()){
2565
        phorum_db_mysql_error("$err: $sql");
2566
    }
2567
 
2568
    if($res){
2569
        $file_id=mysql_insert_id($conn);
2570
    }
2571
 
2572
    return $file_id;
2573
}
2574
 
2575
 
2576
/**
2577
 * This function saves a file to the db
2578
 */
2579
 
2580
function phorum_db_file_delete($file_id)
2581
{
2582
    $PHORUM = $GLOBALS["PHORUM"];
2583
 
2584
    $conn = phorum_db_mysql_connect();
2585
 
2586
    settype($file_id, "int");
2587
 
2588
    $sql="delete from {$PHORUM['files_table']} where file_id=$file_id";
2589
 
2590
    $res = mysql_query($sql, $conn);
2591
 
2592
    if ($err = mysql_error()){
2593
        phorum_db_mysql_error("$err: $sql");
2594
    }
2595
 
2596
    return $res;
2597
}
2598
 
2599
/**
2600
 * This function links a file to a specific message
2601
 */
2602
 
2603
function phorum_db_file_link($file_id, $message_id, $link = null)
2604
{
2605
    $PHORUM = $GLOBALS["PHORUM"];
2606
 
2607
    if (is_null($link)) {
2608
        $link = $message_id ? PHORUM_LINK_MESSAGE : PHORUM_LINK_USER;
2609
    } else {
2610
        $link = addslashes($link);
2611
    }
2612
 
2613
    $conn = phorum_db_mysql_connect();
2614
 
2615
    settype($file_id, "int");
2616
    settype($message_id, "int");
2617
 
2618
    $sql="update {$PHORUM['files_table']} " .
2619
         "set message_id=$message_id, link='$link' " .
2620
         "where file_id=$file_id";
2621
 
2622
    $res = mysql_query($sql, $conn);
2623
 
2624
    if ($err = mysql_error()){
2625
        phorum_db_mysql_error("$err: $sql");
2626
    }
2627
 
2628
    return $res;
2629
}
2630
 
2631
/**
2632
 * This function reads the current total size of all files for a user
2633
 */
2634
 
2635
function phorum_db_get_user_filesize_total($user_id)
2636
{
2637
    $PHORUM = $GLOBALS["PHORUM"];
2638
 
2639
    $conn = phorum_db_mysql_connect();
2640
 
2641
    settype($user_id, "int");
2642
 
2643
    $total=0;
2644
 
2645
    $sql="select sum(filesize) as total from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
2646
 
2647
    $res = mysql_query($sql, $conn);
2648
 
2649
    if ($err = mysql_error()){
2650
        phorum_db_mysql_error("$err: $sql");
2651
    }
2652
 
2653
    if($res){
2654
        $total=mysql_result($res, 0,"total");
2655
    }
2656
 
2657
    return $total;
2658
 
2659
}
2660
 
2661
/**
2662
 * This function is used for cleaning up stale files from the
2663
 * database. Stale files are files that are not linked to
2664
 * anything. These can for example be caused by users that
2665
 * are writing a message with attachments, but never post
2666
 * it.
2667
 * @param live_run - If set to false (default), the function
2668
 *                  will return a list of files that will
2669
 *                  be purged. If set to true, files will
2670
 *                  be purged.
2671
 */
2672
function phorum_db_file_purge_stale_files($live_run = false)
2673
{
2674
    $PHORUM = $GLOBALS["PHORUM"];
2675
 
2676
    $conn = phorum_db_mysql_connect();
2677
 
2678
    $where = "link='" . PHORUM_LINK_EDITOR. "' " .
2679
             "and add_datetime<". (time()-PHORUM_MAX_EDIT_TIME);
2680
 
2681
    // Purge files.
2682
    if ($live_run) {
2683
 
2684
        // Delete files that are linked to the editor and are
2685
        // added a while ago. These are from abandoned posts.
2686
        $sql = "delete from {$PHORUM['files_table']} " .
2687
               "where $where";
2688
        $res = mysql_query($sql, $conn);
2689
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2690
 
2691
        return true;
2692
 
2693
    // Only select a list of files that can be purged.
2694
    } else {
2695
 
2696
        // Select files that are linked to the editor and are
2697
        // added a while ago. These are from abandoned posts.
2698
        $sql = "select file_id, filename, filesize, add_datetime " .
2699
               "from {$PHORUM['files_table']} " .
2700
               "where $where";
2701
 
2702
        $res = mysql_query($sql, $conn);
2703
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2704
 
2705
        $purge_files = array();
2706
        if (mysql_num_rows($res) > 0) {
2707
            while ($row = mysql_fetch_assoc($res)) {
2708
                $row["reason"] = "Stale editor file";
2709
                $purge_files[$row["file_id"]] = $row;
2710
            }
2711
        }
2712
 
2713
        return $purge_files;
2714
    }
2715
}
2716
 
2717
/**
2718
 * This function returns the newinfo-array for markallread
2719
 */
2720
 
2721
function phorum_db_newflag_allread($forum_id=0)
2722
{
2723
    $PHORUM = $GLOBALS['PHORUM'];
2724
    $conn = phorum_db_mysql_connect();
2725
 
2726
    settype($forum_id, "int");
2727
 
2728
    if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
2729
 
2730
    // delete all newflags for this user and forum
2731
    phorum_db_newflag_delete(0,$forum_id);
2732
 
2733
    // get the maximum message-id in this forum
2734
    $sql = "select max(message_id) from {$PHORUM['message_table']} where forum_id=$forum_id";
2735
    $res = mysql_query($sql, $conn);
2736
    if ($err = mysql_error()){
2737
        phorum_db_mysql_error("$err: $sql");
2738
    }elseif (mysql_num_rows($res) > 0){
2739
        $row = mysql_fetch_row($res);
2740
        if($row[0] > 0) {
2741
            // set this message as min-id
2742
            phorum_db_newflag_add_read(array(0=>array('id'=>$row[0],'forum'=>$forum_id)));
2743
        }
2744
    }
2745
 
2746
}
2747
 
2748
 
2749
/**
2750
* This function returns the read messages for the current user and forum
2751
* optionally for a given forum (for the index)
2752
*/
2753
function phorum_db_newflag_get_flags($forum_id=0)
2754
{
2755
    $PHORUM = $GLOBALS["PHORUM"];
2756
 
2757
    settype($forum_id, "int");
2758
 
2759
    $read_msgs=array('min_id'=>0);
2760
 
2761
    if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
2762
 
2763
    $sql="SELECT message_id,forum_id FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id IN({$forum_id},{$PHORUM['vroot']})";
2764
 
2765
    $conn = phorum_db_mysql_connect();
2766
    $res = mysql_query($sql, $conn);
2767
 
2768
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2769
 
2770
    while($row=mysql_fetch_row($res)) {
2771
        // set the min-id if given flag is set
2772
        if($row[1] != $PHORUM['vroot'] && ($read_msgs['min_id']==0 || $row[0] < $read_msgs['min_id'])) {
2773
            $read_msgs['min_id']=$row[0];
2774
        } else {
2775
            $read_msgs[$row[0]]=$row[0];
2776
        }
2777
    }
2778
 
2779
    return $read_msgs;
2780
}
2781
 
2782
 
2783
/**
2784
* This function returns the count of unread messages the current user and forum
2785
* optionally for a given forum (for the index)
2786
*/
2787
function phorum_db_newflag_get_unread_count($forum_id=0)
2788
{
2789
    $PHORUM = $GLOBALS["PHORUM"];
2790
 
2791
    settype($forum_id, "int");
2792
 
2793
    if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
2794
 
2795
    // get the read message array
2796
    $read_msgs = phorum_db_newflag_get_flags($forum_id);
2797
 
2798
    if($read_msgs["min_id"]==0) return array(0,0);
2799
 
2800
    $sql="SELECT count(*) as count FROM ".$PHORUM['message_table']." WHERE message_id NOT in (".implode(",", $read_msgs).") and message_id > {$read_msgs['min_id']} and forum_id in ({$forum_id},0) and status=".PHORUM_STATUS_APPROVED." and not ".PHORUM_SQL_MOVEDMESSAGES;
2801
 
2802
    $conn = phorum_db_mysql_connect();
2803
    $res = mysql_query($sql, $conn);
2804
 
2805
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2806
 
2807
    $counts[] = mysql_result($res, 0, "count");
2808
 
2809
    $sql="SELECT count(*) as count FROM ".$PHORUM['message_table']." WHERE message_id NOT in (".implode(",", $read_msgs).") and message_id > {$read_msgs['min_id']} and forum_id in ({$forum_id},0) and parent_id=0 and status=".PHORUM_STATUS_APPROVED." and not ".PHORUM_SQL_MOVEDMESSAGES;
2810
 
2811
    $conn = phorum_db_mysql_connect();
2812
    $res = mysql_query($sql, $conn);
2813
 
2814
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2815
 
2816
    $counts[] = mysql_result($res, 0, "count");
2817
 
2818
    return $counts;
2819
}
2820
 
2821
 
2822
/**
2823
 * This function marks a message as read
2824
 */
2825
function phorum_db_newflag_add_read($message_ids) {
2826
    $PHORUM = $GLOBALS["PHORUM"];
2827
 
2828
    $num_newflags=phorum_db_newflag_get_count();
2829
 
2830
    // maybe got just one message
2831
    if(!is_array($message_ids)) {
2832
        $message_ids=array(0=>(int)$message_ids);
2833
    }
2834
    // deleting messages which are too much
2835
    $num_end=$num_newflags+count($message_ids);
2836
    if($num_end > PHORUM_MAX_NEW_INFO) {
2837
        phorum_db_newflag_delete($num_end - PHORUM_MAX_NEW_INFO);
2838
    }
2839
    // building the query
2840
    $values=array();
2841
    $cnt=0;
2842
 
2843
    foreach($message_ids as $id=>$data) {
2844
        if(is_array($data)) {
2845
            $values[]="({$PHORUM['user']['user_id']},{$data['forum']},{$data['id']})";
2846
        } else {
2847
            $values[]="({$PHORUM['user']['user_id']},{$PHORUM['forum_id']},$data)";
2848
        }
2849
        $cnt++;
2850
    }
2851
    if($cnt) {
2852
        $insert_sql="INSERT IGNORE INTO ".$PHORUM['user_newflags_table']." (user_id,forum_id,message_id) VALUES".join(",",$values);
2853
 
2854
        // fire away
2855
        $conn = phorum_db_mysql_connect();
2856
        $res = mysql_query($insert_sql, $conn);
2857
 
2858
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $insert_sql");
2859
    }
2860
}
2861
 
2862
/**
2863
* This function returns the number of newflags for this user and forum
2864
*/
2865
function phorum_db_newflag_get_count($forum_id=0)
2866
{
2867
    $PHORUM = $GLOBALS["PHORUM"];
2868
 
2869
    settype($forum_id, "int");
2870
 
2871
    if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
2872
 
2873
    $sql="SELECT count(*) FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id={$forum_id}";
2874
 
2875
    // fire away
2876
    $conn = phorum_db_mysql_connect();
2877
    $res = mysql_query($sql, $conn);
2878
 
2879
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2880
 
2881
    $row=mysql_fetch_row($res);
2882
 
2883
    return $row[0];
2884
}
2885
 
2886
/**
2887
* This function removes a number of newflags for this user and forum
2888
*/
2889
function phorum_db_newflag_delete($numdelete=0,$forum_id=0)
2890
{
2891
    $PHORUM = $GLOBALS["PHORUM"];
2892
 
2893
    settype($forum_id, "int");
2894
    settype($numdelete, "int");
2895
 
2896
    if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
2897
 
2898
    if($numdelete>0) {
2899
        $lvar=" ORDER BY message_id ASC LIMIT $numdelete";
2900
    } else {
2901
        $lvar="";
2902
    }
2903
    // delete the number of newflags given
2904
    $del_sql="DELETE FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id={$forum_id}".$lvar;
2905
    // fire away
2906
    $conn = phorum_db_mysql_connect();
2907
    $res = mysql_query($del_sql, $conn);
2908
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $del_sql");
2909
}
2910
 
2911
/**
2912
 * This function executes a query to get the user ids of the users
2913
 * subscribed to a forum/thread.
2914
 */
2915
 
2916
function phorum_db_get_subscribed_users($forum_id, $thread, $type){
2917
    $PHORUM = $GLOBALS["PHORUM"];
2918
 
2919
    settype($forum_id, "int");
2920
    settype($thread, "int");
2921
    settype($type, "int");
2922
 
2923
    $conn = phorum_db_mysql_connect();
2924
 
2925
    $userignore="";
2926
    if ($PHORUM["DATA"]["LOGGEDIN"])
2927
       $userignore="and b.user_id != {$PHORUM['user']['user_id']}";
2928
 
2929
    $sql = "select DISTINCT(b.email),user_language from {$PHORUM['subscribers_table']} as a,{$PHORUM['user_table']} as b where a.forum_id=$forum_id and (a.thread=$thread or a.thread=0) and a.sub_type=$type and b.user_id=a.user_id $userignore";
2930
 
2931
    $res = mysql_query($sql, $conn);
2932
 
2933
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2934
 
2935
        $arr=array();
2936
 
2937
    while ($rec = mysql_fetch_row($res)){
2938
        if(!empty($rec[1])) // user-language is set
2939
            $arr[$rec[1]][] = $rec[0];
2940
        else // no user-language is set
2941
            $arr[$PHORUM['language']][]= $rec[0];
2942
    }
2943
 
2944
    return $arr;
2945
}
2946
 
2947
/**
2948
 * This function executes a query to get the subscriptions of a user-id,
2949
 * together with the forum-id and subjects of the threads
2950
 */
2951
 
2952
function phorum_db_get_message_subscriptions($user_id,$days=2){
2953
    $PHORUM = $GLOBALS["PHORUM"];
2954
 
2955
    $conn = phorum_db_mysql_connect();
2956
 
2957
    $userignore="";
2958
    if ($PHORUM["DATA"]["LOGGEDIN"])
2959
       $userignore="and b.user_id != {$PHORUM['user']['user_id']}";
2960
 
2961
    if($days > 0) {
2962
         $timestr=" AND (".time()." - b.modifystamp) <= ($days * 86400)";
2963
    } else {
2964
        $timestr="";
2965
    }
2966
 
2967
    $sql = "select a.thread, a.forum_id, a.sub_type, b.subject,b.modifystamp,b.author,b.user_id,b.email from {$PHORUM['subscribers_table']} as a,{$PHORUM['message_table']} as b where a.user_id=$user_id and b.message_id=a.thread and (a.sub_type=".PHORUM_SUBSCRIPTION_MESSAGE." or a.sub_type=".PHORUM_SUBSCRIPTION_BOOKMARK.")"."$timestr ORDER BY b.modifystamp desc";
2968
 
2969
    $res = mysql_query($sql, $conn);
2970
 
2971
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
2972
 
2973
    $arr=array();
2974
    $forum_ids=array();
2975
 
2976
    while ($rec = mysql_fetch_assoc($res)){
2977
        $unsub_url=phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=".PHORUM_CC_SUBSCRIPTION_THREADS, "unsub_id=".$rec['thread'], "unsub_forum=".$rec['forum_id'], "unsub_type=".$rec['sub_type']);
2978
        $rec['unsubscribe_url']=$unsub_url;
2979
        $arr[] = $rec;
2980
        $forum_ids[]=$rec['forum_id'];
2981
    }
2982
    $arr['forum_ids']=$forum_ids;
2983
 
2984
    return $arr;
2985
}
2986
 
2987
/**
2988
 * This function executes a query to find out if a user is subscribed to a thread
2989
 */
2990
 
2991
function phorum_db_get_if_subscribed($forum_id, $thread, $user_id, $type=PHORUM_SUBSCRIPTION_MESSAGE)
2992
{
2993
    $PHORUM = $GLOBALS["PHORUM"];
2994
 
2995
    settype($forum_id, "int");
2996
    settype($thread, "int");
2997
    settype($user_id, "int");
2998
    settype($type, "int");
2999
 
3000
    $conn = phorum_db_mysql_connect();
3001
 
3002
    $sql = "select user_id from {$PHORUM['subscribers_table']} where forum_id=$forum_id and thread=$thread and user_id=$user_id and sub_type=$type";
3003
 
3004
    $res = mysql_query($sql, $conn);
3005
 
3006
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3007
 
3008
    if (mysql_num_rows($res) > 0){
3009
        $retval = true;
3010
    }else{
3011
        $retval = false;
3012
    }
3013
 
3014
    return $retval;
3015
}
3016
 
3017
 
3018
/**
3019
 * This function retrieves the banlists for the current forum
3020
 */
3021
 
3022
function phorum_db_get_banlists($ordered=false) {
3023
    $PHORUM = $GLOBALS["PHORUM"];
3024
 
3025
    $retarr = array();
3026
    $forumstr = "";
3027
 
3028
    $conn = phorum_db_mysql_connect();
3029
 
3030
    if(isset($PHORUM['forum_id']) && !empty($PHORUM['forum_id']))
3031
        $forumstr = "WHERE forum_id = {$PHORUM['forum_id']} OR forum_id = 0";
3032
 
3033
    if(isset($PHORUM['vroot']) && !empty($PHORUM['vroot']))
3034
        $forumstr .= " OR forum_id = {$PHORUM['vroot']}";
3035
 
3036
 
3037
 
3038
    $sql = "SELECT * FROM {$PHORUM['banlist_table']} $forumstr";
3039
 
3040
    if($ordered) {
3041
        $sql.= " ORDER BY type, string";
3042
    }
3043
 
3044
    $res = mysql_query($sql, $conn);
3045
 
3046
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3047
 
3048
    if (mysql_num_rows($res) > 0){
3049
        while($row = mysql_fetch_assoc($res)) {
3050
            $retarr[$row['type']][$row['id']]=array('pcre'=>$row['pcre'],'string'=>$row['string'],'forum_id'=>$row['forum_id']);
3051
        }
3052
    }
3053
    return $retarr;
3054
}
3055
 
3056
 
3057
/**
3058
 * This function retrieves one item from the banlists
3059
 */
3060
 
3061
function phorum_db_get_banitem($banid) {
3062
    $PHORUM = $GLOBALS["PHORUM"];
3063
 
3064
    $retarr = array();
3065
 
3066
    $conn = phorum_db_mysql_connect();
3067
 
3068
    settype($banid, "int");
3069
 
3070
    $sql = "SELECT * FROM {$PHORUM['banlist_table']} WHERE id = $banid";
3071
 
3072
    $res = mysql_query($sql, $conn);
3073
 
3074
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3075
 
3076
    if (mysql_num_rows($res) > 0){
3077
        while($row = mysql_fetch_assoc($res)) {
3078
            $retarr=array('pcre'=>$row['pcre'],'string'=>$row['string'],'forumid'=>$row['forum_id'],'type'=>$row['type']);
3079
        }
3080
    }
3081
    return $retarr;
3082
}
3083
 
3084
 
3085
/**
3086
 * This function deletes one item from the banlists
3087
 */
3088
 
3089
function phorum_db_del_banitem($banid) {
3090
    $PHORUM = $GLOBALS["PHORUM"];
3091
 
3092
    $conn = phorum_db_mysql_connect();
3093
 
3094
    $sql = "DELETE FROM {$PHORUM['banlist_table']} WHERE id = $banid";
3095
 
3096
    $res = mysql_query($sql, $conn);
3097
 
3098
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3099
 
3100
    if(mysql_affected_rows($conn) > 0) {
3101
        return true;
3102
    } else {
3103
        return false;
3104
    }
3105
}
3106
 
3107
 
3108
/**
3109
 * This function adds or modifies a banlist-entry
3110
 */
3111
 
3112
function phorum_db_mod_banlists($type,$pcre,$string,$forum_id,$id=0) {
3113
    $PHORUM = $GLOBALS["PHORUM"];
3114
 
3115
    $retarr = array();
3116
 
3117
    $conn = phorum_db_mysql_connect();
3118
 
3119
    settype($type, "int");
3120
    settype($pcre, "int");
3121
    settype($forum_id, "int");
3122
    settype($id, "int");
3123
 
3124
    if($id > 0) { // modifying an entry
3125
        $sql = "UPDATE {$PHORUM['banlist_table']} SET forum_id = $forum_id, type = $type, pcre = $pcre, string = '".mysql_escape_string($string)."' where id = $id";
3126
    } else { // adding an entry
3127
        $sql = "INSERT INTO {$PHORUM['banlist_table']} (forum_id,type,pcre,string) VALUES($forum_id,$type,$pcre,'".mysql_escape_string($string)."')";
3128
    }
3129
 
3130
    $res = mysql_query($sql, $conn);
3131
 
3132
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3133
 
3134
    if(mysql_affected_rows($conn) > 0) {
3135
        return true;
3136
    } else {
3137
        return false;
3138
    }
3139
}
3140
 
3141
 
3142
 
3143
/**
3144
 * This function lists all private messages in a folder.
3145
 * @param folder - The folder to use. Either a special folder
3146
 *                 (PHORUM_PM_INBOX or PHORUM_PM_OUTBOX) or the
3147
 *                 id of a user's custom folder.
3148
 * @param user_id - The user to retrieve messages for or NULL
3149
 *                 to use the current user (default).
3150
 * @param reverse - If set to a true value (default), sorting
3151
 *                 of messages is done in reverse (newest first).
3152
 */
3153
 
3154
function phorum_db_pm_list($folder, $user_id = NULL, $reverse = true)
3155
{
3156
    $PHORUM = $GLOBALS["PHORUM"];
3157
 
3158
    $conn = phorum_db_mysql_connect();
3159
 
3160
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3161
    settype($user_id, "int");
3162
 
3163
    $folder_sql = "user_id = $user_id AND ";
3164
    if (is_numeric($folder)) {
3165
        $folder_sql .= "pm_folder_id=$folder";
3166
    } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
3167
        $folder_sql .= "pm_folder_id=0 AND special_folder='$folder'";
3168
    } else {
3169
        die ("Illegal folder '$folder' requested for user id '$user_id'");
3170
    }
3171
 
3172
    $sql = "SELECT m.pm_message_id, from_user_id, from_username, subject, " .
3173
           "datestamp, meta, pm_xref_id, user_id, pm_folder_id, " .
3174
           "special_folder, read_flag, reply_flag " .
3175
           "FROM {$PHORUM['pm_messages_table']} as m, {$PHORUM['pm_xref_table']} as x " .
3176
           "WHERE $folder_sql " .
3177
           "AND x.pm_message_id = m.pm_message_id " .
3178
           "ORDER BY x.pm_message_id " . ($reverse ? "DESC" : "ASC");
3179
    $res = mysql_query($sql, $conn);
3180
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3181
 
3182
    $list = array();
3183
    if (mysql_num_rows($res) > 0){
3184
        while($row = mysql_fetch_assoc($res)) {
3185
 
3186
            // Add the recipient information unserialized to the message..
3187
            $meta = unserialize($row['meta']);
3188
            $row['recipients'] = $meta['recipients'];
3189
 
3190
            $list[$row["pm_message_id"]]=$row;
3191
        }
3192
    }
3193
 
3194
    return $list;
3195
}
3196
 
3197
/**
3198
 * This function retrieves a private message from the database.
3199
 * @param pm_id - The id for the private message to retrieve.
3200
 * @param user_id - The user to retrieve messages for or NULL
3201
 *                 to use the current user (default).
3202
 * @param folder_id - The folder to retrieve the message from or
3203
 *                    NULL if the folder does not matter.
3204
 */
3205
 
3206
function phorum_db_pm_get($pm_id, $folder = NULL, $user_id = NULL)
3207
{
3208
    $PHORUM = $GLOBALS["PHORUM"];
3209
 
3210
    $conn = phorum_db_mysql_connect();
3211
 
3212
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3213
    settype($user_id, "int");
3214
    settype($pm_id, "int");
3215
 
3216
    if (is_null($folder)) {
3217
        $folder_sql = '';
3218
    } elseif (is_numeric($folder)) {
3219
        $folder_sql = "pm_folder_id=$folder AND ";
3220
    } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
3221
        $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND ";
3222
    } else {
3223
        die ("Illegal folder '$folder' requested for message id '$pm_id'");
3224
    }
3225
 
3226
    $sql = "SELECT * " .
3227
           "FROM {$PHORUM['pm_messages_table']} as m, {$PHORUM['pm_xref_table']} as x " .
3228
           "WHERE $folder_sql x.pm_message_id = $pm_id AND x.user_id = $user_id " .
3229
           "AND x.pm_message_id = m.pm_message_id";
3230
 
3231
    $res = mysql_query($sql, $conn);
3232
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3233
 
3234
    if (mysql_num_rows($res) > 0){
3235
        $row = mysql_fetch_assoc($res);
3236
 
3237
        // Add the recipient information unserialized to the message..
3238
        $meta = unserialize($row['meta']);
3239
        $row['recipients'] = $meta['recipients'];
3240
 
3241
        return $row;
3242
    } else {
3243
        return NULL;
3244
    }
3245
}
3246
 
3247
/**
3248
 * This function creates a new folder for a user.
3249
 * @param foldername - The name of the folder to create.
3250
 * @param user_id - The user to create the folder for or
3251
 *                  NULL to use the current user (default).
3252
 */
3253
function phorum_db_pm_create_folder($foldername, $user_id = NULL)
3254
{
3255
    $PHORUM = $GLOBALS["PHORUM"];
3256
 
3257
    $conn = phorum_db_mysql_connect();
3258
 
3259
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3260
    settype($user_id, "int");
3261
 
3262
    $sql = "INSERT INTO {$PHORUM['pm_folders_table']} SET " .
3263
           "user_id=$user_id, " .
3264
           "foldername='".mysql_escape_string($foldername)."'";
3265
 
3266
    $res = mysql_query($sql, $conn);
3267
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3268
    return $res;
3269
}
3270
 
3271
/**
3272
 * This function renames a folder for a user.
3273
 * @param folder_id - The id of the folder to rename.
3274
 * @param newname - The new name for the folder.
3275
 * @param user_id - The user to rename the folder for or
3276
 *                  NULL to use the current user (default).
3277
 */
3278
function phorum_db_pm_rename_folder($folder_id, $newname, $user_id = NULL)
3279
{
3280
    $PHORUM = $GLOBALS["PHORUM"];
3281
 
3282
    $conn = phorum_db_mysql_connect();
3283
 
3284
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3285
    settype($user_id, "int");
3286
    settype($folder_id, "int");
3287
 
3288
    $sql = "UPDATE {$PHORUM['pm_folders_table']} " .
3289
           "SET foldername = '".mysql_escape_string($newname)."' " .
3290
           "WHERE pm_folder_id = $folder_id AND user_id = $user_id";
3291
 
3292
    $res = mysql_query($sql, $conn);
3293
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3294
    return $res;
3295
}
3296
 
3297
 
3298
 
3299
/**
3300
 * This function deletes a folder for a user. Along with the
3301
 * folder, all contained messages are deleted as well.
3302
 * @param folder_id - The id of the folder to delete.
3303
 * @param user_id - The user to delete the folder for or
3304
 *                  NULL to use the current user (default).
3305
 */
3306
function phorum_db_pm_delete_folder($folder_id, $user_id = NULL)
3307
{
3308
    $PHORUM = $GLOBALS["PHORUM"];
3309
 
3310
    $conn = phorum_db_mysql_connect();
3311
 
3312
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3313
    settype($user_id, "int");
3314
    settype($folder_id, "int");
3315
 
3316
    // Get messages in this folder and delete them.
3317
    $list = phorum_db_pm_list($folder_id, $user_id);
3318
    foreach ($list as $id => $data) {
3319
        phorum_db_pm_delete($id, $folder_id, $user_id);
3320
    }
3321
 
3322
    // Delete the folder itself.
3323
    $sql = "DELETE FROM {$PHORUM['pm_folders_table']} " .
3324
           "WHERE pm_folder_id = $folder_id AND user_id = $user_id";
3325
    $res = mysql_query($sql, $conn);
3326
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3327
    return $res;
3328
}
3329
 
3330
/**
3331
 * This function retrieves the list of folders for a user.
3332
 * @param user_id - The user to retrieve folders for or NULL
3333
 *                 to use the current user (default).
3334
 * @param count_messages - Count the number of messages for the
3335
 *                 folders. Default, this is not done.
3336
 */
3337
function phorum_db_pm_getfolders($user_id = NULL, $count_messages = false)
3338
{
3339
    $PHORUM = $GLOBALS["PHORUM"];
3340
 
3341
    $conn = phorum_db_mysql_connect();
3342
 
3343
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3344
    settype($user_id, "int");
3345
 
3346
    // Setup the list of folders. Our special folders are
3347
    // not in the database, so these are added here.
3348
    $folders = array(
3349
        PHORUM_PM_INBOX => array(
3350
            'id'   => PHORUM_PM_INBOX,
3351
            'name' => $PHORUM["DATA"]["LANG"]["INBOX"],
3352
        ),
3353
    );
3354
 
3355
    // Select all custom folders for the user.
3356
    $sql = "SELECT * FROM {$PHORUM['pm_folders_table']} " .
3357
           "WHERE user_id = $user_id ORDER BY foldername";
3358
    $res = mysql_query($sql, $conn);
3359
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3360
 
3361
    // Add them to the folderlist.
3362
    if (mysql_num_rows($res) > 0){
3363
        while (($row = mysql_fetch_assoc($res))) {
3364
            $folders[$row["pm_folder_id"]] = array(
3365
                'id' => $row["pm_folder_id"],
3366
                'name' => $row["foldername"],
3367
            );
3368
        }
3369
    }
3370
 
3371
    // Add the outgoing box.
3372
    $folders[PHORUM_PM_OUTBOX] = array(
3373
        'id'   => PHORUM_PM_OUTBOX,
3374
        'name' => $PHORUM["DATA"]["LANG"]["SentItems"],
3375
    );
3376
 
3377
    // Count messages if requested.
3378
    if ($count_messages)
3379
    {
3380
        // Initialize counters.
3381
        foreach ($folders as $id => $data) {
3382
            $folders[$id]["total"] = $folders[$id]["new"] = 0;
3383
        }
3384
 
3385
        // Collect count information.
3386
        $sql = "SELECT pm_folder_id, special_folder, " .
3387
               "count(*) as total, (count(*) - sum(read_flag)) as new " .
3388
               "FROM {$PHORUM['pm_xref_table']}  " .
3389
               "WHERE user_id = $user_id " .
3390
               "GROUP BY pm_folder_id, special_folder";
3391
        $res = mysql_query($sql, $conn);
3392
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3393
 
3394
        // Add counters to the folderlist.
3395
        if (mysql_num_rows($res) > 0){
3396
            while (($row = mysql_fetch_assoc($res))) {
3397
                $folder_id = $row["pm_folder_id"] ? $row["pm_folder_id"] : $row["special_folder"];
3398
                // If there are stale messages, we do not want them
3399
                // to create non-existant mailboxes in the list.
3400
                if (isset($folders[$folder_id])) {
3401
                    $folders[$folder_id]["total"] = $row["total"];
3402
                    $folders[$folder_id]["new"] = $row["new"];
3403
                }
3404
            }
3405
        }
3406
    }
3407
 
3408
    return $folders;
3409
}
3410
 
3411
/**
3412
 * This function computes the number of private messages a user has
3413
 * and returns both the total and the number unread.
3414
 * @param folder - The folder to use. Either a special folder
3415
 *                 (PHORUM_PM_INBOX or PHORUM_PM_OUTBOX), the
3416
 *                 id of a user's custom folder or
3417
 *                 PHORUM_PM_ALLFOLDERS for all folders.
3418
 * @param user_id - The user to retrieve messages for or NULL
3419
 *                 to use the current user (default).
3420
 */
3421
 
3422
function phorum_db_pm_messagecount($folder, $user_id = NULL)
3423
{
3424
    $PHORUM = $GLOBALS["PHORUM"];
3425
 
3426
    $conn = phorum_db_mysql_connect();
3427
 
3428
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3429
    settype($user_id, "int");
3430
 
3431
    if (is_numeric($folder)) {
3432
        $folder_sql = "pm_folder_id=$folder AND";
3433
    } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
3434
        $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND";
3435
    } elseif ($folder == PHORUM_PM_ALLFOLDERS) {
3436
        $folder_sql = '';
3437
    } else {
3438
        die ("Illegal folder '$folder' requested for user id '$user_id'");
3439
    }
3440
 
3441
    $sql = "SELECT count(*) as total, (count(*) - sum(read_flag)) as new " .
3442
           "FROM {$PHORUM['pm_xref_table']}  " .
3443
           "WHERE $folder_sql user_id = $user_id";
3444
 
3445
    $messagecount=array("total" => 0, "new" => 0);
3446
 
3447
    $res = mysql_query($sql, $conn);
3448
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3449
 
3450
    if (mysql_num_rows($res) > 0){
3451
        $row = mysql_fetch_assoc($res);
3452
        $messagecount["total"] = $row["total"];
3453
        $messagecount["new"] = ($row["new"] >= 1) ? $row["new"] : 0;
3454
    }
3455
 
3456
    return $messagecount;
3457
}
3458
 
3459
/**
3460
 * This function does a quick check if the user has new private messages.
3461
 * This is useful in case you only want to know whether the user has
3462
 * new messages or not and when you are not interested in the exact amount
3463
 * of new messages.
3464
 *
3465
 * @param user_id - The user to retrieve messages for or NULL
3466
 *                 to use the current user (default).
3467
 * @return A true value, in case there are new messages available.
3468
 */
3469
function phorum_db_pm_checknew($user_id = NULL)
3470
{
3471
    $PHORUM = $GLOBALS["PHORUM"];
3472
 
3473
    $conn = phorum_db_mysql_connect();
3474
 
3475
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3476
    settype($user_id, "int");
3477
 
3478
    $sql = "SELECT user_id " .
3479
           "FROM {$PHORUM['pm_xref_table']} " .
3480
           "WHERE user_id = $user_id AND read_flag = 0 LIMIT 1";
3481
    $res = mysql_query($sql, $conn);
3482
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3483
 
3484
    return mysql_num_rows($res);
3485
}
3486
 
3487
/**
3488
 * This function inserts a private message in the database. The return value
3489
 * is the pm_message_id of the created message.
3490
 * @param subject - The subject for the private message.
3491
 * @param message - The message text for the private message.
3492
 * @param to - A single user_id or an array of user_ids for the recipients.
3493
 * @param from - The user_id of the sender. The current user is used in case
3494
 *               the parameter is set to NULL (default).
3495
 * @param keepcopy - If set to a true value, a copy of the mail will be put in
3496
 *                   the outbox of the user. Default value is false.
3497
 */
3498
function phorum_db_pm_send($subject, $message, $to, $from=NULL, $keepcopy=false)
3499
{
3500
    $PHORUM = $GLOBALS["PHORUM"];
3501
 
3502
    $conn = phorum_db_mysql_connect();
3503
 
3504
    // Prepare the sender.
3505
    if ($from == NULL) $from = $PHORUM['user']['user_id'];
3506
    settype($from, "int");
3507
    $fromuser = phorum_db_user_get($from, false);
3508
    if (! $fromuser) die("Unknown sender user_id '$from'");
3509
 
3510
    // This array will be filled with xref database entries.
3511
    $xref_entries = array();
3512
 
3513
    // Prepare the list of recipients.
3514
    $rcpts = array();
3515
    if (! is_array($to)) $to = array($to);
3516
    foreach ($to as $user_id) {
3517
        settype($user_id, "int");
3518
        $user = phorum_db_user_get($user_id, false);
3519
        if (! $user) die("Unknown recipient user_id '$user_id'");
3520
        $rcpts[$user_id] = array(
3521
            'user_id' => $user_id,
3522
            'username' => $user["username"],
3523
            'read_flag' => 0,
3524
        );
3525
        $xref_entries[] = array(
3526
            'user_id' => $user_id,
3527
            'pm_folder_id' => 0,
3528
            'special_folder' => PHORUM_PM_INBOX,
3529
            'read_flag' => 0,
3530
        );
3531
    }
3532
 
3533
    // Keep copy of this message in outbox?
3534
    if ($keepcopy) {
3535
        $xref_entries[] = array(
3536
            'user_id' => $from,
3537
            'pm_folder_id' => 0,
3538
            'special_folder' => PHORUM_PM_OUTBOX,
3539
            'read_flag' => 1,
3540
        );
3541
    }
3542
 
3543
    // Prepare message meta data.
3544
    $meta = mysql_escape_string(serialize(array(
3545
        'recipients' => $rcpts
3546
    )));
3547
 
3548
    // Create the message.
3549
    $sql = "INSERT INTO {$PHORUM["pm_messages_table"]} SET " .
3550
           "from_user_id = $from, " .
3551
           "from_username = '".mysql_escape_string($fromuser["username"])."', " .
3552
           "subject = '".mysql_escape_string($subject)."', " .
3553
           "message = '".mysql_escape_string($message)."', " .
3554
           "datestamp = '".time()."', " .
3555
           "meta = '$meta'";
3556
    mysql_query($sql, $conn);
3557
    if ($err = mysql_error()) {
3558
        phorum_db_mysql_error("$err: $sql");
3559
        return;
3560
    }
3561
 
3562
    // Get the message id.
3563
    $pm_message_id = mysql_insert_id($conn);
3564
 
3565
    // Put the message in the recipient inboxes.
3566
    foreach ($xref_entries as $xref) {
3567
        $sql = "INSERT INTO {$PHORUM["pm_xref_table"]} SET " .
3568
               "user_id = {$xref["user_id"]}, " .
3569
               "pm_folder_id={$xref["pm_folder_id"]}, " .
3570
               "special_folder='{$xref["special_folder"]}', " .
3571
               "pm_message_id=$pm_message_id, " .
3572
               "read_flag = {$xref["read_flag"]}, " .
3573
               "reply_flag = 0";
3574
        mysql_query($sql, $conn);
3575
        if ($err = mysql_error()) {
3576
            phorum_db_mysql_error("$err: $sql");
3577
            return;
3578
        }
3579
 
3580
    }
3581
 
3582
    return $pm_message_id;
3583
}
3584
 
3585
/**
3586
 * This function updates a flag for a private message.
3587
 * @param pm_id - The id of the message to update.
3588
 * @param flag - The flag to update. Options are PHORUM_PM_READ_FLAG
3589
 *               and PHORUM_PM_REPLY_FLAG.
3590
 * @param value - The value for the flag (true or false).
3591
 * @param user_id - The user to set a flag for or NULL
3592
 *                 to use the current user (default).
3593
 */
3594
function phorum_db_pm_setflag($pm_id, $flag, $value, $user_id = NULL)
3595
{
3596
    $PHORUM = $GLOBALS["PHORUM"];
3597
 
3598
    $conn = phorum_db_mysql_connect();
3599
 
3600
    settype($pm_id, "int");
3601
 
3602
    if ($flag != PHORUM_PM_READ_FLAG && $flag != PHORUM_PM_REPLY_FLAG) {
3603
        trigger_error("Invalid value for \$flag in function phorum_db_pm_setflag(): $flag", E_USER_WARNING);
3604
        return 0;
3605
    }
3606
 
3607
    $value = $value ? 1 : 0;
3608
 
3609
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3610
    settype($user_id, "int");
3611
 
3612
    // Update the flag in the database.
3613
    $sql = "UPDATE {$PHORUM["pm_xref_table"]} " .
3614
           "SET $flag = $value " .
3615
           "WHERE pm_message_id = $pm_id AND user_id = $user_id";
3616
    $res = mysql_query($sql, $conn);
3617
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3618
 
3619
    // Update message counters.
3620
    if ($flag == PHORUM_PM_READ_FLAG) {
3621
        phorum_db_pm_update_message_info($pm_id);
3622
    }
3623
 
3624
    return $res;
3625
}
3626
 
3627
/**
3628
 * This function deletes a private message from a folder.
3629
 * @param folder - The folder from which to delete the message
3630
 * @param pm_id - The id of the private message to delete
3631
 * @param user_id - The user to delete the message for or NULL
3632
 *                 to use the current user (default).
3633
 */
3634
function phorum_db_pm_delete($pm_id, $folder, $user_id = NULL)
3635
{
3636
    $PHORUM = $GLOBALS["PHORUM"];
3637
 
3638
    $conn = phorum_db_mysql_connect();
3639
 
3640
    settype($pm_id, "int");
3641
 
3642
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3643
    settype($user_id, "int");
3644
 
3645
    if (is_numeric($folder)) {
3646
        $folder_sql = "pm_folder_id=$folder AND";
3647
    } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
3648
        $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND";
3649
    } else {
3650
        die ("Illegal folder '$folder' requested for user id '$user_id'");
3651
    }
3652
 
3653
    $sql = "DELETE FROM {$PHORUM["pm_xref_table"]} " .
3654
           "WHERE $folder_sql " .
3655
           "user_id = $user_id AND pm_message_id = $pm_id";
3656
 
3657
    $res = mysql_query($sql, $conn);
3658
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3659
 
3660
    // Update message counters.
3661
    phorum_db_pm_update_message_info($pm_id);
3662
 
3663
    return $res;
3664
}
3665
 
3666
/**
3667
 * This function moves a private message to a different folder.
3668
 * @param pm_id - The id of the private message to move.
3669
 * @param from - The folder to move the message from.
3670
 * @param to - The folder to move the message to.
3671
 * @param user_id - The user to move the message for or NULL
3672
 *                 to use the current user (default).
3673
 */
3674
function phorum_db_pm_move($pm_id, $from, $to, $user_id = NULL)
3675
{
3676
    $PHORUM = $GLOBALS["PHORUM"];
3677
 
3678
    $conn = phorum_db_mysql_connect();
3679
 
3680
    settype($pm_id, "int");
3681
 
3682
    if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
3683
    settype($user_id, "int");
3684
 
3685
    if (is_numeric($from)) {
3686
        $folder_sql = "pm_folder_id=$from AND";
3687
    } elseif ($from == PHORUM_PM_INBOX || $from == PHORUM_PM_OUTBOX) {
3688
        $folder_sql = "pm_folder_id=0 AND special_folder='$from' AND";
3689
    } else {
3690
        die ("Illegal source folder '$from' specified");
3691
    }
3692
 
3693
    if (is_numeric($to)) {
3694
        $pm_folder_id = $to;
3695
        $special_folder = 'NULL';
3696
    } elseif ($to == PHORUM_PM_INBOX || $to == PHORUM_PM_OUTBOX) {
3697
        $pm_folder_id = 0;
3698
        $special_folder = "'$to'";
3699
    } else {
3700
        die ("Illegal target folder '$to' specified");
3701
    }
3702
 
3703
    $sql = "UPDATE {$PHORUM["pm_xref_table"]} SET " .
3704
           "pm_folder_id = $pm_folder_id, " .
3705
           "special_folder = $special_folder " .
3706
           "WHERE $folder_sql user_id = $user_id AND pm_message_id = $pm_id";
3707
 
3708
    $res = mysql_query($sql, $conn);
3709
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3710
    return $res;
3711
}
3712
 
3713
/**
3714
 * This function updates the meta information for a message. If it
3715
 * detects that no xrefs are available for the message anymore,
3716
 * the message will be deleted from the database. So this function
3717
 * has to be called after setting the read_flag and after deleting
3718
 * a message.
3719
 * PMTODO maybe we need some locking here to prevent concurrent
3720
 * updates of the message info.
3721
 */
3722
function phorum_db_pm_update_message_info($pm_id)
3723
{
3724
    $PHORUM = $GLOBALS['PHORUM'];
3725
 
3726
    $conn = phorum_db_mysql_connect();
3727
 
3728
    settype($pm_id, "int");
3729
 
3730
    // Find the message record. Return immediately if no message is found.
3731
    $sql = "SELECT * " .
3732
           "FROM {$PHORUM['pm_messages_table']} " .
3733
           "WHERE pm_message_id = $pm_id";
3734
    $res = mysql_query($sql, $conn);
3735
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3736
    if (mysql_num_rows($res) == 0) return $res;
3737
    $pm = mysql_fetch_assoc($res);
3738
 
3739
    // Find the xrefs for this message.
3740
    $sql = "SELECT * " .
3741
           "FROM {$PHORUM["pm_xref_table"]} " .
3742
           "WHERE pm_message_id = $pm_id";
3743
    $res = mysql_query($sql, $conn);
3744
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3745
 
3746
    // No xrefs left? Then the message can be fully deleted.
3747
    if (mysql_num_rows($res) == 0) {
3748
        $sql = "DELETE FROM {$PHORUM['pm_messages_table']} " .
3749
               "WHERE pm_message_id = $pm_id";
3750
        $res = mysql_query($sql, $conn);
3751
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3752
        return $res;
3753
    }
3754
 
3755
    // Update the read flags for the recipients in the meta data.
3756
    $meta = unserialize($pm["meta"]);
3757
    $rcpts = $meta["recipients"];
3758
    while ($row = mysql_fetch_assoc($res)) {
3759
        // Only update if available. A kept copy in the outbox will
3760
        // not be in the meta list, so if the copy is read, the
3761
        // meta data does not have to be updated here.
3762
        if (isset($rcpts[$row["user_id"]])) {
3763
            $rcpts[$row["user_id"]]["read_flag"] = $row["read_flag"];
3764
        }
3765
    }
3766
    $meta["recipients"] = $rcpts;
3767
 
3768
    // Store the new meta data.
3769
    $meta = mysql_escape_string(serialize($meta));
3770
    $sql = "UPDATE {$PHORUM['pm_messages_table']} " .
3771
           "SET meta = '$meta' " .
3772
           "WHERE pm_message_id = $pm_id";
3773
    $res = mysql_query($sql, $conn);
3774
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3775
    return $res;
3776
}
3777
 
3778
/* Take care of warning about deprecation of the old PM API functions. */
3779
function phorum_db_get_private_messages($arg1, $arg2) {
3780
    phorum_db_pm_deprecated('phorum_db_get_private_messages'); }
3781
function phorum_db_get_private_message($arg1) {
3782
    phorum_db_pm_deprecated('phorum_db_get_private_message'); }
3783
function phorum_db_get_private_message_count($arg1) {
3784
    phorum_db_pm_deprecated('phorum_db_get_private_message_count'); }
3785
function phorum_db_put_private_messages($arg1, $arg2, $arg3, $arg4, $arg5) {
3786
    phorum_db_pm_deprecated('phorum_db_put_private_messages'); }
3787
function phorum_db_update_private_message($arg1, $arg2, $arg3){
3788
    phorum_db_pm_deprecated('phorum_db_update_private_message'); }
3789
function phorum_db_pm_deprecated($func) {
3790
    die("${func}() has been deprecated. Please use the new private message API.");
3791
}
3792
 
3793
/**
3794
 * This function checks if a certain user is buddy of another user.
3795
 * The function return the pm_buddy_id in case the user is a buddy
3796
 * or NULL in case the user isn't.
3797
 * @param buddy_user_id - The user_id to check for if it's a buddy.
3798
 * @param user_id - The user_id for which the buddy list must be
3799
 *                  checked or NULL to use the current user (default).
3800
 */
3801
function phorum_db_pm_is_buddy($buddy_user_id, $user_id = NULL)
3802
{
3803
    $PHORUM = $GLOBALS['PHORUM'];
3804
    $conn = phorum_db_mysql_connect();
3805
    settype($buddyuser_id, "int");
3806
    if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
3807
    settype($user_id, "int");
3808
 
3809
    $sql = "SELECT pm_buddy_id FROM {$PHORUM["pm_buddies_table"]} " .
3810
           "WHERE user_id = $user_id AND buddy_user_id = $buddy_user_id";
3811
 
3812
    $res = mysql_query($sql, $conn);
3813
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3814
    if (mysql_num_rows($res)) {
3815
        $row = mysql_fetch_array($res);
3816
        return $row[0];
3817
    } else {
3818
        return NULL;
3819
    }
3820
}
3821
 
3822
/**
3823
 * This function adds a buddy for a user. It will return the
3824
 * pm_buddy_id for the new buddy. If the buddy already exists,
3825
 * it will return the existing pm_buddy_id. If a non existant
3826
 * user_id is used for the buddy_user_id, the function will
3827
 * return NULL.
3828
 * @param buddy_user_id - The user_id that has to be added as a buddy.
3829
 * @param user_id - The user_id the buddy has to be added for or
3830
 *                  NULL to use the current user (default).
3831
 */
3832
function phorum_db_pm_buddy_add($buddy_user_id, $user_id = NULL)
3833
{
3834
    $PHORUM = $GLOBALS['PHORUM'];
3835
    $conn = phorum_db_mysql_connect();
3836
    settype($buddyuser_id, "int");
3837
    if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
3838
    settype($user_id, "int");
3839
 
3840
    // Check if the buddy_user_id is a valid user_id.
3841
    $valid = phorum_db_user_get($buddy_user_id, false);
3842
    if (! $valid) return NULL;
3843
 
3844
    $pm_buddy_id = phorum_db_pm_is_buddy($buddy_user_id);
3845
    if (is_null($pm_buddy_id)) {
3846
        $sql = "INSERT INTO {$PHORUM["pm_buddies_table"]} SET " .
3847
               "user_id = $user_id, " .
3848
               "buddy_user_id = $buddy_user_id";
3849
        $res = mysql_query($sql, $conn);
3850
        if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3851
        $pm_buddy_id = mysql_insert_id($conn);
3852
    }
3853
 
3854
    return $pm_buddy_id;
3855
}
3856
 
3857
/**
3858
 * This function deletes a buddy for a user.
3859
 * @param buddy_user_id - The user_id that has to be deleted as a buddy.
3860
 * @param user_id - The user_id the buddy has to be delete for or
3861
 *                  NULL to use the current user (default).
3862
 */
3863
function phorum_db_pm_buddy_delete($buddy_user_id, $user_id = NULL)
3864
{
3865
    $PHORUM = $GLOBALS['PHORUM'];
3866
    $conn = phorum_db_mysql_connect();
3867
    settype($buddyuser_id, "int");
3868
    if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
3869
    settype($user_id, "int");
3870
 
3871
    $sql = "DELETE FROM {$PHORUM["pm_buddies_table"]} WHERE " .
3872
           "buddy_user_id = $buddy_user_id AND user_id = $user_id";
3873
    $res = mysql_query($sql, $conn);
3874
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3875
    return $res;
3876
}
3877
 
3878
/**
3879
 * This function retrieves a list of buddies for a user.
3880
 * @param user_id - The user_id for which to retrieve the buddies
3881
 *                  or NULL to user the current user (default).
3882
 * @param find_mutual - Wheter to find mutual buddies or not (default not).
3883
 */
3884
function phorum_db_pm_buddy_list($user_id = NULL, $find_mutual = false)
3885
{
3886
    $PHORUM = $GLOBALS['PHORUM'];
3887
    $conn = phorum_db_mysql_connect();
3888
    if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
3889
    settype($user_id, "int");
3890
 
3891
    // Get all buddies for this user.
3892
    $sql = "SELECT buddy_user_id FROM {$PHORUM["pm_buddies_table"]} " .
3893
           "WHERE user_id = $user_id";
3894
    $res = mysql_query($sql, $conn);
3895
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3896
 
3897
    $buddies = array();
3898
    if (mysql_num_rows($res)) {
3899
        while ($row = mysql_fetch_array($res)) {
3900
            $buddies[$row[0]] = array (
3901
                'user_id' => $row[0]
3902
            );
3903
        }
3904
    }
3905
 
3906
    // If we do not have to lookup mutual buddies, we're done.
3907
    if (! $find_mutual) return $buddies;
3908
 
3909
    // Initialize mutual buddy value.
3910
    foreach ($buddies as $id => $data) {
3911
        $buddies[$id]["mutual"] = false;
3912
    }
3913
 
3914
    // Get all mutual buddies.
3915
    $sql = "SELECT DISTINCT a.buddy_user_id " .
3916
           "FROM {$PHORUM["pm_buddies_table"]} as a, {$PHORUM["pm_buddies_table"]} as b " .
3917
           "WHERE a.user_id=$user_id " .
3918
           "AND b.user_id=a.buddy_user_id " .
3919
           "AND b.buddy_user_id=$user_id";
3920
    $res = mysql_query($sql, $conn);
3921
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3922
 
3923
    if (mysql_num_rows($res)) {
3924
        while ($row = mysql_fetch_array($res)) {
3925
            $buddies[$row[0]]["mutual"] = true;
3926
        }
3927
    }
3928
 
3929
    return $buddies;
3930
}
3931
 
3932
/**
3933
* This function returns messages or threads which are newer or older
3934
* than the given timestamp
3935
*
3936
* $time  - holds the timestamp the comparison is done against
3937
* $forum - get Threads from this forum
3938
* $mode  - should we compare against datestamp (1) or modifystamp (2)
3939
*
3940
*/
3941
function phorum_db_prune_oldThreads($time,$forum=0,$mode=1) {
3942
 
3943
    $PHORUM = $GLOBALS['PHORUM'];
3944
 
3945
    $conn = phorum_db_mysql_connect();
3946
    $numdeleted=0;
3947
 
3948
    $compare_field = "datestamp";
3949
    if($mode == 2) {
3950
      $compare_field = "modifystamp";
3951
    }
3952
 
3953
    $forummode="";
3954
    if($forum > 0) {
3955
      $forummode=" AND forum_id = $forum";
3956
    }
3957
 
3958
    // retrieving which threads to delete
3959
    $sql = "select thread from {$PHORUM['message_table']} where $compare_field < $time AND parent_id=0 $forummode";
3960
 
3961
    $res = mysql_query($sql, $conn);
3962
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3963
 
3964
    $ret=array();
3965
    while($row=mysql_fetch_row($res)) {
3966
        $ret[]=$row[0];
3967
    }
3968
 
3969
    $thread_ids=implode(",",$ret);
3970
 
3971
    if(count($ret)) {
3972
      // deleting the messages/threads
3973
      $sql="delete from {$PHORUM['message_table']} where thread IN ($thread_ids)";
3974
      $res = mysql_query($sql, $conn);
3975
      if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3976
 
3977
      $numdeleted = mysql_affected_rows($conn);
3978
      if($numdeleted < 0) {
3979
        $numdeleted=0;
3980
      }
3981
 
3982
      // deleting the associated notification-entries
3983
      $sql="delete from {$PHORUM['subscribers_table']} where thread IN ($thread_ids)";
3984
      $res = mysql_query($sql, $conn);
3985
      if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3986
 
3987
 
3988
      // optimizing the message-table
3989
      $sql="optimize table {$PHORUM['message_table']}";
3990
      $res = mysql_query($sql, $conn);
3991
      if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
3992
    }
3993
 
3994
    return $numdeleted;
3995
}
3996
 
3997
/**
3998
 * split thread
3999
 */
4000
function phorum_db_split_thread($message, $forum_id)
4001
{
4002
    settype($message, "int");
4003
    settype($forum_id, "int");
4004
 
4005
    if($message > 0 && $forum_id > 0){
4006
        // get message tree for update thread id
4007
        $tree =phorum_db_get_messagetree($message, $forum_id);
4008
        $queries =array();
4009
        $queries[0]="UPDATE {$GLOBALS['PHORUM']['message_table']} SET thread='$message', parent_id='0' WHERE message_id ='$message'";
4010
        $queries[1]="UPDATE {$GLOBALS['PHORUM']['message_table']} SET thread='$message' WHERE message_id IN ($tree)";
4011
        phorum_db_run_queries($queries);
4012
    }
4013
}
4014
 
4015
/**
4016
 * This function returns the maximum message-id in the database
4017
 */
4018
function phorum_db_get_max_messageid() {
4019
    $PHORUM = $GLOBALS["PHORUM"];
4020
 
4021
    $conn = phorum_db_mysql_connect();
4022
    $maxid = 0;
4023
 
4024
    $sql="SELECT max(message_id) from ".$PHORUM["message_table"];
4025
    $res = mysql_query($sql, $conn);
4026
 
4027
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
4028
 
4029
    if (mysql_num_rows($res) > 0){
4030
        $row = mysql_fetch_row($res);
4031
        $maxid = $row[0];
4032
    }
4033
 
4034
    return $maxid;
4035
}
4036
 
4037
/**
4038
 * This function increments the viewcount for a post
4039
 */
4040
 
4041
function phorum_db_viewcount_inc($message_id) {
4042
    if($message_id < 1 || !is_numeric($message_id)) {
4043
        return false;
4044
    }
4045
 
4046
    $conn = phorum_db_mysql_connect();
4047
    $sql="UPDATE ".$GLOBALS['PHORUM']['message_table']." SET viewcount=viewcount+1 WHERE message_id=$message_id";
4048
    $res = mysql_query($sql, $conn);
4049
 
4050
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
4051
 
4052
 
4053
    return true;
4054
 
4055
}
4056
 
4057
 
4058
function phorum_db_get_custom_field_users($field_id,$field_content,$match) {
4059
 
4060
 
4061
    $field_id=(int)$field_id;
4062
    $field_content=mysql_real_escape_string($field_content);
4063
 
4064
    $conn = phorum_db_mysql_connect();
4065
 
4066
    if($match) {
4067
        $compval="LIKE";
4068
    } else {
4069
        $compval="=";
4070
    }
4071
 
4072
    $sql = "select user_id from {$GLOBALS['PHORUM']['user_custom_fields_table']} where type=$field_id and data $compval '$field_content'";
4073
    $res = mysql_query($sql, $conn);
4074
 
4075
    if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
4076
 
4077
    if(mysql_num_rows($res)) {
4078
        $retval=array();
4079
        while ($row = mysql_fetch_row($res)){
4080
            $retval[$row[0]]=$row[0];
4081
        }
4082
    } else {
4083
        $retval=NULL;
4084
    }
4085
 
4086
    return $retval;
4087
 
4088
}
4089
 
4090
 
4091
/**
4092
 * This function creates the tables needed in the database.
4093
 */
4094
 
4095
function phorum_db_create_tables()
4096
{
4097
    $PHORUM = $GLOBALS["PHORUM"];
4098
 
4099
    $conn = phorum_db_mysql_connect();
4100
 
4101
    $retmsg = "";
4102
 
4103
    $queries = array(
4104
 
4105
        // create tables
4106
        "CREATE TABLE {$PHORUM['forums_table']} ( forum_id int(10) unsigned NOT NULL auto_increment, name varchar(50) NOT NULL default '', active smallint(6) NOT NULL default '0', description text NOT NULL default '', template varchar(50) NOT NULL default '', folder_flag tinyint(1) NOT NULL default '0', parent_id int(10) unsigned NOT NULL default '0', list_length_flat int(10) unsigned NOT NULL default '0', list_length_threaded int(10) unsigned NOT NULL default '0', moderation int(10) unsigned NOT NULL default '0', threaded_list tinyint(4) NOT NULL default '0', threaded_read tinyint(4) NOT NULL default '0', float_to_top tinyint(4) NOT NULL default '0', check_duplicate tinyint(4) NOT NULL default '0', allow_attachment_types varchar(100) NOT NULL default '', max_attachment_size int(10) unsigned NOT NULL default '0', max_totalattachment_size int(10) unsigned NOT NULL default '0', max_attachments int(10) unsigned NOT NULL default '0', pub_perms int(10) unsigned NOT NULL default '0', reg_perms int(10) unsigned NOT NULL default '0', display_ip_address smallint(5) unsigned NOT NULL default '1', allow_email_notify smallint(5) unsigned NOT NULL default '1', language varchar(100) NOT NULL default 'english', email_moderators tinyint(1) NOT NULL default '0', message_count int(10) unsigned NOT NULL default '0', sticky_count int(10) unsigned NOT NULL default '0', thread_count int(10) unsigned NOT NULL default '0', last_post_time int(10) unsigned NOT NULL default '0', display_order int(10) unsigned NOT NULL default '0', read_length int(10) unsigned NOT NULL default '0', vroot int(10) unsigned NOT NULL default '0', edit_post tinyint(1) NOT NULL default '1',template_settings text NOT NULL default '', count_views tinyint(1) unsigned NOT NULL default '0', display_fixed tinyint(1) unsigned NOT NULL default '0', reverse_threading tinyint(1) NOT NULL default '0',inherit_id int(10) unsigned NULL default NULL, PRIMARY KEY (forum_id), KEY name (name), KEY active (active,parent_id), KEY group_id (parent_id)) TYPE=MyISAM",
4107
        "CREATE TABLE {$PHORUM['message_table']} ( message_id int(10) unsigned NOT NULL auto_increment, forum_id int(10) unsigned NOT NULL default '0', thread int(10) unsigned NOT NULL default '0', parent_id int(10) unsigned NOT NULL default '0', author varchar(37) NOT NULL default '', subject varchar(255) NOT NULL default '', body text NOT NULL, email varchar(100) NOT NULL default '', ip varchar(255) NOT NULL default '', status tinyint(4) NOT NULL default '2', msgid varchar(100) NOT NULL default '', modifystamp int(10) unsigned NOT NULL default '0', user_id int(10) unsigned NOT NULL default '0', thread_count int(10) unsigned NOT NULL default '0', moderator_post tinyint(3) unsigned NOT NULL default '0', sort tinyint(4) NOT NULL default '2', datestamp int(10) unsigned NOT NULL default '0', meta mediumtext NOT NULL, viewcount int(10) unsigned NOT NULL default '0', closed tinyint(4) NOT NULL default '0', PRIMARY KEY (message_id), KEY thread_message (thread,message_id), KEY thread_forum (thread,forum_id), KEY special_threads (sort,forum_id), KEY status_forum (status,forum_id), KEY list_page_float (forum_id,parent_id,modifystamp), KEY list_page_flat (forum_id,parent_id,thread), KEY post_count (forum_id,status,parent_id), KEY dup_check (forum_id,author,subject,datestamp), KEY forum_max_message (forum_id,message_id,status,parent_id), KEY last_post_time (forum_id,status,modifystamp), KEY next_prev_thread (forum_id,status,thread)  ) TYPE=MyISAM",
4108
        "CREATE TABLE {$PHORUM['settings_table']} ( name varchar(255) NOT NULL default '', type enum('V','S') NOT NULL default 'V', data text NOT NULL, PRIMARY KEY (name)) TYPE=MyISAM",
4109
        "CREATE TABLE {$PHORUM['subscribers_table']} ( user_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0', sub_type int(10) unsigned NOT NULL default '0', thread int(10) unsigned NOT NULL default '0', PRIMARY KEY (user_id,forum_id,thread), KEY forum_id (forum_id,thread,sub_type)) TYPE=MyISAM",
4110
        "CREATE TABLE {$PHORUM['user_permissions_table']} ( user_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0', permission int(10) unsigned NOT NULL default '0', PRIMARY KEY  (user_id,forum_id), KEY forum_id (forum_id,permission) ) TYPE=MyISAM",
4111
        "CREATE TABLE {$PHORUM['user_table']} ( user_id int(10) unsigned NOT NULL auto_increment, username varchar(50) NOT NULL default '', password varchar(50) NOT NULL default '',cookie_sessid_lt varchar(50) NOT NULL default '', sessid_st varchar(50) NOT NULL default '', sessid_st_timeout int(10) unsigned NOT NULL default 0, password_temp varchar(50) NOT NULL default '', email varchar(100) NOT NULL default '',  email_temp varchar(110) NOT NULL default '', hide_email tinyint(1) NOT NULL default '0', active tinyint(1) NOT NULL default '0', user_data text NOT NULL default '', signature text NOT NULL default '', threaded_list tinyint(4) NOT NULL default '0', posts int(10) NOT NULL default '0', admin tinyint(1) NOT NULL default '0', threaded_read tinyint(4) NOT NULL default '0', date_added int(10) unsigned NOT NULL default '0', date_last_active int(10) unsigned NOT NULL default '0', last_active_forum int(10) unsigned NOT NULL default '0', hide_activity tinyint(1) NOT NULL default '0',show_signature TINYINT( 1 ) DEFAULT '0' NOT NULL, email_notify TINYINT( 1 ) DEFAULT '0' NOT NULL, pm_email_notify TINYINT ( 1 ) DEFAULT '1' NOT NULL, tz_offset TINYINT( 2 ) DEFAULT '-99' NOT NULL,is_dst TINYINT( 1 ) DEFAULT '0' NOT NULL ,user_language VARCHAR( 100 ) NOT NULL default '',user_template VARCHAR( 100 ) NOT NULL default '', moderator_data text NOT NULL default '', moderation_email tinyint(2) unsigned not null default 1, PRIMARY KEY (user_id), UNIQUE KEY username (username), KEY active (active), KEY userpass (username,password), KEY sessid_st (sessid_st), KEY cookie_sessid_lt (cookie_sessid_lt), KEY activity (date_last_active,hide_activity,last_active_forum), KEY date_added (date_added), KEY email_temp (email_temp) ) TYPE=MyISAM",
4112
        "CREATE TABLE {$PHORUM['user_newflags_table']} ( user_id int(11) NOT NULL default '0', forum_id int(11) NOT NULL default '0', message_id int(11) NOT NULL default '0', PRIMARY KEY  (user_id,forum_id,message_id) ) TYPE=MyISAM",
4113
        "CREATE TABLE {$PHORUM['groups_table']} ( group_id int(11) NOT NULL auto_increment, name varchar(255) NOT NULL default '0', open tinyint(3) NOT NULL default '0', PRIMARY KEY  (group_id) ) TYPE=MyISAM",
4114
        "CREATE TABLE {$PHORUM['forum_group_xref_table']} ( forum_id int(11) NOT NULL default '0', group_id int(11) NOT NULL default '0', permission int(10) unsigned NOT NULL default '0', PRIMARY KEY  (forum_id,group_id) ) TYPE=MyISAM",
4115
        "CREATE TABLE {$PHORUM['user_group_xref_table']} ( user_id int(11) NOT NULL default '0', group_id int(11) NOT NULL default '0', status tinyint(3) NOT NULL default '1', PRIMARY KEY  (user_id,group_id) ) TYPE=MyISAM",
4116
        "CREATE TABLE {$PHORUM['files_table']} ( file_id int(11) NOT NULL auto_increment, user_id int(11) NOT NULL default '0', filename varchar(255) NOT NULL default '', filesize int(11) NOT NULL default '0', file_data mediumtext NOT NULL default '', add_datetime int(10) unsigned NOT NULL default '0', message_id int(10) unsigned NOT NULL default '0', link varchar(10) NOT NULL default '', PRIMARY KEY (file_id), KEY add_datetime (add_datetime), KEY message_id_link (message_id,link)) TYPE=MyISAM",
4117
        "CREATE TABLE {$PHORUM['banlist_table']} ( id int(11) NOT NULL auto_increment, forum_id int(11) NOT NULL default '0', type tinyint(4) NOT NULL default '0', pcre tinyint(4) NOT NULL default '0', string varchar(255) NOT NULL default '', PRIMARY KEY  (id), KEY forum_id (forum_id)) TYPE=MyISAM",
4118
        "CREATE TABLE {$PHORUM['search_table']} ( message_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0',search_text mediumtext NOT NULL default '', PRIMARY KEY  (message_id), KEY forum_id (forum_id), FULLTEXT KEY search_text (search_text) ) TYPE=MyISAM",
4119
        "CREATE TABLE {$PHORUM['user_custom_fields_table']} ( user_id INT DEFAULT '0' NOT NULL , type INT DEFAULT '0' NOT NULL , data TEXT NOT NULL default '', PRIMARY KEY ( user_id , type )) TYPE=MyISAM",
4120
        "CREATE TABLE {$PHORUM['pm_messages_table']} ( pm_message_id int(10) unsigned NOT NULL auto_increment, from_user_id int(10) unsigned NOT NULL default '0', from_username varchar(50) NOT NULL default '', subject varchar(100) NOT NULL default '', message text NOT NULL default '', datestamp int(10) unsigned NOT NULL default '0', meta mediumtext NOT NULL default '', PRIMARY KEY(pm_message_id)) TYPE=MyISAM",
4121
        "CREATE TABLE {$PHORUM['pm_folders_table']} ( pm_folder_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', foldername varchar(20) NOT NULL default '', PRIMARY KEY (pm_folder_id)) TYPE=MyISAM",
4122
        "CREATE TABLE {$PHORUM['pm_xref_table']} ( pm_xref_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', pm_folder_id int(10) unsigned NOT NULL default '0', special_folder varchar(10), pm_message_id int(10) unsigned NOT NULL default '0', read_flag tinyint(1) NOT NULL default '0', reply_flag tinyint(1) NOT NULL default '0', PRIMARY KEY (pm_xref_id), KEY xref (user_id,pm_folder_id,pm_message_id), KEY read_flag (read_flag)) TYPE=MyISAM",
4123
        "CREATE TABLE {$PHORUM['pm_buddies_table']} ( pm_buddy_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', buddy_user_id int(10) unsigned NOT NULL default '0', PRIMARY KEY pm_buddy_id (pm_buddy_id), UNIQUE KEY userids (user_id, buddy_user_id), KEY buddy_user_id (buddy_user_id)) TYPE=MyISAM",
4124
 
4125
    );
4126
    foreach($queries as $sql){
4127
        $res = mysql_query($sql, $conn);
4128
        if ($err = mysql_error()){
4129
            $retmsg = "$err<br />";
4130
            phorum_db_mysql_error("$err: $sql");
4131
            break;
4132
        }
4133
    }
4134
 
4135
    return $retmsg;
4136
}
4137
 
4138
// uses the database-dependant functions to escape a string
4139
function phorum_db_escape_string($str) {
4140
    $str_tmp=mysql_real_escape_string($str);
4141
 
4142
    return $str_tmp;
4143
}
4144
 
4145
/**
4146
 * This function goes through an array of queries and executes them
4147
 */
4148
 
4149
function phorum_db_run_queries($queries){
4150
    $PHORUM = $GLOBALS["PHORUM"];
4151
 
4152
    $conn = phorum_db_mysql_connect();
4153
 
4154
    $retmsg = "";
4155
 
4156
    foreach($queries as $sql){
4157
        $res = mysql_query($sql, $conn);
4158
        if ($err = mysql_error()){
4159
            // skip duplicate column name errors
4160
            if(!stristr($err, "duplicate column")){
4161
                $retmsg.= "$err<br />";
4162
                phorum_db_mysql_error("$err: $sql");
4163
            }
4164
        }
4165
    }
4166
 
4167
    return $retmsg;
4168
}
4169
 
4170
/**
4171
 * This function checks that a database connection can be made.
4172
 */
4173
 
4174
function phorum_db_check_connection(){
4175
    $conn = phorum_db_mysql_connect();
4176
 
4177
    return ($conn > 0) ? true : false;
4178
}
4179
 
4180
/**
4181
 * handy little connection function.  This allows us to not connect to the
4182
 * server until a query is actually run.
4183
 * NOTE: This is not a required part of abstraction
4184
 */
4185
 
4186
function phorum_db_mysql_connect(){
4187
    $PHORUM = $GLOBALS["PHORUM"];
4188
 
4189
    static $conn;
4190
    if (empty($conn)){
4191
        $conn = mysql_connect($PHORUM["DBCONFIG"]["server"], $PHORUM["DBCONFIG"]["user"], $PHORUM["DBCONFIG"]["password"], true);
4192
        mysql_select_db($PHORUM["DBCONFIG"]["name"], $conn);
4193
    }
4194
    return $conn;
4195
}
4196
 
4197
/**
4198
 * error handling function
4199
 * NOTE: This is not a required part of abstraction
4200
 */
4201
 
4202
function phorum_db_mysql_error($err){
4203
 
4204
    if(isset($GLOBALS['PHORUM']['error_logging'])) {
4205
        $logsetting = $GLOBALS['PHORUM']['error_logging'];
4206
    } else {
4207
        $logsetting = "";
4208
    }
4209
    $adminemail = $GLOBALS['PHORUM']['system_email_from_address'];
4210
    $cache_dir  = $GLOBALS['PHORUM']['cache'];
4211
 
4212
    if (!defined("PHORUM_ADMIN")){
4213
        if($logsetting == 'mail') {
4214
            include_once("./include/email_functions.php");
4215
 
4216
            $data=array('mailmessage'=>"An SQL-error occured in your phorum-installation.\n\nThe error-message was:\n$err\n\n",
4217
                        'mailsubject'=>'Phorum: an SQL-error occured');
4218
            phorum_email_user(array($adminemail),$data);
4219
 
4220
        } elseif($logsetting == 'file') {
4221
            $fp = fopen($cache_dir."/phorum-sql-errors.log",'a');
4222
            fputs($fp,time().": $err\n");
4223
            fclose($fp);
4224
 
4225
        } else {
4226
            echo htmlspecialchars($err);
4227
        }
4228
        exit();
4229
    }else{
4230
        echo "<!-- $err -->";
4231
    }
4232
}
4233
 
4234
/**
4235
 * This function is used by the sanity checking system in the
4236
 * admin interface to determine how much data can be transferred
4237
 * in one query. This is used to detect problems with uploads that
4238
 * are larger than the database server can handle.
4239
 * The function returns the size in bytes. For database implementations
4240
 * which do not have this kind of limit, NULL can be returned.
4241
 */
4242
function phorum_db_maxpacketsize ()
4243
{
4244
    $conn = phorum_db_mysql_connect();
4245
    $res = mysql_query("SELECT @@global.max_allowed_packet",$conn);
4246
    if (!$res) return NULL;
4247
    if (mysql_num_rows($res)) {
4248
        $row = mysql_fetch_array($res);
4249
        return $row[0];
4250
    }
4251
    return NULL;
4252
}
4253
 
4254
/**
4255
 * This function is used by the sanity checking system to let the
4256
 * database layer do sanity checks of its own. This function can
4257
 * be used by every database layer to implement specific checks.
4258
 *
4259
 * The return value for this function should be exactly the same
4260
 * as the return value expected for regular sanity checking
4261
 * function (see include/admin/sanity_checks.php for information).
4262
 *
4263
 * There's no need to load the sanity_check.php file for the needed
4264
 * constants, because this function should only be called from the
4265
 * sanity checking system.
4266
 */
4267
function phorum_db_sanitychecks()
4268
{
4269
    $PHORUM = $GLOBALS["PHORUM"];
4270
 
4271
    // Retrieve the MySQL server version.
4272
    $conn = phorum_db_mysql_connect();
4273
    $res = mysql_query("SELECT @@global.version",$conn);
4274
    if (!$res) return array(
4275
        PHORUM_SANITY_WARN,
4276
        "The database layer could not retrieve the version of the
4277
         running MySQL server",
4278
        "This probably means that you are running a really old MySQL
4279
         server, which does not support \"SELECT @@global.version\"
4280
         as an SQL command. If you are not running a MySQL server
4281
         with version 4.0.18 or higher, then please upgrade your
4282
         MySQL server. Else, contact the Phorum developers to see
4283
         where this warning is coming from"
4284
    );
4285
 
4286
    if (mysql_num_rows($res))
4287
    {
4288
        $row = mysql_fetch_array($res);
4289
        $ver = explode(".", $row[0]);
4290
 
4291
        // Version numbering format which is not recognized.
4292
        if (count($ver) != 3) return array(
4293
            PHORUM_SANITY_WARN,
4294
            "The database layer was unable to recognize the MySQL server's
4295
             version number \"" . htmlspecialchars($row[0]) . "\". Therefore,
4296
             checking if the right version of MySQL is used is not possible.",
4297
            "Contact the Phorum developers and report this specific
4298
             version number, so the checking scripts can be updated."
4299
        );
4300
 
4301
        settype($ver[0], 'int');
4302
        settype($ver[1], 'int');
4303
        settype($ver[2], 'int');
4304
 
4305
        // MySQL before version 4.
4306
        if ($ver[0] < 4) return array(
4307
            PHORUM_SANITY_CRIT,
4308
            "The MySQL database server that is used is too old. The
4309
             running version is \"" . htmlspecialchars($row[0]) . "\",
4310
             while MySQL version 4.0.18 or higher is recommended.",
4311
            "Upgrade your MySQL server to a newer version. If your
4312
             website is hosted with a service provider, please contact
4313
             the service provider to upgrade your MySQL database."
4314
        );
4315
 
4316
        // MySQL before version 4.0.18, with full text search enabled.
4317
        if ($PHORUM["DBCONFIG"]["mysql_use_ft"] &&
4318
            $ver[0] == 4 && $ver[1] == 0 && $ver[2] < 18) return array(
4319
            PHORUM_SANITY_WARN,
4320
            "The MySQL database server that is used does not
4321
             support all Phorum features. The running version is
4322
             \"" . htmlspecialchars($row[0]) . "\", while MySQL version
4323
             4.0.18 or higher is recommended.",
4324
            "Upgrade your MySQL server to a newer version. If your
4325
             website is hosted with a service provider, please contact
4326
             the service provider to upgrade your MySQL database."
4327
        );
4328
 
4329
        // All checks are okay.
4330
        return array (PHORUM_SANITY_OK, NULL);
4331
    }
4332
 
4333
    return array(
4334
        PHORUM_SANITY_CRIT,
4335
        "An unexpected problem was found in running the sanity
4336
         check function phorum_db_sanitychecks().",
4337
        "Contact the Phorum developers to find out what the problem is."
4338
    );
4339
}
4340
 
4341
?>