[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id$ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * @ignore 13 */ 14 if (!defined('IN_PHPBB')) 15 { 16 exit; 17 } 18 19 /** 20 * Fill smiley templates (or just the variables) with smilies, either in a window or inline 21 */ 22 function generate_smilies($mode, $forum_id) 23 { 24 global $auth, $db, $user, $config, $template; 25 global $phpEx, $phpbb_root_path; 26 27 $start = request_var('start', 0); 28 29 if ($mode == 'window') 30 { 31 if ($forum_id) 32 { 33 $sql = 'SELECT forum_style 34 FROM ' . FORUMS_TABLE . " 35 WHERE forum_id = $forum_id"; 36 $result = $db->sql_query_limit($sql, 1); 37 $row = $db->sql_fetchrow($result); 38 $db->sql_freeresult($result); 39 40 $user->setup('posting', (int) $row['forum_style']); 41 } 42 else 43 { 44 $user->setup('posting'); 45 } 46 47 page_header($user->lang['SMILIES']); 48 49 $sql = 'SELECT COUNT(smiley_id) AS item_count 50 FROM ' . SMILIES_TABLE . ' 51 GROUP BY smiley_url'; 52 $result = $db->sql_query($sql, 3600); 53 54 $smiley_count = 0; 55 while ($row = $db->sql_fetchrow($result)) 56 { 57 ++$smiley_count; 58 } 59 $db->sql_freeresult($result); 60 61 $template->set_filenames(array( 62 'body' => 'posting_smilies.html') 63 ); 64 65 $template->assign_var('PAGINATION', 66 generate_pagination(append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id), 67 $smiley_count, $config['smilies_per_page'], $start, true) 68 ); 69 } 70 71 $display_link = false; 72 if ($mode == 'inline') 73 { 74 $sql = 'SELECT smiley_id 75 FROM ' . SMILIES_TABLE . ' 76 WHERE display_on_posting = 0'; 77 $result = $db->sql_query_limit($sql, 1, 0, 3600); 78 79 if ($row = $db->sql_fetchrow($result)) 80 { 81 $display_link = true; 82 } 83 $db->sql_freeresult($result); 84 } 85 86 if ($mode == 'window') 87 { 88 $sql = 'SELECT smiley_url, MIN(emotion) as emotion, MIN(code) AS code, smiley_width, smiley_height, MIN(smiley_order) AS min_smiley_order 89 FROM ' . SMILIES_TABLE . ' 90 GROUP BY smiley_url, smiley_width, smiley_height 91 ORDER BY min_smiley_order'; 92 $result = $db->sql_query_limit($sql, $config['smilies_per_page'], $start, 3600); 93 } 94 else 95 { 96 $sql = 'SELECT * 97 FROM ' . SMILIES_TABLE . ' 98 WHERE display_on_posting = 1 99 ORDER BY smiley_order'; 100 $result = $db->sql_query($sql, 3600); 101 } 102 103 $smilies = array(); 104 while ($row = $db->sql_fetchrow($result)) 105 { 106 if (empty($smilies[$row['smiley_url']])) 107 { 108 $smilies[$row['smiley_url']] = $row; 109 } 110 } 111 $db->sql_freeresult($result); 112 113 if (sizeof($smilies)) 114 { 115 $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path; 116 117 foreach ($smilies as $row) 118 { 119 $template->assign_block_vars('smiley', array( 120 'SMILEY_CODE' => $row['code'], 121 'A_SMILEY_CODE' => addslashes($row['code']), 122 'SMILEY_IMG' => $root_path . $config['smilies_path'] . '/' . $row['smiley_url'], 123 'SMILEY_WIDTH' => $row['smiley_width'], 124 'SMILEY_HEIGHT' => $row['smiley_height'], 125 'SMILEY_DESC' => $row['emotion']) 126 ); 127 } 128 } 129 130 if ($mode == 'inline' && $display_link) 131 { 132 $template->assign_vars(array( 133 'S_SHOW_SMILEY_LINK' => true, 134 'U_MORE_SMILIES' => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id)) 135 ); 136 } 137 138 if ($mode == 'window') 139 { 140 page_footer(); 141 } 142 } 143 144 /** 145 * Update last post information 146 * Should be used instead of sync() if only the last post information are out of sync... faster 147 * 148 * @param string $type Can be forum|topic 149 * @param mixed $ids topic/forum ids 150 * @param bool $return_update_sql true: SQL query shall be returned, false: execute SQL 151 */ 152 function update_post_information($type, $ids, $return_update_sql = false) 153 { 154 global $db; 155 156 if (empty($ids)) 157 { 158 return; 159 } 160 if (!is_array($ids)) 161 { 162 $ids = array($ids); 163 } 164 165 166 $update_sql = $empty_forums = $not_empty_forums = array(); 167 168 if ($type != 'topic') 169 { 170 $topic_join = ', ' . TOPICS_TABLE . ' t'; 171 $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_approved = 1'; 172 } 173 else 174 { 175 $topic_join = ''; 176 $topic_condition = ''; 177 } 178 179 if (sizeof($ids) == 1) 180 { 181 $sql = 'SELECT MAX(p.post_id) as last_post_id 182 FROM ' . POSTS_TABLE . " p $topic_join 183 WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . " 184 $topic_condition 185 AND p.post_approved = 1"; 186 } 187 else 188 { 189 $sql = 'SELECT p.' . $type . '_id, MAX(p.post_id) as last_post_id 190 FROM ' . POSTS_TABLE . " p $topic_join 191 WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . " 192 $topic_condition 193 AND p.post_approved = 1 194 GROUP BY p.{$type}_id"; 195 } 196 $result = $db->sql_query($sql); 197 198 $last_post_ids = array(); 199 while ($row = $db->sql_fetchrow($result)) 200 { 201 if (sizeof($ids) == 1) 202 { 203 $row[$type . '_id'] = $ids[0]; 204 } 205 206 if ($type == 'forum') 207 { 208 $not_empty_forums[] = $row['forum_id']; 209 210 if (empty($row['last_post_id'])) 211 { 212 $empty_forums[] = $row['forum_id']; 213 } 214 } 215 216 $last_post_ids[] = $row['last_post_id']; 217 } 218 $db->sql_freeresult($result); 219 220 if ($type == 'forum') 221 { 222 $empty_forums = array_merge($empty_forums, array_diff($ids, $not_empty_forums)); 223 224 foreach ($empty_forums as $void => $forum_id) 225 { 226 $update_sql[$forum_id][] = 'forum_last_post_id = 0'; 227 $update_sql[$forum_id][] = "forum_last_post_subject = ''"; 228 $update_sql[$forum_id][] = 'forum_last_post_time = 0'; 229 $update_sql[$forum_id][] = 'forum_last_poster_id = 0'; 230 $update_sql[$forum_id][] = "forum_last_poster_name = ''"; 231 $update_sql[$forum_id][] = "forum_last_poster_colour = ''"; 232 } 233 } 234 235 if (sizeof($last_post_ids)) 236 { 237 $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 238 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u 239 WHERE p.poster_id = u.user_id 240 AND ' . $db->sql_in_set('p.post_id', $last_post_ids); 241 $result = $db->sql_query($sql); 242 243 while ($row = $db->sql_fetchrow($result)) 244 { 245 $update_sql[$row["{$type}_id"]][] = $type . '_last_post_id = ' . (int) $row['post_id']; 246 $update_sql[$row["{$type}_id"]][] = "{$type}_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; 247 $update_sql[$row["{$type}_id"]][] = $type . '_last_post_time = ' . (int) $row['post_time']; 248 $update_sql[$row["{$type}_id"]][] = $type . '_last_poster_id = ' . (int) $row['poster_id']; 249 $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; 250 $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'"; 251 } 252 $db->sql_freeresult($result); 253 } 254 unset($empty_forums, $ids, $last_post_ids); 255 256 if ($return_update_sql || !sizeof($update_sql)) 257 { 258 return $update_sql; 259 } 260 261 $table = ($type == 'forum') ? FORUMS_TABLE : TOPICS_TABLE; 262 263 foreach ($update_sql as $update_id => $update_sql_ary) 264 { 265 $sql = "UPDATE $table 266 SET " . implode(', ', $update_sql_ary) . " 267 WHERE {$type}_id = $update_id"; 268 $db->sql_query($sql); 269 } 270 271 return; 272 } 273 274 /** 275 * Generate Topic Icons for display 276 */ 277 function posting_gen_topic_icons($mode, $icon_id) 278 { 279 global $phpbb_root_path, $config, $template, $cache; 280 281 // Grab icons 282 $icons = $cache->obtain_icons(); 283 284 if (!$icon_id) 285 { 286 $template->assign_var('S_NO_ICON_CHECKED', ' checked="checked"'); 287 } 288 289 if (sizeof($icons)) 290 { 291 $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path; 292 293 foreach ($icons as $id => $data) 294 { 295 if ($data['display']) 296 { 297 $template->assign_block_vars('topic_icon', array( 298 'ICON_ID' => $id, 299 'ICON_IMG' => $root_path . $config['icons_path'] . '/' . $data['img'], 300 'ICON_WIDTH' => $data['width'], 301 'ICON_HEIGHT' => $data['height'], 302 303 'S_CHECKED' => ($id == $icon_id) ? true : false, 304 'S_ICON_CHECKED' => ($id == $icon_id) ? ' checked="checked"' : '') 305 ); 306 } 307 } 308 309 return true; 310 } 311 312 return false; 313 } 314 315 /** 316 * Build topic types able to be selected 317 */ 318 function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) 319 { 320 global $auth, $user, $template, $topic_type; 321 322 $toggle = false; 323 324 $topic_types = array( 325 'sticky' => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'), 326 'announce' => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'), 327 'global' => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL') 328 ); 329 330 $topic_type_array = array(); 331 332 foreach ($topic_types as $auth_key => $topic_value) 333 { 334 // We do not have a special post global announcement permission 335 $auth_key = ($auth_key == 'global') ? 'announce' : $auth_key; 336 337 if ($auth->acl_get('f_' . $auth_key, $forum_id)) 338 { 339 $toggle = true; 340 341 $topic_type_array[] = array( 342 'VALUE' => $topic_value['const'], 343 'S_CHECKED' => ($cur_topic_type == $topic_value['const'] || ($forum_id == 0 && $topic_value['const'] == POST_GLOBAL)) ? ' checked="checked"' : '', 344 'L_TOPIC_TYPE' => $user->lang[$topic_value['lang']] 345 ); 346 } 347 } 348 349 if ($toggle) 350 { 351 $topic_type_array = array_merge(array(0 => array( 352 'VALUE' => POST_NORMAL, 353 'S_CHECKED' => ($cur_topic_type == POST_NORMAL) ? ' checked="checked"' : '', 354 'L_TOPIC_TYPE' => $user->lang['POST_NORMAL'])), 355 356 $topic_type_array 357 ); 358 359 foreach ($topic_type_array as $array) 360 { 361 $template->assign_block_vars('topic_type', $array); 362 } 363 364 $template->assign_vars(array( 365 'S_TOPIC_TYPE_STICKY' => ($auth->acl_get('f_sticky', $forum_id)), 366 'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_get('f_announce', $forum_id))) 367 ); 368 } 369 370 return $toggle; 371 } 372 373 // 374 // Attachment related functions 375 // 376 377 /** 378 * Upload Attachment - filedata is generated here 379 * Uses upload class 380 */ 381 function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) 382 { 383 global $auth, $user, $config, $db, $cache; 384 global $phpbb_root_path, $phpEx; 385 386 $filedata = array( 387 'error' => array() 388 ); 389 390 include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx); 391 $upload = new fileupload(); 392 393 if ($config['check_attachment_content'] && isset($config['mime_triggers'])) 394 { 395 $upload->set_disallowed_content(explode('|', $config['mime_triggers'])); 396 } 397 398 if (!$local) 399 { 400 $filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false; 401 } 402 else 403 { 404 $filedata['post_attach'] = true; 405 } 406 407 if (!$filedata['post_attach']) 408 { 409 $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND']; 410 return $filedata; 411 } 412 413 $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); 414 $upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); 415 416 $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name); 417 418 if ($file->init_error) 419 { 420 $filedata['post_attach'] = false; 421 return $filedata; 422 } 423 424 $cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE; 425 426 // Do we have to create a thumbnail? 427 $filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0; 428 429 // Check Image Size, if it is an image 430 if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE) 431 { 432 $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']); 433 } 434 435 // Admins and mods are allowed to exceed the allowed filesize 436 if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id)) 437 { 438 if (!empty($extensions[$file->get('extension')]['max_filesize'])) 439 { 440 $allowed_filesize = $extensions[$file->get('extension')]['max_filesize']; 441 } 442 else 443 { 444 $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize']; 445 } 446 447 $file->upload->set_max_filesize($allowed_filesize); 448 } 449 450 $file->clean_filename('unique', $user->data['user_id'] . '_'); 451 452 // Are we uploading an image *and* this image being within the image category? Only then perform additional image checks. 453 $no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true; 454 455 $file->move_file($config['upload_path'], false, $no_image); 456 457 if (sizeof($file->error)) 458 { 459 $file->remove(); 460 $filedata['error'] = array_merge($filedata['error'], $file->error); 461 $filedata['post_attach'] = false; 462 463 return $filedata; 464 } 465 466 // Make sure the image category only holds valid images... 467 if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image()) 468 { 469 $file->remove(); 470 471 // If this error occurs a user tried to exploit an IE Bug by renaming extensions 472 // Since the image category is displaying content inline we need to catch this. 473 trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']); 474 } 475 476 $filedata['filesize'] = $file->get('filesize'); 477 $filedata['mimetype'] = $file->get('mimetype'); 478 $filedata['extension'] = $file->get('extension'); 479 $filedata['physical_filename'] = $file->get('realname'); 480 $filedata['real_filename'] = $file->get('uploadname'); 481 $filedata['filetime'] = time(); 482 483 // Check our complete quota 484 if ($config['attachment_quota']) 485 { 486 if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota']) 487 { 488 $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED']; 489 $filedata['post_attach'] = false; 490 491 $file->remove(); 492 493 return $filedata; 494 } 495 } 496 497 // Check free disk space 498 if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path'])) 499 { 500 if ($free_space <= $file->get('filesize')) 501 { 502 if ($auth->acl_get('a_')) 503 { 504 $filedata['error'][] = $user->lang['ATTACH_DISK_FULL']; 505 } 506 else 507 { 508 $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED']; 509 } 510 $filedata['post_attach'] = false; 511 512 $file->remove(); 513 514 return $filedata; 515 } 516 } 517 518 // Create Thumbnail 519 if ($filedata['thumbnail']) 520 { 521 $source = $file->get('destination_file'); 522 $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname'); 523 524 if (!create_thumbnail($source, $destination, $file->get('mimetype'))) 525 { 526 $filedata['thumbnail'] = 0; 527 } 528 } 529 530 return $filedata; 531 } 532 533 /** 534 * Calculate the needed size for Thumbnail 535 */ 536 function get_img_size_format($width, $height) 537 { 538 global $config; 539 540 // Maximum Width the Image can take 541 $max_width = ($config['img_max_thumb_width']) ? $config['img_max_thumb_width'] : 400; 542 543 if ($width > $height) 544 { 545 return array( 546 round($width * ($max_width / $width)), 547 round($height * ($max_width / $width)) 548 ); 549 } 550 else 551 { 552 return array( 553 round($width * ($max_width / $height)), 554 round($height * ($max_width / $height)) 555 ); 556 } 557 } 558 559 /** 560 * Return supported image types 561 */ 562 function get_supported_image_types($type = false) 563 { 564 if (@extension_loaded('gd')) 565 { 566 $format = imagetypes(); 567 $new_type = 0; 568 569 if ($type !== false) 570 { 571 // Type is one of the IMAGETYPE constants - it is fetched from getimagesize() 572 // We do not use the constants here, because some were not available in PHP 4.3.x 573 switch ($type) 574 { 575 // GIF 576 case 1: 577 $new_type = ($format & IMG_GIF) ? IMG_GIF : false; 578 break; 579 580 // JPG, JPC, JP2 581 case 2: 582 case 9: 583 case 10: 584 case 11: 585 case 12: 586 $new_type = ($format & IMG_JPG) ? IMG_JPG : false; 587 break; 588 589 // PNG 590 case 3: 591 $new_type = ($format & IMG_PNG) ? IMG_PNG : false; 592 break; 593 594 // WBMP 595 case 15: 596 $new_type = ($format & IMG_WBMP) ? IMG_WBMP : false; 597 break; 598 } 599 } 600 else 601 { 602 $new_type = array(); 603 $go_through_types = array(IMG_GIF, IMG_JPG, IMG_PNG, IMG_WBMP); 604 605 foreach ($go_through_types as $check_type) 606 { 607 if ($format & $check_type) 608 { 609 $new_type[] = $check_type; 610 } 611 } 612 } 613 614 return array( 615 'gd' => ($new_type) ? true : false, 616 'format' => $new_type, 617 'version' => (function_exists('imagecreatetruecolor')) ? 2 : 1 618 ); 619 } 620 621 return array('gd' => false); 622 } 623 624 /** 625 * Create Thumbnail 626 */ 627 function create_thumbnail($source, $destination, $mimetype) 628 { 629 global $config; 630 631 $min_filesize = (int) $config['img_min_thumb_filesize']; 632 $img_filesize = (file_exists($source)) ? @filesize($source) : false; 633 634 if (!$img_filesize || $img_filesize <= $min_filesize) 635 { 636 return false; 637 } 638 639 $dimension = @getimagesize($source); 640 641 if ($dimension === false) 642 { 643 return false; 644 } 645 646 list($width, $height, $type, ) = $dimension; 647 648 if (empty($width) || empty($height)) 649 { 650 return false; 651 } 652 653 list($new_width, $new_height) = get_img_size_format($width, $height); 654 655 // Do not create a thumbnail if the resulting width/height is bigger than the original one 656 if ($new_width >= $width && $new_height >= $height) 657 { 658 return false; 659 } 660 661 $used_imagick = false; 662 663 // Only use imagemagick if defined and the passthru function not disabled 664 if ($config['img_imagick'] && function_exists('passthru')) 665 { 666 if (substr($config['img_imagick'], -1) !== '/') 667 { 668 $config['img_imagick'] .= '/'; 669 } 670 671 @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -geometry ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" "' . str_replace('\\', '/', $destination) . '"'); 672 673 if (file_exists($destination)) 674 { 675 $used_imagick = true; 676 } 677 } 678 679 if (!$used_imagick) 680 { 681 $type = get_supported_image_types($type); 682 683 if ($type['gd']) 684 { 685 // If the type is not supported, we are not able to create a thumbnail 686 if ($type['format'] === false) 687 { 688 return false; 689 } 690 691 switch ($type['format']) 692 { 693 case IMG_GIF: 694 $image = @imagecreatefromgif($source); 695 break; 696 697 case IMG_JPG: 698 @ini_set('gd.jpeg_ignore_warning', 1); 699 $image = @imagecreatefromjpeg($source); 700 break; 701 702 case IMG_PNG: 703 $image = @imagecreatefrompng($source); 704 break; 705 706 case IMG_WBMP: 707 $image = @imagecreatefromwbmp($source); 708 break; 709 } 710 711 if (empty($image)) 712 { 713 return false; 714 } 715 716 if ($type['version'] == 1) 717 { 718 $new_image = imagecreate($new_width, $new_height); 719 720 if ($new_image === false) 721 { 722 return false; 723 } 724 725 imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); 726 } 727 else 728 { 729 $new_image = imagecreatetruecolor($new_width, $new_height); 730 731 if ($new_image === false) 732 { 733 return false; 734 } 735 736 // Preserve alpha transparency (png for example) 737 @imagealphablending($new_image, false); 738 @imagesavealpha($new_image, true); 739 740 imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); 741 } 742 743 // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug 744 if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on') 745 { 746 @touch($destination); 747 } 748 749 switch ($type['format']) 750 { 751 case IMG_GIF: 752 imagegif($new_image, $destination); 753 break; 754 755 case IMG_JPG: 756 imagejpeg($new_image, $destination, 90); 757 break; 758 759 case IMG_PNG: 760 imagepng($new_image, $destination); 761 break; 762 763 case IMG_WBMP: 764 imagewbmp($new_image, $destination); 765 break; 766 } 767 768 imagedestroy($new_image); 769 } 770 else 771 { 772 return false; 773 } 774 } 775 776 if (!file_exists($destination)) 777 { 778 return false; 779 } 780 781 phpbb_chmod($destination, CHMOD_READ | CHMOD_WRITE); 782 783 return true; 784 } 785 786 /** 787 * Assign Inline attachments (build option fields) 788 */ 789 function posting_gen_inline_attachments(&$attachment_data) 790 { 791 global $template; 792 793 if (sizeof($attachment_data)) 794 { 795 $s_inline_attachment_options = ''; 796 797 foreach ($attachment_data as $i => $attachment) 798 { 799 $s_inline_attachment_options .= '<option value="' . $i . '">' . utf8_basename($attachment['real_filename']) . '</option>'; 800 } 801 802 $template->assign_var('S_INLINE_ATTACHMENT_OPTIONS', $s_inline_attachment_options); 803 804 return true; 805 } 806 807 return false; 808 } 809 810 /** 811 * Generate inline attachment entry 812 */ 813 function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_attach_box = true) 814 { 815 global $template, $config, $phpbb_root_path, $phpEx, $user, $auth; 816 817 // Some default template variables 818 $template->assign_vars(array( 819 'S_SHOW_ATTACH_BOX' => $show_attach_box, 820 'S_HAS_ATTACHMENTS' => sizeof($attachment_data), 821 'FILESIZE' => $config['max_filesize'], 822 'FILE_COMMENT' => (isset($filename_data['filecomment'])) ? $filename_data['filecomment'] : '', 823 )); 824 825 if (sizeof($attachment_data)) 826 { 827 // We display the posted attachments within the desired order. 828 ($config['display_order']) ? krsort($attachment_data) : ksort($attachment_data); 829 830 foreach ($attachment_data as $count => $attach_row) 831 { 832 $hidden = ''; 833 $attach_row['real_filename'] = utf8_basename($attach_row['real_filename']); 834 835 foreach ($attach_row as $key => $value) 836 { 837 $hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />'; 838 } 839 840 $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); 841 842 $template->assign_block_vars('attach_row', array( 843 'FILENAME' => utf8_basename($attach_row['real_filename']), 844 'A_FILENAME' => addslashes(utf8_basename($attach_row['real_filename'])), 845 'FILE_COMMENT' => $attach_row['attach_comment'], 846 'ATTACH_ID' => $attach_row['attach_id'], 847 'S_IS_ORPHAN' => $attach_row['is_orphan'], 848 'ASSOC_INDEX' => $count, 849 850 'U_VIEW_ATTACHMENT' => $download_link, 851 'S_HIDDEN' => $hidden) 852 ); 853 } 854 } 855 856 return sizeof($attachment_data); 857 } 858 859 // 860 // General Post functions 861 // 862 863 /** 864 * Load Drafts 865 */ 866 function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $msg_id = 0) 867 { 868 global $user, $db, $template, $auth; 869 global $phpbb_root_path, $phpEx; 870 871 $topic_ids = $forum_ids = $draft_rows = array(); 872 873 // Load those drafts not connected to forums/topics 874 // If forum_id == 0 AND topic_id == 0 then this is a PM draft 875 if (!$topic_id && !$forum_id) 876 { 877 $sql_and = ' AND d.forum_id = 0 AND d.topic_id = 0'; 878 } 879 else 880 { 881 $sql_and = ''; 882 $sql_and .= ($forum_id) ? ' AND d.forum_id = ' . (int) $forum_id : ''; 883 $sql_and .= ($topic_id) ? ' AND d.topic_id = ' . (int) $topic_id : ''; 884 } 885 886 $sql = 'SELECT d.*, f.forum_id, f.forum_name 887 FROM ' . DRAFTS_TABLE . ' d 888 LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = d.forum_id) 889 WHERE d.user_id = ' . $user->data['user_id'] . " 890 $sql_and 891 ORDER BY d.save_time DESC"; 892 $result = $db->sql_query($sql); 893 894 while ($row = $db->sql_fetchrow($result)) 895 { 896 if ($row['topic_id']) 897 { 898 $topic_ids[] = (int) $row['topic_id']; 899 } 900 $draft_rows[] = $row; 901 } 902 $db->sql_freeresult($result); 903 904 if (!sizeof($draft_rows)) 905 { 906 return; 907 } 908 909 $topic_rows = array(); 910 if (sizeof($topic_ids)) 911 { 912 $sql = 'SELECT topic_id, forum_id, topic_title 913 FROM ' . TOPICS_TABLE . ' 914 WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids)); 915 $result = $db->sql_query($sql); 916 917 while ($row = $db->sql_fetchrow($result)) 918 { 919 $topic_rows[$row['topic_id']] = $row; 920 } 921 $db->sql_freeresult($result); 922 } 923 unset($topic_ids); 924 925 $template->assign_var('S_SHOW_DRAFTS', true); 926 927 foreach ($draft_rows as $draft) 928 { 929 $link_topic = $link_forum = $link_pm = false; 930 $insert_url = $view_url = $title = ''; 931 932 if (isset($topic_rows[$draft['topic_id']]) 933 && ( 934 ($topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_get('f_read', $topic_rows[$draft['topic_id']]['forum_id'])) 935 || 936 (!$topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_getf_global('f_read')) 937 )) 938 { 939 $topic_forum_id = ($topic_rows[$draft['topic_id']]['forum_id']) ? $topic_rows[$draft['topic_id']]['forum_id'] : $forum_id; 940 941 $link_topic = true; 942 $view_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id']); 943 $title = $topic_rows[$draft['topic_id']]['topic_title']; 944 945 $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $topic_forum_id . '&t=' . $draft['topic_id'] . '&mode=reply&d=' . $draft['draft_id']); 946 } 947 else if ($draft['forum_id'] && $auth->acl_get('f_read', $draft['forum_id'])) 948 { 949 $link_forum = true; 950 $view_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $draft['forum_id']); 951 $title = $draft['forum_name']; 952 953 $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $draft['forum_id'] . '&mode=post&d=' . $draft['draft_id']); 954 } 955 else 956 { 957 // Either display as PM draft if forum_id and topic_id are empty or if access to the forums has been denied afterwards... 958 $link_pm = true; 959 $insert_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=compose&d={$draft['draft_id']}" . (($pm_action) ? "&action=$pm_action" : '') . (($msg_id) ? "&p=$msg_id" : '')); 960 } 961 962 $template->assign_block_vars('draftrow', array( 963 'DRAFT_ID' => $draft['draft_id'], 964 'DATE' => $user->format_date($draft['save_time']), 965 'DRAFT_SUBJECT' => $draft['draft_subject'], 966 967 'TITLE' => $title, 968 'U_VIEW' => $view_url, 969 'U_INSERT' => $insert_url, 970 971 'S_LINK_PM' => $link_pm, 972 'S_LINK_TOPIC' => $link_topic, 973 'S_LINK_FORUM' => $link_forum) 974 ); 975 } 976 } 977 978 /** 979 * Topic Review 980 */ 981 function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true) 982 { 983 global $user, $auth, $db, $template, $bbcode, $cache; 984 global $config, $phpbb_root_path, $phpEx; 985 986 // Go ahead and pull all data for this topic 987 $sql = 'SELECT p.post_id 988 FROM ' . POSTS_TABLE . ' p' . " 989 WHERE p.topic_id = $topic_id 990 " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . ' 991 ' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . ' 992 ' . (($mode == 'post_review_edit') ? " AND p.post_id = $cur_post_id" : '') . ' 993 ORDER BY p.post_time '; 994 $sql .= ($mode == 'post_review') ? 'ASC' : 'DESC'; 995 $result = $db->sql_query_limit($sql, $config['posts_per_page']); 996 997 $post_list = array(); 998 999 while ($row = $db->sql_fetchrow($result)) 1000 { 1001 $post_list[] = $row['post_id']; 1002 } 1003 1004 $db->sql_freeresult($result); 1005 1006 if (!sizeof($post_list)) 1007 { 1008 return false; 1009 } 1010 1011 // Handle 'post_review_edit' like 'post_review' from now on 1012 if ($mode == 'post_review_edit') 1013 { 1014 $mode = 'post_review'; 1015 } 1016 1017 $sql = $db->sql_build_query('SELECT', array( 1018 'SELECT' => 'u.username, u.user_id, u.user_colour, p.*, z.friend, z.foe', 1019 1020 'FROM' => array( 1021 USERS_TABLE => 'u', 1022 POSTS_TABLE => 'p', 1023 ), 1024 1025 'LEFT_JOIN' => array( 1026 array( 1027 'FROM' => array(ZEBRA_TABLE => 'z'), 1028 'ON' => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id' 1029 ) 1030 ), 1031 1032 'WHERE' => $db->sql_in_set('p.post_id', $post_list) . ' 1033 AND u.user_id = p.poster_id' 1034 )); 1035 1036 $result = $db->sql_query($sql); 1037 1038 $bbcode_bitfield = ''; 1039 $rowset = array(); 1040 $has_attachments = false; 1041 while ($row = $db->sql_fetchrow($result)) 1042 { 1043 $rowset[$row['post_id']] = $row; 1044 $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']); 1045 1046 if ($row['post_attachment']) 1047 { 1048 $has_attachments = true; 1049 } 1050 } 1051 $db->sql_freeresult($result); 1052 1053 // Instantiate BBCode class 1054 if (!isset($bbcode) && $bbcode_bitfield !== '') 1055 { 1056 include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx); 1057 $bbcode = new bbcode(base64_encode($bbcode_bitfield)); 1058 } 1059 1060 // Grab extensions 1061 $extensions = $attachments = array(); 1062 if ($has_attachments && $auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id)) 1063 { 1064 $extensions = $cache->obtain_attach_extensions($forum_id); 1065 1066 // Get attachments... 1067 $sql = 'SELECT * 1068 FROM ' . ATTACHMENTS_TABLE . ' 1069 WHERE ' . $db->sql_in_set('post_msg_id', $post_list) . ' 1070 AND in_message = 0 1071 ORDER BY filetime DESC, post_msg_id ASC'; 1072 $result = $db->sql_query($sql); 1073 1074 while ($row = $db->sql_fetchrow($result)) 1075 { 1076 $attachments[$row['post_msg_id']][] = $row; 1077 } 1078 $db->sql_freeresult($result); 1079 } 1080 1081 for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 1082 { 1083 // A non-existing rowset only happens if there was no user present for the entered poster_id 1084 // This could be a broken posts table. 1085 if (!isset($rowset[$post_list[$i]])) 1086 { 1087 continue; 1088 } 1089 1090 $row =& $rowset[$post_list[$i]]; 1091 1092 $poster_id = $row['user_id']; 1093 $post_subject = $row['post_subject']; 1094 $message = censor_text($row['post_text']); 1095 1096 $decoded_message = false; 1097 1098 if ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) 1099 { 1100 $decoded_message = $message; 1101 decode_message($decoded_message, $row['bbcode_uid']); 1102 1103 $decoded_message = bbcode_nl2br($decoded_message); 1104 } 1105 1106 if ($row['bbcode_bitfield']) 1107 { 1108 $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']); 1109 } 1110 1111 $message = bbcode_nl2br($message); 1112 $message = smiley_text($message, !$row['enable_smilies']); 1113 1114 if (!empty($attachments[$row['post_id']])) 1115 { 1116 $update_count = array(); 1117 parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count); 1118 } 1119 1120 $post_subject = censor_text($post_subject); 1121 1122 $post_anchor = ($mode == 'post_review') ? 'ppr' . $row['post_id'] : 'pr' . $row['post_id']; 1123 $u_show_post = append_sid($phpbb_root_path . 'viewtopic.' . $phpEx, "f=$forum_id&t=$topic_id&p={$row['post_id']}&view=show#p{$row['post_id']}"); 1124 1125 $template->assign_block_vars($mode . '_row', array( 1126 'POST_AUTHOR_FULL' => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 1127 'POST_AUTHOR_COLOUR' => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 1128 'POST_AUTHOR' => get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 1129 'U_POST_AUTHOR' => get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 1130 1131 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, 1132 'S_FRIEND' => ($row['friend']) ? true : false, 1133 'S_IGNORE_POST' => ($row['foe']) ? true : false, 1134 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), "<a href=\"{$u_show_post}\" onclick=\"dE('{$post_anchor}', 1); return false;\">", '</a>') : '', 1135 1136 'POST_SUBJECT' => $post_subject, 1137 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']), 1138 'POST_DATE' => $user->format_date($row['post_time']), 1139 'MESSAGE' => $message, 1140 'DECODED_MESSAGE' => $decoded_message, 1141 'POST_ID' => $row['post_id'], 1142 'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'], 1143 '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) : '', 1144 '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'])) : '') 1145 ); 1146 1147 // Display not already displayed Attachments for this post, we already parsed them. ;) 1148 if (!empty($attachments[$row['post_id']])) 1149 { 1150 foreach ($attachments[$row['post_id']] as $attachment) 1151 { 1152 $template->assign_block_vars($mode . '_row.attachment', array( 1153 'DISPLAY_ATTACHMENT' => $attachment) 1154 ); 1155 } 1156 } 1157 1158 unset($rowset[$post_list[$i]]); 1159 } 1160 1161 if ($mode == 'topic_review') 1162 { 1163 $template->assign_var('QUOTE_IMG', $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE'])); 1164 } 1165 1166 return true; 1167 } 1168 1169 /** 1170 * User Notification 1171 */ 1172 function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id, $author_name = '') 1173 { 1174 global $db, $user, $config, $phpbb_root_path, $phpEx, $auth; 1175 1176 $topic_notification = ($mode == 'reply' || $mode == 'quote') ? true : false; 1177 $forum_notification = ($mode == 'post') ? true : false; 1178 1179 if (!$topic_notification && !$forum_notification) 1180 { 1181 trigger_error('NO_MODE'); 1182 } 1183 1184 if (($topic_notification && !$config['allow_topic_notify']) || ($forum_notification && !$config['allow_forum_notify'])) 1185 { 1186 return; 1187 } 1188 1189 $topic_title = ($topic_notification) ? $topic_title : $subject; 1190 $topic_title = censor_text($topic_title); 1191 1192 // Exclude guests, current user and banned users from notifications 1193 if (!function_exists('phpbb_get_banned_user_ids')) 1194 { 1195 include($phpbb_root_path . 'includes/functions_user.' . $phpEx); 1196 } 1197 $sql_ignore_users = phpbb_get_banned_user_ids(); 1198 $sql_ignore_users[ANONYMOUS] = ANONYMOUS; 1199 $sql_ignore_users[$user->data['user_id']] = $user->data['user_id']; 1200 1201 $notify_rows = array(); 1202 1203 // -- get forum_userids || topic_userids 1204 $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber 1205 FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u 1206 WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . ' 1207 AND ' . $db->sql_in_set('w.user_id', $sql_ignore_users, true) . ' 1208 AND w.notify_status = ' . NOTIFY_YES . ' 1209 AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') 1210 AND u.user_id = w.user_id'; 1211 $result = $db->sql_query($sql); 1212 1213 while ($row = $db->sql_fetchrow($result)) 1214 { 1215 $notify_user_id = (int) $row['user_id']; 1216 $notify_rows[$notify_user_id] = array( 1217 'user_id' => $notify_user_id, 1218 'username' => $row['username'], 1219 'user_email' => $row['user_email'], 1220 'user_jabber' => $row['user_jabber'], 1221 'user_lang' => $row['user_lang'], 1222 'notify_type' => ($topic_notification) ? 'topic' : 'forum', 1223 'template' => ($topic_notification) ? 'topic_notify' : 'newtopic_notify', 1224 'method' => $row['user_notify_type'], 1225 'allowed' => false 1226 ); 1227 1228 // Add users who have been already notified to ignore list 1229 $sql_ignore_users[$notify_user_id] = $notify_user_id; 1230 } 1231 $db->sql_freeresult($result); 1232 1233 // forum notification is sent to those not already receiving topic notifications 1234 if ($topic_notification) 1235 { 1236 $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber 1237 FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u 1238 WHERE fw.forum_id = $forum_id 1239 AND " . $db->sql_in_set('fw.user_id', $sql_ignore_users, true) . ' 1240 AND fw.notify_status = ' . NOTIFY_YES . ' 1241 AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') 1242 AND u.user_id = fw.user_id'; 1243 $result = $db->sql_query($sql); 1244 1245 while ($row = $db->sql_fetchrow($result)) 1246 { 1247 $notify_user_id = (int) $row['user_id']; 1248 $notify_rows[$notify_user_id] = array( 1249 'user_id' => $notify_user_id, 1250 'username' => $row['username'], 1251 'user_email' => $row['user_email'], 1252 'user_jabber' => $row['user_jabber'], 1253 'user_lang' => $row['user_lang'], 1254 'notify_type' => 'forum', 1255 'template' => 'forum_notify', 1256 'method' => $row['user_notify_type'], 1257 'allowed' => false 1258 ); 1259 } 1260 $db->sql_freeresult($result); 1261 } 1262 1263 if (!sizeof($notify_rows)) 1264 { 1265 return; 1266 } 1267 1268 // Make sure users are allowed to read the forum 1269 foreach ($auth->acl_get_list(array_keys($notify_rows), 'f_read', $forum_id) as $forum_id => $forum_ary) 1270 { 1271 foreach ($forum_ary as $auth_option => $user_ary) 1272 { 1273 foreach ($user_ary as $user_id) 1274 { 1275 $notify_rows[$user_id]['allowed'] = true; 1276 } 1277 } 1278 } 1279 1280 // Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;) 1281 $msg_users = $delete_ids = $update_notification = array(); 1282 foreach ($notify_rows as $user_id => $row) 1283 { 1284 if (!$row['allowed'] || !trim($row['user_email'])) 1285 { 1286 $delete_ids[$row['notify_type']][] = $row['user_id']; 1287 } 1288 else 1289 { 1290 $msg_users[] = $row; 1291 $update_notification[$row['notify_type']][] = $row['user_id']; 1292 1293 /* 1294 * We also update the forums watch table for this user when we are 1295 * sending out a topic notification to prevent sending out another 1296 * notification in case this user is also subscribed to the forum 1297 * this topic was posted in. 1298 * Since an UPDATE query is used, this has no effect on users only 1299 * subscribed to the topic (i.e. no row is created) and should not 1300 * be a performance issue. 1301 */ 1302 if ($row['notify_type'] === 'topic') 1303 { 1304 $update_notification['forum'][] = $row['user_id']; 1305 } 1306 } 1307 } 1308 unset($notify_rows); 1309 1310 // Now, we are able to really send out notifications 1311 if (sizeof($msg_users)) 1312 { 1313 include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); 1314 $messenger = new messenger(); 1315 1316 $msg_list_ary = array(); 1317 foreach ($msg_users as $row) 1318 { 1319 $pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]); 1320 1321 $msg_list_ary[$row['template']][$pos]['method'] = $row['method']; 1322 $msg_list_ary[$row['template']][$pos]['email'] = $row['user_email']; 1323 $msg_list_ary[$row['template']][$pos]['jabber'] = $row['user_jabber']; 1324 $msg_list_ary[$row['template']][$pos]['name'] = $row['username']; 1325 $msg_list_ary[$row['template']][$pos]['lang'] = $row['user_lang']; 1326 $msg_list_ary[$row['template']][$pos]['user_id']= $row['user_id']; 1327 } 1328 unset($msg_users); 1329 1330 foreach ($msg_list_ary as $email_template => $email_list) 1331 { 1332 foreach ($email_list as $addr) 1333 { 1334 $messenger->template($email_template, $addr['lang']); 1335 1336 $messenger->to($addr['email'], $addr['name']); 1337 $messenger->im($addr['jabber'], $addr['name']); 1338 1339 $messenger->assign_vars(array( 1340 'USERNAME' => htmlspecialchars_decode($addr['name']), 1341 'TOPIC_TITLE' => htmlspecialchars_decode($topic_title), 1342 'FORUM_NAME' => htmlspecialchars_decode($forum_name), 1343 'AUTHOR_NAME' => htmlspecialchars_decode($author_name), 1344 1345 'U_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id", 1346 'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id", 1347 'U_NEWEST_POST' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&p=$post_id&e=$post_id", 1348 'U_STOP_WATCHING_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?uid={$addr['user_id']}&f=$forum_id&t=$topic_id&unwatch=topic", 1349 'U_STOP_WATCHING_FORUM' => generate_board_url() . "/viewforum.$phpEx?uid={$addr['user_id']}&f=$forum_id&unwatch=forum", 1350 )); 1351 1352 $messenger->send($addr['method']); 1353 } 1354 } 1355 unset($msg_list_ary); 1356 1357 $messenger->save_queue(); 1358 } 1359 1360 // Handle the DB updates 1361 $db->sql_transaction('begin'); 1362 1363 if (!empty($update_notification['topic'])) 1364 { 1365 $sql = 'UPDATE ' . TOPICS_WATCH_TABLE . ' 1366 SET notify_status = ' . NOTIFY_NO . " 1367 WHERE topic_id = $topic_id 1368 AND " . $db->sql_in_set('user_id', $update_notification['topic']); 1369 $db->sql_query($sql); 1370 } 1371 1372 if (!empty($update_notification['forum'])) 1373 { 1374 $sql = 'UPDATE ' . FORUMS_WATCH_TABLE . ' 1375 SET notify_status = ' . NOTIFY_NO . " 1376 WHERE forum_id = $forum_id 1377 AND " . $db->sql_in_set('user_id', $update_notification['forum']); 1378 $db->sql_query($sql); 1379 } 1380 1381 // Now delete the user_ids not authorised to receive notifications on this topic/forum 1382 if (!empty($delete_ids['topic'])) 1383 { 1384 $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . " 1385 WHERE topic_id = $topic_id 1386 AND " . $db->sql_in_set('user_id', $delete_ids['topic']); 1387 $db->sql_query($sql); 1388 } 1389 1390 if (!empty($delete_ids['forum'])) 1391 { 1392 $sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . " 1393 WHERE forum_id = $forum_id 1394 AND " . $db->sql_in_set('user_id', $delete_ids['forum']); 1395 $db->sql_query($sql); 1396 } 1397 1398 $db->sql_transaction('commit'); 1399 } 1400 1401 // 1402 // Post handling functions 1403 // 1404 1405 /** 1406 * Delete Post 1407 */ 1408 function delete_post($forum_id, $topic_id, $post_id, &$data) 1409 { 1410 global $db, $user, $auth; 1411 global $config, $phpEx, $phpbb_root_path; 1412 1413 // Specify our post mode 1414 $post_mode = 'delete'; 1415 if (($data['topic_first_post_id'] === $data['topic_last_post_id']) && $data['topic_replies_real'] == 0) 1416 { 1417 $post_mode = 'delete_topic'; 1418 } 1419 else if ($data['topic_first_post_id'] == $post_id) 1420 { 1421 $post_mode = 'delete_first_post'; 1422 } 1423 else if ($data['topic_last_post_id'] == $post_id) 1424 { 1425 $post_mode = 'delete_last_post'; 1426 } 1427 $sql_data = array(); 1428 $next_post_id = false; 1429 1430 include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx); 1431 1432 $db->sql_transaction('begin'); 1433 1434 // we must make sure to update forums that contain the shadow'd topic 1435 if ($post_mode == 'delete_topic') 1436 { 1437 $shadow_forum_ids = array(); 1438 1439 $sql = 'SELECT forum_id 1440 FROM ' . TOPICS_TABLE . ' 1441 WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id); 1442 $result = $db->sql_query($sql); 1443 while ($row = $db->sql_fetchrow($result)) 1444 { 1445 if (!isset($shadow_forum_ids[(int) $row['forum_id']])) 1446 { 1447 $shadow_forum_ids[(int) $row['forum_id']] = 1; 1448 } 1449 else 1450 { 1451 $shadow_forum_ids[(int) $row['forum_id']]++; 1452 } 1453 } 1454 $db->sql_freeresult($result); 1455 } 1456 1457 if (!delete_posts('post_id', array($post_id), false, false)) 1458 { 1459 // Try to delete topic, we may had an previous error causing inconsistency 1460 if ($post_mode == 'delete_topic') 1461 { 1462 delete_topics('topic_id', array($topic_id), false); 1463 } 1464 trigger_error('ALREADY_DELETED'); 1465 } 1466 1467 $db->sql_transaction('commit'); 1468 1469 // Collect the necessary information for updating the tables 1470 $sql_data[FORUMS_TABLE] = ''; 1471 switch ($post_mode) 1472 { 1473 case 'delete_topic': 1474 1475 foreach ($shadow_forum_ids as $updated_forum => $topic_count) 1476 { 1477 // counting is fun! we only have to do sizeof($forum_ids) number of queries, 1478 // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum) 1479 $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); 1480 update_post_information('forum', $updated_forum); 1481 } 1482 1483 delete_topics('topic_id', array($topic_id), false); 1484 1485 if ($data['topic_type'] != POST_GLOBAL) 1486 { 1487 $sql_data[FORUMS_TABLE] .= 'forum_topics_real = forum_topics_real - 1'; 1488 $sql_data[FORUMS_TABLE] .= ($data['topic_approved']) ? ', forum_posts = forum_posts - 1, forum_topics = forum_topics - 1' : ''; 1489 } 1490 1491 $update_sql = update_post_information('forum', $forum_id, true); 1492 if (sizeof($update_sql)) 1493 { 1494 $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : ''; 1495 $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]); 1496 } 1497 break; 1498 1499 case 'delete_first_post': 1500 $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour 1501 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u 1502 WHERE p.topic_id = $topic_id 1503 AND p.poster_id = u.user_id 1504 ORDER BY p.post_time ASC"; 1505 $result = $db->sql_query_limit($sql, 1); 1506 $row = $db->sql_fetchrow($result); 1507 $db->sql_freeresult($result); 1508 1509 if ($data['topic_type'] != POST_GLOBAL) 1510 { 1511 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; 1512 } 1513 1514 $sql_data[TOPICS_TABLE] = 'topic_poster = ' . intval($row['poster_id']) . ', 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'])) . "', topic_time = " . (int) $row['post_time']; 1515 1516 // 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" 1517 $sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : ''); 1518 1519 $next_post_id = (int) $row['post_id']; 1520 break; 1521 1522 case 'delete_last_post': 1523 if ($data['topic_type'] != POST_GLOBAL) 1524 { 1525 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; 1526 } 1527 1528 $update_sql = update_post_information('forum', $forum_id, true); 1529 if (sizeof($update_sql)) 1530 { 1531 $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : ''; 1532 $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]); 1533 } 1534 1535 $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' : ''); 1536 1537 $update_sql = update_post_information('topic', $topic_id, true); 1538 if (sizeof($update_sql)) 1539 { 1540 $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]); 1541 $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]); 1542 } 1543 else 1544 { 1545 $sql = 'SELECT MAX(post_id) as last_post_id 1546 FROM ' . POSTS_TABLE . " 1547 WHERE topic_id = $topic_id " . 1548 ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : ''); 1549 $result = $db->sql_query($sql); 1550 $row = $db->sql_fetchrow($result); 1551 $db->sql_freeresult($result); 1552 1553 $next_post_id = (int) $row['last_post_id']; 1554 } 1555 break; 1556 1557 case 'delete': 1558 $sql = 'SELECT post_id 1559 FROM ' . POSTS_TABLE . " 1560 WHERE topic_id = $topic_id " . 1561 ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '') . ' 1562 AND post_time > ' . $data['post_time'] . ' 1563 ORDER BY post_time ASC'; 1564 $result = $db->sql_query_limit($sql, 1); 1565 $row = $db->sql_fetchrow($result); 1566 $db->sql_freeresult($result); 1567 1568 if ($data['topic_type'] != POST_GLOBAL) 1569 { 1570 $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; 1571 } 1572 1573 $sql_data[TOPICS_TABLE] = 'topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : ''); 1574 $next_post_id = (int) $row['post_id']; 1575 break; 1576 } 1577 1578 if (($post_mode == 'delete') || ($post_mode == 'delete_last_post') || ($post_mode == 'delete_first_post')) 1579 { 1580 $sql = 'SELECT 1 AS has_attachments 1581 FROM ' . ATTACHMENTS_TABLE . ' 1582 WHERE topic_id = ' . $topic_id; 1583 $result = $db->sql_query_limit($sql, 1); 1584 $has_attachments = (int) $db->sql_fetchfield('has_attachments'); 1585 $db->sql_freeresult($result); 1586 1587 if (!$has_attachments) 1588 { 1589 $sql_data[TOPICS_TABLE] .= ', topic_attachment = 0'; 1590 } 1591 } 1592 1593 // $sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : ''; 1594 1595 $db->sql_transaction('begin'); 1596 1597 $where_sql = array( 1598 FORUMS_TABLE => "forum_id = $forum_id", 1599 TOPICS_TABLE => "topic_id = $topic_id", 1600 USERS_TABLE => 'user_id = ' . $data['poster_id'] 1601 ); 1602 1603 foreach ($sql_data as $table => $update_sql) 1604 { 1605 if ($update_sql) 1606 { 1607 $db->sql_query("UPDATE $table SET $update_sql WHERE " . $where_sql[$table]); 1608 } 1609 } 1610 1611 // Adjust posted info for this user by looking for a post by him/her within this topic... 1612 if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS) 1613 { 1614 $sql = 'SELECT poster_id 1615 FROM ' . POSTS_TABLE . ' 1616 WHERE topic_id = ' . $topic_id . ' 1617 AND poster_id = ' . $data['poster_id']; 1618 $result = $db->sql_query_limit($sql, 1); 1619 $poster_id = (int) $db->sql_fetchfield('poster_id'); 1620 $db->sql_freeresult($result); 1621 1622 // The user is not having any more posts within this topic 1623 if (!$poster_id) 1624 { 1625 $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . ' 1626 WHERE topic_id = ' . $topic_id . ' 1627 AND user_id = ' . $data['poster_id']; 1628 $db->sql_query($sql); 1629 } 1630 } 1631 1632 $db->sql_transaction('commit'); 1633 1634 if ($data['post_reported'] && ($post_mode != 'delete_topic')) 1635 { 1636 sync('topic_reported', 'topic_id', array($topic_id)); 1637 } 1638 1639 return $next_post_id; 1640 } 1641 1642 /** 1643 * Submit Post 1644 * @todo Split up and create lightweight, simple API for this. 1645 */ 1646 function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true, $update_search_index = true) 1647 { 1648 global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path; 1649 1650 // We do not handle erasing posts here 1651 if ($mode == 'delete') 1652 { 1653 return false; 1654 } 1655 1656 $current_time = time(); 1657 1658 if ($mode == 'post') 1659 { 1660 $post_mode = 'post'; 1661 $update_message = true; 1662 } 1663 else if ($mode != 'edit') 1664 { 1665 $post_mode = 'reply'; 1666 $update_message = true; 1667 } 1668 else if ($mode == 'edit') 1669 { 1670 $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')); 1671 } 1672 1673 // First of all make sure the subject and topic title are having the correct length. 1674 // To achieve this without cutting off between special chars we convert to an array and then count the elements. 1675 $subject = truncate_string($subject); 1676 $data['topic_title'] = truncate_string($data['topic_title']); 1677 1678 // Collect some basic information about which tables and which rows to update/insert 1679 $sql_data = $topic_row = array(); 1680 $poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id']; 1681 1682 // Retrieve some additional information if not present 1683 if ($mode == 'edit' && (!isset($data['post_approved']) || !isset($data['topic_approved']) || $data['post_approved'] === false || $data['topic_approved'] === false)) 1684 { 1685 $sql = 'SELECT p.post_approved, t.topic_type, t.topic_replies, t.topic_replies_real, t.topic_approved 1686 FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p 1687 WHERE t.topic_id = p.topic_id 1688 AND p.post_id = ' . $data['post_id']; 1689 $result = $db->sql_query($sql); 1690 $topic_row = $db->sql_fetchrow($result); 1691 $db->sql_freeresult($result); 1692 1693 $data['topic_approved'] = $topic_row['topic_approved']; 1694 $data['post_approved'] = $topic_row['post_approved']; 1695 } 1696 1697 // This variable indicates if the user is able to post or put into the queue - it is used later for all code decisions regarding approval 1698 // The variable name should be $post_approved, because it indicates if the post is approved or not 1699 $post_approval = 1; 1700 1701 // Check the permissions for post approval. 1702 // Moderators must go through post approval like ordinary users. 1703 if (!$auth->acl_get('f_noapprove', $data['forum_id'])) 1704 { 1705 // Post not approved, but in queue 1706 $post_approval = 0; 1707 } 1708 1709 // Mods are able to force approved/unapproved posts. True means the post is approved, false the post is unapproved 1710 if (isset($data['force_approved_state'])) 1711 { 1712 $post_approval = ($data['force_approved_state']) ? 1 : 0; 1713 } 1714 1715 // Start the transaction here 1716 $db->sql_transaction('begin'); 1717 1718 // Collect Information 1719 switch ($post_mode) 1720 { 1721 case 'post': 1722 case 'reply': 1723 $sql_data[POSTS_TABLE]['sql'] = array( 1724 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], 1725 'poster_id' => (int) $user->data['user_id'], 1726 'icon_id' => $data['icon_id'], 1727 'poster_ip' => $user->ip, 1728 'post_time' => $current_time, 1729 'post_approved' => $post_approval, 1730 'enable_bbcode' => $data['enable_bbcode'], 1731 'enable_smilies' => $data['enable_smilies'], 1732 'enable_magic_url' => $data['enable_urls'], 1733 'enable_sig' => $data['enable_sig'], 1734 'post_username' => (!$user->data['is_registered']) ? $username : '', 1735 'post_subject' => $subject, 1736 'post_text' => $data['message'], 1737 'post_checksum' => $data['message_md5'], 1738 'post_attachment' => (!empty($data['attachment_data'])) ? 1 : 0, 1739 'bbcode_bitfield' => $data['bbcode_bitfield'], 1740 'bbcode_uid' => $data['bbcode_uid'], 1741 'post_postcount' => ($auth->acl_get('f_postcount', $data['forum_id'])) ? 1 : 0, 1742 'post_edit_locked' => $data['post_edit_locked'] 1743 ); 1744 break; 1745 1746 case 'edit_first_post': 1747 case 'edit': 1748 1749 case 'edit_last_post': 1750 case 'edit_topic': 1751 1752 // If edit reason is given always display edit info 1753 1754 // If editing last post then display no edit info 1755 // If m_edit permission then display no edit info 1756 // If normal edit display edit info 1757 1758 // Display edit info if edit reason given or user is editing his post, which is not the last within the topic. 1759 if ($data['post_edit_reason'] || (!$auth->acl_get('m_edit', $data['forum_id']) && ($post_mode == 'edit' || $post_mode == 'edit_first_post'))) 1760 { 1761 $data['post_edit_reason'] = truncate_string($data['post_edit_reason'], 255, 255, false); 1762 1763 $sql_data[POSTS_TABLE]['sql'] = array( 1764 'post_edit_time' => $current_time, 1765 'post_edit_reason' => $data['post_edit_reason'], 1766 'post_edit_user' => (int) $data['post_edit_user'], 1767 ); 1768 1769 $sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1'; 1770 } 1771 else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id'])) 1772 { 1773 $sql_data[POSTS_TABLE]['sql'] = array( 1774 'post_edit_reason' => '', 1775 ); 1776 } 1777 1778 // If the person editing this post is different to the one having posted then we will add a log entry stating the edit 1779 // Could be simplified by only adding to the log if the edit is not tracked - but this may confuse admins/mods 1780 if ($user->data['user_id'] != $poster_id) 1781 { 1782 $log_subject = ($subject) ? $subject : $data['topic_title']; 1783 add_log('mod', $data['forum_id'], $data['topic_id'], 'LOG_POST_EDITED', $log_subject, (!empty($username)) ? $username : $user->lang['GUEST']); 1784 } 1785 1786 if (!isset($sql_data[POSTS_TABLE]['sql'])) 1787 { 1788 $sql_data[POSTS_TABLE]['sql'] = array(); 1789 } 1790 1791 $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array( 1792 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], 1793 'poster_id' => $data['poster_id'], 1794 'icon_id' => $data['icon_id'], 1795 'post_approved' => (!$post_approval) ? 0 : $data['post_approved'], 1796 'enable_bbcode' => $data['enable_bbcode'], 1797 'enable_smilies' => $data['enable_smilies'], 1798 'enable_magic_url' => $data['enable_urls'], 1799 'enable_sig' => $data['enable_sig'], 1800 'post_username' => ($username && $data['poster_id'] == ANONYMOUS) ? $username : '', 1801 'post_subject' => $subject, 1802 'post_checksum' => $data['message_md5'], 1803 'post_attachment' => (!empty($data['attachment_data'])) ? 1 : 0, 1804 'bbcode_bitfield' => $data['bbcode_bitfield'], 1805 'bbcode_uid' => $data['bbcode_uid'], 1806 'post_edit_locked' => $data['post_edit_locked']) 1807 ); 1808 1809 if ($update_message) 1810 { 1811 $sql_data[POSTS_TABLE]['sql']['post_text'] = $data['message']; 1812 } 1813 1814 break; 1815 } 1816 1817 $post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved']; 1818 $topic_row = array(); 1819 1820 // And the topic ladies and gentlemen 1821 switch ($post_mode) 1822 { 1823 case 'post': 1824 $sql_data[TOPICS_TABLE]['sql'] = array( 1825 'topic_poster' => (int) $user->data['user_id'], 1826 'topic_time' => $current_time, 1827 'topic_last_view_time' => $current_time, 1828 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], 1829 'icon_id' => $data['icon_id'], 1830 'topic_approved' => $post_approval, 1831 'topic_title' => $subject, 1832 'topic_first_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''), 1833 'topic_first_poster_colour' => $user->data['user_colour'], 1834 'topic_type' => $topic_type, 1835 'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0, 1836 'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : 0, 1837 ); 1838 1839 if (isset($poll['poll_options']) && !empty($poll['poll_options'])) 1840 { 1841 $poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time; 1842 $poll_length = $poll['poll_length'] * 86400; 1843 if ($poll_length < 0) 1844 { 1845 $poll_start = $poll_start + $poll_length; 1846 if ($poll_start < 0) 1847 { 1848 $poll_start = 0; 1849 } 1850 $poll_length = 1; 1851 } 1852 1853 $sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array( 1854 'poll_title' => $poll['poll_title'], 1855 'poll_start' => $poll_start, 1856 'poll_max_options' => $poll['poll_max_options'], 1857 'poll_length' => $poll_length, 1858 'poll_vote_change' => $poll['poll_vote_change']) 1859 ); 1860 } 1861 1862 $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : ''); 1863 1864 if ($topic_type != POST_GLOBAL) 1865 { 1866 if ($post_approval) 1867 { 1868 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1'; 1869 } 1870 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($post_approval) ? ', forum_topics = forum_topics + 1' : ''); 1871 } 1872 break; 1873 1874 case 'reply': 1875 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_view_time = ' . $current_time . ', 1876 topic_replies_real = topic_replies_real + 1, 1877 topic_bumped = 0, 1878 topic_bumper = 0' . 1879 (($post_approval) ? ', topic_replies = topic_replies + 1' : '') . 1880 ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : ''); 1881 1882 $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : ''); 1883 1884 if ($post_approval && $topic_type != POST_GLOBAL) 1885 { 1886 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1'; 1887 } 1888 break; 1889 1890 case 'edit_topic': 1891 case 'edit_first_post': 1892 if (isset($poll['poll_options'])) 1893 { 1894 $poll_start = ($poll['poll_start'] || empty($poll['poll_options'])) ? $poll['poll_start'] : $current_time; 1895 $poll_length = $poll['poll_length'] * 86400; 1896 if ($poll_length < 0) 1897 { 1898 $poll_start = $poll_start + $poll_length; 1899 if ($poll_start < 0) 1900 { 1901 $poll_start = 0; 1902 } 1903 $poll_length = 1; 1904 } 1905 } 1906 1907 $sql_data[TOPICS_TABLE]['sql'] = array( 1908 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], 1909 'icon_id' => $data['icon_id'], 1910 'topic_approved' => (!$post_approval) ? 0 : $data['topic_approved'], 1911 'topic_title' => $subject, 1912 'topic_first_poster_name' => $username, 1913 'topic_type' => $topic_type, 1914 'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0, 1915 'poll_title' => (isset($poll['poll_options'])) ? $poll['poll_title'] : '', 1916 'poll_start' => (isset($poll['poll_options'])) ? $poll_start : 0, 1917 'poll_max_options' => (isset($poll['poll_options'])) ? $poll['poll_max_options'] : 1, 1918 'poll_length' => (isset($poll['poll_options'])) ? $poll_length : 0, 1919 'poll_vote_change' => (isset($poll['poll_vote_change'])) ? $poll['poll_vote_change'] : 0, 1920 'topic_last_view_time' => $current_time, 1921 1922 'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0), 1923 ); 1924 1925 // Correctly set back the topic replies and forum posts... only if the topic was approved before and now gets disapproved 1926 if (!$post_approval && $data['topic_approved']) 1927 { 1928 // Do we need to grab some topic informations? 1929 if (!sizeof($topic_row)) 1930 { 1931 $sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved 1932 FROM ' . TOPICS_TABLE . ' 1933 WHERE topic_id = ' . $data['topic_id']; 1934 $result = $db->sql_query($sql); 1935 $topic_row = $db->sql_fetchrow($result); 1936 $db->sql_freeresult($result); 1937 } 1938 1939 // If this is the only post remaining we do not need to decrement topic_replies. 1940 // Also do not decrement if first post - then the topic_replies will not be adjusted if approving the topic again. 1941 1942 // If this is an edited topic or the first post the topic gets completely disapproved later on... 1943 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1'; 1944 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1); 1945 1946 set_config_count('num_topics', -1, true); 1947 set_config_count('num_posts', ($topic_row['topic_replies'] + 1) * (-1), true); 1948 1949 // Only decrement this post, since this is the one non-approved now 1950 if ($auth->acl_get('f_postcount', $data['forum_id'])) 1951 { 1952 $sql_data[USERS_TABLE]['stat'][] = 'user_posts = user_posts - 1'; 1953 } 1954 } 1955 1956 break; 1957 1958 case 'edit': 1959 case 'edit_last_post': 1960 1961 // Correctly set back the topic replies and forum posts... but only if the post was approved before. 1962 if (!$post_approval && $data['post_approved']) 1963 { 1964 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1, topic_last_view_time = ' . $current_time; 1965 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1'; 1966 1967 set_config_count('num_posts', -1, true); 1968 1969 if ($auth->acl_get('f_postcount', $data['forum_id'])) 1970 { 1971 $sql_data[USERS_TABLE]['stat'][] = 'user_posts = user_posts - 1'; 1972 } 1973 } 1974 1975 break; 1976 } 1977 1978 // Submit new topic 1979 if ($post_mode == 'post') 1980 { 1981 $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . 1982 $db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']); 1983 $db->sql_query($sql); 1984 1985 $data['topic_id'] = $db->sql_nextid(); 1986 1987 $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array( 1988 'topic_id' => $data['topic_id']) 1989 ); 1990 unset($sql_data[TOPICS_TABLE]['sql']); 1991 } 1992 1993 // Submit new post 1994 if ($post_mode == 'post' || $post_mode == 'reply') 1995 { 1996 if ($post_mode == 'reply') 1997 { 1998 $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array( 1999 'topic_id' => $data['topic_id']) 2000 ); 2001 } 2002 2003 $sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']); 2004 $db->sql_query($sql); 2005 $data['post_id'] = $db->sql_nextid(); 2006 2007 if ($post_mode == 'post') 2008 { 2009 $sql_data[TOPICS_TABLE]['sql'] = array( 2010 'topic_first_post_id' => $data['post_id'], 2011 'topic_last_post_id' => $data['post_id'], 2012 'topic_last_post_time' => $current_time, 2013 'topic_last_poster_id' => (int) $user->data['user_id'], 2014 'topic_last_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''), 2015 'topic_last_poster_colour' => $user->data['user_colour'], 2016 'topic_last_post_subject' => (string) $subject, 2017 ); 2018 } 2019 2020 unset($sql_data[POSTS_TABLE]['sql']); 2021 } 2022 2023 $make_global = false; 2024 2025 // Are we globalising or unglobalising? 2026 if ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic') 2027 { 2028 if (!sizeof($topic_row)) 2029 { 2030 $sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved, topic_last_post_id 2031 FROM ' . TOPICS_TABLE . ' 2032 WHERE topic_id = ' . $data['topic_id']; 2033 $result = $db->sql_query($sql); 2034 $topic_row = $db->sql_fetchrow($result); 2035 $db->sql_freeresult($result); 2036 } 2037 2038 // globalise/unglobalise? 2039 if (($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL) || ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL)) 2040 { 2041 if (!empty($sql_data[FORUMS_TABLE]['stat']) && implode('', $sql_data[FORUMS_TABLE]['stat'])) 2042 { 2043 $db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET ' . implode(', ', $sql_data[FORUMS_TABLE]['stat']) . ' WHERE forum_id = ' . $data['forum_id']); 2044 } 2045 2046 $make_global = true; 2047 $sql_data[FORUMS_TABLE]['stat'] = array(); 2048 } 2049 2050 // globalise 2051 if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL) 2052 { 2053 // Decrement topic/post count 2054 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies_real'] + 1); 2055 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real - 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics - 1' : ''); 2056 2057 // Update forum_ids for all posts 2058 $sql = 'UPDATE ' . POSTS_TABLE . ' 2059 SET forum_id = 0 2060 WHERE topic_id = ' . $data['topic_id']; 2061 $db->sql_query($sql); 2062 } 2063 // unglobalise 2064 else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL) 2065 { 2066 // Increment topic/post count 2067 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + ' . ($topic_row['topic_replies_real'] + 1); 2068 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics + 1' : ''); 2069 2070 // Update forum_ids for all posts 2071 $sql = 'UPDATE ' . POSTS_TABLE . ' 2072 SET forum_id = ' . $data['forum_id'] . ' 2073 WHERE topic_id = ' . $data['topic_id']; 2074 $db->sql_query($sql); 2075 } 2076 } 2077 2078 // Update the topics table 2079 if (isset($sql_data[TOPICS_TABLE]['sql'])) 2080 { 2081 $sql = 'UPDATE ' . TOPICS_TABLE . ' 2082 SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . ' 2083 WHERE topic_id = ' . $data['topic_id']; 2084 $db->sql_query($sql); 2085 } 2086 2087 // Update the posts table 2088 if (isset($sql_data[POSTS_TABLE]['sql'])) 2089 { 2090 $sql = 'UPDATE ' . POSTS_TABLE . ' 2091 SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . ' 2092 WHERE post_id = ' . $data['post_id']; 2093 $db->sql_query($sql); 2094 } 2095 2096 // Update Poll Tables 2097 if (isset($poll['poll_options'])) 2098 { 2099 $cur_poll_options = array(); 2100 2101 if ($mode == 'edit') 2102 { 2103 $sql = 'SELECT * 2104 FROM ' . POLL_OPTIONS_TABLE . ' 2105 WHERE topic_id = ' . $data['topic_id'] . ' 2106 ORDER BY poll_option_id'; 2107 $result = $db->sql_query($sql); 2108 2109 $cur_poll_options = array(); 2110 while ($row = $db->sql_fetchrow($result)) 2111 { 2112 $cur_poll_options[] = $row; 2113 } 2114 $db->sql_freeresult($result); 2115 } 2116 2117 $sql_insert_ary = array(); 2118 2119 for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++) 2120 { 2121 if (strlen(trim($poll['poll_options'][$i]))) 2122 { 2123 if (empty($cur_poll_options[$i])) 2124 { 2125 // If we add options we need to put them to the end to be able to preserve votes... 2126 $sql_insert_ary[] = array( 2127 'poll_option_id' => (int) sizeof($cur_poll_options) + 1 + sizeof($sql_insert_ary), 2128 'topic_id' => (int) $data['topic_id'], 2129 'poll_option_text' => (string) $poll['poll_options'][$i] 2130 ); 2131 } 2132 else if ($poll['poll_options'][$i] != $cur_poll_options[$i]) 2133 { 2134 $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . " 2135 SET poll_option_text = '" . $db->sql_escape($poll['poll_options'][$i]) . "' 2136 WHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . ' 2137 AND topic_id = ' . $data['topic_id']; 2138 $db->sql_query($sql); 2139 } 2140 } 2141 } 2142 2143 $db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary); 2144 2145 if (sizeof($poll['poll_options']) < sizeof($cur_poll_options)) 2146 { 2147 $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . ' 2148 WHERE poll_option_id > ' . sizeof($poll['poll_options']) . ' 2149 AND topic_id = ' . $data['topic_id']; 2150 $db->sql_query($sql); 2151 } 2152 2153 // 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 2154 if ($mode == 'edit' && sizeof($poll['poll_options']) != sizeof($cur_poll_options)) 2155 { 2156 $db->sql_query('DELETE FROM ' . POLL_VOTES_TABLE . ' WHERE topic_id = ' . $data['topic_id']); 2157 $db->sql_query('UPDATE ' . POLL_OPTIONS_TABLE . ' SET poll_option_total = 0 WHERE topic_id = ' . $data['topic_id']); 2158 } 2159 } 2160 2161 // Submit Attachments 2162 if (!empty($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit'))) 2163 { 2164 $space_taken = $files_added = 0; 2165 $orphan_rows = array(); 2166 2167 foreach ($data['attachment_data'] as $pos => $attach_row) 2168 { 2169 $orphan_rows[(int) $attach_row['attach_id']] = array(); 2170 } 2171 2172 if (sizeof($orphan_rows)) 2173 { 2174 $sql = 'SELECT attach_id, filesize, physical_filename 2175 FROM ' . ATTACHMENTS_TABLE . ' 2176 WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . ' 2177 AND is_orphan = 1 2178 AND poster_id = ' . $user->data['user_id']; 2179 $result = $db->sql_query($sql); 2180 2181 $orphan_rows = array(); 2182 while ($row = $db->sql_fetchrow($result)) 2183 { 2184 $orphan_rows[$row['attach_id']] = $row; 2185 } 2186 $db->sql_freeresult($result); 2187 } 2188 2189 foreach ($data['attachment_data'] as $pos => $attach_row) 2190 { 2191 if ($attach_row['is_orphan'] && !isset($orphan_rows[$attach_row['attach_id']])) 2192 { 2193 continue; 2194 } 2195 2196 if (!$attach_row['is_orphan']) 2197 { 2198 // update entry in db if attachment already stored in db and filespace 2199 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . " 2200 SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "' 2201 WHERE attach_id = " . (int) $attach_row['attach_id'] . ' 2202 AND is_orphan = 0'; 2203 $db->sql_query($sql); 2204 } 2205 else 2206 { 2207 // insert attachment into db 2208 if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename']))) 2209 { 2210 continue; 2211 } 2212 2213 $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize']; 2214 $files_added++; 2215 2216 $attach_sql = array( 2217 'post_msg_id' => $data['post_id'], 2218 'topic_id' => $data['topic_id'], 2219 'is_orphan' => 0, 2220 'poster_id' => $poster_id, 2221 'attach_comment' => $attach_row['attach_comment'], 2222 ); 2223 2224 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . ' 2225 WHERE attach_id = ' . $attach_row['attach_id'] . ' 2226 AND is_orphan = 1 2227 AND poster_id = ' . $user->data['user_id']; 2228 $db->sql_query($sql); 2229 } 2230 } 2231 2232 if ($space_taken && $files_added) 2233 { 2234 set_config_count('upload_dir_size', $space_taken, true); 2235 set_config_count('num_files', $files_added, true); 2236 } 2237 } 2238 2239 // we need to update the last forum information 2240 // only applicable if the topic is not global and it is approved 2241 // we also check to make sure we are not dealing with globaling the latest topic (pretty rare but still needs to be checked) 2242 if ($topic_type != POST_GLOBAL && !$make_global && ($post_approved || !$data['post_approved'])) 2243 { 2244 // the last post makes us update the forum table. This can happen if... 2245 // We make a new topic 2246 // We reply to a topic 2247 // We edit the last post in a topic and this post is the latest in the forum (maybe) 2248 // We edit the only post in the topic 2249 // We edit the first post in the topic and all the other posts are not approved 2250 if (($post_mode == 'post' || $post_mode == 'reply') && $post_approved) 2251 { 2252 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id']; 2253 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'"; 2254 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time; 2255 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id']; 2256 $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'] : '')) . "'"; 2257 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'"; 2258 } 2259 else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])) 2260 { 2261 // this does not _necessarily_ mean that we must update the info again, 2262 // it just means that we might have to 2263 $sql = 'SELECT forum_last_post_id, forum_last_post_subject 2264 FROM ' . FORUMS_TABLE . ' 2265 WHERE forum_id = ' . (int) $data['forum_id']; 2266 $result = $db->sql_query($sql); 2267 $row = $db->sql_fetchrow($result); 2268 $db->sql_freeresult($result); 2269 2270 // this post is the latest post in the forum, better update 2271 if ($row['forum_last_post_id'] == $data['post_id']) 2272 { 2273 // If post approved and subject changed, or poster is anonymous, we need to update the forum_last* rows 2274 if ($post_approved && ($row['forum_last_post_subject'] !== $subject || $data['poster_id'] == ANONYMOUS)) 2275 { 2276 // the post's subject changed 2277 if ($row['forum_last_post_subject'] !== $subject) 2278 { 2279 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_subject = \'' . $db->sql_escape($subject) . '\''; 2280 } 2281 2282 // Update the user name if poster is anonymous... just in case an admin changed it 2283 if ($data['poster_id'] == ANONYMOUS) 2284 { 2285 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape($username) . "'"; 2286 } 2287 } 2288 else if ($data['post_approved'] !== $post_approved) 2289 { 2290 // we need a fresh change of socks, everything has become invalidated 2291 $sql = 'SELECT MAX(topic_last_post_id) as last_post_id 2292 FROM ' . TOPICS_TABLE . ' 2293 WHERE forum_id = ' . (int) $data['forum_id'] . ' 2294 AND topic_approved = 1'; 2295 $result = $db->sql_query($sql); 2296 $row = $db->sql_fetchrow($result); 2297 $db->sql_freeresult($result); 2298 2299 // any posts left in this forum? 2300 if (!empty($row['last_post_id'])) 2301 { 2302 $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 2303 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u 2304 WHERE p.poster_id = u.user_id 2305 AND p.post_id = ' . (int) $row['last_post_id']; 2306 $result = $db->sql_query($sql); 2307 $row = $db->sql_fetchrow($result); 2308 $db->sql_freeresult($result); 2309 2310 // salvation, a post is found! jam it into the forums table 2311 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id']; 2312 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; 2313 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time']; 2314 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id']; 2315 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; 2316 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; 2317 } 2318 else 2319 { 2320 // just our luck, the last topic in the forum has just been turned unapproved... 2321 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0'; 2322 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''"; 2323 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0'; 2324 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0'; 2325 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''"; 2326 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''"; 2327 } 2328 } 2329 } 2330 } 2331 } 2332 else if ($make_global) 2333 { 2334 // somebody decided to be a party pooper, we must recalculate the whole shebang (maybe) 2335 $sql = 'SELECT forum_last_post_id 2336 FROM ' . FORUMS_TABLE . ' 2337 WHERE forum_id = ' . (int) $data['forum_id']; 2338 $result = $db->sql_query($sql); 2339 $forum_row = $db->sql_fetchrow($result); 2340 $db->sql_freeresult($result); 2341 2342 // we made a topic global, go get new data 2343 if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL && $forum_row['forum_last_post_id'] == $topic_row['topic_last_post_id']) 2344 { 2345 // we need a fresh change of socks, everything has become invalidated 2346 $sql = 'SELECT MAX(topic_last_post_id) as last_post_id 2347 FROM ' . TOPICS_TABLE . ' 2348 WHERE forum_id = ' . (int) $data['forum_id'] . ' 2349 AND topic_approved = 1'; 2350 $result = $db->sql_query($sql); 2351 $row = $db->sql_fetchrow($result); 2352 $db->sql_freeresult($result); 2353 2354 // any posts left in this forum? 2355 if (!empty($row['last_post_id'])) 2356 { 2357 $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 2358 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u 2359 WHERE p.poster_id = u.user_id 2360 AND p.post_id = ' . (int) $row['last_post_id']; 2361 $result = $db->sql_query($sql); 2362 $row = $db->sql_fetchrow($result); 2363 $db->sql_freeresult($result); 2364 2365 // salvation, a post is found! jam it into the forums table 2366 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id']; 2367 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; 2368 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time']; 2369 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id']; 2370 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; 2371 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; 2372 } 2373 else 2374 { 2375 // just our luck, the last topic in the forum has just been globalized... 2376 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0'; 2377 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''"; 2378 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0'; 2379 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0'; 2380 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''"; 2381 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''"; 2382 } 2383 } 2384 else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL && $forum_row['forum_last_post_id'] < $topic_row['topic_last_post_id']) 2385 { 2386 // this post has a higher id, it is newer 2387 $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 2388 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u 2389 WHERE p.poster_id = u.user_id 2390 AND p.post_id = ' . (int) $topic_row['topic_last_post_id']; 2391 $result = $db->sql_query($sql); 2392 $row = $db->sql_fetchrow($result); 2393 $db->sql_freeresult($result); 2394 2395 // salvation, a post is found! jam it into the forums table 2396 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id']; 2397 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; 2398 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time']; 2399 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id']; 2400 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; 2401 $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; 2402 } 2403 } 2404 2405 // topic sync time! 2406 // simply, we update if it is a reply or the last post is edited 2407 if ($post_approved) 2408 { 2409 // reply requires the whole thing 2410 if ($post_mode == 'reply') 2411 { 2412 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $data['post_id']; 2413 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $user->data['user_id']; 2414 $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'] : '')) . "'"; 2415 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . (($user->data['user_id'] != ANONYMOUS) ? $db->sql_escape($user->data['user_colour']) : '') . "'"; 2416 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'"; 2417 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $current_time; 2418 } 2419 else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])) 2420 { 2421 // only the subject can be changed from edit 2422 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'"; 2423 2424 // Maybe not only the subject, but also changing anonymous usernames. ;) 2425 if ($data['poster_id'] == ANONYMOUS) 2426 { 2427 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape($username) . "'"; 2428 } 2429 } 2430 } 2431 else if (!$data['post_approved'] && ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))) 2432 { 2433 // like having the rug pulled from under us 2434 $sql = 'SELECT MAX(post_id) as last_post_id 2435 FROM ' . POSTS_TABLE . ' 2436 WHERE topic_id = ' . (int) $data['topic_id'] . ' 2437 AND post_approved = 1'; 2438 $result = $db->sql_query($sql); 2439 $row = $db->sql_fetchrow($result); 2440 $db->sql_freeresult($result); 2441 2442 // any posts left in this forum? 2443 if (!empty($row['last_post_id'])) 2444 { 2445 $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 2446 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u 2447 WHERE p.poster_id = u.user_id 2448 AND p.post_id = ' . (int) $row['last_post_id']; 2449 $result = $db->sql_query($sql); 2450 $row = $db->sql_fetchrow($result); 2451 $db->sql_freeresult($result); 2452 2453 // salvation, a post is found! jam it into the topics table 2454 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $row['post_id']; 2455 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; 2456 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $row['post_time']; 2457 $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $row['poster_id']; 2458 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; 2459 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; 2460 } 2461 } 2462 2463 // Update total post count, do not consider moderated posts/topics 2464 if ($post_approval) 2465 { 2466 if ($post_mode == 'post') 2467 { 2468 set_config_count('num_topics', 1, true); 2469 set_config_count('num_posts', 1, true); 2470 } 2471 2472 if ($post_mode == 'reply') 2473 { 2474 set_config_count('num_posts', 1, true); 2475 } 2476 } 2477 2478 // Update forum stats 2479 $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 = ' . $poster_id); 2480 2481 foreach ($sql_data as $table => $update_ary) 2482 { 2483 if (isset($update_ary['stat']) && implode('', $update_ary['stat'])) 2484 { 2485 $sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table]; 2486 $db->sql_query($sql); 2487 } 2488 } 2489 2490 // Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement 2491 if ($make_global) 2492 { 2493 $sql = 'DELETE FROM ' . TOPICS_TABLE . ' 2494 WHERE topic_moved_id = ' . $data['topic_id']; 2495 $db->sql_query($sql); 2496 } 2497 2498 // Committing the transaction before updating search index 2499 $db->sql_transaction('commit'); 2500 2501 // Delete draft if post was loaded... 2502 $draft_id = request_var('draft_loaded', 0); 2503 if ($draft_id) 2504 { 2505 $sql = 'DELETE FROM ' . DRAFTS_TABLE . " 2506 WHERE draft_id = $draft_id 2507 AND user_id = {$user->data['user_id']}"; 2508 $db->sql_query($sql); 2509 } 2510 2511 // Index message contents 2512 if ($update_search_index && $data['enable_indexing']) 2513 { 2514 // Select the search method and do some additional checks to ensure it can actually be utilised 2515 $search_type = basename($config['search_type']); 2516 2517 if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) 2518 { 2519 trigger_error('NO_SUCH_SEARCH_MODULE'); 2520 } 2521 2522 if (!class_exists($search_type)) 2523 { 2524 include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); 2525 } 2526 2527 $error = false; 2528 $search = new $search_type($error); 2529 2530 if ($error) 2531 { 2532 trigger_error($error); 2533 } 2534 2535 $search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']); 2536 } 2537 2538 // Topic Notification, do not change if moderator is changing other users posts... 2539 if ($user->data['user_id'] == $poster_id) 2540 { 2541 if (!$data['notify_set'] && $data['notify']) 2542 { 2543 $sql = 'INSERT INTO ' . TOPICS_WATCH_TABLE . ' (user_id, topic_id) 2544 VALUES (' . $user->data['user_id'] . ', ' . $data['topic_id'] . ')'; 2545 $db->sql_query($sql); 2546 } 2547 else if (($config['email_enable'] || $config['jab_enable']) && $data['notify_set'] && !$data['notify']) 2548 { 2549 $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . ' 2550 WHERE user_id = ' . $user->data['user_id'] . ' 2551 AND topic_id = ' . $data['topic_id']; 2552 $db->sql_query($sql); 2553 } 2554 } 2555 2556 if ($mode == 'post' || $mode == 'reply' || $mode == 'quote') 2557 { 2558 // Mark this topic as posted to 2559 markread('post', $data['forum_id'], $data['topic_id']); 2560 } 2561 2562 // Mark this topic as read 2563 // We do not use post_time here, this is intended (post_time can have a date in the past if editing a message) 2564 markread('topic', (($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']), $data['topic_id'], time()); 2565 2566 // 2567 if ($config['load_db_lastread'] && $user->data['is_registered']) 2568 { 2569 $sql = 'SELECT mark_time 2570 FROM ' . FORUMS_TRACK_TABLE . ' 2571 WHERE user_id = ' . $user->data['user_id'] . ' 2572 AND forum_id = ' . (($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']); 2573 $result = $db->sql_query($sql); 2574 $f_mark_time = (int) $db->sql_fetchfield('mark_time'); 2575 $db->sql_freeresult($result); 2576 } 2577 else if ($config['load_anon_lastread'] || $user->data['is_registered']) 2578 { 2579 $f_mark_time = false; 2580 } 2581 2582 if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered']) 2583 { 2584 // Update forum info 2585 if ($topic_type == POST_GLOBAL) 2586 { 2587 $sql = 'SELECT MAX(topic_last_post_time) as forum_last_post_time 2588 FROM ' . TOPICS_TABLE . ' 2589 WHERE forum_id = 0'; 2590 } 2591 else 2592 { 2593 $sql = 'SELECT forum_last_post_time 2594 FROM ' . FORUMS_TABLE . ' 2595 WHERE forum_id = ' . $data['forum_id']; 2596 } 2597 $result = $db->sql_query($sql); 2598 $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time'); 2599 $db->sql_freeresult($result); 2600 2601 update_forum_tracking_info((($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']), $forum_last_post_time, $f_mark_time, false); 2602 } 2603 2604 // Send Notifications 2605 if (($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_approval) 2606 { 2607 // If a username was supplied or the poster is a guest, we will use the supplied username. 2608 // Doing it this way we can use "...post by guest-username..." in notifications when 2609 // "guest-username" is supplied or ommit the username if it is not. 2610 $username = ($username !== '' || !$user->data['is_registered']) ? $username : $user->data['username']; 2611 user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id'], $username); 2612 } 2613 2614 $params = $add_anchor = ''; 2615 2616 if ($post_approval) 2617 { 2618 $params .= '&t=' . $data['topic_id']; 2619 2620 if ($mode != 'post') 2621 { 2622 $params .= '&p=' . $data['post_id']; 2623 $add_anchor = '#p' . $data['post_id']; 2624 } 2625 } 2626 else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic') 2627 { 2628 $params .= '&t=' . $data['topic_id']; 2629 } 2630 2631 $url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx"; 2632 $url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor; 2633 2634 return $url; 2635 } 2636 2637 /** 2638 * Handle topic bumping 2639 * @param int $forum_id The ID of the forum the topic is being bumped belongs to 2640 * @param int $topic_id The ID of the topic is being bumping 2641 * @param array $post_data Passes some topic parameters: 2642 * - 'topic_title' 2643 * - 'topic_last_post_id' 2644 * - 'topic_last_poster_id' 2645 * - 'topic_last_post_subject' 2646 * - 'topic_last_poster_name' 2647 * - 'topic_last_poster_colour' 2648 * @param int $bump_time The time at which topic was bumped, usually it is a current time as obtained via time(). 2649 * @return string An URL to the bumped topic, example: ./viewtopic.php?forum_id=1&topic_id=2&p=3#p3 2650 */ 2651 function phpbb_bump_topic($forum_id, $topic_id, $post_data, $bump_time = false) 2652 { 2653 global $config, $db, $user, $phpEx, $phpbb_root_path; 2654 2655 if ($bump_time === false) 2656 { 2657 $bump_time = time(); 2658 } 2659 2660 // Begin bumping 2661 $db->sql_transaction('begin'); 2662 2663 // Update the topic's last post post_time 2664 $sql = 'UPDATE ' . POSTS_TABLE . " 2665 SET post_time = $bump_time 2666 WHERE post_id = {$post_data['topic_last_post_id']} 2667 AND topic_id = $topic_id"; 2668 $db->sql_query($sql); 2669 2670 // Sync the topic's last post time, the rest of the topic's last post data isn't changed 2671 $sql = 'UPDATE ' . TOPICS_TABLE . " 2672 SET topic_last_post_time = $bump_time, 2673 topic_bumped = 1, 2674 topic_bumper = " . $user->data['user_id'] . " 2675 WHERE topic_id = $topic_id"; 2676 $db->sql_query($sql); 2677 2678 // Update the forum's last post info 2679 $sql = 'UPDATE ' . FORUMS_TABLE . " 2680 SET forum_last_post_id = " . $post_data['topic_last_post_id'] . ", 2681 forum_last_poster_id = " . $post_data['topic_last_poster_id'] . ", 2682 forum_last_post_subject = '" . $db->sql_escape($post_data['topic_last_post_subject']) . "', 2683 forum_last_post_time = $bump_time, 2684 forum_last_poster_name = '" . $db->sql_escape($post_data['topic_last_poster_name']) . "', 2685 forum_last_poster_colour = '" . $db->sql_escape($post_data['topic_last_poster_colour']) . "' 2686 WHERE forum_id = $forum_id"; 2687 $db->sql_query($sql); 2688 2689 // Update bumper's time of the last posting to prevent flood 2690 $sql = 'UPDATE ' . USERS_TABLE . " 2691 SET user_lastpost_time = $bump_time 2692 WHERE user_id = " . $user->data['user_id']; 2693 $db->sql_query($sql); 2694 2695 $db->sql_transaction('commit'); 2696 2697 // Mark this topic as posted to 2698 markread('post', $forum_id, $topic_id, $bump_time); 2699 2700 // Mark this topic as read 2701 markread('topic', $forum_id, $topic_id, $bump_time); 2702 2703 // Update forum tracking info 2704 if ($config['load_db_lastread'] && $user->data['is_registered']) 2705 { 2706 $sql = 'SELECT mark_time 2707 FROM ' . FORUMS_TRACK_TABLE . ' 2708 WHERE user_id = ' . $user->data['user_id'] . ' 2709 AND forum_id = ' . $forum_id; 2710 $result = $db->sql_query($sql); 2711 $f_mark_time = (int) $db->sql_fetchfield('mark_time'); 2712 $db->sql_freeresult($result); 2713 } 2714 else if ($config['load_anon_lastread'] || $user->data['is_registered']) 2715 { 2716 $f_mark_time = false; 2717 } 2718 2719 if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered']) 2720 { 2721 // Update forum info 2722 $sql = 'SELECT forum_last_post_time 2723 FROM ' . FORUMS_TABLE . ' 2724 WHERE forum_id = ' . $forum_id; 2725 $result = $db->sql_query($sql); 2726 $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time'); 2727 $db->sql_freeresult($result); 2728 2729 update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time, false); 2730 } 2731 2732 add_log('mod', $forum_id, $topic_id, 'LOG_BUMP_TOPIC', $post_data['topic_title']); 2733 2734 $url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p={$post_data['topic_last_post_id']}") . "#p{$post_data['topic_last_post_id']}"; 2735 2736 return $url; 2737 } 2738 2739 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 2 15:03:47 2013 | Cross-referenced by PHPXref 0.7.1 |