Verzeichnisstruktur phpBB-3.0.0
- Veröffentlicht
- 12.12.2007
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
functions_posting.php
0001 <?php
0002 /**
0003 *
0004 * @package phpBB3
0005 * @version $Id$
0006 * @copyright (c) 2005 phpBB Group
0007 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
0008 *
0009 */
0010
0011 /**
0012 * @ignore
0013 */
0014 if (!defined('IN_PHPBB'))
0015 {
0016 exit;
0017 }
0018
0019 /**
0020 * Fill smiley templates (or just the variables) with smilies, either in a window or inline
0021 */
0022 function generate_smilies($mode, $forum_id)
0023 {
0024 global $auth, $db, $user, $config, $template;
0025 global $phpEx, $phpbb_root_path;
0026
0027 if ($mode == 'window')
0028 {
0029 if ($forum_id)
0030 {
0031 $sql = 'SELECT forum_style
0032 FROM ' . FORUMS_TABLE . "
0033 WHERE forum_id = $forum_id";
0034 $result = $db->sql_query_limit($sql, 1);
0035 $row = $db->sql_fetchrow($result);
0036 $db->sql_freeresult($result);
0037
0038 $user->setup('posting', (int) $row['forum_style']);
0039 }
0040 else
0041 {
0042 $user->setup('posting');
0043 }
0044
0045 page_header($user->lang['SMILIES']);
0046
0047 $template->set_filenames(array(
0048 'body' => 'posting_smilies.html')
0049 );
0050 }
0051
0052 $display_link = false;
0053 if ($mode == 'inline')
0054 {
0055 $sql = 'SELECT smiley_id
0056 FROM ' . SMILIES_TABLE . '
0057 WHERE display_on_posting = 0';
0058 $result = $db->sql_query_limit($sql, 1, 0, 3600);
0059
0060 if ($row = $db->sql_fetchrow($result))
0061 {
0062 $display_link = true;
0063 }
0064 $db->sql_freeresult($result);
0065 }
0066
0067 $last_url = '';
0068
0069 $sql = 'SELECT *
0070 FROM ' . SMILIES_TABLE .
0071 (($mode == 'inline') ? ' WHERE display_on_posting = 1 ' : '') . '
0072 ORDER BY smiley_order';
0073 $result = $db->sql_query($sql, 3600);
0074
0075 $smilies = array();
0076 while ($row = $db->sql_fetchrow($result))
0077 {
0078 if (empty($smilies[$row['smiley_url']]))
0079 {
0080 $smilies[$row['smiley_url']] = $row;
0081 }
0082 }
0083 $db->sql_freeresult($result);
0084
0085 if (sizeof($smilies))
0086 {
0087 foreach ($smilies as $row)
0088 {
0089 $template->assign_block_vars('smiley', array(
0090 'SMILEY_CODE' => $row['code'],
0091 'A_SMILEY_CODE' => addslashes($row['code']),
0092 'SMILEY_IMG' => $phpbb_root_path . $config['smilies_path'] . '/' . $row['smiley_url'],
0093 'SMILEY_WIDTH' => $row['smiley_width'],
0094 'SMILEY_HEIGHT' => $row['smiley_height'],
0095 'SMILEY_DESC' => $row['emotion'])
0096 );
0097 }
0098 }
0099
0100 if ($mode == 'inline' && $display_link)
0101 {
0102 $template->assign_vars(array(
0103 'S_SHOW_SMILEY_LINK' => true,
0104 'U_MORE_SMILIES' => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id))
0105 );
0106 }
0107
0108 if ($mode == 'window')
0109 {
0110 page_footer();
0111 }
0112 }
0113
0114 /**
0115 * Update last post information
0116 * Should be used instead of sync() if only the last post information are out of sync... faster
0117 *
0118 * @param string $type Can be forum|topic
0119 * @param mixed $ids topic/forum ids
0120 * @param bool $return_update_sql true: SQL query shall be returned, false: execute SQL
0121 */
0122 function update_post_information($type, $ids, $return_update_sql = false)
0123 {
0124 global $db;
0125
0126 if (empty($ids))
0127 {
0128 return;
0129 }
0130 if (!is_array($ids))
0131 {
0132 $ids = array($ids);
0133 }
0134
0135
0136 $update_sql = $empty_forums = $not_empty_forums = array();
0137
0138 if ($type != 'topic')
0139 {
0140 $topic_join = ', ' . TOPICS_TABLE . ' t';
0141 $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_approved = 1';
0142 }
0143 else
0144 {
0145 $topic_join = '';
0146 $topic_condition = '';
0147 }
0148
0149 if (sizeof($ids) == 1)
0150 {
0151 $sql = 'SELECT MAX(p.post_id) as last_post_id
0152 FROM ' . POSTS_TABLE . " p $topic_join
0153 WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
0154 $topic_condition
0155 AND p.post_approved = 1";
0156 }
0157 else
0158 {
0159 $sql = 'SELECT p.' . $type . '_id, MAX(p.post_id) as last_post_id
0160 FROM ' . POSTS_TABLE . " p $topic_join
0161 WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
0162 $topic_condition
0163 AND p.post_approved = 1
0164 GROUP BY p.{$type}_id";
0165 }
0166 $result = $db->sql_query($sql);
0167
0168 $last_post_ids = array();
0169 while ($row = $db->sql_fetchrow($result))
0170 {
0171 if (sizeof($ids) == 1)
0172 {
0173 $row[$type . '_id'] = $ids[0];
0174 }
0175
0176 if ($type == 'forum')
0177 {
0178 $not_empty_forums[] = $row['forum_id'];
0179
0180 if (empty($row['last_post_id']))
0181 {
0182 $empty_forums[] = $row['forum_id'];
0183 }
0184 }
0185
0186 $last_post_ids[] = $row['last_post_id'];
0187 }
0188 $db->sql_freeresult($result);
0189
0190 if ($type == 'forum')
0191 {
0192 $empty_forums = array_merge($empty_forums, array_diff($ids, $not_empty_forums));
0193
0194 foreach ($empty_forums as $void => $forum_id)
0195 {
0196 $update_sql[$forum_id][] = 'forum_last_post_id = 0';
0197 $update_sql[$forum_id][] = "forum_last_post_subject = ''";
0198 $update_sql[$forum_id][] = 'forum_last_post_time = 0';
0199 $update_sql[$forum_id][] = 'forum_last_poster_id = 0';
0200 $update_sql[$forum_id][] = "forum_last_poster_name = ''";
0201 $update_sql[$forum_id][] = "forum_last_poster_colour = ''";
0202 }
0203 }
0204
0205 if (sizeof($last_post_ids))
0206 {
0207 $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
0208 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
0209 WHERE p.poster_id = u.user_id
0210 AND ' . $db->sql_in_set('p.post_id', $last_post_ids);
0211 $result = $db->sql_query($sql);
0212
0213 while ($row = $db->sql_fetchrow($result))
0214 {
0215 $update_sql[$row["{$type}_id"]][] = $type . '_last_post_id = ' . (int) $row['post_id'];
0216 $update_sql[$row["{$type}_id"]][] = "{$type}_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
0217 $update_sql[$row["{$type}_id"]][] = $type . '_last_post_time = ' . (int) $row['post_time'];
0218 $update_sql[$row["{$type}_id"]][] = $type . '_last_poster_id = ' . (int) $row['poster_id'];
0219 $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
0220 $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'";
0221 }
0222 $db->sql_freeresult($result);
0223 }
0224 unset($empty_forums, $ids, $last_post_ids);
0225
0226 if ($return_update_sql || !sizeof($update_sql))
0227 {
0228 return $update_sql;
0229 }
0230
0231 $table = ($type == 'forum') ? FORUMS_TABLE : TOPICS_TABLE;
0232
0233 foreach ($update_sql as $update_id => $update_sql_ary)
0234 {
0235 $sql = "UPDATE $table
0236 SET " . implode(', ', $update_sql_ary) . "
0237 WHERE {$type}_id = $update_id";
0238 $db->sql_query($sql);
0239 }
0240
0241 return;
0242 }
0243
0244 /**
0245 * Generate Topic Icons for display
0246 */
0247 function posting_gen_topic_icons($mode, $icon_id)
0248 {
0249 global $phpbb_root_path, $config, $template, $cache;
0250
0251 // Grab icons
0252 $icons = $cache->obtain_icons();
0253
0254 if (!$icon_id)
0255 {
0256 $template->assign_var('S_NO_ICON_CHECKED', ' checked="checked"');
0257 }
0258
0259 if (sizeof($icons))
0260 {
0261 foreach ($icons as $id => $data)
0262 {
0263 if ($data['display'])
0264 {
0265 $template->assign_block_vars('topic_icon', array(
0266 'ICON_ID' => $id,
0267 'ICON_IMG' => $phpbb_root_path . $config['icons_path'] . '/' . $data['img'],
0268 'ICON_WIDTH' => $data['width'],
0269 'ICON_HEIGHT' => $data['height'],
0270
0271 'S_CHECKED' => ($id == $icon_id) ? true : false,
0272 'S_ICON_CHECKED' => ($id == $icon_id) ? ' checked="checked"' : '')
0273 );
0274 }
0275 }
0276
0277 return true;
0278 }
0279
0280 return false;
0281 }
0282
0283 /**
0284 * Build topic types able to be selected
0285 */
0286 function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
0287 {
0288 global $auth, $user, $template, $topic_type;
0289
0290 $toggle = false;
0291
0292 $topic_types = array(
0293 'sticky' => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
0294 'announce' => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
0295 'global' => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
0296 );
0297
0298 $topic_type_array = array();
0299
0300 foreach ($topic_types as $auth_key => $topic_value)
0301 {
0302 // We do not have a special post global announcement permission
0303 $auth_key = ($auth_key == 'global') ? 'announce' : $auth_key;
0304
0305 if ($auth->acl_get('f_' . $auth_key, $forum_id))
0306 {
0307 $toggle = true;
0308
0309 $topic_type_array[] = array(
0310 'VALUE' => $topic_value['const'],
0311 'S_CHECKED' => ($cur_topic_type == $topic_value['const'] || ($forum_id == 0 && $topic_value['const'] == POST_GLOBAL)) ? ' checked="checked"' : '',
0312 'L_TOPIC_TYPE' => $user->lang[$topic_value['lang']]
0313 );
0314 }
0315 }
0316
0317 if ($toggle)
0318 {
0319 $topic_type_array = array_merge(array(0 => array(
0320 'VALUE' => POST_NORMAL,
0321 'S_CHECKED' => ($topic_type == POST_NORMAL) ? ' checked="checked"' : '',
0322 'L_TOPIC_TYPE' => $user->lang['POST_NORMAL'])),
0323
0324 $topic_type_array
0325 );
0326
0327 foreach ($topic_type_array as $array)
0328 {
0329 $template->assign_block_vars('topic_type', $array);
0330 }
0331
0332 $template->assign_vars(array(
0333 'S_TOPIC_TYPE_STICKY' => ($auth->acl_get('f_sticky', $forum_id)),
0334 'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_get('f_announce', $forum_id)))
0335 );
0336 }
0337
0338 return $toggle;
0339 }
0340
0341 //
0342 // Attachment related functions
0343 //
0344
0345 /**
0346 * Upload Attachment - filedata is generated here
0347 * Uses upload class
0348 */
0349 function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
0350 {
0351 global $auth, $user, $config, $db, $cache;
0352 global $phpbb_root_path, $phpEx;
0353
0354 $filedata = array(
0355 'error' => array()
0356 );
0357
0358 include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
0359 $upload = new fileupload();
0360
0361 if (!$local)
0362 {
0363 $filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
0364 }
0365 else
0366 {
0367 $filedata['post_attach'] = true;
0368 }
0369
0370 if (!$filedata['post_attach'])
0371 {
0372 $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
0373 return $filedata;
0374 }
0375
0376 $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
0377 $upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
0378
0379 $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name);
0380
0381 if ($file->init_error)
0382 {
0383 $filedata['post_attach'] = false;
0384 return $filedata;
0385 }
0386
0387 $cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE;
0388
0389 // Make sure the image category only holds valid images...
0390 if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
0391 {
0392 $file->remove();
0393
0394 // If this error occurs a user tried to exploit an IE Bug by renaming extensions
0395 // Since the image category is displaying content inline we need to catch this.
0396 trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
0397 }
0398
0399 // Do we have to create a thumbnail?
0400 $filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
0401
0402 // Check Image Size, if it is an image
0403 if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE)
0404 {
0405 $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
0406 }
0407
0408 // Admins and mods are allowed to exceed the allowed filesize
0409 if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
0410 {
0411 if (!empty($extensions[$file->get('extension')]['max_filesize']))
0412 {
0413 $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
0414 }
0415 else
0416 {
0417 $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
0418 }
0419
0420 $file->upload->set_max_filesize($allowed_filesize);
0421 }
0422
0423 $file->clean_filename('unique', $user->data['user_id'] . '_');
0424
0425 // Are we uploading an image *and* this image being within the image category? Only then perform additional image checks.
0426 $no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true;
0427
0428 $file->move_file($config['upload_path'], false, $no_image);
0429
0430 if (sizeof($file->error))
0431 {
0432 $file->remove();
0433 $filedata['error'] = array_merge($filedata['error'], $file->error);
0434 $filedata['post_attach'] = false;
0435
0436 return $filedata;
0437 }
0438
0439 $filedata['filesize'] = $file->get('filesize');
0440 $filedata['mimetype'] = $file->get('mimetype');
0441 $filedata['extension'] = $file->get('extension');
0442 $filedata['physical_filename'] = $file->get('realname');
0443 $filedata['real_filename'] = $file->get('uploadname');
0444 $filedata['filetime'] = time();
0445
0446 // Check our complete quota
0447 if ($config['attachment_quota'])
0448 {
0449 if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
0450 {
0451 $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
0452 $filedata['post_attach'] = false;
0453
0454 $file->remove();
0455
0456 return $filedata;
0457 }
0458 }
0459
0460 // Check free disk space
0461 if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
0462 {
0463 if ($free_space <= $file->get('filesize'))
0464 {
0465 $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
0466 $filedata['post_attach'] = false;
0467
0468 $file->remove();
0469
0470 return $filedata;
0471 }
0472 }
0473
0474 // Create Thumbnail
0475 if ($filedata['thumbnail'])
0476 {
0477 $source = $file->get('destination_file');
0478 $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
0479
0480 if (!create_thumbnail($source, $destination, $file->get('mimetype')))
0481 {
0482 $filedata['thumbnail'] = 0;
0483 }
0484 }
0485
0486 return $filedata;
0487 }
0488
0489 /**
0490 * Calculate the needed size for Thumbnail
0491 */
0492 function get_img_size_format($width, $height)
0493 {
0494 global $config;
0495
0496 // Maximum Width the Image can take
0497 $max_width = ($config['img_max_thumb_width']) ? $config['img_max_thumb_width'] : 400;
0498
0499 if ($width > $height)
0500 {
0501 return array(
0502 round($width * ($max_width / $width)),
0503 round($height * ($max_width / $width))
0504 );
0505 }
0506 else
0507 {
0508 return array(
0509 round($width * ($max_width / $height)),
0510 round($height * ($max_width / $height))
0511 );
0512 }
0513 }
0514
0515 /**
0516 * Return supported image types
0517 */
0518 function get_supported_image_types($type = false)
0519 {
0520 if (@extension_loaded('gd'))
0521 {
0522 $format = imagetypes();
0523 $new_type = 0;
0524
0525 if ($type !== false)
0526 {
0527 switch ($type)
0528 {
0529 // GIF
0530 case 1:
0531 $new_type = ($format & IMG_GIF) ? IMG_GIF : false;
0532 break;
0533
0534 // JPG, JPC, JP2
0535 case 2:
0536 case 9:
0537 case 10:
0538 case 11:
0539 case 12:
0540 $new_type = ($format & IMG_JPG) ? IMG_JPG : false;
0541 break;
0542
0543 // PNG
0544 case 3:
0545 $new_type = ($format & IMG_PNG) ? IMG_PNG : false;
0546 break;
0547
0548 // BMP, WBMP
0549 case 6:
0550 case 15:
0551 $new_type = ($format & IMG_WBMP) ? IMG_WBMP : false;
0552 break;
0553 }
0554 }
0555 else
0556 {
0557 $new_type = array();
0558 $go_through_types = array(IMG_GIF, IMG_JPG, IMG_PNG, IMG_WBMP);
0559
0560 foreach ($go_through_types as $check_type)
0561 {
0562 if ($format & $check_type)
0563 {
0564 $new_type[] = $check_type;
0565 }
0566 }
0567 }
0568
0569 return array(
0570 'gd' => ($new_type) ? true : false,
0571 'format' => $new_type,
0572 'version' => (function_exists('imagecreatetruecolor')) ? 2 : 1
0573 );
0574 }
0575
0576 return array('gd' => false);
0577 }
0578
0579 /**
0580 * Create Thumbnail
0581 */
0582 function create_thumbnail($source, $destination, $mimetype)
0583 {
0584 global $config;
0585
0586 $min_filesize = (int) $config['img_min_thumb_filesize'];
0587 $img_filesize = (file_exists($source)) ? @filesize($source) : false;
0588
0589 if (!$img_filesize || $img_filesize <= $min_filesize)
0590 {
0591 return false;
0592 }
0593
0594 $dimension = @getimagesize($source);
0595
0596 if ($dimension === false)
0597 {
0598 return false;
0599 }
0600
0601 list($width, $height, $type, ) = $dimension;
0602
0603 if (empty($width) || empty($height))
0604 {
0605 return false;
0606 }
0607
0608 list($new_width, $new_height) = get_img_size_format($width, $height);
0609
0610 // Do not create a thumbnail if the resulting width/height is bigger than the original one
0611 if ($new_width > $width && $new_height > $height)
0612 {
0613 return false;
0614 }
0615
0616 $used_imagick = false;
0617
0618 // Only use imagemagick if defined and the passthru function not disabled
0619 if ($config['img_imagick'] && function_exists('passthru'))
0620 {
0621 @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) . '"');
0622
0623 if (file_exists($destination))
0624 {
0625 $used_imagick = true;
0626 }
0627 }
0628
0629 if (!$used_imagick)
0630 {
0631 $type = get_supported_image_types($type);
0632
0633 if ($type['gd'])
0634 {
0635 // If the type is not supported, we are not able to create a thumbnail
0636 if ($type['format'] === false)
0637 {
0638 return false;
0639 }
0640
0641 switch ($type['format'])
0642 {
0643 case IMG_GIF:
0644 $image = @imagecreatefromgif($source);
0645 break;
0646
0647 case IMG_JPG:
0648 $image = @imagecreatefromjpeg($source);
0649 break;
0650
0651 case IMG_PNG:
0652 $image = @imagecreatefrompng($source);
0653 break;
0654
0655 case IMG_WBMP:
0656 $image = @imagecreatefromwbmp($source);
0657 break;
0658 }
0659
0660 if ($type['version'] == 1)
0661 {
0662 $new_image = imagecreate($new_width, $new_height);
0663
0664 if ($new_image === false)
0665 {
0666 return false;
0667 }
0668
0669 imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
0670 }
0671 else
0672 {
0673 $new_image = imagecreatetruecolor($new_width, $new_height);
0674
0675 if ($new_image === false)
0676 {
0677 return false;
0678 }
0679
0680 imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
0681 }
0682
0683 // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug
0684 if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on')
0685 {
0686 @touch($destination);
0687 }
0688
0689 switch ($type['format'])
0690 {
0691 case IMG_GIF:
0692 imagegif($new_image, $destination);
0693 break;
0694
0695 case IMG_JPG:
0696 imagejpeg($new_image, $destination, 90);
0697 break;
0698
0699 case IMG_PNG:
0700 imagepng($new_image, $destination);
0701 break;
0702
0703 case IMG_WBMP:
0704 imagewbmp($new_image, $destination);
0705 break;
0706 }
0707
0708 imagedestroy($new_image);
0709 }
0710 else
0711 {
0712 return false;
0713 }
0714 }
0715
0716 if (!file_exists($destination))
0717 {
0718 return false;
0719 }
0720
0721 @chmod($destination, 0666);
0722
0723 return true;
0724 }
0725
0726 /**
0727 * Assign Inline attachments (build option fields)
0728 */
0729 function posting_gen_inline_attachments(&$attachment_data)
0730 {
0731 global $template;
0732
0733 if (sizeof($attachment_data))
0734 {
0735 $s_inline_attachment_options = '';
0736
0737 foreach ($attachment_data as $i => $attachment)
0738 {
0739 $s_inline_attachment_options .= '<option value="' . $i . '">' . basename($attachment['real_filename']) . '</option>';
0740 }
0741
0742 $template->assign_var('S_INLINE_ATTACHMENT_OPTIONS', $s_inline_attachment_options);
0743
0744 return true;
0745 }
0746
0747 return false;
0748 }
0749
0750 /**
0751 * Generate inline attachment entry
0752 */
0753 function posting_gen_attachment_entry($attachment_data, &$filename_data)
0754 {
0755 global $template, $config, $phpbb_root_path, $phpEx, $user;
0756
0757 $template->assign_vars(array(
0758 'S_SHOW_ATTACH_BOX' => true)
0759 );
0760
0761 if (sizeof($attachment_data))
0762 {
0763 $template->assign_vars(array(
0764 'S_HAS_ATTACHMENTS' => true)
0765 );
0766
0767 // We display the posted attachments within the desired order.
0768 ($config['display_order']) ? krsort($attachment_data) : ksort($attachment_data);
0769
0770 foreach ($attachment_data as $count => $attach_row)
0771 {
0772 $hidden = '';
0773 $attach_row['real_filename'] = basename($attach_row['real_filename']);
0774
0775 foreach ($attach_row as $key => $value)
0776 {
0777 $hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />';
0778 }
0779
0780 $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);
0781
0782 $template->assign_block_vars('attach_row', array(
0783 'FILENAME' => basename($attach_row['real_filename']),
0784 'A_FILENAME' => addslashes(basename($attach_row['real_filename'])),
0785 'FILE_COMMENT' => $attach_row['attach_comment'],
0786 'ATTACH_ID' => $attach_row['attach_id'],
0787 'S_IS_ORPHAN' => $attach_row['is_orphan'],
0788 'ASSOC_INDEX' => $count,
0789
0790 'U_VIEW_ATTACHMENT' => $download_link,
0791 'S_HIDDEN' => $hidden)
0792 );
0793 }
0794 }
0795
0796 $template->assign_vars(array(
0797 'FILE_COMMENT' => $filename_data['filecomment'],
0798 'FILESIZE' => $config['max_filesize'])
0799 );
0800
0801 return sizeof($attachment_data);
0802 }
0803
0804 //
0805 // General Post functions
0806 //
0807
0808 /**
0809 * Load Drafts
0810 */
0811 function load_drafts($topic_id = 0, $forum_id = 0, $id = 0)
0812 {
0813 global $user, $db, $template, $auth;
0814 global $phpbb_root_path, $phpEx;
0815
0816 $topic_ids = $forum_ids = $draft_rows = array();
0817
0818 // Load those drafts not connected to forums/topics
0819 // If forum_id == 0 AND topic_id == 0 then this is a PM draft
0820 if (!$topic_id && !$forum_id)
0821 {
0822 $sql_and = ' AND d.forum_id = 0 AND d.topic_id = 0';
0823 }
0824 else
0825 {
0826 $sql_and = '';
0827 $sql_and .= ($forum_id) ? ' AND d.forum_id = ' . (int) $forum_id : '';
0828 $sql_and .= ($topic_id) ? ' AND d.topic_id = ' . (int) $topic_id : '';
0829 }
0830
0831 $sql = 'SELECT d.*, f.forum_id, f.forum_name
0832 FROM ' . DRAFTS_TABLE . ' d
0833 LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = d.forum_id)
0834 WHERE d.user_id = ' . $user->data['user_id'] . "
0835 $sql_and
0836 ORDER BY d.save_time DESC";
0837 $result = $db->sql_query($sql);
0838
0839 while ($row = $db->sql_fetchrow($result))
0840 {
0841 if ($row['topic_id'])
0842 {
0843 $topic_ids[] = (int) $row['topic_id'];
0844 }
0845 $draft_rows[] = $row;
0846 }
0847 $db->sql_freeresult($result);
0848
0849 if (!sizeof($draft_rows))
0850 {
0851 return;
0852 }
0853
0854 $topic_rows = array();
0855 if (sizeof($topic_ids))
0856 {
0857 $sql = 'SELECT topic_id, forum_id, topic_title
0858 FROM ' . TOPICS_TABLE . '
0859 WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids));
0860 $result = $db->sql_query($sql);
0861
0862 while ($row = $db->sql_fetchrow($result))
0863 {
0864 $topic_rows[$row['topic_id']] = $row;
0865 }
0866 $db->sql_freeresult($result);
0867 }
0868 unset($topic_ids);
0869
0870 $template->assign_var('S_SHOW_DRAFTS', true);
0871
0872 foreach ($draft_rows as $draft)
0873 {
0874 $link_topic = $link_forum = $link_pm = false;
0875 $insert_url = $view_url = $title = '';
0876
0877 if (isset($topic_rows[$draft['topic_id']])
0878 && (
0879 ($topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_get('f_read', $topic_rows[$draft['topic_id']]['forum_id']))
0880 ||
0881 (!$topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_getf_global('f_read'))
0882 ))
0883 {
0884 $topic_forum_id = ($topic_rows[$draft['topic_id']]['forum_id']) ? $topic_rows[$draft['topic_id']]['forum_id'] : $forum_id;
0885
0886 $link_topic = true;
0887 $view_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id']);
0888 $title = $topic_rows[$draft['topic_id']]['topic_title'];
0889
0890 $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id'] . '&mode=reply&d=' . $draft['draft_id']);
0891 }
0892 else if ($draft['forum_id'] && $auth->acl_get('f_read', $draft['forum_id']))
0893 {
0894 $link_forum = true;
0895 $view_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $draft['forum_id']);
0896 $title = $draft['forum_name'];
0897
0898 $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $draft['forum_id'] . '&mode=post&d=' . $draft['draft_id']);
0899 }
0900 else
0901 {
0902 // Either display as PM draft if forum_id and topic_id are empty or if access to the forums has been denied afterwards...
0903 $link_pm = true;
0904 $insert_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=compose&d={$draft['draft_id']}");
0905 }
0906
0907 $template->assign_block_vars('draftrow', array(
0908 'DRAFT_ID' => $draft['draft_id'],
0909 'DATE' => $user->format_date($draft['save_time']),
0910 'DRAFT_SUBJECT' => $draft['draft_subject'],
0911
0912 'TITLE' => $title,
0913 'U_VIEW' => $view_url,
0914 'U_INSERT' => $insert_url,
0915
0916 'S_LINK_PM' => $link_pm,
0917 'S_LINK_TOPIC' => $link_topic,
0918 'S_LINK_FORUM' => $link_forum)
0919 );
0920 }
0921 }
0922
0923 /**
0924 * Topic Review
0925 */
0926 function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true)
0927 {
0928 global $user, $auth, $db, $template, $bbcode, $cache;
0929 global $config, $phpbb_root_path, $phpEx;
0930
0931 // Go ahead and pull all data for this topic
0932 $sql = 'SELECT p.post_id
0933 FROM ' . POSTS_TABLE . ' p' . "
0934 WHERE p.topic_id = $topic_id
0935 " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . '
0936 ' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
0937 ORDER BY p.post_time DESC';
0938 $result = $db->sql_query_limit($sql, $config['posts_per_page']);
0939
0940 $post_list = array();
0941
0942 while ($row = $db->sql_fetchrow($result))
0943 {
0944 $post_list[] = $row['post_id'];
0945 }
0946
0947 $db->sql_freeresult($result);
0948
0949 if (!sizeof($post_list))
0950 {
0951 return false;
0952 }
0953
0954 $sql = $db->sql_build_query('SELECT', array(
0955 'SELECT' => 'u.username, u.user_id, u.user_colour, p.*',
0956
0957 'FROM' => array(
0958 USERS_TABLE => 'u',
0959 POSTS_TABLE => 'p',
0960 ),
0961
0962 'WHERE' => $db->sql_in_set('p.post_id', $post_list) . '
0963 AND u.user_id = p.poster_id'
0964 ));
0965
0966 $result = $db->sql_query($sql);
0967
0968 $bbcode_bitfield = '';
0969 $rowset = array();
0970 $has_attachments = false;
0971 while ($row = $db->sql_fetchrow($result))
0972 {
0973 $rowset[$row['post_id']] = $row;
0974 $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
0975
0976 if ($row['post_attachment'])
0977 {
0978 $has_attachments = true;
0979 }
0980 }
0981 $db->sql_freeresult($result);
0982
0983 // Instantiate BBCode class
0984 if (!isset($bbcode) && $bbcode_bitfield !== '')
0985 {
0986 include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx);
0987 $bbcode = new bbcode(base64_encode($bbcode_bitfield));
0988 }
0989
0990 // Grab extensions
0991 $extensions = $attachments = array();
0992 if ($has_attachments && $auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
0993 {
0994 $extensions = $cache->obtain_attach_extensions($forum_id);
0995
0996 // Get attachments...
0997 $sql = 'SELECT *
0998 FROM ' . ATTACHMENTS_TABLE . '
0999 WHERE ' . $db->sql_in_set('post_msg_id', $post_list) . '
1000 AND in_message = 0
1001 ORDER BY filetime DESC, post_msg_id ASC';
1002 $result = $db->sql_query($sql);
1003
1004 while ($row = $db->sql_fetchrow($result))
1005 {
1006 $attachments[$row['post_msg_id']][] = $row;
1007 }
1008 $db->sql_freeresult($result);
1009 }
1010
1011 for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
1012 {
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]]))
1016 {
1017 continue;
1018 }
1019
1020 $row =& $rowset[$post_list[$i]];
1021
1022 $poster_id = $row['user_id'];
1023 $post_subject = $row['post_subject'];
1024 $message = censor_text($row['post_text']);
1025
1026 $decoded_message = false;
1027
1028 if ($show_quote_button && $auth->acl_get('f_reply', $forum_id))
1029 {
1030 $decoded_message = $message;
1031 decode_message($decoded_message, $row['bbcode_uid']);
1032
1033 $decoded_message = bbcode_nl2br($decoded_message);
1034 }
1035
1036 if ($row['bbcode_bitfield'])
1037 {
1038 $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
1039 }
1040
1041 $message = bbcode_nl2br($message);
1042 $message = smiley_text($message, !$row['enable_smilies']);
1043
1044 if (!empty($attachments[$row['post_id']]))
1045 {
1046 $update_count = array();
1047 parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count);
1048 }
1049
1050 $post_subject = censor_text($post_subject);
1051
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']),
1057
1058 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
1059
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'])) : '')
1069 );
1070
1071 // Display not already displayed Attachments for this post, we already parsed them. ;)
1072 if (!empty($attachments[$row['post_id']]))
1073 {
1074 foreach ($attachments[$row['post_id']] as $attachment)
1075 {
1076 $template->assign_block_vars($mode . '_row.attachment', array(
1077 'DISPLAY_ATTACHMENT' => $attachment)
1078 );
1079 }
1080 }
1081
1082 unset($rowset[$i]);
1083 }
1084
1085 if ($mode == 'topic_review')
1086 {
1087 $template->assign_var('QUOTE_IMG', $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']));
1088 }
1089
1090 return true;
1091 }
1092
1093 /**
1094 * User Notification
1095 */
1096 function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id)
1097 {
1098 global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
1099
1100 $topic_notification = ($mode == 'reply' || $mode == 'quote') ? true : false;
1101 $forum_notification = ($mode == 'post') ? true : false;
1102
1103 if (!$topic_notification && !$forum_notification)
1104 {
1105 trigger_error('WRONG_NOTIFICATION_MODE');
1106 }
1107
1108 if (!$config['allow_topic_notify'])
1109 {
1110 return;
1111 }
1112
1113 $topic_title = ($topic_notification) ? $topic_title : $subject;
1114 $topic_title = censor_text($topic_title);
1115
1116 // Get banned User ID's
1117 $sql = 'SELECT ban_userid
1118 FROM ' . BANLIST_TABLE;
1119 $result = $db->sql_query($sql);
1120
1121 $sql_ignore_users = ANONYMOUS . ', ' . $user->data['user_id'];
1122 while ($row = $db->sql_fetchrow($result))
1123 {
1124 if (isset($row['ban_userid']))
1125 {
1126 $sql_ignore_users .= ', ' . $row['ban_userid'];
1127 }
1128 }
1129 $db->sql_freeresult($result);
1130
1131 $notify_rows = array();
1132
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);
1142
1143 while ($row = $db->sql_fetchrow($result))
1144 {
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'],
1154 'allowed' => false
1155 );
1156 }
1157 $db->sql_freeresult($result);
1158
1159 // forum notification is sent to those not already receiving topic notifications
1160 if ($topic_notification)
1161 {
1162 if (sizeof($notify_rows))
1163 {
1164 $sql_ignore_users .= ', ' . implode(', ', array_keys($notify_rows));
1165 }
1166
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);
1175
1176 while ($row = $db->sql_fetchrow($result))
1177 {
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'],
1187 'allowed' => false
1188 );
1189 }
1190 $db->sql_freeresult($result);
1191 }
1192
1193 if (!sizeof($notify_rows))
1194 {
1195 return;
1196 }
1197
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)
1200 {
1201 foreach ($forum_ary as $auth_option => $user_ary)
1202 {
1203 foreach ($user_ary as $user_id)
1204 {
1205 $notify_rows[$user_id]['allowed'] = true;
1206 }
1207 }
1208 }
1209
1210
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)
1214 {
1215 if (!$row['allowed'] || !trim($row['user_email']))
1216 {
1217 $delete_ids[$row['notify_type']][] = $row['user_id'];
1218 }
1219 else
1220 {
1221 $msg_users[] = $row;
1222 $update_notification[$row['notify_type']][] = $row['user_id'];
1223 }
1224 }
1225 unset($notify_rows);
1226
1227 // Now, we are able to really send out notifications
1228 if (sizeof($msg_users))
1229 {
1230 include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1231 $messenger = new messenger();
1232
1233 $msg_list_ary = array();
1234 foreach ($msg_users as $row)
1235 {
1236 $pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]);
1237
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'];
1243 }
1244 unset($msg_users);
1245
1246 foreach ($msg_list_ary as $email_template => $email_list)
1247 {
1248 foreach ($email_list as $addr)
1249 {
1250 $messenger->template($email_template, $addr['lang']);
1251
1252 $messenger->to($addr['email'], $addr['name']);
1253 $messenger->im($addr['jabber'], $addr['name']);
1254
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),
1259
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",
1265 ));
1266
1267 $messenger->send($addr['method']);
1268 }
1269 }
1270 unset($msg_list_ary);
1271
1272 $messenger->save_queue();
1273 }
1274
1275 // Handle the DB updates
1276 $db->sql_transaction('begin');
1277
1278 if (!empty($update_notification['topic']))
1279 {
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);
1285 }
1286
1287 if (!empty($update_notification['forum']))
1288 {
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);
1294 }
1295
1296 // Now delete the user_ids not authorised to receive notifications on this topic/forum
1297 if (!empty($delete_ids['topic']))
1298 {
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);
1303 }
1304
1305 if (!empty($delete_ids['forum']))
1306 {
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);
1311 }
1312
1313 $db->sql_transaction('commit');
1314 }
1315
1316 //
1317 // Post handling functions
1318 //
1319
1320 /**
1321 * Delete Post
1322 */
1323 function delete_post($forum_id, $topic_id, $post_id, &$data)
1324 {
1325 global $db, $user, $auth;
1326 global $config, $phpEx, $phpbb_root_path;
1327
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();
1331 $next_post_id = 0;
1332
1333 include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1334
1335 $db->sql_transaction('begin');
1336
1337 // we must make sure to update forums that contain the shadow'd topic
1338 if ($post_mode == 'delete_topic')
1339 {
1340 $shadow_forum_ids = array();
1341
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))
1347 {
1348 if (!isset($shadow_forum_ids[(int) $row['forum_id']]))
1349 {
1350 $shadow_forum_ids[(int) $row['forum_id']] = 1;
1351 }
1352 else
1353 {
1354 $shadow_forum_ids[(int) $row['forum_id']]++;
1355 }
1356 }
1357 $db->sql_freeresult($result);
1358 }
1359
1360 if (!delete_posts('post_id', array($post_id), false, false))
1361 {
1362 // Try to delete topic, we may had an previous error causing inconsistency
1363 if ($post_mode == 'delete_topic')
1364 {
1365 delete_topics('topic_id', array($topic_id), false);
1366 }
1367 trigger_error('ALREADY_DELETED');
1368 }
1369
1370 $db->sql_transaction('commit');
1371
1372 // Collect the necessary information for updating the tables
1373 $sql_data[FORUMS_TABLE] = '';
1374 switch ($post_mode)
1375 {
1376 case 'delete_topic':
1377
1378 foreach ($shadow_forum_ids as $updated_forum => $topic_count)
1379 {
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);
1384 }
1385
1386 delete_topics('topic_id', array($topic_id), false);
1387
1388 if ($data['topic_type'] != POST_GLOBAL)
1389 {
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' : '';
1392 }
1393
1394 $update_sql = update_post_information('forum', $forum_id, true);
1395 if (sizeof($update_sql))
1396 {
1397 $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
1398 $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
1399 }
1400 break;
1401
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);
1411
1412 if ($data['topic_type'] != POST_GLOBAL)
1413 {
1414 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1415 }
1416
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'])) . "'";
1418
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' : '');
1421
1422 $next_post_id = (int) $row['post_id'];
1423 break;
1424
1425 case 'delete_last_post':
1426 if ($data['topic_type'] != POST_GLOBAL)
1427 {
1428 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1429 }
1430
1431 $update_sql = update_post_information('forum', $forum_id, true);
1432 if (sizeof($update_sql))
1433 {
1434 $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
1435 $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
1436 }
1437
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' : '');
1439
1440 $update_sql = update_post_information('topic', $topic_id, true);
1441 if (sizeof($update_sql))
1442 {
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]);
1445 }
1446 else
1447 {
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);
1455
1456 $next_post_id = (int) $row['last_post_id'];
1457 }
1458 break;
1459
1460 case 'delete':
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);
1470
1471 if ($data['topic_type'] != POST_GLOBAL)
1472 {
1473 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
1474 }
1475
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'];
1478 break;
1479 }
1480
1481 // $sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : '';
1482
1483 $db->sql_transaction('begin');
1484
1485 $where_sql = array(
1486 FORUMS_TABLE => "forum_id = $forum_id",
1487 TOPICS_TABLE => "topic_id = $topic_id",
1488 USERS_TABLE => 'user_id = ' . $data['poster_id']
1489 );
1490
1491 foreach ($sql_data as $table => $update_sql)
1492 {
1493 if ($update_sql)
1494 {
1495 $db->sql_query("UPDATE $table SET $update_sql WHERE " . $where_sql[$table]);
1496 }
1497 }
1498
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)
1501 {
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);
1509
1510 // The user is not having any more posts within this topic
1511 if (!$poster_id)
1512 {
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);
1517 }
1518 }
1519
1520 $db->sql_transaction('commit');
1521
1522 if ($data['post_reported'] && ($post_mode != 'delete_topic'))
1523 {
1524 sync('topic_reported', 'topic_id', array($topic_id));
1525 }
1526
1527 return $next_post_id;
1528 }
1529
1530 /**
1531 * Submit Post
1532 */
1533 function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true)
1534 {
1535 global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
1536
1537 // We do not handle erasing posts here
1538 if ($mode == 'delete')
1539 {
1540 return false;
1541 }
1542
1543 $current_time = time();
1544
1545 if ($mode == 'post')
1546 {
1547 $post_mode = 'post';
1548 $update_message = true;
1549 }
1550 else if ($mode != 'edit')
1551 {
1552 $post_mode = 'reply';
1553 $update_message = true;
1554 }
1555 else if ($mode == 'edit')
1556 {
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'));
1558 }
1559
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']);
1564
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'];
1568
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))
1571 {
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);
1579
1580 $data['topic_approved'] = $topic_row['topic_approved'];
1581 $data['post_approved'] = $topic_row['post_approved'];
1582 }
1583
1584 // Start the transaction here
1585 $db->sql_transaction('begin');
1586
1587
1588 // Collect Information
1589 switch ($post_mode)
1590 {
1591 case 'post':
1592 case 'reply':
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']
1613 );
1614 break;
1615
1616 case 'edit_first_post':
1617 case 'edit':
1618
1619 case 'edit_last_post':
1620 case 'edit_topic':
1621
1622 // If edit reason is given always display edit info
1623
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
1627
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')))
1630 {
1631 $data['post_edit_reason'] = truncate_string($data['post_edit_reason'], 255, false);
1632
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'],
1637 );
1638
1639 $sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
1640 }
1641 else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id']))
1642 {
1643 $sql_data[POSTS_TABLE]['sql'] = array(
1644 'post_edit_reason' => '',
1645 );
1646 }
1647
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)
1651 {
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']);
1654 }
1655
1656 if (!isset($sql_data[POSTS_TABLE]['sql']))
1657 {
1658 $sql_data[POSTS_TABLE]['sql'] = array();
1659 }
1660
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'])
1677 );
1678
1679 if ($update_message)
1680 {
1681 $sql_data[POSTS_TABLE]['sql']['post_text'] = $data['message'];
1682 }
1683
1684 break;
1685 }
1686
1687 $post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved'];
1688 $topic_row = array();
1689
1690 // And the topic ladies and gentlemen
1691 switch ($post_mode)
1692 {
1693 case 'post':
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,
1706 );
1707
1708 if (isset($poll['poll_options']) && !empty($poll['poll_options']))
1709 {
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'])
1716 );
1717 }
1718
1719 $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
1720
1721 if ($topic_type != POST_GLOBAL)
1722 {
1723 if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
1724 {
1725 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
1726 }
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' : '');
1728 }
1729 break;
1730
1731 case 'reply':
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' : '');
1733
1734 $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
1735
1736 if (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) && $topic_type != POST_GLOBAL)
1737 {
1738 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
1739 }
1740 break;
1741
1742 case 'edit_topic':
1743 case 'edit_first_post':
1744
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,
1758
1759 'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0),
1760 );
1761
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'])
1764 {
1765 // Do we need to grab some topic informations?
1766 if (!sizeof($topic_row))
1767 {
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);
1774 }
1775
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.
1778
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);
1782
1783 set_config('num_topics', $config['num_topics'] - 1, true);
1784 set_config('num_posts', $config['num_posts'] - ($topic_row['topic_replies'] + 1), true);
1785 }
1786
1787 break;
1788
1789 case 'edit':
1790 case 'edit_last_post':
1791
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'])
1794 {
1795 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1';
1796 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1';
1797
1798 set_config('num_posts', $config['num_posts'] - 1, true);
1799 }
1800
1801 break;
1802 }
1803
1804 // Submit new topic
1805 if ($post_mode == 'post')
1806 {
1807 $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
1808 $db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
1809 $db->sql_query($sql);
1810
1811 $data['topic_id'] = $db->sql_nextid();
1812
1813 $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
1814 'topic_id' => $data['topic_id'])
1815 );
1816 unset($sql_data[TOPICS_TABLE]['sql']);
1817 }
1818
1819 // Submit new post
1820 if ($post_mode == 'post' || $post_mode == 'reply')
1821 {
1822 if ($post_mode == 'reply')
1823 {
1824 $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
1825 'topic_id' => $data['topic_id'])
1826 );
1827 }
1828
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();
1832
1833 if ($post_mode == 'post')
1834 {
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'],
1842 );
1843 }
1844
1845 unset($sql_data[POSTS_TABLE]['sql']);
1846 }
1847
1848 $make_global = false;
1849
1850 // Are we globalising or unglobalising?
1851 if ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic')
1852 {
1853 if (!sizeof($topic_row))
1854 {
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);
1861 }
1862
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))
1865 {
1866 if (!empty($sql_data[FORUMS_TABLE]['stat']) && implode('', $sql_data[FORUMS_TABLE]['stat']))
1867 {
1868 $db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET ' . implode(', ', $sql_data[FORUMS_TABLE]['stat']) . ' WHERE forum_id = ' . $data['forum_id']);
1869 }
1870
1871 $make_global = true;
1872 $sql_data[FORUMS_TABLE]['stat'] = array();
1873 }
1874
1875 // globalise
1876 if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL)
1877 {
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' : '');
1881
1882 // Update forum_ids for all posts
1883 $sql = 'UPDATE ' . POSTS_TABLE . '
1884 SET forum_id = 0
1885 WHERE topic_id = ' . $data['topic_id'];
1886 $db->sql_query($sql);
1887 }
1888 // unglobalise
1889 else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL)
1890 {
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' : '');
1894
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);
1900 }
1901 }
1902
1903 // Update the topics table
1904 if (isset($sql_data[TOPICS_TABLE]['sql']))
1905 {
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);
1910 }
1911
1912 // Update the posts table
1913 if (isset($sql_data[POSTS_TABLE]['sql']))
1914 {
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);
1919 }
1920
1921 // Update Poll Tables
1922 if (isset($poll['poll_options']) && !empty($poll['poll_options']))
1923 {
1924 $cur_poll_options = array();
1925
1926 if ($poll['poll_start'] && $mode == 'edit')
1927 {
1928 $sql = 'SELECT *
1929 FROM ' . POLL_OPTIONS_TABLE . '
1930 WHERE topic_id = ' . $data['topic_id'] . '
1931 ORDER BY poll_option_id';
1932 $result = $db->sql_query($sql);
1933
1934 $cur_poll_options = array();
1935 while ($row = $db->sql_fetchrow($result))
1936 {
1937 $cur_poll_options[] = $row;
1938 }
1939 $db->sql_freeresult($result);
1940 }
1941
1942 $sql_insert_ary = array();
1943
1944 for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++)
1945 {
1946 if (strlen(trim($poll['poll_options'][$i])))
1947 {
1948 if (empty($cur_poll_options[$i]))
1949 {
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]
1955 );
1956 }
1957 else if ($poll['poll_options'][$i] != $cur_poll_options[$i])
1958 {
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);
1964 }
1965 }
1966 }
1967
1968 $db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);
1969
1970 if (sizeof($poll['poll_options']) < sizeof($cur_poll_options))
1971 {
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);
1976 }
1977
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))
1980 {
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']);
1983 }
1984 }
1985
1986 // Submit Attachments
1987 if (!empty($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit')))
1988 {
1989 $space_taken = $files_added = 0;
1990 $orphan_rows = array();
1991
1992 foreach ($data['attachment_data'] as $pos => $attach_row)
1993 {
1994 $orphan_rows[(int) $attach_row['attach_id']] = array();
1995 }
1996
1997 if (sizeof($orphan_rows))
1998 {
1999 $sql = 'SELECT attach_id, filesize, physical_filename
2000 FROM ' . ATTACHMENTS_TABLE . '
2001 WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
2002 AND is_orphan = 1
2003 AND poster_id = ' . $user->data['user_id'];
2004 $result = $db->sql_query($sql);
2005
2006 $orphan_rows = array();
2007 while ($row = $db->sql_fetchrow($result))
2008 {
2009 $orphan_rows[$row['attach_id']] = $row;
2010 }
2011 $db->sql_freeresult($result);
2012 }
2013
2014 foreach ($data['attachment_data'] as $pos => $attach_row)
2015 {
2016 if ($attach_row['is_orphan'] && !in_array($attach_row['attach_id'], array_keys($orphan_rows)))
2017 {
2018 continue;
2019 }
2020
2021 if (!$attach_row['is_orphan'])
2022 {
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'] . '
2027 AND is_orphan = 0';
2028 $db->sql_query($sql);
2029 }
2030 else
2031 {
2032 // insert attachment into db
2033 if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
2034 {
2035 continue;
2036 }
2037
2038 $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
2039 $files_added++;
2040
2041 $attach_sql = array(
2042 'post_msg_id' => $data['post_id'],
2043 'topic_id' => $data['topic_id'],
2044 'is_orphan' => 0,
2045 'poster_id' => $poster_id,
2046 'attach_comment' => $attach_row['attach_comment'],
2047 );
2048
2049 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
2050 WHERE attach_id = ' . $attach_row['attach_id'] . '
2051 AND is_orphan = 1
2052 AND poster_id = ' . $user->data['user_id'];
2053 $db->sql_query($sql);
2054 }
2055 }
2056
2057 if ($space_taken && $files_added)
2058 {
2059 set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
2060 set_config('num_files', $config['num_files'] + $files_added, true);
2061 }
2062 }
2063
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']))
2068 {
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)
2076 {
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']) . "'";
2083 }
2084 else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
2085 {
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);
2094
2095 // this post is the latest post in the forum, better update
2096 if ($row['forum_last_post_id'] == $data['post_id'])
2097 {
2098 if ($post_approved && $row['forum_last_post_subject'] !== $subject)
2099 {
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) . '\'';
2102 }
2103 else if ($data['post_approved'] !== $post_approved)
2104 {
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);
2113
2114 // any posts left in this forum?
2115 if (!empty($row['last_post_id']))
2116 {
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);
2124
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']) . "'";
2132 }
2133 else
2134 {
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 = ''";
2142 }
2143 }
2144 }
2145 }
2146 }
2147 else if ($make_global)
2148 {
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);
2156
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'])
2159 {
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);
2168
2169 // any posts left in this forum?
2170 if (!empty($row['last_post_id']))
2171 {
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);
2179
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']) . "'";
2187 }
2188 else
2189 {
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 = ''";
2197 }
2198 }
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'])
2200 {
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);
2209
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']) . "'";
2217 }
2218 }
2219
2220 // topic sync time!
2221 // simply, we update if it is a reply or the last post is edited
2222 if ($post_approved)
2223 {
2224 // reply requires the whole thing
2225 if ($post_mode == 'reply')
2226 {
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;
2233 }
2234 else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
2235 {
2236 // only the subject can be changed from edit
2237 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
2238 }
2239 }
2240 else if (!$data['post_approved'] && ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])))
2241 {
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);
2250
2251 // any posts left in this forum?
2252 if (!empty($row['last_post_id']))
2253 {
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);
2261
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']) . "'";
2269 }
2270 }
2271
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']))
2274 {
2275 if ($post_mode == 'post')
2276 {
2277 set_config('num_topics', $config['num_topics'] + 1, true);
2278 set_config('num_posts', $config['num_posts'] + 1, true);
2279 }
2280
2281 if ($post_mode == 'reply')
2282 {
2283 set_config('num_posts', $config['num_posts'] + 1, true);
2284 }
2285 }
2286
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']);
2289
2290 foreach ($sql_data as $table => $update_ary)
2291 {
2292 if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
2293 {
2294 $sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
2295 $db->sql_query($sql);
2296 }
2297 }
2298
2299 // Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
2300 if ($make_global)
2301 {
2302 $sql = 'DELETE FROM ' . TOPICS_TABLE . '
2303 WHERE topic_moved_id = ' . $data['topic_id'];
2304 $db->sql_query($sql);
2305 }
2306
2307 // Committing the transaction before updating search index
2308 $db->sql_transaction('commit');
2309
2310 // Delete draft if post was loaded...
2311 $draft_id = request_var('draft_loaded', 0);
2312 if ($draft_id)
2313 {
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);
2318 }
2319
2320 // Index message contents
2321 if ($update_message && $data['enable_indexing'])
2322 {
2323 // Select the search method and do some additional checks to ensure it can actually be utilised
2324 $search_type = basename($config['search_type']);
2325
2326 if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
2327 {
2328 trigger_error('NO_SUCH_SEARCH_MODULE');
2329 }
2330
2331 if (!class_exists($search_type))
2332 {
2333 include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
2334 }
2335
2336 $error = false;
2337 $search = new $search_type($error);
2338
2339 if ($error)
2340 {
2341 trigger_error($error);
2342 }
2343
2344 $search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']);
2345 }
2346
2347 // Topic Notification, do not change if moderator is changing other users posts...
2348 if ($user->data['user_id'] == $poster_id)
2349 {
2350 if (!$data['notify_set'] && $data['notify'])
2351 {
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);
2355 }
2356 else if ($data['notify_set'] && !$data['notify'])
2357 {
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);
2362 }
2363 }
2364
2365 if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
2366 {
2367 // Mark this topic as posted to
2368 markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
2369 }
2370
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());
2374
2375 //
2376 if ($config['load_db_lastread'] && $user->data['is_registered'])
2377 {
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);
2385 }
2386 else if ($config['load_anon_lastread'] || $user->data['is_registered'])
2387 {
2388 $f_mark_time = false;
2389 }
2390
2391 if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
2392 {
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);
2400
2401 update_forum_tracking_info($data['forum_id'], $forum_last_post_time, $f_mark_time, false);
2402 }
2403
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'])))
2406 {
2407 user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
2408 }
2409
2410 $params = $add_anchor = '';
2411
2412 if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
2413 {
2414 $params .= '&t=' . $data['topic_id'];
2415
2416 if ($mode != 'post')
2417 {
2418 $params .= '&p=' . $data['post_id'];
2419 $add_anchor = '#p' . $data['post_id'];
2420 }
2421 }
2422 else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic')
2423 {
2424 $params .= '&t=' . $data['topic_id'];
2425 }
2426
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;
2429
2430 return $url;
2431 }
2432
2433 ?>