5
* @version $Id: functions_posting.php,v 1.274 2007/11/27 15:13:49 kellanved Exp $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
14
if (!defined('IN_PHPBB'))
20
* Fill smiley templates (or just the variables) with smilies, either in a window or inline
22
function generate_smilies($mode, $forum_id)
24
global $auth, $db, $user, $config, $template;
25
global $phpEx, $phpbb_root_path;
27
if ($mode == 'window')
31
$sql = 'SELECT forum_style
32
FROM ' . FORUMS_TABLE . "
33
WHERE forum_id = $forum_id";
34
$result = $db->sql_query_limit($sql, 1);
35
$row = $db->sql_fetchrow($result);
36
$db->sql_freeresult($result);
38
$user->setup('posting', (int) $row['forum_style']);
42
$user->setup('posting');
45
page_header($user->lang['SMILIES']);
47
$template->set_filenames(array(
48
'body' => 'posting_smilies.html')
52
$display_link = false;
53
if ($mode == 'inline')
55
$sql = 'SELECT smiley_id
56
FROM ' . SMILIES_TABLE . '
57
WHERE display_on_posting = 0';
58
$result = $db->sql_query_limit($sql, 1, 0, 3600);
60
if ($row = $db->sql_fetchrow($result))
64
$db->sql_freeresult($result);
70
FROM ' . SMILIES_TABLE .
71
(($mode == 'inline') ? ' WHERE display_on_posting = 1 ' : '') . '
72
ORDER BY smiley_order';
73
$result = $db->sql_query($sql, 3600);
76
while ($row = $db->sql_fetchrow($result))
78
if (empty($smilies[$row['smiley_url']]))
80
$smilies[$row['smiley_url']] = $row;
83
$db->sql_freeresult($result);
87
foreach ($smilies as $row)
89
$template->assign_block_vars('smiley', array(
90
'SMILEY_CODE' => $row['code'],
91
'A_SMILEY_CODE' => addslashes($row['code']),
92
'SMILEY_IMG' => $phpbb_root_path . $config['smilies_path'] . '/' . $row['smiley_url'],
93
'SMILEY_WIDTH' => $row['smiley_width'],
94
'SMILEY_HEIGHT' => $row['smiley_height'],
95
'SMILEY_DESC' => $row['emotion'])
100
if ($mode == 'inline' && $display_link)
102
$template->assign_vars(array(
103
'S_SHOW_SMILEY_LINK' => true,
104
'U_MORE_SMILIES' => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id))
108
if ($mode == 'window')
115
* Update last post information
116
* Should be used instead of sync() if only the last post information are out of sync... faster
118
* @param string $type Can be forum|topic
119
* @param mixed $ids topic/forum ids
120
* @param bool $return_update_sql true: SQL query shall be returned, false: execute SQL
122
function update_post_information($type, $ids, $return_update_sql = false)
136
$update_sql = $empty_forums = $not_empty_forums = array();
138
if ($type != 'topic')
140
$topic_join = ', ' . TOPICS_TABLE . ' t';
141
$topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_approved = 1';
146
$topic_condition = '';
149
if (sizeof($ids) == 1)
151
$sql = 'SELECT MAX(p.post_id) as last_post_id
152
FROM ' . POSTS_TABLE . " p $topic_join
153
WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
155
AND p.post_approved = 1";
159
$sql = 'SELECT p.' . $type . '_id, MAX(p.post_id) as last_post_id
160
FROM ' . POSTS_TABLE . " p $topic_join
161
WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
163
AND p.post_approved = 1
164
GROUP BY p.{$type}_id";
166
$result = $db->sql_query($sql);
168
$last_post_ids = array();
169
while ($row = $db->sql_fetchrow($result))
171
if (sizeof($ids) == 1)
173
$row[$type . '_id'] = $ids[0];
176
if ($type == 'forum')
178
$not_empty_forums[] = $row['forum_id'];
180
if (empty($row['last_post_id']))
182
$empty_forums[] = $row['forum_id'];
186
$last_post_ids[] = $row['last_post_id'];
188
$db->sql_freeresult($result);
190
if ($type == 'forum')
192
$empty_forums = array_merge($empty_forums, array_diff($ids, $not_empty_forums));
194
foreach ($empty_forums as $void => $forum_id)
196
$update_sql[$forum_id][] = 'forum_last_post_id = 0';
197
$update_sql[$forum_id][] = "forum_last_post_subject = ''";
198
$update_sql[$forum_id][] = 'forum_last_post_time = 0';
199
$update_sql[$forum_id][] = 'forum_last_poster_id = 0';
200
$update_sql[$forum_id][] = "forum_last_poster_name = ''";
201
$update_sql[$forum_id][] = "forum_last_poster_colour = ''";
205
if (sizeof($last_post_ids))
207
$sql = 'SELECT p.' . $type . '_id, p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
208
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
209
WHERE p.poster_id = u.user_id
210
AND ' . $db->sql_in_set('p.post_id', $last_post_ids);
211
$result = $db->sql_query($sql);
213
while ($row = $db->sql_fetchrow($result))
215
$update_sql[$row["{$type}_id"]][] = $type . '_last_post_id = ' . (int) $row['post_id'];
216
$update_sql[$row["{$type}_id"]][] = "{$type}_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
217
$update_sql[$row["{$type}_id"]][] = $type . '_last_post_time = ' . (int) $row['post_time'];
218
$update_sql[$row["{$type}_id"]][] = $type . '_last_poster_id = ' . (int) $row['poster_id'];
219
$update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
220
$update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'";
222
$db->sql_freeresult($result);
224
unset($empty_forums, $ids, $last_post_ids);
226
if ($return_update_sql || !sizeof($update_sql))
231
$table = ($type == 'forum') ? FORUMS_TABLE : TOPICS_TABLE;
233
foreach ($update_sql as $update_id => $update_sql_ary)
235
$sql = "UPDATE $table
236
SET " . implode(', ', $update_sql_ary) . "
237
WHERE {$type}_id = $update_id";
238
$db->sql_query($sql);
245
* Generate Topic Icons for display
247
function posting_gen_topic_icons($mode, $icon_id)
249
global $phpbb_root_path, $config, $template, $cache;
252
$icons = $cache->obtain_icons();
256
$template->assign_var('S_NO_ICON_CHECKED', ' checked="checked"');
261
foreach ($icons as $id => $data)
263
if ($data['display'])
265
$template->assign_block_vars('topic_icon', array(
267
'ICON_IMG' => $phpbb_root_path . $config['icons_path'] . '/' . $data['img'],
268
'ICON_WIDTH' => $data['width'],
269
'ICON_HEIGHT' => $data['height'],
271
'S_CHECKED' => ($id == $icon_id) ? true : false,
272
'S_ICON_CHECKED' => ($id == $icon_id) ? ' checked="checked"' : '')
284
* Build topic types able to be selected
286
function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
288
global $auth, $user, $template, $topic_type;
292
$topic_types = array(
293
'sticky' => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
294
'announce' => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
295
'global' => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
298
$topic_type_array = array();
300
foreach ($topic_types as $auth_key => $topic_value)
302
// We do not have a special post global announcement permission
303
$auth_key = ($auth_key == 'global') ? 'announce' : $auth_key;
305
if ($auth->acl_get('f_' . $auth_key, $forum_id))
309
$topic_type_array[] = array(
310
'VALUE' => $topic_value['const'],
311
'S_CHECKED' => ($cur_topic_type == $topic_value['const'] || ($forum_id == 0 && $topic_value['const'] == POST_GLOBAL)) ? ' checked="checked"' : '',
312
'L_TOPIC_TYPE' => $user->lang[$topic_value['lang']]
319
$topic_type_array = array_merge(array(0 => array(
320
'VALUE' => POST_NORMAL,
321
'S_CHECKED' => ($topic_type == POST_NORMAL) ? ' checked="checked"' : '',
322
'L_TOPIC_TYPE' => $user->lang['POST_NORMAL'])),
327
foreach ($topic_type_array as $array)
329
$template->assign_block_vars('topic_type', $array);
332
$template->assign_vars(array(
333
'S_TOPIC_TYPE_STICKY' => ($auth->acl_get('f_sticky', $forum_id)),
334
'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_get('f_announce', $forum_id)))
342
// Attachment related functions
346
* Upload Attachment - filedata is generated here
349
function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
351
global $auth, $user, $config, $db, $cache;
352
global $phpbb_root_path, $phpEx;
358
include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
359
$upload = new fileupload();
363
$filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
367
$filedata['post_attach'] = true;
370
if (!$filedata['post_attach'])
372
$filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
376
$extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
377
$upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
379
$file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name);
381
if ($file->init_error)
383
$filedata['post_attach'] = false;
387
$cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE;
389
// Make sure the image category only holds valid images...
390
if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
394
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
395
// Since the image category is displaying content inline we need to catch this.
396
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
399
// Do we have to create a thumbnail?
400
$filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
402
// Check Image Size, if it is an image
403
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE)
405
$file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
408
// Admins and mods are allowed to exceed the allowed filesize
409
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
411
if (!empty($extensions[$file->get('extension')]['max_filesize']))
413
$allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
417
$allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
420
$file->upload->set_max_filesize($allowed_filesize);
423
$file->clean_filename('unique', $user->data['user_id'] . '_');
425
// Are we uploading an image *and* this image being within the image category? Only then perform additional image checks.
426
$no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true;
428
$file->move_file($config['upload_path'], false, $no_image);
430
if (sizeof($file->error))
433
$filedata['error'] = array_merge($filedata['error'], $file->error);
434
$filedata['post_attach'] = false;
439
$filedata['filesize'] = $file->get('filesize');
440
$filedata['mimetype'] = $file->get('mimetype');
441
$filedata['extension'] = $file->get('extension');
442
$filedata['physical_filename'] = $file->get('realname');
443
$filedata['real_filename'] = $file->get('uploadname');
444
$filedata['filetime'] = time();
446
// Check our complete quota
447
if ($config['attachment_quota'])
449
if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
451
$filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
452
$filedata['post_attach'] = false;
460
// Check free disk space
461
if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
463
if ($free_space <= $file->get('filesize'))
465
$filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
466
$filedata['post_attach'] = false;
475
if ($filedata['thumbnail'])
477
$source = $file->get('destination_file');
478
$destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
480
if (!create_thumbnail($source, $destination, $file->get('mimetype')))
482
$filedata['thumbnail'] = 0;
490
* Calculate the needed size for Thumbnail
492
function get_img_size_format($width, $height)
496
// Maximum Width the Image can take
497
$max_width = ($config['img_max_thumb_width']) ? $config['img_max_thumb_width'] : 400;
499
if ($width > $height)
502
round($width * ($max_width / $width)),
503
round($height * ($max_width / $width))
509
round($width * ($max_width / $height)),
510
round($height * ($max_width / $height))
516
* Return supported image types
518
function get_supported_image_types($type = false)
520
if (@extension_loaded('gd'))
522
$format = imagetypes();
531
$new_type = ($format & IMG_GIF) ? IMG_GIF : false;
540
$new_type = ($format & IMG_JPG) ? IMG_JPG : false;
545
$new_type = ($format & IMG_PNG) ? IMG_PNG : false;
551
$new_type = ($format & IMG_WBMP) ? IMG_WBMP : false;
558
$go_through_types = array(IMG_GIF, IMG_JPG, IMG_PNG, IMG_WBMP);
560
foreach ($go_through_types as $check_type)
562
if ($format & $check_type)
564
$new_type[] = $check_type;
570
'gd' => ($new_type) ? true : false,
571
'format' => $new_type,
572
'version' => (function_exists('imagecreatetruecolor')) ? 2 : 1
576
return array('gd' => false);
582
function create_thumbnail($source, $destination, $mimetype)
586
$min_filesize = (int) $config['img_min_thumb_filesize'];
587
$img_filesize = (file_exists($source)) ? @filesize($source) : false;
589
if (!$img_filesize || $img_filesize <= $min_filesize)
594
$dimension = @getimagesize($source);
596
if ($dimension === false)
601
list($width, $height, $type, ) = $dimension;
603
if (empty($width) || empty($height))
608
list($new_width, $new_height) = get_img_size_format($width, $height);
610
// Do not create a thumbnail if the resulting width/height is bigger than the original one
611
if ($new_width > $width && $new_height > $height)
616
$used_imagick = false;
618
// Only use imagemagick if defined and the passthru function not disabled
619
if ($config['img_imagick'] && function_exists('passthru'))
621
@passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -antialias -sample ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" +profile "*" "' . str_replace('\\', '/', $destination) . '"');
623
if (file_exists($destination))
625
$used_imagick = true;
631
$type = get_supported_image_types($type);
635
// If the type is not supported, we are not able to create a thumbnail
636
if ($type['format'] === false)
641
switch ($type['format'])
644
$image = @imagecreatefromgif($source);
648
$image = @imagecreatefromjpeg($source);
652
$image = @imagecreatefrompng($source);
656
$image = @imagecreatefromwbmp($source);
660
if ($type['version'] == 1)
662
$new_image = imagecreate($new_width, $new_height);
664
if ($new_image === false)
669
imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
673
$new_image = imagecreatetruecolor($new_width, $new_height);
675
if ($new_image === false)
680
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
683
// If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug
684
if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on')
686
@touch($destination);
689
switch ($type['format'])
692
imagegif($new_image, $destination);
696
imagejpeg($new_image, $destination, 90);
700
imagepng($new_image, $destination);
704
imagewbmp($new_image, $destination);
708
imagedestroy($new_image);
716
if (!file_exists($destination))
721
@chmod($destination, 0666);
727
* Assign Inline attachments (build option fields)
729
function posting_gen_inline_attachments(&$attachment_data)
733
if (sizeof($attachment_data))
735
$s_inline_attachment_options = '';
737
foreach ($attachment_data as $i => $attachment)
739
$s_inline_attachment_options .= '<option value="' . $i . '">' . basename($attachment['real_filename']) . '</option>';
742
$template->assign_var('S_INLINE_ATTACHMENT_OPTIONS', $s_inline_attachment_options);
751
* Generate inline attachment entry
753
function posting_gen_attachment_entry($attachment_data, &$filename_data)
755
global $template, $config, $phpbb_root_path, $phpEx, $user;
757
$template->assign_vars(array(
758
'S_SHOW_ATTACH_BOX' => true)
761
if (sizeof($attachment_data))
763
$template->assign_vars(array(
764
'S_HAS_ATTACHMENTS' => true)
767
// We display the posted attachments within the desired order.
768
($config['display_order']) ? krsort($attachment_data) : ksort($attachment_data);
770
foreach ($attachment_data as $count => $attach_row)
773
$attach_row['real_filename'] = basename($attach_row['real_filename']);
775
foreach ($attach_row as $key => $value)
777
$hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />';
780
$download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&id=' . (int) $attach_row['attach_id'], true, ($attach_row['is_orphan']) ? $user->session_id : false);
782
$template->assign_block_vars('attach_row', array(
783
'FILENAME' => basename($attach_row['real_filename']),
784
'A_FILENAME' => addslashes(basename($attach_row['real_filename'])),
785
'FILE_COMMENT' => $attach_row['attach_comment'],
786
'ATTACH_ID' => $attach_row['attach_id'],
787
'S_IS_ORPHAN' => $attach_row['is_orphan'],
788
'ASSOC_INDEX' => $count,
790
'U_VIEW_ATTACHMENT' => $download_link,
791
'S_HIDDEN' => $hidden)
796
$template->assign_vars(array(
797
'FILE_COMMENT' => $filename_data['filecomment'],
798
'FILESIZE' => $config['max_filesize'])
801
return sizeof($attachment_data);
805
// General Post functions
811
function load_drafts($topic_id = 0, $forum_id = 0, $id = 0)
813
global $user, $db, $template, $auth;
814
global $phpbb_root_path, $phpEx;
816
$topic_ids = $forum_ids = $draft_rows = array();
818
// Load those drafts not connected to forums/topics
819
// If forum_id == 0 AND topic_id == 0 then this is a PM draft
820
if (!$topic_id && !$forum_id)
822
$sql_and = ' AND d.forum_id = 0 AND d.topic_id = 0';
827
$sql_and .= ($forum_id) ? ' AND d.forum_id = ' . (int) $forum_id : '';
828
$sql_and .= ($topic_id) ? ' AND d.topic_id = ' . (int) $topic_id : '';
831
$sql = 'SELECT d.*, f.forum_id, f.forum_name
832
FROM ' . DRAFTS_TABLE . ' d
833
LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = d.forum_id)
834
WHERE d.user_id = ' . $user->data['user_id'] . "
836
ORDER BY d.save_time DESC";
837
$result = $db->sql_query($sql);
839
while ($row = $db->sql_fetchrow($result))
841
if ($row['topic_id'])
843
$topic_ids[] = (int) $row['topic_id'];
845
$draft_rows[] = $row;
847
$db->sql_freeresult($result);
849
if (!sizeof($draft_rows))
854
$topic_rows = array();
855
if (sizeof($topic_ids))
857
$sql = 'SELECT topic_id, forum_id, topic_title
858
FROM ' . TOPICS_TABLE . '
859
WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids));
860
$result = $db->sql_query($sql);
862
while ($row = $db->sql_fetchrow($result))
864
$topic_rows[$row['topic_id']] = $row;
866
$db->sql_freeresult($result);
870
$template->assign_var('S_SHOW_DRAFTS', true);
872
foreach ($draft_rows as $draft)
874
$link_topic = $link_forum = $link_pm = false;
875
$insert_url = $view_url = $title = '';
877
if (isset($topic_rows[$draft['topic_id']])
879
($topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_get('f_read', $topic_rows[$draft['topic_id']]['forum_id']))
881
(!$topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_getf_global('f_read'))
884
$topic_forum_id = ($topic_rows[$draft['topic_id']]['forum_id']) ? $topic_rows[$draft['topic_id']]['forum_id'] : $forum_id;
887
$view_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id']);
888
$title = $topic_rows[$draft['topic_id']]['topic_title'];
890
$insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id'] . '&mode=reply&d=' . $draft['draft_id']);
892
else if ($draft['forum_id'] && $auth->acl_get('f_read', $draft['forum_id']))
895
$view_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $draft['forum_id']);
896
$title = $draft['forum_name'];
898
$insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $draft['forum_id'] . '&mode=post&d=' . $draft['draft_id']);
902
// Either display as PM draft if forum_id and topic_id are empty or if access to the forums has been denied afterwards...
904
$insert_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=compose&d={$draft['draft_id']}");
907
$template->assign_block_vars('draftrow', array(
908
'DRAFT_ID' => $draft['draft_id'],
909
'DATE' => $user->format_date($draft['save_time']),
910
'DRAFT_SUBJECT' => $draft['draft_subject'],
913
'U_VIEW' => $view_url,
914
'U_INSERT' => $insert_url,
916
'S_LINK_PM' => $link_pm,
917
'S_LINK_TOPIC' => $link_topic,
918
'S_LINK_FORUM' => $link_forum)
926
function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true)
928
global $user, $auth, $db, $template, $bbcode, $cache;
929
global $config, $phpbb_root_path, $phpEx;
931
// Go ahead and pull all data for this topic
932
$sql = 'SELECT p.post_id
933
FROM ' . POSTS_TABLE . ' p' . "
934
WHERE p.topic_id = $topic_id
935
" . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . '
936
' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
937
ORDER BY p.post_time DESC';
938
$result = $db->sql_query_limit($sql, $config['posts_per_page']);
940
$post_list = array();
942
while ($row = $db->sql_fetchrow($result))
944
$post_list[] = $row['post_id'];
947
$db->sql_freeresult($result);
949
if (!sizeof($post_list))
954
$sql = $db->sql_build_query('SELECT', array(
955
'SELECT' => 'u.username, u.user_id, u.user_colour, p.*',
962
'WHERE' => $db->sql_in_set('p.post_id', $post_list) . '
963
AND u.user_id = p.poster_id'
966
$result = $db->sql_query($sql);
968
$bbcode_bitfield = '';
970
$has_attachments = false;
971
while ($row = $db->sql_fetchrow($result))
973
$rowset[$row['post_id']] = $row;
974
$bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
976
if ($row['post_attachment'])
978
$has_attachments = true;
981
$db->sql_freeresult($result);
983
// Instantiate BBCode class
984
if (!isset($bbcode) && $bbcode_bitfield !== '')
986
include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx);
987
$bbcode = new bbcode(base64_encode($bbcode_bitfield));
991
$extensions = $attachments = array();
992
if ($has_attachments && $auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
994
$extensions = $cache->obtain_attach_extensions($forum_id);
996
// Get attachments...
998
FROM ' . ATTACHMENTS_TABLE . '
999
WHERE ' . $db->sql_in_set('post_msg_id', $post_list) . '
1001
ORDER BY filetime DESC, post_msg_id ASC';
1002
$result = $db->sql_query($sql);
1004
while ($row = $db->sql_fetchrow($result))
1006
$attachments[$row['post_msg_id']][] = $row;
1008
$db->sql_freeresult($result);
1011
for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
1013
// A non-existing rowset only happens if there was no user present for the entered poster_id
1014
// This could be a broken posts table.
1015
if (!isset($rowset[$post_list[$i]]))
1020
$row =& $rowset[$post_list[$i]];
1022
$poster_id = $row['user_id'];
1023
$post_subject = $row['post_subject'];
1024
$message = censor_text($row['post_text']);
1026
$decoded_message = false;
1028
if ($show_quote_button && $auth->acl_get('f_reply', $forum_id))
1030
$decoded_message = $message;
1031
decode_message($decoded_message, $row['bbcode_uid']);
1033
$decoded_message = bbcode_nl2br($decoded_message);
1036
if ($row['bbcode_bitfield'])
1038
$bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
1041
$message = bbcode_nl2br($message);
1042
$message = smiley_text($message, !$row['enable_smilies']);
1044
if (!empty($attachments[$row['post_id']]))
1046
$update_count = array();
1047
parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count);
1050
$post_subject = censor_text($post_subject);
1052
$template->assign_block_vars($mode . '_row', array(
1053
'POST_AUTHOR_FULL' => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
1054
'POST_AUTHOR_COLOUR' => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
1055
'POST_AUTHOR' => get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
1056
'U_POST_AUTHOR' => get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
1058
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
1060
'POST_SUBJECT' => $post_subject,
1061
'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']),
1062
'POST_DATE' => $user->format_date($row['post_time']),
1063
'MESSAGE' => $message,
1064
'DECODED_MESSAGE' => $decoded_message,
1065
'POST_ID' => $row['post_id'],
1066
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
1067
'U_MCP_DETAILS' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=post_details&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '',
1068
'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '')
1071
// Display not already displayed Attachments for this post, we already parsed them. ;)
1072
if (!empty($attachments[$row['post_id']]))
1074
foreach ($attachments[$row['post_id']] as $attachment)
1076
$template->assign_block_vars($mode . '_row.attachment', array(
1077
'DISPLAY_ATTACHMENT' => $attachment)
1085
if ($mode == 'topic_review')
1087
$template->assign_var('QUOTE_IMG', $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']));
1096
function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id)
1098
global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
1100
$topic_notification = ($mode == 'reply' || $mode == 'quote') ? true : false;
1101
$forum_notification = ($mode == 'post') ? true : false;
1103
if (!$topic_notification && !$forum_notification)
1105
trigger_error('WRONG_NOTIFICATION_MODE');
1108
if (!$config['allow_topic_notify'])
1113
$topic_title = ($topic_notification) ? $topic_title : $subject;
1114
$topic_title = censor_text($topic_title);
1116
// Get banned User ID's
1117
$sql = 'SELECT ban_userid
1118
FROM ' . BANLIST_TABLE;
1119
$result = $db->sql_query($sql);
1121
$sql_ignore_users = ANONYMOUS . ', ' . $user->data['user_id'];
1122
while ($row = $db->sql_fetchrow($result))
1124
if (isset($row['ban_userid']))
1126
$sql_ignore_users .= ', ' . $row['ban_userid'];
1129
$db->sql_freeresult($result);
1131
$notify_rows = array();
1133
// -- get forum_userids || topic_userids
1134
$sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
1135
FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u
1136
WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . "
1137
AND w.user_id NOT IN ($sql_ignore_users)
1138
AND w.notify_status = 0
1139
AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')
1140
AND u.user_id = w.user_id';
1141
$result = $db->sql_query($sql);
1143
while ($row = $db->sql_fetchrow($result))
1145
$notify_rows[$row['user_id']] = array(
1146
'user_id' => $row['user_id'],
1147
'username' => $row['username'],
1148
'user_email' => $row['user_email'],
1149
'user_jabber' => $row['user_jabber'],
1150
'user_lang' => $row['user_lang'],
1151
'notify_type' => ($topic_notification) ? 'topic' : 'forum',
1152
'template' => ($topic_notification) ? 'topic_notify' : 'newtopic_notify',
1153
'method' => $row['user_notify_type'],
1157
$db->sql_freeresult($result);
1159
// forum notification is sent to those not already receiving topic notifications
1160
if ($topic_notification)
1162
if (sizeof($notify_rows))
1164
$sql_ignore_users .= ', ' . implode(', ', array_keys($notify_rows));
1167
$sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
1168
FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u
1169
WHERE fw.forum_id = $forum_id
1170
AND fw.user_id NOT IN ($sql_ignore_users)
1171
AND fw.notify_status = 0
1172
AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')
1173
AND u.user_id = fw.user_id';
1174
$result = $db->sql_query($sql);
1176
while ($row = $db->sql_fetchrow($result))
1178
$notify_rows[$row['user_id']] = array(
1179
'user_id' => $row['user_id'],
1180
'username' => $row['username'],
1181
'user_email' => $row['user_email'],
1182
'user_jabber' => $row['user_jabber'],
1183
'user_lang' => $row['user_lang'],
1184
'notify_type' => 'forum',
1185
'template' => 'forum_notify',
1186
'method' => $row['user_notify_type'],
1190
$db->sql_freeresult($result);
1193
if (!sizeof($notify_rows))
1198
// Make sure users are allowed to read the forum
1199
foreach ($auth->acl_get_list(array_keys($notify_rows), 'f_read', $forum_id) as $forum_id => $forum_ary)
1201
foreach ($forum_ary as $auth_option => $user_ary)
1203
foreach ($user_ary as $user_id)
1205
$notify_rows[$user_id]['allowed'] = true;
1211
// Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;)
1212
$msg_users = $delete_ids = $update_notification = array();
1213
foreach ($notify_rows as $user_id => $row)
1215
if (!$row['allowed'] || !trim($row['user_email']))
1217
$delete_ids[$row['notify_type']][] = $row['user_id'];
1221
$msg_users[] = $row;
1222
$update_notification[$row['notify_type']][] = $row['user_id'];
1225
unset($notify_rows);
1227
// Now, we are able to really send out notifications
1228
if (sizeof($msg_users))
1230
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1231
$messenger = new messenger();
1233
$msg_list_ary = array();
1234
foreach ($msg_users as $row)
1236
$pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]);
1238
$msg_list_ary[$row['template']][$pos]['method'] = $row['method'];
1239
$msg_list_ary[$row['template']][$pos]['email'] = $row['user_email'];
1240
$msg_list_ary[$row['template']][$pos]['jabber'] = $row['user_jabber'];
1241
$msg_list_ary[$row['template']][$pos]['name'] = $row['username'];
1242
$msg_list_ary[$row['template']][$pos]['lang'] = $row['user_lang'];
1246
foreach ($msg_list_ary as $email_template => $email_list)
1248
foreach ($email_list as $addr)
1250
$messenger->template($email_template, $addr['lang']);
1252
$messenger->to($addr['email'], $addr['name']);
1253
$messenger->im($addr['jabber'], $addr['name']);
1255
$messenger->assign_vars(array(
1256
'USERNAME' => htmlspecialchars_decode($addr['name']),
1257
'TOPIC_TITLE' => htmlspecialchars_decode($topic_title),
1258
'FORUM_NAME' => htmlspecialchars_decode($forum_name),
1260
'U_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id",
1261
'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id",
1262
'U_NEWEST_POST' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&p=$post_id&e=$post_id",
1263
'U_STOP_WATCHING_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&unwatch=topic",
1264
'U_STOP_WATCHING_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id&unwatch=forum",
1267
$messenger->send($addr['method']);
1270
unset($msg_list_ary);
1272
$messenger->save_queue();
1275
// Handle the DB updates
1276
$db->sql_transaction('begin');
1278
if (!empty($update_notification['topic']))
1280
$sql = 'UPDATE ' . TOPICS_WATCH_TABLE . "
1281
SET notify_status = 1
1282
WHERE topic_id = $topic_id
1283
AND " . $db->sql_in_set('user_id', $update_notification['topic']);
1284
$db->sql_query($sql);
1287
if (!empty($update_notification['forum']))
1289
$sql = 'UPDATE ' . FORUMS_WATCH_TABLE . "
1290
SET notify_status = 1
1291
WHERE forum_id = $forum_id
1292
AND " . $db->sql_in_set('user_id', $update_notification['forum']);
1293
$db->sql_query($sql);
1296
// Now delete the user_ids not authorised to receive notifications on this topic/forum
1297
if (!empty($delete_ids['topic']))
1299
$sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . "
1300
WHERE topic_id = $topic_id
1301
AND " . $db->sql_in_set('user_id', $delete_ids['topic']);
1302
$db->sql_query($sql);
1305
if (!empty($delete_ids['forum']))
1307
$sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . "
1308
WHERE forum_id = $forum_id
1309
AND " . $db->sql_in_set('user_id', $delete_ids['forum']);
1310
$db->sql_query($sql);
1313
$db->sql_transaction('commit');
1317
// Post handling functions
1323
function delete_post($forum_id, $topic_id, $post_id, &$data)
1325
global $db, $user, $auth;
1326
global $config, $phpEx, $phpbb_root_path;
1328
// Specify our post mode
1329
$post_mode = ($data['topic_first_post_id'] == $data['topic_last_post_id']) ? 'delete_topic' : (($data['topic_first_post_id'] == $post_id) ? 'delete_first_post' : (($data['topic_last_post_id'] == $post_id) ? 'delete_last_post' : 'delete'));
1330
$sql_data = array();
1333
include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1335
$db->sql_transaction('begin');
1337
// we must make sure to update forums that contain the shadow'd topic
1338
if ($post_mode == 'delete_topic')
1340
$shadow_forum_ids = array();
1342
$sql = 'SELECT forum_id
1343
FROM ' . TOPICS_TABLE . '
1344
WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id);
1345
$result = $db->sql_query($sql);
1346
while ($row = $db->sql_fetchrow($result))
1348
if (!isset($shadow_forum_ids[(int) $row['forum_id']]))
1350
$shadow_forum_ids[(int) $row['forum_id']] = 1;
1354
$shadow_forum_ids[(int) $row['forum_id']]++;
1357
$db->sql_freeresult($result);
1360
if (!delete_posts('post_id', array($post_id), false, false))
1362
// Try to delete topic, we may had an previous error causing inconsistency
1363
if ($post_mode == 'delete_topic')
1365
delete_topics('topic_id', array($topic_id), false);
1367
trigger_error('ALREADY_DELETED');
1370
$db->sql_transaction('commit');
1372
// Collect the necessary information for updating the tables
1373
$sql_data[FORUMS_TABLE] = '';
1376
case 'delete_topic':
1378
foreach ($shadow_forum_ids as $updated_forum => $topic_count)
1380
// counting is fun! we only have to do sizeof($forum_ids) number of queries,
1381
// even if the topic is moved back to where its shadow lives (we count how many times it is in a forum)
1382
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET forum_topics_real = forum_topics_real - ' . $topic_count . ', forum_topics = forum_topics - ' . $topic_count . ' WHERE forum_id = ' . $updated_forum);
1383
update_post_information('forum', $updated_forum);
1386
delete_topics('topic_id', array($topic_id), false);
1388
if ($data['topic_type'] != POST_GLOBAL)
1390
$sql_data[FORUMS_TABLE] .= 'forum_topics_real = forum_topics_real - 1';
1391
$sql_data[FORUMS_TABLE] .= ($data['topic_approved']) ? ', forum_posts = forum_posts - 1, forum_topics = forum_topics - 1' : '';
1394
$update_sql = update_post_information('forum', $forum_id, true);
1395
if (sizeof($update_sql))
1397
$sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
1398
$sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
1402
case 'delete_first_post':
1403
$sql = 'SELECT p.post_id, p.poster_id, p.post_username, u.username, u.user_colour
1404
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
1405
WHERE p.topic_id = $topic_id
1406
AND p.poster_id = u.user_id
1407
ORDER BY p.post_time ASC";
1408
$result = $db->sql_query_limit($sql, 1);
1409
$row = $db->sql_fetchrow($result);
1410
$db->sql_freeresult($result);
1412
if ($data['topic_type'] != POST_GLOBAL)
1414
$sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1417
$sql_data[TOPICS_TABLE] = 'topic_first_post_id = ' . intval($row['post_id']) . ", topic_first_poster_colour = '" . $db->sql_escape($row['user_colour']) . "', topic_first_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'";
1419
// Decrementing topic_replies here is fine because this case only happens if there is more than one post within the topic - basically removing one "reply"
1420
$sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : '');
1422
$next_post_id = (int) $row['post_id'];
1425
case 'delete_last_post':
1426
if ($data['topic_type'] != POST_GLOBAL)
1428
$sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1431
$update_sql = update_post_information('forum', $forum_id, true);
1432
if (sizeof($update_sql))
1434
$sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
1435
$sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
1438
$sql_data[TOPICS_TABLE] = 'topic_bumped = 0, topic_bumper = 0, topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : '');
1440
$update_sql = update_post_information('topic', $topic_id, true);
1441
if (sizeof($update_sql))
1443
$sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]);
1444
$next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]);
1448
$sql = 'SELECT MAX(post_id) as last_post_id
1449
FROM ' . POSTS_TABLE . "
1450
WHERE topic_id = $topic_id " .
1451
((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '');
1452
$result = $db->sql_query($sql);
1453
$row = $db->sql_fetchrow($result);
1454
$db->sql_freeresult($result);
1456
$next_post_id = (int) $row['last_post_id'];
1461
$sql = 'SELECT post_id
1462
FROM ' . POSTS_TABLE . "
1463
WHERE topic_id = $topic_id " .
1464
((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '') . '
1465
AND post_time > ' . $data['post_time'] . '
1466
ORDER BY post_time ASC';
1467
$result = $db->sql_query_limit($sql, 1);
1468
$row = $db->sql_fetchrow($result);
1469
$db->sql_freeresult($result);
1471
if ($data['topic_type'] != POST_GLOBAL)
1473
$sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1476
$sql_data[TOPICS_TABLE] = 'topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : '');
1477
$next_post_id = (int) $row['post_id'];
1481
// $sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : '';
1483
$db->sql_transaction('begin');
1486
FORUMS_TABLE => "forum_id = $forum_id",
1487
TOPICS_TABLE => "topic_id = $topic_id",
1488
USERS_TABLE => 'user_id = ' . $data['poster_id']
1491
foreach ($sql_data as $table => $update_sql)
1495
$db->sql_query("UPDATE $table SET $update_sql WHERE " . $where_sql[$table]);
1499
// Adjust posted info for this user by looking for a post by him/her within this topic...
1500
if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS)
1502
$sql = 'SELECT poster_id
1503
FROM ' . POSTS_TABLE . '
1504
WHERE topic_id = ' . $topic_id . '
1505
AND poster_id = ' . $data['poster_id'];
1506
$result = $db->sql_query_limit($sql, 1);
1507
$poster_id = (int) $db->sql_fetchfield('poster_id');
1508
$db->sql_freeresult($result);
1510
// The user is not having any more posts within this topic
1513
$sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
1514
WHERE topic_id = ' . $topic_id . '
1515
AND user_id = ' . $data['poster_id'];
1516
$db->sql_query($sql);
1520
$db->sql_transaction('commit');
1522
if ($data['post_reported'] && ($post_mode != 'delete_topic'))
1524
sync('topic_reported', 'topic_id', array($topic_id));
1527
return $next_post_id;
1533
function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true)
1535
global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
1537
// We do not handle erasing posts here
1538
if ($mode == 'delete')
1543
$current_time = time();
1545
if ($mode == 'post')
1547
$post_mode = 'post';
1548
$update_message = true;
1550
else if ($mode != 'edit')
1552
$post_mode = 'reply';
1553
$update_message = true;
1555
else if ($mode == 'edit')
1557
$post_mode = ($data['topic_replies_real'] == 0) ? 'edit_topic' : (($data['topic_first_post_id'] == $data['post_id']) ? 'edit_first_post' : (($data['topic_last_post_id'] == $data['post_id']) ? 'edit_last_post' : 'edit'));
1560
// First of all make sure the subject and topic title are having the correct length.
1561
// To achieve this without cutting off between special chars we convert to an array and then count the elements.
1562
$subject = truncate_string($subject);
1563
$data['topic_title'] = truncate_string($data['topic_title']);
1565
// Collect some basic information about which tables and which rows to update/insert
1566
$sql_data = $topic_row = array();
1567
$poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id'];
1569
// Retrieve some additional information if not present
1570
if ($mode == 'edit' && (!isset($data['post_approved']) || !isset($data['topic_approved']) || $data['post_approved'] === false || $data['topic_approved'] === false))
1572
$sql = 'SELECT p.post_approved, t.topic_type, t.topic_replies, t.topic_replies_real, t.topic_approved
1573
FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
1574
WHERE t.topic_id = p.topic_id
1575
AND p.post_id = ' . $data['post_id'];
1576
$result = $db->sql_query($sql);
1577
$topic_row = $db->sql_fetchrow($result);
1578
$db->sql_freeresult($result);
1580
$data['topic_approved'] = $topic_row['topic_approved'];
1581
$data['post_approved'] = $topic_row['post_approved'];
1584
// Start the transaction here
1585
$db->sql_transaction('begin');
1588
// Collect Information
1593
$sql_data[POSTS_TABLE]['sql'] = array(
1594
'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
1595
'poster_id' => (int) $user->data['user_id'],
1596
'icon_id' => $data['icon_id'],
1597
'poster_ip' => $user->ip,
1598
'post_time' => $current_time,
1599
'post_approved' => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : 1,
1600
'enable_bbcode' => $data['enable_bbcode'],
1601
'enable_smilies' => $data['enable_smilies'],
1602
'enable_magic_url' => $data['enable_urls'],
1603
'enable_sig' => $data['enable_sig'],
1604
'post_username' => (!$user->data['is_registered']) ? $username : '',
1605
'post_subject' => $subject,
1606
'post_text' => $data['message'],
1607
'post_checksum' => $data['message_md5'],
1608
'post_attachment' => (!empty($data['attachment_data'])) ? 1 : 0,
1609
'bbcode_bitfield' => $data['bbcode_bitfield'],
1610
'bbcode_uid' => $data['bbcode_uid'],
1611
'post_postcount' => ($auth->acl_get('f_postcount', $data['forum_id'])) ? 1 : 0,
1612
'post_edit_locked' => $data['post_edit_locked']
1616
case 'edit_first_post':
1619
case 'edit_last_post':
1622
// If edit reason is given always display edit info
1624
// If editing last post then display no edit info
1625
// If m_edit permission then display no edit info
1626
// If normal edit display edit info
1628
// Display edit info if edit reason given or user is editing his post, which is not the last within the topic.
1629
if ($data['post_edit_reason'] || (!$auth->acl_get('m_edit', $data['forum_id']) && ($post_mode == 'edit' || $post_mode == 'edit_first_post')))
1631
$data['post_edit_reason'] = truncate_string($data['post_edit_reason'], 255, false);
1633
$sql_data[POSTS_TABLE]['sql'] = array(
1634
'post_edit_time' => $current_time,
1635
'post_edit_reason' => $data['post_edit_reason'],
1636
'post_edit_user' => (int) $data['post_edit_user'],
1639
$sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
1641
else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id']))
1643
$sql_data[POSTS_TABLE]['sql'] = array(
1644
'post_edit_reason' => '',
1648
// If the person editing this post is different to the one having posted then we will add a log entry stating the edit
1649
// Could be simplified by only adding to the log if the edit is not tracked - but this may confuse admins/mods
1650
if ($user->data['user_id'] != $poster_id)
1652
$log_subject = ($subject) ? $subject : $data['topic_title'];
1653
add_log('mod', $data['forum_id'], $data['topic_id'], 'LOG_POST_EDITED', $log_subject, (!empty($username)) ? $username : $user->lang['GUEST']);
1656
if (!isset($sql_data[POSTS_TABLE]['sql']))
1658
$sql_data[POSTS_TABLE]['sql'] = array();
1661
$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
1662
'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
1663
'poster_id' => $data['poster_id'],
1664
'icon_id' => $data['icon_id'],
1665
'post_approved' => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : $data['post_approved'],
1666
'enable_bbcode' => $data['enable_bbcode'],
1667
'enable_smilies' => $data['enable_smilies'],
1668
'enable_magic_url' => $data['enable_urls'],
1669
'enable_sig' => $data['enable_sig'],
1670
'post_username' => ($username && $data['poster_id'] == ANONYMOUS) ? $username : '',
1671
'post_subject' => $subject,
1672
'post_checksum' => $data['message_md5'],
1673
'post_attachment' => (!empty($data['attachment_data'])) ? 1 : 0,
1674
'bbcode_bitfield' => $data['bbcode_bitfield'],
1675
'bbcode_uid' => $data['bbcode_uid'],
1676
'post_edit_locked' => $data['post_edit_locked'])
1679
if ($update_message)
1681
$sql_data[POSTS_TABLE]['sql']['post_text'] = $data['message'];
1687
$post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved'];
1688
$topic_row = array();
1690
// And the topic ladies and gentlemen
1694
$sql_data[TOPICS_TABLE]['sql'] = array(
1695
'topic_poster' => (int) $user->data['user_id'],
1696
'topic_time' => $current_time,
1697
'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
1698
'icon_id' => $data['icon_id'],
1699
'topic_approved' => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : 1,
1700
'topic_title' => $subject,
1701
'topic_first_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
1702
'topic_first_poster_colour' => $user->data['user_colour'],
1703
'topic_type' => $topic_type,
1704
'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
1705
'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : 0,
1708
if (isset($poll['poll_options']) && !empty($poll['poll_options']))
1710
$sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array(
1711
'poll_title' => $poll['poll_title'],
1712
'poll_start' => ($poll['poll_start']) ? $poll['poll_start'] : $current_time,
1713
'poll_max_options' => $poll['poll_max_options'],
1714
'poll_length' => ($poll['poll_length'] * 86400),
1715
'poll_vote_change' => $poll['poll_vote_change'])
1719
$sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
1721
if ($topic_type != POST_GLOBAL)
1723
if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
1725
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
1727
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) ? ', forum_topics = forum_topics + 1' : '');
1732
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0' . (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) ? ', topic_replies = topic_replies + 1' : '') . ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : '');
1734
$sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
1736
if (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) && $topic_type != POST_GLOBAL)
1738
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
1743
case 'edit_first_post':
1745
$sql_data[TOPICS_TABLE]['sql'] = array(
1746
'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
1747
'icon_id' => $data['icon_id'],
1748
'topic_approved' => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : $data['topic_approved'],
1749
'topic_title' => $subject,
1750
'topic_first_poster_name' => $username,
1751
'topic_type' => $topic_type,
1752
'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
1753
'poll_title' => (isset($poll['poll_options'])) ? $poll['poll_title'] : '',
1754
'poll_start' => (isset($poll['poll_options'])) ? (($poll['poll_start']) ? $poll['poll_start'] : $current_time) : 0,
1755
'poll_max_options' => (isset($poll['poll_options'])) ? $poll['poll_max_options'] : 1,
1756
'poll_length' => (isset($poll['poll_options'])) ? ($poll['poll_length'] * 86400) : 0,
1757
'poll_vote_change' => (isset($poll['poll_vote_change'])) ? $poll['poll_vote_change'] : 0,
1759
'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0),
1762
// Correctly set back the topic replies and forum posts... only if the topic was approved before and now gets disapproved
1763
if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id']) && $data['topic_approved'])
1765
// Do we need to grab some topic informations?
1766
if (!sizeof($topic_row))
1768
$sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved
1769
FROM ' . TOPICS_TABLE . '
1770
WHERE topic_id = ' . $data['topic_id'];
1771
$result = $db->sql_query($sql);
1772
$topic_row = $db->sql_fetchrow($result);
1773
$db->sql_freeresult($result);
1776
// If this is the only post remaining we do not need to decrement topic_replies.
1777
// Also do not decrement if first post - then the topic_replies will not be adjusted if approving the topic again.
1779
// If this is an edited topic or the first post the topic gets completely disapproved later on...
1780
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1';
1781
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1);
1783
set_config('num_topics', $config['num_topics'] - 1, true);
1784
set_config('num_posts', $config['num_posts'] - ($topic_row['topic_replies'] + 1), true);
1790
case 'edit_last_post':
1792
// Correctly set back the topic replies and forum posts... but only if the post was approved before.
1793
if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id']) && $data['post_approved'])
1795
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1';
1796
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1';
1798
set_config('num_posts', $config['num_posts'] - 1, true);
1805
if ($post_mode == 'post')
1807
$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
1808
$db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
1809
$db->sql_query($sql);
1811
$data['topic_id'] = $db->sql_nextid();
1813
$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
1814
'topic_id' => $data['topic_id'])
1816
unset($sql_data[TOPICS_TABLE]['sql']);
1820
if ($post_mode == 'post' || $post_mode == 'reply')
1822
if ($post_mode == 'reply')
1824
$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
1825
'topic_id' => $data['topic_id'])
1829
$sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']);
1830
$db->sql_query($sql);
1831
$data['post_id'] = $db->sql_nextid();
1833
if ($post_mode == 'post')
1835
$sql_data[TOPICS_TABLE]['sql'] = array(
1836
'topic_first_post_id' => $data['post_id'],
1837
'topic_last_post_id' => $data['post_id'],
1838
'topic_last_post_time' => $current_time,
1839
'topic_last_poster_id' => (int) $user->data['user_id'],
1840
'topic_last_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
1841
'topic_last_poster_colour' => $user->data['user_colour'],
1845
unset($sql_data[POSTS_TABLE]['sql']);
1848
$make_global = false;
1850
// Are we globalising or unglobalising?
1851
if ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic')
1853
if (!sizeof($topic_row))
1855
$sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved, topic_last_post_id
1856
FROM ' . TOPICS_TABLE . '
1857
WHERE topic_id = ' . $data['topic_id'];
1858
$result = $db->sql_query($sql);
1859
$topic_row = $db->sql_fetchrow($result);
1860
$db->sql_freeresult($result);
1863
// globalise/unglobalise?
1864
if (($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL) || ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL))
1866
if (!empty($sql_data[FORUMS_TABLE]['stat']) && implode('', $sql_data[FORUMS_TABLE]['stat']))
1868
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET ' . implode(', ', $sql_data[FORUMS_TABLE]['stat']) . ' WHERE forum_id = ' . $data['forum_id']);
1871
$make_global = true;
1872
$sql_data[FORUMS_TABLE]['stat'] = array();
1876
if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL)
1878
// Decrement topic/post count
1879
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies_real'] + 1);
1880
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real - 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics - 1' : '');
1882
// Update forum_ids for all posts
1883
$sql = 'UPDATE ' . POSTS_TABLE . '
1885
WHERE topic_id = ' . $data['topic_id'];
1886
$db->sql_query($sql);
1889
else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL)
1891
// Increment topic/post count
1892
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + ' . ($topic_row['topic_replies_real'] + 1);
1893
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics + 1' : '');
1895
// Update forum_ids for all posts
1896
$sql = 'UPDATE ' . POSTS_TABLE . '
1897
SET forum_id = ' . $data['forum_id'] . '
1898
WHERE topic_id = ' . $data['topic_id'];
1899
$db->sql_query($sql);
1903
// Update the topics table
1904
if (isset($sql_data[TOPICS_TABLE]['sql']))
1906
$sql = 'UPDATE ' . TOPICS_TABLE . '
1907
SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . '
1908
WHERE topic_id = ' . $data['topic_id'];
1909
$db->sql_query($sql);
1912
// Update the posts table
1913
if (isset($sql_data[POSTS_TABLE]['sql']))
1915
$sql = 'UPDATE ' . POSTS_TABLE . '
1916
SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . '
1917
WHERE post_id = ' . $data['post_id'];
1918
$db->sql_query($sql);
1921
// Update Poll Tables
1922
if (isset($poll['poll_options']) && !empty($poll['poll_options']))
1924
$cur_poll_options = array();
1926
if ($poll['poll_start'] && $mode == 'edit')
1929
FROM ' . POLL_OPTIONS_TABLE . '
1930
WHERE topic_id = ' . $data['topic_id'] . '
1931
ORDER BY poll_option_id';
1932
$result = $db->sql_query($sql);
1934
$cur_poll_options = array();
1935
while ($row = $db->sql_fetchrow($result))
1937
$cur_poll_options[] = $row;
1939
$db->sql_freeresult($result);
1942
$sql_insert_ary = array();
1944
for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++)
1946
if (strlen(trim($poll['poll_options'][$i])))
1948
if (empty($cur_poll_options[$i]))
1950
// If we add options we need to put them to the end to be able to preserve votes...
1951
$sql_insert_ary[] = array(
1952
'poll_option_id' => (int) sizeof($cur_poll_options) + 1 + sizeof($sql_insert_ary),
1953
'topic_id' => (int) $data['topic_id'],
1954
'poll_option_text' => (string) $poll['poll_options'][$i]
1957
else if ($poll['poll_options'][$i] != $cur_poll_options[$i])
1959
$sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
1960
SET poll_option_text = '" . $db->sql_escape($poll['poll_options'][$i]) . "'
1961
WHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . '
1962
AND topic_id = ' . $data['topic_id'];
1963
$db->sql_query($sql);
1968
$db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);
1970
if (sizeof($poll['poll_options']) < sizeof($cur_poll_options))
1972
$sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
1973
WHERE poll_option_id > ' . sizeof($poll['poll_options']) . '
1974
AND topic_id = ' . $data['topic_id'];
1975
$db->sql_query($sql);
1978
// If edited, we would need to reset votes (since options can be re-ordered above, you can't be sure if the change is for changing the text or adding an option
1979
if ($mode == 'edit' && sizeof($poll['poll_options']) != sizeof($cur_poll_options))
1981
$db->sql_query('DELETE FROM ' . POLL_VOTES_TABLE . ' WHERE topic_id = ' . $data['topic_id']);
1982
$db->sql_query('UPDATE ' . POLL_OPTIONS_TABLE . ' SET poll_option_total = 0 WHERE topic_id = ' . $data['topic_id']);
1986
// Submit Attachments
1987
if (!empty($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit')))
1989
$space_taken = $files_added = 0;
1990
$orphan_rows = array();
1992
foreach ($data['attachment_data'] as $pos => $attach_row)
1994
$orphan_rows[(int) $attach_row['attach_id']] = array();
1997
if (sizeof($orphan_rows))
1999
$sql = 'SELECT attach_id, filesize, physical_filename
2000
FROM ' . ATTACHMENTS_TABLE . '
2001
WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
2003
AND poster_id = ' . $user->data['user_id'];
2004
$result = $db->sql_query($sql);
2006
$orphan_rows = array();
2007
while ($row = $db->sql_fetchrow($result))
2009
$orphan_rows[$row['attach_id']] = $row;
2011
$db->sql_freeresult($result);
2014
foreach ($data['attachment_data'] as $pos => $attach_row)
2016
if ($attach_row['is_orphan'] && !in_array($attach_row['attach_id'], array_keys($orphan_rows)))
2021
if (!$attach_row['is_orphan'])
2023
// update entry in db if attachment already stored in db and filespace
2024
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
2025
SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
2026
WHERE attach_id = " . (int) $attach_row['attach_id'] . '
2028
$db->sql_query($sql);
2032
// insert attachment into db
2033
if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
2038
$space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
2041
$attach_sql = array(
2042
'post_msg_id' => $data['post_id'],
2043
'topic_id' => $data['topic_id'],
2045
'poster_id' => $poster_id,
2046
'attach_comment' => $attach_row['attach_comment'],
2049
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
2050
WHERE attach_id = ' . $attach_row['attach_id'] . '
2052
AND poster_id = ' . $user->data['user_id'];
2053
$db->sql_query($sql);
2057
if ($space_taken && $files_added)
2059
set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
2060
set_config('num_files', $config['num_files'] + $files_added, true);
2064
// we need to update the last forum information
2065
// only applicable if the topic is not global and it is approved
2066
// we also check to make sure we are not dealing with globaling the latest topic (pretty rare but still needs to be checked)
2067
if ($topic_type != POST_GLOBAL && !$make_global && ($post_approved || !$data['post_approved']))
2069
// the last post makes us update the forum table. This can happen if...
2070
// We make a new topic
2071
// We reply to a topic
2072
// We edit the last post in a topic and this post is the latest in the forum (maybe)
2073
// We edit the only post in the topic
2074
// We edit the first post in the topic and all the other posts are not approved
2075
if (($post_mode == 'post' || $post_mode == 'reply') && $post_approved)
2077
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id'];
2078
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'";
2079
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time;
2080
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id'];
2081
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'";
2082
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'";
2084
else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
2086
// this does not _necessarily_ mean that we must update the info again,
2087
// it just means that we might have to
2088
$sql = 'SELECT forum_last_post_id, forum_last_post_subject
2089
FROM ' . FORUMS_TABLE . '
2090
WHERE forum_id = ' . (int) $data['forum_id'];
2091
$result = $db->sql_query($sql);
2092
$row = $db->sql_fetchrow($result);
2093
$db->sql_freeresult($result);
2095
// this post is the latest post in the forum, better update
2096
if ($row['forum_last_post_id'] == $data['post_id'])
2098
if ($post_approved && $row['forum_last_post_subject'] !== $subject)
2100
// the only data that can really be changed is the post's subject
2101
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_subject = \'' . $db->sql_escape($subject) . '\'';
2103
else if ($data['post_approved'] !== $post_approved)
2105
// we need a fresh change of socks, everything has become invalidated
2106
$sql = 'SELECT MAX(topic_last_post_id) as last_post_id
2107
FROM ' . TOPICS_TABLE . '
2108
WHERE forum_id = ' . (int) $data['forum_id'] . '
2109
AND topic_approved = 1';
2110
$result = $db->sql_query($sql);
2111
$row = $db->sql_fetchrow($result);
2112
$db->sql_freeresult($result);
2114
// any posts left in this forum?
2115
if (!empty($row['last_post_id']))
2117
$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
2118
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
2119
WHERE p.poster_id = u.user_id
2120
AND p.post_id = ' . (int) $row['last_post_id'];
2121
$result = $db->sql_query($sql);
2122
$row = $db->sql_fetchrow($result);
2123
$db->sql_freeresult($result);
2125
// salvation, a post is found! jam it into the forums table
2126
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
2127
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
2128
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
2129
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
2130
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
2131
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
2135
// just our luck, the last topic in the forum has just been turned unapproved...
2136
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
2137
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
2138
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
2139
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
2140
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
2141
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
2147
else if ($make_global)
2149
// somebody decided to be a party pooper, we must recalculate the whole shebang (maybe)
2150
$sql = 'SELECT forum_last_post_id
2151
FROM ' . FORUMS_TABLE . '
2152
WHERE forum_id = ' . (int) $data['forum_id'];
2153
$result = $db->sql_query($sql);
2154
$forum_row = $db->sql_fetchrow($result);
2155
$db->sql_freeresult($result);
2157
// we made a topic global, go get new data
2158
if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL && $forum_row['forum_last_post_id'] == $topic_row['topic_last_post_id'])
2160
// we need a fresh change of socks, everything has become invalidated
2161
$sql = 'SELECT MAX(topic_last_post_id) as last_post_id
2162
FROM ' . TOPICS_TABLE . '
2163
WHERE forum_id = ' . (int) $data['forum_id'] . '
2164
AND topic_approved = 1';
2165
$result = $db->sql_query($sql);
2166
$row = $db->sql_fetchrow($result);
2167
$db->sql_freeresult($result);
2169
// any posts left in this forum?
2170
if (!empty($row['last_post_id']))
2172
$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
2173
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
2174
WHERE p.poster_id = u.user_id
2175
AND p.post_id = ' . (int) $row['last_post_id'];
2176
$result = $db->sql_query($sql);
2177
$row = $db->sql_fetchrow($result);
2178
$db->sql_freeresult($result);
2180
// salvation, a post is found! jam it into the forums table
2181
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
2182
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
2183
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
2184
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
2185
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
2186
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
2190
// just our luck, the last topic in the forum has just been globalized...
2191
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
2192
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
2193
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
2194
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
2195
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
2196
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
2199
else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL && $forum_row['forum_last_post_id'] < $topic_row['topic_last_post_id'])
2201
// this post has a higher id, it is newer
2202
$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
2203
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
2204
WHERE p.poster_id = u.user_id
2205
AND p.post_id = ' . (int) $topic_row['topic_last_post_id'];
2206
$result = $db->sql_query($sql);
2207
$row = $db->sql_fetchrow($result);
2208
$db->sql_freeresult($result);
2210
// salvation, a post is found! jam it into the forums table
2211
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
2212
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
2213
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
2214
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
2215
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
2216
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
2221
// simply, we update if it is a reply or the last post is edited
2224
// reply requires the whole thing
2225
if ($post_mode == 'reply')
2227
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $data['post_id'];
2228
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $user->data['user_id'];
2229
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'";
2230
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . (($user->data['user_id'] != ANONYMOUS) ? $db->sql_escape($user->data['user_colour']) : '') . "'";
2231
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
2232
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $current_time;
2234
else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
2236
// only the subject can be changed from edit
2237
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
2240
else if (!$data['post_approved'] && ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])))
2242
// like having the rug pulled from under us
2243
$sql = 'SELECT MAX(post_id) as last_post_id
2244
FROM ' . POSTS_TABLE . '
2245
WHERE topic_id = ' . (int) $data['topic_id'] . '
2246
AND post_approved = 1';
2247
$result = $db->sql_query($sql);
2248
$row = $db->sql_fetchrow($result);
2249
$db->sql_freeresult($result);
2251
// any posts left in this forum?
2252
if (!empty($row['last_post_id']))
2254
$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
2255
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
2256
WHERE p.poster_id = u.user_id
2257
AND p.post_id = ' . (int) $row['last_post_id'];
2258
$result = $db->sql_query($sql);
2259
$row = $db->sql_fetchrow($result);
2260
$db->sql_freeresult($result);
2262
// salvation, a post is found! jam it into the topics table
2263
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $row['post_id'];
2264
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
2265
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $row['post_time'];
2266
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $row['poster_id'];
2267
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
2268
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
2272
// Update total post count, do not consider moderated posts/topics
2273
if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
2275
if ($post_mode == 'post')
2277
set_config('num_topics', $config['num_topics'] + 1, true);
2278
set_config('num_posts', $config['num_posts'] + 1, true);
2281
if ($post_mode == 'reply')
2283
set_config('num_posts', $config['num_posts'] + 1, true);
2287
// Update forum stats
2288
$where_sql = array(POSTS_TABLE => 'post_id = ' . $data['post_id'], TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], FORUMS_TABLE => 'forum_id = ' . $data['forum_id'], USERS_TABLE => 'user_id = ' . $user->data['user_id']);
2290
foreach ($sql_data as $table => $update_ary)
2292
if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
2294
$sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
2295
$db->sql_query($sql);
2299
// Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
2302
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
2303
WHERE topic_moved_id = ' . $data['topic_id'];
2304
$db->sql_query($sql);
2307
// Committing the transaction before updating search index
2308
$db->sql_transaction('commit');
2310
// Delete draft if post was loaded...
2311
$draft_id = request_var('draft_loaded', 0);
2314
$sql = 'DELETE FROM ' . DRAFTS_TABLE . "
2315
WHERE draft_id = $draft_id
2316
AND user_id = {$user->data['user_id']}";
2317
$db->sql_query($sql);
2320
// Index message contents
2321
if ($update_message && $data['enable_indexing'])
2323
// Select the search method and do some additional checks to ensure it can actually be utilised
2324
$search_type = basename($config['search_type']);
2326
if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
2328
trigger_error('NO_SUCH_SEARCH_MODULE');
2331
if (!class_exists($search_type))
2333
include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
2337
$search = new $search_type($error);
2341
trigger_error($error);
2344
$search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']);
2347
// Topic Notification, do not change if moderator is changing other users posts...
2348
if ($user->data['user_id'] == $poster_id)
2350
if (!$data['notify_set'] && $data['notify'])
2352
$sql = 'INSERT INTO ' . TOPICS_WATCH_TABLE . ' (user_id, topic_id)
2353
VALUES (' . $user->data['user_id'] . ', ' . $data['topic_id'] . ')';
2354
$db->sql_query($sql);
2356
else if ($data['notify_set'] && !$data['notify'])
2358
$sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . '
2359
WHERE user_id = ' . $user->data['user_id'] . '
2360
AND topic_id = ' . $data['topic_id'];
2361
$db->sql_query($sql);
2365
if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
2367
// Mark this topic as posted to
2368
markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
2371
// Mark this topic as read
2372
// We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
2373
markread('topic', $data['forum_id'], $data['topic_id'], time());
2376
if ($config['load_db_lastread'] && $user->data['is_registered'])
2378
$sql = 'SELECT mark_time
2379
FROM ' . FORUMS_TRACK_TABLE . '
2380
WHERE user_id = ' . $user->data['user_id'] . '
2381
AND forum_id = ' . $data['forum_id'];
2382
$result = $db->sql_query($sql);
2383
$f_mark_time = (int) $db->sql_fetchfield('mark_time');
2384
$db->sql_freeresult($result);
2386
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
2388
$f_mark_time = false;
2391
if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
2393
// Update forum info
2394
$sql = 'SELECT forum_last_post_time
2395
FROM ' . FORUMS_TABLE . '
2396
WHERE forum_id = ' . $data['forum_id'];
2397
$result = $db->sql_query($sql);
2398
$forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
2399
$db->sql_freeresult($result);
2401
update_forum_tracking_info($data['forum_id'], $forum_last_post_time, $f_mark_time, false);
2404
// Send Notifications
2405
if ($mode != 'edit' && $mode != 'delete' && ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])))
2407
user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
2410
$params = $add_anchor = '';
2412
if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
2414
$params .= '&t=' . $data['topic_id'];
2416
if ($mode != 'post')
2418
$params .= '&p=' . $data['post_id'];
2419
$add_anchor = '#p' . $data['post_id'];
2422
else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic')
2424
$params .= '&t=' . $data['topic_id'];
2427
$url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
2428
$url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;
b'\\ No newline at end of file'