[ Index ] |
PHP Cross Reference of phpBB-3.3.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 /** 15 * @ignore 16 */ 17 define('IN_PHPBB', true); 18 $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; 19 $phpEx = substr(strrchr(__FILE__, '.'), 1); 20 include($phpbb_root_path . 'common.' . $phpEx); 21 include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); 22 include($phpbb_root_path . 'includes/functions_display.' . $phpEx); 23 include($phpbb_root_path . 'includes/message_parser.' . $phpEx); 24 25 26 // Start session management 27 $user->session_begin(); 28 $auth->acl($user->data); 29 30 31 // Grab only parameters needed here 32 $draft_id = $request->variable('d', 0); 33 34 $preview = (isset($_POST['preview'])) ? true : false; 35 $save = (isset($_POST['save'])) ? true : false; 36 $load = (isset($_POST['load'])) ? true : false; 37 $confirm = $request->is_set_post('confirm'); 38 $cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false; 39 40 $refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load || $preview); 41 $submit = $request->is_set_post('post') && !$refresh && !$preview; 42 $mode = $request->variable('mode', ''); 43 44 // Only assign required URL parameters 45 $forum_id = 0; 46 $topic_id = 0; 47 $post_id = 0; 48 49 switch ($mode) 50 { 51 case 'popup': 52 case 'smilies': 53 $forum_id = $request->variable('f', 0); 54 break; 55 56 case 'post': 57 $forum_id = $request->variable('f', 0); 58 if (!$forum_id) 59 { 60 trigger_error('NO_FORUM'); 61 } 62 break; 63 64 case 'bump': 65 case 'reply': 66 $topic_id = $request->variable('t', 0); 67 if ($topic_id) 68 { 69 $sql = 'SELECT forum_id 70 FROM ' . TOPICS_TABLE . " 71 WHERE topic_id = $topic_id"; 72 $result = $db->sql_query($sql); 73 $forum_id = (int) $db->sql_fetchfield('forum_id'); 74 $db->sql_freeresult($result); 75 } 76 77 if (!$topic_id || !$forum_id) 78 { 79 trigger_error('NO_TOPIC'); 80 } 81 break; 82 83 case 'edit': 84 case 'delete': 85 case 'quote': 86 case 'soft_delete': 87 $post_id = $request->variable('p', 0); 88 if ($post_id) 89 { 90 $topic_forum = []; 91 92 $sql = 'SELECT t.topic_id, t.forum_id 93 FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p 94 WHERE p.post_id = ' . $post_id . ' 95 AND t.topic_id = p.topic_id'; 96 $result = $db->sql_query($sql); 97 $topic_forum = $db->sql_fetchrow($result); 98 $db->sql_freeresult($result); 99 } 100 101 if (!$post_id || !$topic_forum) 102 { 103 $user->setup('posting'); 104 trigger_error('NO_POST'); 105 } 106 107 $topic_id = (int) $topic_forum['topic_id']; 108 $forum_id = (int) $topic_forum['forum_id']; 109 break; 110 } 111 112 // If the user is not allowed to delete the post, we try to soft delete it, so we overwrite the mode here. 113 if ($mode == 'delete' && (($confirm && !$request->is_set_post('delete_permanent')) || !$auth->acl_gets('f_delete', 'm_delete', $forum_id))) 114 { 115 $mode = 'soft_delete'; 116 } 117 118 $error = $post_data = array(); 119 $current_time = time(); 120 121 /** 122 * This event allows you to alter the above parameters, such as submit and mode 123 * 124 * Note: $refresh must be true to retain previously submitted form data. 125 * 126 * Note: The template class will not work properly until $user->setup() is 127 * called, and it has not been called yet. Extensions requiring template 128 * assignments should use an event that comes later in this file. 129 * 130 * @event core.modify_posting_parameters 131 * @var int post_id ID of the post 132 * @var int topic_id ID of the topic 133 * @var int forum_id ID of the forum 134 * @var int draft_id ID of the draft 135 * @var bool submit Whether or not the form has been submitted 136 * @var bool preview Whether or not the post is being previewed 137 * @var bool save Whether or not a draft is being saved 138 * @var bool load Whether or not a draft is being loaded 139 * @var bool cancel Whether or not to cancel the form (returns to 140 * viewtopic or viewforum depending on if the user 141 * is posting a new topic or editing a post) 142 * @var bool refresh Whether or not to retain previously submitted data 143 * @var string mode What action to take if the form has been submitted 144 * post|reply|quote|edit|delete|bump|smilies|popup 145 * @var array error Any error strings; a non-empty array aborts 146 * form submission. 147 * NOTE: Should be actual language strings, NOT 148 * language keys. 149 * @since 3.1.0-a1 150 * @changed 3.1.2-RC1 Removed 'delete' var as it does not exist 151 * @changed 3.2.4-RC1 Remove unused 'lastclick' var 152 */ 153 $vars = array( 154 'post_id', 155 'topic_id', 156 'forum_id', 157 'draft_id', 158 'submit', 159 'preview', 160 'save', 161 'load', 162 'cancel', 163 'refresh', 164 'mode', 165 'error', 166 ); 167 extract($phpbb_dispatcher->trigger_event('core.modify_posting_parameters', compact($vars))); 168 169 // Was cancel pressed? If so then redirect to the appropriate page 170 if ($cancel) 171 { 172 $redirect = ($post_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $post_id) . '#p' . $post_id : (($topic_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id) : (($forum_id) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) : append_sid("{$phpbb_root_path}index.$phpEx"))); 173 redirect($redirect); 174 } 175 176 /* @var $phpbb_content_visibility \phpbb\content_visibility */ 177 $phpbb_content_visibility = $phpbb_container->get('content.visibility'); 178 179 // We need to know some basic information in all cases before we do anything. 180 switch ($mode) 181 { 182 case 'post': 183 $sql = 'SELECT * 184 FROM ' . FORUMS_TABLE . " 185 WHERE forum_id = $forum_id"; 186 break; 187 188 case 'bump': 189 case 'reply': 190 $sql = 'SELECT f.*, t.* 191 FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f 192 WHERE t.topic_id = $topic_id 193 AND f.forum_id = t.forum_id 194 AND " . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'); 195 break; 196 197 case 'quote': 198 case 'edit': 199 case 'delete': 200 case 'soft_delete': 201 $sql = 'SELECT f.*, t.*, p.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_sig_bbcode_bitfield 202 FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . ' f, ' . USERS_TABLE . " u 203 WHERE p.post_id = $post_id 204 AND t.topic_id = p.topic_id 205 AND u.user_id = p.poster_id 206 AND f.forum_id = t.forum_id 207 AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.'); 208 break; 209 210 case 'smilies': 211 $sql = ''; 212 generate_smilies('window', $forum_id); 213 break; 214 215 case 'popup': 216 if ($forum_id) 217 { 218 $sql = 'SELECT forum_style 219 FROM ' . FORUMS_TABLE . ' 220 WHERE forum_id = ' . $forum_id; 221 } 222 else 223 { 224 phpbb_upload_popup(); 225 return; 226 } 227 break; 228 229 default: 230 $sql = ''; 231 break; 232 } 233 234 if (!$sql) 235 { 236 $user->setup('posting'); 237 trigger_error('NO_POST_MODE'); 238 } 239 240 $result = $db->sql_query($sql); 241 $post_data = $db->sql_fetchrow($result); 242 $db->sql_freeresult($result); 243 244 if (!$post_data) 245 { 246 if (!($mode == 'post' || $mode == 'bump' || $mode == 'reply')) 247 { 248 $user->setup('posting'); 249 } 250 trigger_error(($mode == 'post' || $mode == 'bump' || $mode == 'reply') ? 'NO_TOPIC' : 'NO_POST'); 251 } 252 253 /** 254 * This event allows you to bypass reply/quote test of an unapproved post. 255 * 256 * @event core.posting_modify_row_data 257 * @var array post_data All post data from database 258 * @var string mode What action to take if the form has been submitted 259 * post|reply|quote|edit|delete|bump|smilies|popup 260 * @var int topic_id ID of the topic 261 * @var int forum_id ID of the forum 262 * @since 3.2.8-RC1 263 */ 264 $vars = array( 265 'post_data', 266 'mode', 267 'topic_id', 268 'forum_id', 269 ); 270 extract($phpbb_dispatcher->trigger_event('core.posting_modify_row_data', compact($vars))); 271 272 // Not able to reply to unapproved posts/topics 273 // TODO: add more descriptive language key 274 if ($auth->acl_get('m_approve', $forum_id) && ((($mode == 'reply' || $mode == 'bump') && $post_data['topic_visibility'] != ITEM_APPROVED) || ($mode == 'quote' && $post_data['post_visibility'] != ITEM_APPROVED))) 275 { 276 trigger_error(($mode == 'reply' || $mode == 'bump') ? 'TOPIC_UNAPPROVED' : 'POST_UNAPPROVED'); 277 } 278 279 if ($mode == 'popup') 280 { 281 phpbb_upload_popup($post_data['forum_style']); 282 return; 283 } 284 285 $user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']); 286 287 // Need to login to passworded forum first? 288 if ($post_data['forum_password']) 289 { 290 login_forum_box(array( 291 'forum_id' => $forum_id, 292 'forum_name' => $post_data['forum_name'], 293 'forum_password' => $post_data['forum_password']) 294 ); 295 } 296 297 // Check permissions 298 if ($user->data['is_bot']) 299 { 300 redirect(append_sid("{$phpbb_root_path}index.$phpEx")); 301 } 302 303 // Is the user able to read within this forum? 304 if (!$auth->acl_get('f_read', $forum_id)) 305 { 306 if ($user->data['user_id'] != ANONYMOUS) 307 { 308 trigger_error('USER_CANNOT_READ'); 309 } 310 $message = $user->lang['LOGIN_EXPLAIN_POST']; 311 312 if ($request->is_ajax()) 313 { 314 $json = new phpbb\json_response(); 315 $json->send(array( 316 'title' => $user->lang['INFORMATION'], 317 'message' => $message, 318 )); 319 } 320 321 login_box('', $message); 322 } 323 324 // Permission to do the action asked? 325 $is_authed = false; 326 327 switch ($mode) 328 { 329 case 'post': 330 if ($auth->acl_get('f_post', $forum_id)) 331 { 332 $is_authed = true; 333 } 334 break; 335 336 case 'bump': 337 if ($auth->acl_get('f_bump', $forum_id)) 338 { 339 $is_authed = true; 340 } 341 break; 342 343 case 'quote': 344 345 $post_data['post_edit_locked'] = 0; 346 347 // no break; 348 349 case 'reply': 350 if ($auth->acl_get('f_reply', $forum_id)) 351 { 352 $is_authed = true; 353 } 354 break; 355 356 case 'edit': 357 if ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id)) 358 { 359 $is_authed = true; 360 } 361 break; 362 363 case 'delete': 364 if ($user->data['is_registered'] && ($auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)))) 365 { 366 $is_authed = true; 367 } 368 369 // no break; 370 371 case 'soft_delete': 372 if (!$is_authed && $user->data['is_registered'] && $phpbb_content_visibility->can_soft_delete($forum_id, $post_data['poster_id'], $post_data['post_edit_locked'])) 373 { 374 // Fall back to soft_delete if we have no permissions to delete posts but to soft delete them 375 $is_authed = true; 376 $mode = 'soft_delete'; 377 } 378 break; 379 } 380 /** 381 * This event allows you to do extra auth checks and verify if the user 382 * has the required permissions 383 * 384 * Extensions should only change the error and is_authed variables. 385 * 386 * @event core.modify_posting_auth 387 * @var int post_id ID of the post 388 * @var int topic_id ID of the topic 389 * @var int forum_id ID of the forum 390 * @var int draft_id ID of the draft 391 * @var bool submit Whether or not the form has been submitted 392 * @var bool preview Whether or not the post is being previewed 393 * @var bool save Whether or not a draft is being saved 394 * @var bool load Whether or not a draft is being loaded 395 * @var bool refresh Whether or not to retain previously submitted data 396 * @var string mode What action to take if the form has been submitted 397 * post|reply|quote|edit|delete|bump|smilies|popup 398 * @var array error Any error strings; a non-empty array aborts 399 * form submission. 400 * NOTE: Should be actual language strings, NOT 401 * language keys. 402 * @var bool is_authed Does the user have the required permissions? 403 * @var array post_data All post data from database 404 * @since 3.1.3-RC1 405 * @changed 3.1.10-RC1 Added post_data 406 * @changed 3.2.4-RC1 Remove unused 'lastclick' var 407 */ 408 $vars = array( 409 'post_id', 410 'topic_id', 411 'forum_id', 412 'draft_id', 413 'submit', 414 'preview', 415 'save', 416 'load', 417 'refresh', 418 'mode', 419 'error', 420 'is_authed', 421 'post_data', 422 ); 423 extract($phpbb_dispatcher->trigger_event('core.modify_posting_auth', compact($vars))); 424 425 if (!$is_authed || !empty($error)) 426 { 427 $check_auth = ($mode == 'quote') ? 'reply' : (($mode == 'soft_delete') ? 'delete' : $mode); 428 429 if ($user->data['is_registered']) 430 { 431 trigger_error(empty($error) ? 'USER_CANNOT_' . strtoupper($check_auth) : implode('<br/>', $error)); 432 } 433 $message = $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)]; 434 435 if ($request->is_ajax()) 436 { 437 $json = new phpbb\json_response(); 438 $json->send(array( 439 'title' => $user->lang['INFORMATION'], 440 'message' => $message, 441 )); 442 } 443 444 login_box('', $message); 445 } 446 447 if ($config['enable_post_confirm'] && !$user->data['is_registered']) 448 { 449 $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']); 450 $captcha->init(CONFIRM_POST); 451 } 452 453 // Is the user able to post within this forum? 454 if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply'))) 455 { 456 trigger_error('USER_CANNOT_FORUM_POST'); 457 } 458 459 // Forum/Topic locked? 460 if (($post_data['forum_status'] == ITEM_LOCKED || (isset($post_data['topic_status']) && $post_data['topic_status'] == ITEM_LOCKED)) && !$auth->acl_get($mode == 'reply' ? 'm_lock' : 'm_edit', $forum_id)) 461 { 462 trigger_error(($post_data['forum_status'] == ITEM_LOCKED) ? 'FORUM_LOCKED' : 'TOPIC_LOCKED'); 463 } 464 465 // Can we edit this post ... if we're a moderator with rights then always yes 466 // else it depends on editing times, lock status and if we're the correct user 467 if ($mode == 'edit' && !$auth->acl_get('m_edit', $forum_id)) 468 { 469 $force_edit_allowed = false; 470 471 $s_cannot_edit = $user->data['user_id'] != $post_data['poster_id']; 472 $s_cannot_edit_time = $config['edit_time'] && $post_data['post_time'] <= time() - ($config['edit_time'] * 60); 473 $s_cannot_edit_locked = $post_data['post_edit_locked']; 474 475 /** 476 * This event allows you to modify the conditions for the "cannot edit post" checks 477 * 478 * @event core.posting_modify_cannot_edit_conditions 479 * @var array post_data Array with post data 480 * @var bool force_edit_allowed Allow the user to edit the post (all permissions and conditions are ignored) 481 * @var bool s_cannot_edit User can not edit the post because it's not his 482 * @var bool s_cannot_edit_locked User can not edit the post because it's locked 483 * @var bool s_cannot_edit_time User can not edit the post because edit_time has passed 484 * @since 3.1.0-b4 485 */ 486 $vars = array( 487 'post_data', 488 'force_edit_allowed', 489 's_cannot_edit', 490 's_cannot_edit_locked', 491 's_cannot_edit_time', 492 ); 493 extract($phpbb_dispatcher->trigger_event('core.posting_modify_cannot_edit_conditions', compact($vars))); 494 495 if (!$force_edit_allowed) 496 { 497 if ($s_cannot_edit) 498 { 499 trigger_error('USER_CANNOT_EDIT'); 500 } 501 else if ($s_cannot_edit_time) 502 { 503 trigger_error('CANNOT_EDIT_TIME'); 504 } 505 else if ($s_cannot_edit_locked) 506 { 507 trigger_error('CANNOT_EDIT_POST_LOCKED'); 508 } 509 } 510 } 511 512 // Handle delete mode... 513 if ($mode == 'delete' || $mode == 'soft_delete') 514 { 515 if ($mode == 'soft_delete' && $post_data['post_visibility'] == ITEM_DELETED) 516 { 517 $user->setup('posting'); 518 trigger_error('NO_POST'); 519 } 520 521 $delete_reason = $request->variable('delete_reason', '', true); 522 phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, ($mode == 'soft_delete' && !$request->is_set_post('delete_permanent')), $delete_reason); 523 return; 524 } 525 526 // Handle bump mode... 527 if ($mode == 'bump') 528 { 529 if ($bump_time = bump_topic_allowed($forum_id, $post_data['topic_bumped'], $post_data['topic_last_post_time'], $post_data['topic_poster'], $post_data['topic_last_poster_id']) 530 && check_link_hash($request->variable('hash', ''), "topic_{$post_data['topic_id']}")) 531 { 532 $meta_url = phpbb_bump_topic($forum_id, $topic_id, $post_data, $current_time); 533 meta_refresh(3, $meta_url); 534 $message = $user->lang['TOPIC_BUMPED']; 535 536 if (!$request->is_ajax()) 537 { 538 $message .= '<br /><br />' . $user->lang('VIEW_MESSAGE', '<a href="' . $meta_url . '">', '</a>'); 539 $message .= '<br /><br />' . $user->lang('RETURN_FORUM', '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); 540 } 541 542 trigger_error($message); 543 } 544 545 trigger_error('BUMP_ERROR'); 546 } 547 548 // Subject length limiting to 60 characters if first post... 549 if ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_data['post_id'])) 550 { 551 $template->assign_var('S_NEW_MESSAGE', true); 552 } 553 554 // Determine some vars 555 if (isset($post_data['poster_id']) && $post_data['poster_id'] == ANONYMOUS) 556 { 557 $post_data['quote_username'] = (!empty($post_data['post_username'])) ? $post_data['post_username'] : $user->lang['GUEST']; 558 } 559 else 560 { 561 $post_data['quote_username'] = isset($post_data['username']) ? $post_data['username'] : ''; 562 } 563 564 $post_data['post_edit_locked'] = (isset($post_data['post_edit_locked'])) ? (int) $post_data['post_edit_locked'] : 0; 565 $post_data['post_subject_md5'] = (isset($post_data['post_subject']) && $mode == 'edit') ? md5($post_data['post_subject']) : ''; 566 $post_data['post_subject'] = (in_array($mode, array('quote', 'edit'))) ? $post_data['post_subject'] : ((isset($post_data['topic_title'])) ? $post_data['topic_title'] : ''); 567 $post_data['topic_time_limit'] = (isset($post_data['topic_time_limit'])) ? (($post_data['topic_time_limit']) ? (int) $post_data['topic_time_limit'] / 86400 : (int) $post_data['topic_time_limit']) : 0; 568 $post_data['poll_length'] = (!empty($post_data['poll_length'])) ? (int) $post_data['poll_length'] / 86400 : 0; 569 $post_data['poll_start'] = (!empty($post_data['poll_start'])) ? (int) $post_data['poll_start'] : 0; 570 $post_data['icon_id'] = (!isset($post_data['icon_id']) || in_array($mode, array('quote', 'reply'))) ? 0 : (int) $post_data['icon_id']; 571 $post_data['poll_options'] = array(); 572 573 // Get Poll Data 574 if ($post_data['poll_start']) 575 { 576 $sql = 'SELECT poll_option_text 577 FROM ' . POLL_OPTIONS_TABLE . " 578 WHERE topic_id = $topic_id 579 ORDER BY poll_option_id"; 580 $result = $db->sql_query($sql); 581 582 while ($row = $db->sql_fetchrow($result)) 583 { 584 $post_data['poll_options'][] = trim($row['poll_option_text']); 585 } 586 $db->sql_freeresult($result); 587 } 588 589 /** 590 * This event allows you to modify the post data before parsing 591 * 592 * @event core.posting_modify_post_data 593 * @var int forum_id ID of the forum 594 * @var string mode What action to take if the form has been submitted 595 * post|reply|quote|edit|delete|bump|smilies|popup 596 * @var array post_data Array with post data 597 * @var int post_id ID of the post 598 * @var int topic_id ID of the topic 599 * @since 3.2.2-RC1 600 */ 601 $vars = array( 602 'forum_id', 603 'mode', 604 'post_data', 605 'post_id', 606 'topic_id', 607 ); 608 extract($phpbb_dispatcher->trigger_event('core.posting_modify_post_data', compact($vars))); 609 610 if ($mode == 'edit') 611 { 612 $original_poll_data = array( 613 'poll_title' => $post_data['poll_title'], 614 'poll_length' => $post_data['poll_length'], 615 'poll_max_options' => $post_data['poll_max_options'], 616 'poll_option_text' => implode("\n", $post_data['poll_options']), 617 'poll_start' => $post_data['poll_start'], 618 'poll_last_vote' => $post_data['poll_last_vote'], 619 'poll_vote_change' => $post_data['poll_vote_change'], 620 ); 621 } 622 623 $orig_poll_options_size = count($post_data['poll_options']); 624 625 $message_parser = new parse_message(); 626 /* @var $plupload \phpbb\plupload\plupload */ 627 $plupload = $phpbb_container->get('plupload'); 628 629 /* @var $mimetype_guesser \phpbb\mimetype\guesser */ 630 $mimetype_guesser = $phpbb_container->get('mimetype.guesser'); 631 $message_parser->set_plupload($plupload); 632 633 if (isset($post_data['post_text'])) 634 { 635 $message_parser->message = &$post_data['post_text']; 636 unset($post_data['post_text']); 637 } 638 639 // Set some default variables 640 $uninit = array('post_attachment' => 0, 'poster_id' => $user->data['user_id'], 'enable_magic_url' => 0, 'topic_status' => 0, 'topic_type' => POST_NORMAL, 'post_subject' => '', 'topic_title' => '', 'post_time' => 0, 'post_edit_reason' => '', 'notify_set' => 0); 641 642 /** 643 * This event allows you to modify the default variables for post_data, and unset them in post_data if needed 644 * 645 * @event core.posting_modify_default_variables 646 * @var array post_data Array with post data 647 * @var array uninit Array with default vars to put into post_data, if they aren't there 648 * @since 3.2.5-RC1 649 */ 650 $vars = array( 651 'post_data', 652 'uninit', 653 ); 654 extract($phpbb_dispatcher->trigger_event('core.posting_modify_default_variables', compact($vars))); 655 656 foreach ($uninit as $var_name => $default_value) 657 { 658 if (!isset($post_data[$var_name])) 659 { 660 $post_data[$var_name] = $default_value; 661 } 662 } 663 unset($uninit); 664 665 // Always check if the submitted attachment data is valid and belongs to the user. 666 // Further down (especially in submit_post()) we do not check this again. 667 $message_parser->get_submitted_attachment_data($post_data['poster_id']); 668 669 if ($post_data['post_attachment'] && !$submit && !$refresh && !$preview && $mode == 'edit') 670 { 671 // Do not change to SELECT * 672 $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename, filesize 673 FROM ' . ATTACHMENTS_TABLE . " 674 WHERE post_msg_id = $post_id 675 AND in_message = 0 676 AND is_orphan = 0 677 ORDER BY attach_id DESC"; 678 $result = $db->sql_query($sql); 679 $message_parser->attachment_data = array_merge($message_parser->attachment_data, $db->sql_fetchrowset($result)); 680 $db->sql_freeresult($result); 681 } 682 683 if ($post_data['poster_id'] == ANONYMOUS) 684 { 685 $post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['post_username']) : ''; 686 } 687 else 688 { 689 $post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['username']) : ''; 690 } 691 692 $post_data['enable_urls'] = $post_data['enable_magic_url']; 693 694 if ($mode != 'edit') 695 { 696 $post_data['enable_sig'] = ($config['allow_sig'] && $user->optionget('attachsig')) ? true: false; 697 $post_data['enable_smilies'] = ($config['allow_smilies'] && $user->optionget('smilies')) ? true : false; 698 $post_data['enable_bbcode'] = ($config['allow_bbcode'] && $user->optionget('bbcode')) ? true : false; 699 $post_data['enable_urls'] = true; 700 } 701 702 if ($mode == 'post') 703 { 704 $post_data['topic_status'] = ($request->is_set_post('lock_topic') && $auth->acl_gets('m_lock', 'f_user_lock', $forum_id)) ? ITEM_LOCKED : ITEM_UNLOCKED; 705 } 706 707 $post_data['enable_magic_url'] = $post_data['drafts'] = false; 708 709 // User own some drafts? 710 if ($user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote')) 711 { 712 $sql = 'SELECT draft_id 713 FROM ' . DRAFTS_TABLE . ' 714 WHERE user_id = ' . $user->data['user_id'] . 715 (($forum_id) ? ' AND forum_id = ' . (int) $forum_id : '') . 716 (($topic_id) ? ' AND topic_id = ' . (int) $topic_id : '') . 717 (($draft_id) ? " AND draft_id <> $draft_id" : ''); 718 $result = $db->sql_query_limit($sql, 1); 719 720 if ($db->sql_fetchrow($result)) 721 { 722 $post_data['drafts'] = true; 723 } 724 $db->sql_freeresult($result); 725 } 726 727 $check_value = (($post_data['enable_bbcode']+1) << 8) + (($post_data['enable_smilies']+1) << 4) + (($post_data['enable_urls']+1) << 2) + (($post_data['enable_sig']+1) << 1); 728 729 // Check if user is watching this topic 730 if ($mode != 'post' && $config['allow_topic_notify'] && $user->data['is_registered']) 731 { 732 $sql = 'SELECT topic_id 733 FROM ' . TOPICS_WATCH_TABLE . ' 734 WHERE topic_id = ' . $topic_id . ' 735 AND user_id = ' . $user->data['user_id']; 736 $result = $db->sql_query($sql); 737 $post_data['notify_set'] = (int) $db->sql_fetchfield('topic_id'); 738 $db->sql_freeresult($result); 739 } 740 741 // Do we want to edit our post ? 742 if ($mode == 'edit' && $post_data['bbcode_uid']) 743 { 744 $message_parser->bbcode_uid = $post_data['bbcode_uid']; 745 } 746 747 // HTML, BBCode, Smilies, Images and Flash status 748 $bbcode_status = ($config['allow_bbcode'] && $auth->acl_get('f_bbcode', $forum_id)) ? true : false; 749 $smilies_status = ($config['allow_smilies'] && $auth->acl_get('f_smilies', $forum_id)) ? true : false; 750 $img_status = ($bbcode_status && $auth->acl_get('f_img', $forum_id)) ? true : false; 751 $url_status = ($config['allow_post_links']) ? true : false; 752 $flash_status = ($bbcode_status && $auth->acl_get('f_flash', $forum_id) && $config['allow_post_flash']) ? true : false; 753 $quote_status = true; 754 755 /** 756 * Event to override message BBCode status indications 757 * 758 * @event core.posting_modify_bbcode_status 759 * 760 * @var bool bbcode_status BBCode status 761 * @var bool smilies_status Smilies status 762 * @var bool img_status Image BBCode status 763 * @var bool url_status URL BBCode status 764 * @var bool flash_status Flash BBCode status 765 * @var bool quote_status Quote BBCode status 766 * @since 3.3.3-RC1 767 */ 768 $vars = [ 769 'bbcode_status', 770 'smilies_status', 771 'img_status', 772 'url_status', 773 'flash_status', 774 'quote_status', 775 ]; 776 extract($phpbb_dispatcher->trigger_event('core.posting_modify_bbcode_status', compact($vars))); 777 778 // Save Draft 779 if ($save && $user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote')) 780 { 781 $subject = $request->variable('subject', '', true); 782 $subject = (!$subject && $mode != 'post') ? $post_data['topic_title'] : $subject; 783 $message = $request->variable('message', '', true); 784 785 /** 786 * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR. 787 * Using their Numeric Character Reference's Hexadecimal notation. 788 */ 789 $subject = utf8_encode_ucr($subject); 790 791 if ($subject && $message) 792 { 793 if (confirm_box(true)) 794 { 795 $message_parser->message = $message; 796 $message_parser->parse($post_data['enable_bbcode'], ($config['allow_post_links']) ? $post_data['enable_urls'] : false, $post_data['enable_smilies'], $img_status, $flash_status, $quote_status, $config['allow_post_links']); 797 798 $sql = 'INSERT INTO ' . DRAFTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( 799 'user_id' => (int) $user->data['user_id'], 800 'topic_id' => (int) $topic_id, 801 'forum_id' => (int) $forum_id, 802 'save_time' => (int) $current_time, 803 'draft_subject' => (string) $subject, 804 'draft_message' => (string) $message_parser->message) 805 ); 806 $db->sql_query($sql); 807 808 /** @var \phpbb\attachment\manager $attachment_manager */ 809 $attachment_manager = $phpbb_container->get('attachment.manager'); 810 $attachment_manager->delete('attach', array_column($message_parser->attachment_data, 'attach_id')); 811 812 $meta_info = ($mode == 'post') ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) : append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id"); 813 814 meta_refresh(3, $meta_info); 815 816 $message = $user->lang['DRAFT_SAVED'] . '<br /><br />'; 817 $message .= ($mode != 'post') ? sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>') . '<br /><br />' : ''; 818 $message .= sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); 819 820 trigger_error($message); 821 } 822 else 823 { 824 $s_hidden_fields = build_hidden_fields(array( 825 'mode' => $mode, 826 'save' => true, 827 'f' => $forum_id, 828 't' => $topic_id, 829 'subject' => $subject, 830 'message' => $message, 831 'attachment_data' => $message_parser->attachment_data, 832 ) 833 ); 834 835 $hidden_fields = array( 836 'icon_id' => 0, 837 838 'disable_bbcode' => false, 839 'disable_smilies' => false, 840 'disable_magic_url' => false, 841 'attach_sig' => true, 842 'lock_topic' => false, 843 844 'topic_type' => POST_NORMAL, 845 'topic_time_limit' => 0, 846 847 'poll_title' => '', 848 'poll_option_text' => '', 849 'poll_max_options' => 1, 850 'poll_length' => 0, 851 'poll_vote_change' => false, 852 ); 853 854 foreach ($hidden_fields as $name => $default) 855 { 856 if (!isset($_POST[$name])) 857 { 858 // Don't include it, if its not available 859 unset($hidden_fields[$name]); 860 continue; 861 } 862 863 if (is_bool($default)) 864 { 865 // Use the string representation 866 $hidden_fields[$name] = $request->variable($name, ''); 867 } 868 else 869 { 870 $hidden_fields[$name] = $request->variable($name, $default); 871 } 872 } 873 874 $s_hidden_fields .= build_hidden_fields($hidden_fields); 875 876 confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields); 877 } 878 } 879 else 880 { 881 if (utf8_clean_string($subject) === '') 882 { 883 $error[] = $user->lang['EMPTY_SUBJECT']; 884 } 885 886 if (utf8_clean_string($message) === '') 887 { 888 $error[] = $user->lang['TOO_FEW_CHARS']; 889 } 890 } 891 unset($subject, $message); 892 } 893 894 // Load requested Draft 895 if ($draft_id && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $user->data['is_registered'] && $auth->acl_get('u_savedrafts')) 896 { 897 $sql = 'SELECT draft_subject, draft_message 898 FROM ' . DRAFTS_TABLE . " 899 WHERE draft_id = $draft_id 900 AND user_id = " . $user->data['user_id']; 901 $result = $db->sql_query_limit($sql, 1); 902 $row = $db->sql_fetchrow($result); 903 $db->sql_freeresult($result); 904 905 if ($row) 906 { 907 $post_data['post_subject'] = $row['draft_subject']; 908 $message_parser->message = $row['draft_message']; 909 910 $template->assign_var('S_DRAFT_LOADED', true); 911 } 912 else 913 { 914 $draft_id = 0; 915 } 916 } 917 918 // Load draft overview 919 if ($load && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_data['drafts']) 920 { 921 load_drafts($topic_id, $forum_id); 922 } 923 924 /** @var \phpbb\textformatter\utils_interface $bbcode_utils */ 925 $bbcode_utils = $phpbb_container->get('text_formatter.utils'); 926 927 if ($submit || $preview || $refresh) 928 { 929 $post_data['topic_cur_post_id'] = $request->variable('topic_cur_post_id', 0); 930 $post_data['post_subject'] = $request->variable('subject', '', true); 931 $message_parser->message = $request->variable('message', '', true); 932 933 $post_data['username'] = $request->variable('username', $post_data['username'], true); 934 $post_data['post_edit_reason'] = ($request->variable('edit_reason', false, false, \phpbb\request\request_interface::POST) && $mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? $request->variable('edit_reason', '', true) : ''; 935 936 $post_data['orig_topic_type'] = $post_data['topic_type']; 937 $post_data['topic_type'] = $request->variable('topic_type', (($mode != 'post') ? (int) $post_data['topic_type'] : POST_NORMAL)); 938 $post_data['topic_time_limit'] = $request->variable('topic_time_limit', (($mode != 'post') ? (int) $post_data['topic_time_limit'] : 0)); 939 940 if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id)) 941 { 942 $post_data['icon_id'] = $request->variable('icon', (int) $post_data['icon_id']); 943 } 944 945 $post_data['enable_bbcode'] = (!$bbcode_status || isset($_POST['disable_bbcode'])) ? false : true; 946 $post_data['enable_smilies'] = (!$smilies_status || isset($_POST['disable_smilies'])) ? false : true; 947 $post_data['enable_urls'] = (isset($_POST['disable_magic_url'])) ? 0 : 1; 948 $post_data['enable_sig'] = (!$config['allow_sig'] || !$auth->acl_get('f_sigs', $forum_id) || !$auth->acl_get('u_sig')) ? false : ((isset($_POST['attach_sig']) && $user->data['is_registered']) ? true : false); 949 950 if ($config['allow_topic_notify'] && $user->data['is_registered']) 951 { 952 $notify = (isset($_POST['notify'])) ? true : false; 953 } 954 else 955 { 956 $notify = false; 957 } 958 959 $topic_lock = (isset($_POST['lock_topic'])) ? true : false; 960 $post_lock = (isset($_POST['lock_post'])) ? true : false; 961 $poll_delete = (isset($_POST['poll_delete'])) ? true : false; 962 963 if ($submit) 964 { 965 $status_switch = (($post_data['enable_bbcode']+1) << 8) + (($post_data['enable_smilies']+1) << 4) + (($post_data['enable_urls']+1) << 2) + (($post_data['enable_sig']+1) << 1); 966 $status_switch = ($status_switch != $check_value); 967 } 968 else 969 { 970 $status_switch = 1; 971 } 972 973 // Delete Poll 974 if ($poll_delete && $mode == 'edit' && count($post_data['poll_options']) && 975 ((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id))) 976 { 977 if ($submit && check_form_key('posting')) 978 { 979 $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . " 980 WHERE topic_id = $topic_id"; 981 $db->sql_query($sql); 982 983 $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . " 984 WHERE topic_id = $topic_id"; 985 $db->sql_query($sql); 986 987 $topic_sql = array( 988 'poll_title' => '', 989 'poll_start' => 0, 990 'poll_length' => 0, 991 'poll_last_vote' => 0, 992 'poll_max_options' => 0, 993 'poll_vote_change' => 0 994 ); 995 996 $sql = 'UPDATE ' . TOPICS_TABLE . ' 997 SET ' . $db->sql_build_array('UPDATE', $topic_sql) . " 998 WHERE topic_id = $topic_id"; 999 $db->sql_query($sql); 1000 } 1001 1002 $post_data['poll_title'] = $post_data['poll_option_text'] = ''; 1003 $post_data['poll_vote_change'] = $post_data['poll_max_options'] = $post_data['poll_length'] = 0; 1004 } 1005 else 1006 { 1007 $post_data['poll_title'] = $request->variable('poll_title', '', true); 1008 $post_data['poll_length'] = $request->variable('poll_length', 0); 1009 $post_data['poll_option_text'] = $request->variable('poll_option_text', '', true); 1010 $post_data['poll_max_options'] = $request->variable('poll_max_options', 1); 1011 $post_data['poll_vote_change'] = ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id) && isset($_POST['poll_vote_change'])) ? 1 : 0; 1012 } 1013 1014 // If replying/quoting and last post id has changed 1015 // give user option to continue submit or return to post 1016 // notify and show user the post made between his request and the final submit 1017 if (($mode == 'reply' || $mode == 'quote') && $post_data['topic_cur_post_id'] && $post_data['topic_cur_post_id'] != $post_data['topic_last_post_id']) 1018 { 1019 // Only do so if it is allowed forum-wide 1020 if ($post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW) 1021 { 1022 if (topic_review($topic_id, $forum_id, 'post_review', $post_data['topic_cur_post_id'])) 1023 { 1024 $template->assign_var('S_POST_REVIEW', true); 1025 } 1026 1027 $submit = false; 1028 $refresh = true; 1029 } 1030 } 1031 1032 // Parse Attachments - before checksum is calculated 1033 if ($message_parser->check_attachment_form_token($language, $request, 'posting')) 1034 { 1035 $message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh); 1036 } 1037 1038 /** 1039 * This event allows you to modify message text before parsing 1040 * 1041 * @event core.posting_modify_message_text 1042 * @var array post_data Array with post data 1043 * @var string mode What action to take if the form is submitted 1044 * post|reply|quote|edit|delete|bump|smilies|popup 1045 * @var int post_id ID of the post 1046 * @var int topic_id ID of the topic 1047 * @var int forum_id ID of the forum 1048 * @var bool submit Whether or not the form has been submitted 1049 * @var bool preview Whether or not the post is being previewed 1050 * @var bool save Whether or not a draft is being saved 1051 * @var bool load Whether or not a draft is being loaded 1052 * @var bool cancel Whether or not to cancel the form (returns to 1053 * viewtopic or viewforum depending on if the user 1054 * is posting a new topic or editing a post) 1055 * @var bool refresh Whether or not to retain previously submitted data 1056 * @var object message_parser The message parser object 1057 * @var array error Array of errors 1058 * @since 3.1.2-RC1 1059 * @changed 3.1.11-RC1 Added error 1060 */ 1061 $vars = array( 1062 'post_data', 1063 'mode', 1064 'post_id', 1065 'topic_id', 1066 'forum_id', 1067 'submit', 1068 'preview', 1069 'save', 1070 'load', 1071 'cancel', 1072 'refresh', 1073 'message_parser', 1074 'error', 1075 ); 1076 extract($phpbb_dispatcher->trigger_event('core.posting_modify_message_text', compact($vars))); 1077 1078 // Grab md5 'checksum' of new message 1079 $message_md5 = md5($message_parser->message); 1080 1081 // If editing and checksum has changed we know the post was edited while we're editing 1082 // Notify and show user the changed post 1083 if ($mode == 'edit' && $post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW) 1084 { 1085 $edit_post_message_checksum = $request->variable('edit_post_message_checksum', ''); 1086 $edit_post_subject_checksum = $request->variable('edit_post_subject_checksum', ''); 1087 1088 // $post_data['post_checksum'] is the checksum of the post submitted in the meantime 1089 // $message_md5 is the checksum of the post we're about to submit 1090 // $edit_post_message_checksum is the checksum of the post we're editing 1091 // ... 1092 1093 // We make sure nobody else made exactly the same change 1094 // we're about to submit by also checking $message_md5 != $post_data['post_checksum'] 1095 if ($edit_post_message_checksum !== '' && 1096 $edit_post_message_checksum != $post_data['post_checksum'] && 1097 $message_md5 != $post_data['post_checksum'] 1098 || 1099 $edit_post_subject_checksum !== '' && 1100 $edit_post_subject_checksum != $post_data['post_subject_md5'] && 1101 md5($post_data['post_subject']) != $post_data['post_subject_md5']) 1102 { 1103 if (topic_review($topic_id, $forum_id, 'post_review_edit', $post_id)) 1104 { 1105 $template->assign_vars(array( 1106 'S_POST_REVIEW' => true, 1107 1108 'L_POST_REVIEW' => $user->lang['POST_REVIEW_EDIT'], 1109 'L_POST_REVIEW_EXPLAIN' => $user->lang['POST_REVIEW_EDIT_EXPLAIN'], 1110 )); 1111 } 1112 1113 $submit = false; 1114 $refresh = true; 1115 } 1116 } 1117 1118 // Check checksum ... don't re-parse message if the same 1119 $update_message = ($mode != 'edit' || $message_md5 != $post_data['post_checksum'] || $status_switch || strlen($post_data['bbcode_uid']) < BBCODE_UID_LEN) ? true : false; 1120 1121 // Also check if subject got updated... 1122 $update_subject = $mode != 'edit' || ($post_data['post_subject_md5'] && $post_data['post_subject_md5'] != md5($post_data['post_subject'])); 1123 1124 // Parse message 1125 if ($update_message) 1126 { 1127 if (count($message_parser->warn_msg)) 1128 { 1129 $error[] = implode('<br />', $message_parser->warn_msg); 1130 $message_parser->warn_msg = array(); 1131 } 1132 1133 if (!$preview || !empty($message_parser->message)) 1134 { 1135 $message_parser->parse($post_data['enable_bbcode'], ($config['allow_post_links']) ? $post_data['enable_urls'] : false, $post_data['enable_smilies'], $img_status, $flash_status, $quote_status, $config['allow_post_links']); 1136 } 1137 1138 // On a refresh we do not care about message parsing errors 1139 if (count($message_parser->warn_msg) && $refresh && !$preview) 1140 { 1141 $message_parser->warn_msg = array(); 1142 } 1143 } 1144 else 1145 { 1146 $message_parser->bbcode_bitfield = $post_data['bbcode_bitfield']; 1147 } 1148 1149 $ignore_flood = $auth->acl_get('u_ignoreflood') ? true : $auth->acl_get('f_ignoreflood', $forum_id); 1150 if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$ignore_flood) 1151 { 1152 // Flood check 1153 $last_post_time = 0; 1154 1155 if ($user->data['is_registered']) 1156 { 1157 $last_post_time = $user->data['user_lastpost_time']; 1158 } 1159 else 1160 { 1161 $sql = 'SELECT post_time AS last_post_time 1162 FROM ' . POSTS_TABLE . " 1163 WHERE poster_ip = '" . $user->ip . "' 1164 AND post_time > " . ($current_time - $config['flood_interval']); 1165 $result = $db->sql_query_limit($sql, 1); 1166 if ($row = $db->sql_fetchrow($result)) 1167 { 1168 $last_post_time = $row['last_post_time']; 1169 } 1170 $db->sql_freeresult($result); 1171 } 1172 1173 if ($last_post_time && ($current_time - $last_post_time) < intval($config['flood_interval'])) 1174 { 1175 $error[] = $user->lang['FLOOD_ERROR']; 1176 } 1177 } 1178 1179 // Validate username 1180 if (($post_data['username'] && !$user->data['is_registered']) || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS && $post_data['username'] && $post_data['post_username'] && $post_data['post_username'] != $post_data['username'])) 1181 { 1182 if (!function_exists('validate_username')) 1183 { 1184 include($phpbb_root_path . 'includes/functions_user.' . $phpEx); 1185 } 1186 1187 $user->add_lang('ucp'); 1188 1189 if (($result = validate_username($post_data['username'], (!empty($post_data['post_username'])) ? $post_data['post_username'] : '')) !== false) 1190 { 1191 $error[] = $user->lang[$result . '_USERNAME']; 1192 } 1193 1194 if (($result = validate_string($post_data['username'], false, $config['min_name_chars'], $config['max_name_chars'])) !== false) 1195 { 1196 $min_max_amount = ($result == 'TOO_SHORT') ? $config['min_name_chars'] : $config['max_name_chars']; 1197 $error[] = $user->lang('FIELD_' . $result, $min_max_amount, $user->lang['USERNAME']); 1198 } 1199 } 1200 1201 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply'))) 1202 { 1203 $captcha_data = array( 1204 'message' => $request->variable('message', '', true), 1205 'subject' => $request->variable('subject', '', true), 1206 'username' => $request->variable('username', '', true), 1207 ); 1208 $vc_response = $captcha->validate($captcha_data); 1209 if ($vc_response) 1210 { 1211 $error[] = $vc_response; 1212 } 1213 } 1214 1215 // check form 1216 if (($submit || $preview) && !check_form_key('posting')) 1217 { 1218 $error[] = $user->lang['FORM_INVALID']; 1219 } 1220 1221 if ($submit && $mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED && !$request->is_set_post('delete') && $auth->acl_get('m_approve', $forum_id)) 1222 { 1223 $is_first_post = ($post_id <= $post_data['topic_first_post_id'] || !$post_data['topic_posts_approved']); 1224 $is_last_post = ($post_id >= $post_data['topic_last_post_id'] || !$post_data['topic_posts_approved']); 1225 $updated_post_data = $phpbb_content_visibility->set_post_visibility(ITEM_APPROVED, $post_id, $post_data['topic_id'], $post_data['forum_id'], $user->data['user_id'], time(), '', $is_first_post, $is_last_post); 1226 1227 if (!empty($updated_post_data)) 1228 { 1229 // Update the post_data, so we don't need to refetch it. 1230 $post_data = array_merge($post_data, $updated_post_data); 1231 } 1232 } 1233 1234 // Parse subject 1235 if (!$preview && !$refresh && utf8_clean_string($post_data['post_subject']) === '' && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id))) 1236 { 1237 $error[] = $user->lang['EMPTY_SUBJECT']; 1238 } 1239 1240 /** 1241 * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR. 1242 * Using their Numeric Character Reference's Hexadecimal notation. 1243 * Check the permissions for posting Emojis first. 1244 */ 1245 if ($auth->acl_get('u_emoji')) 1246 { 1247 $post_data['post_subject'] = utf8_encode_ucr($post_data['post_subject']); 1248 } 1249 else 1250 { 1251 /** 1252 * Check for out-of-bounds characters that are currently 1253 * not supported by utf8_bin in MySQL 1254 */ 1255 if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $post_data['post_subject'], $matches)) 1256 { 1257 $character_list = implode('<br>', $matches[0]); 1258 1259 $error[] = $user->lang('UNSUPPORTED_CHARACTERS_SUBJECT', $character_list); 1260 } 1261 } 1262 1263 $post_data['poll_last_vote'] = (isset($post_data['poll_last_vote'])) ? $post_data['poll_last_vote'] : 0; 1264 1265 if ($post_data['poll_option_text'] && 1266 ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/)) 1267 && $auth->acl_get('f_poll', $forum_id)) 1268 { 1269 $poll = array( 1270 'poll_title' => $post_data['poll_title'], 1271 'poll_length' => $post_data['poll_length'], 1272 'poll_max_options' => $post_data['poll_max_options'], 1273 'poll_option_text' => $post_data['poll_option_text'], 1274 'poll_start' => $post_data['poll_start'], 1275 'poll_last_vote' => $post_data['poll_last_vote'], 1276 'poll_vote_change' => $post_data['poll_vote_change'], 1277 'enable_bbcode' => $post_data['enable_bbcode'], 1278 'enable_urls' => $post_data['enable_urls'], 1279 'enable_smilies' => $post_data['enable_smilies'], 1280 'img_status' => $img_status 1281 ); 1282 1283 $message_parser->parse_poll($poll); 1284 1285 $post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array(); 1286 $post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : ''; 1287 1288 /* We reset votes, therefore also allow removing options 1289 if ($post_data['poll_last_vote'] && ($poll['poll_options_size'] < $orig_poll_options_size)) 1290 { 1291 $message_parser->warn_msg[] = $user->lang['NO_DELETE_POLL_OPTIONS']; 1292 }*/ 1293 } 1294 else if ($mode == 'edit' && $post_id == $post_data['topic_first_post_id'] && $auth->acl_get('f_poll', $forum_id)) 1295 { 1296 // The user removed all poll options, this is equal to deleting the poll. 1297 $poll = array( 1298 'poll_title' => '', 1299 'poll_length' => 0, 1300 'poll_max_options' => 0, 1301 'poll_option_text' => '', 1302 'poll_start' => 0, 1303 'poll_last_vote' => 0, 1304 'poll_vote_change' => 0, 1305 'poll_options' => array(), 1306 ); 1307 1308 $post_data['poll_options'] = array(); 1309 $post_data['poll_title'] = ''; 1310 $post_data['poll_start'] = $post_data['poll_length'] = $post_data['poll_max_options'] = $post_data['poll_last_vote'] = $post_data['poll_vote_change'] = 0; 1311 } 1312 else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && !$bbcode_utils->is_empty($original_poll_data['poll_title'])) 1313 { 1314 // We have a poll but the editing user is not permitted to create/edit it. 1315 // So we just keep the original poll-data. 1316 // Decode the poll title and options text fisrt. 1317 $original_poll_data['poll_title'] = $bbcode_utils->unparse($original_poll_data['poll_title']); 1318 $original_poll_data['poll_option_text'] = $bbcode_utils->unparse($original_poll_data['poll_option_text']); 1319 $original_poll_data['poll_options'] = explode("\n", $original_poll_data['poll_option_text']); 1320 1321 $poll = array_merge($original_poll_data, array( 1322 'enable_bbcode' => $post_data['enable_bbcode'], 1323 'enable_urls' => $post_data['enable_urls'], 1324 'enable_smilies' => $post_data['enable_smilies'], 1325 'img_status' => $img_status, 1326 )); 1327 1328 $message_parser->parse_poll($poll); 1329 1330 $post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array(); 1331 $post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : ''; 1332 } 1333 else 1334 { 1335 $poll = array(); 1336 } 1337 1338 // Check topic type 1339 if ($post_data['topic_type'] != POST_NORMAL && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id))) 1340 { 1341 switch ($post_data['topic_type']) 1342 { 1343 case POST_GLOBAL: 1344 $auth_option = 'f_announce_global'; 1345 break; 1346 1347 case POST_ANNOUNCE: 1348 $auth_option = 'f_announce'; 1349 break; 1350 1351 case POST_STICKY: 1352 $auth_option = 'f_sticky'; 1353 break; 1354 1355 default: 1356 $auth_option = ''; 1357 break; 1358 } 1359 1360 if ($auth_option != '' && !$auth->acl_get($auth_option, $forum_id)) 1361 { 1362 // There is a special case where a user edits his post whereby the topic type got changed by an admin/mod. 1363 // Another case would be a mod not having sticky permissions for example but edit permissions. 1364 if ($mode == 'edit') 1365 { 1366 // To prevent non-authed users messing around with the topic type we reset it to the original one. 1367 $post_data['topic_type'] = $post_data['orig_topic_type']; 1368 } 1369 else 1370 { 1371 $error[] = $user->lang['CANNOT_POST_' . str_replace('F_', '', strtoupper($auth_option))]; 1372 } 1373 } 1374 } 1375 1376 if (count($message_parser->warn_msg)) 1377 { 1378 $error[] = implode('<br />', $message_parser->warn_msg); 1379 } 1380 1381 // DNSBL check 1382 if ($config['check_dnsbl'] && !$refresh) 1383 { 1384 if (($dnsbl = $user->check_dnsbl('post')) !== false) 1385 { 1386 $error[] = sprintf($user->lang['IP_BLACKLISTED'], $user->ip, $dnsbl[1]); 1387 } 1388 } 1389 1390 /** 1391 * This event allows you to define errors before the post action is performed 1392 * 1393 * @event core.posting_modify_submission_errors 1394 * @var array post_data Array with post data 1395 * @var array poll Array with poll data from post (must be used instead of the post_data equivalent) 1396 * @var string mode What action to take if the form is submitted 1397 * post|reply|quote|edit|delete|bump|smilies|popup 1398 * @var int post_id ID of the post 1399 * @var int topic_id ID of the topic 1400 * @var int forum_id ID of the forum 1401 * @var bool submit Whether or not the form has been submitted 1402 * @var array error Any error strings; a non-empty array aborts form submission. 1403 * NOTE: Should be actual language strings, NOT language keys. 1404 * @since 3.1.0-RC5 1405 * @changed 3.1.5-RC1 Added poll array to the event 1406 * @changed 3.2.0-a1 Removed undefined page_title 1407 */ 1408 $vars = array( 1409 'post_data', 1410 'poll', 1411 'mode', 1412 'post_id', 1413 'topic_id', 1414 'forum_id', 1415 'submit', 1416 'error', 1417 ); 1418 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submission_errors', compact($vars))); 1419 1420 // Store message, sync counters 1421 if (!count($error) && $submit) 1422 { 1423 if ($submit) 1424 { 1425 // Lock/Unlock Topic 1426 $change_topic_status = $post_data['topic_status']; 1427 $perm_lock_unlock = ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED)) ? true : false; 1428 1429 if ($post_data['topic_status'] == ITEM_LOCKED && !$topic_lock && $perm_lock_unlock) 1430 { 1431 $change_topic_status = ITEM_UNLOCKED; 1432 } 1433 else if ($post_data['topic_status'] == ITEM_UNLOCKED && $topic_lock && $perm_lock_unlock) 1434 { 1435 $change_topic_status = ITEM_LOCKED; 1436 } 1437 1438 if ($change_topic_status != $post_data['topic_status']) 1439 { 1440 $sql = 'UPDATE ' . TOPICS_TABLE . " 1441 SET topic_status = $change_topic_status 1442 WHERE topic_id = $topic_id 1443 AND topic_moved_id = 0"; 1444 $db->sql_query($sql); 1445 1446 $user_lock = ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $post_data['topic_poster']) ? 'USER_' : ''; 1447 1448 $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_' . $user_lock . (($change_topic_status == ITEM_LOCKED) ? 'LOCK' : 'UNLOCK'), false, array( 1449 'forum_id' => $forum_id, 1450 'topic_id' => $topic_id, 1451 $post_data['topic_title'] 1452 )); 1453 } 1454 1455 // Lock/Unlock Post Edit 1456 if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_LOCKED && !$post_lock && $auth->acl_get('m_edit', $forum_id)) 1457 { 1458 $post_data['post_edit_locked'] = ITEM_UNLOCKED; 1459 } 1460 else if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_UNLOCKED && $post_lock && $auth->acl_get('m_edit', $forum_id)) 1461 { 1462 $post_data['post_edit_locked'] = ITEM_LOCKED; 1463 } 1464 1465 $data = array( 1466 'topic_title' => (empty($post_data['topic_title'])) ? $post_data['post_subject'] : $post_data['topic_title'], 1467 'topic_first_post_id' => (isset($post_data['topic_first_post_id'])) ? (int) $post_data['topic_first_post_id'] : 0, 1468 'topic_last_post_id' => (isset($post_data['topic_last_post_id'])) ? (int) $post_data['topic_last_post_id'] : 0, 1469 'topic_time_limit' => (int) $post_data['topic_time_limit'], 1470 'topic_attachment' => (isset($post_data['topic_attachment'])) ? (int) $post_data['topic_attachment'] : 0, 1471 'post_id' => (int) $post_id, 1472 'topic_id' => (int) $topic_id, 1473 'forum_id' => (int) $forum_id, 1474 'icon_id' => (int) $post_data['icon_id'], 1475 'poster_id' => (int) $post_data['poster_id'], 1476 'enable_sig' => (bool) $post_data['enable_sig'], 1477 'enable_bbcode' => (bool) $post_data['enable_bbcode'], 1478 'enable_smilies' => (bool) $post_data['enable_smilies'], 1479 'enable_urls' => (bool) $post_data['enable_urls'], 1480 'enable_indexing' => (bool) $post_data['enable_indexing'], 1481 'message_md5' => (string) $message_md5, 1482 'post_checksum' => (isset($post_data['post_checksum'])) ? (string) $post_data['post_checksum'] : '', 1483 'post_edit_reason' => $post_data['post_edit_reason'], 1484 'post_edit_user' => ($mode == 'edit') ? $user->data['user_id'] : ((isset($post_data['post_edit_user'])) ? (int) $post_data['post_edit_user'] : 0), 1485 'forum_parents' => $post_data['forum_parents'], 1486 'forum_name' => $post_data['forum_name'], 1487 'notify' => $notify, 1488 'notify_set' => $post_data['notify_set'], 1489 'poster_ip' => (isset($post_data['poster_ip'])) ? $post_data['poster_ip'] : $user->ip, 1490 'post_edit_locked' => (int) $post_data['post_edit_locked'], 1491 'bbcode_bitfield' => $message_parser->bbcode_bitfield, 1492 'bbcode_uid' => $message_parser->bbcode_uid, 1493 'message' => $message_parser->message, 1494 'attachment_data' => $message_parser->attachment_data, 1495 'filename_data' => $message_parser->filename_data, 1496 'topic_status' => $post_data['topic_status'], 1497 1498 'topic_visibility' => (isset($post_data['topic_visibility'])) ? $post_data['topic_visibility'] : false, 1499 'post_visibility' => (isset($post_data['post_visibility'])) ? $post_data['post_visibility'] : false, 1500 ); 1501 1502 if ($mode == 'edit') 1503 { 1504 $data['topic_posts_approved'] = $post_data['topic_posts_approved']; 1505 $data['topic_posts_unapproved'] = $post_data['topic_posts_unapproved']; 1506 $data['topic_posts_softdeleted'] = $post_data['topic_posts_softdeleted']; 1507 } 1508 1509 // Only return the username when it is either a guest posting or we are editing a post and 1510 // the username was supplied; otherwise post_data might hold the data of the post that is 1511 // being quoted (which could result in the username being returned being that of the quoted 1512 // post's poster, not the poster of the current post). See: PHPBB3-11769 for more information. 1513 $post_author_name = ((!$user->data['is_registered'] || $mode == 'edit') && $post_data['username'] !== '') ? $post_data['username'] : ''; 1514 1515 /** 1516 * This event allows you to define errors before the post action is performed 1517 * 1518 * @event core.posting_modify_submit_post_before 1519 * @var array post_data Array with post data 1520 * @var array poll Array with poll data 1521 * @var array data Array with post data going to be stored in the database 1522 * @var string mode What action to take if the form is submitted 1523 * post|reply|quote|edit|delete 1524 * @var int post_id ID of the post 1525 * @var int topic_id ID of the topic 1526 * @var int forum_id ID of the forum 1527 * @var string post_author_name Author name for guest posts 1528 * @var bool update_message Boolean if the post message was changed 1529 * @var bool update_subject Boolean if the post subject was changed 1530 * NOTE: Should be actual language strings, NOT language keys. 1531 * @since 3.1.0-RC5 1532 * @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event 1533 * @change 3.2.0-a1 Removed undefined page_title 1534 */ 1535 $vars = array( 1536 'post_data', 1537 'poll', 1538 'data', 1539 'mode', 1540 'post_id', 1541 'topic_id', 1542 'forum_id', 1543 'post_author_name', 1544 'update_message', 1545 'update_subject', 1546 ); 1547 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_before', compact($vars))); 1548 1549 // The last parameter tells submit_post if search indexer has to be run 1550 $redirect_url = submit_post($mode, $post_data['post_subject'], $post_author_name, $post_data['topic_type'], $poll, $data, $update_message, ($update_message || $update_subject) ? true : false); 1551 1552 /** 1553 * This event allows you to define errors after the post action is performed 1554 * 1555 * @event core.posting_modify_submit_post_after 1556 * @var array post_data Array with post data 1557 * @var array poll Array with poll data 1558 * @var array data Array with post data going to be stored in the database 1559 * @var string mode What action to take if the form is submitted 1560 * post|reply|quote|edit|delete 1561 * @var int post_id ID of the post 1562 * @var int topic_id ID of the topic 1563 * @var int forum_id ID of the forum 1564 * @var string post_author_name Author name for guest posts 1565 * @var bool update_message Boolean if the post message was changed 1566 * @var bool update_subject Boolean if the post subject was changed 1567 * @var string redirect_url URL the user is going to be redirected to 1568 * NOTE: Should be actual language strings, NOT language keys. 1569 * @since 3.1.0-RC5 1570 * @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event 1571 * @change 3.2.0-a1 Removed undefined page_title 1572 */ 1573 $vars = array( 1574 'post_data', 1575 'poll', 1576 'data', 1577 'mode', 1578 'post_id', 1579 'topic_id', 1580 'forum_id', 1581 'post_author_name', 1582 'update_message', 1583 'update_subject', 1584 'redirect_url', 1585 ); 1586 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_after', compact($vars))); 1587 1588 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === true) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote')) 1589 { 1590 $captcha->reset(); 1591 } 1592 1593 // Handle delete mode... 1594 if ($request->is_set_post('delete_permanent') || ($request->is_set_post('delete') && $post_data['post_visibility'] != ITEM_DELETED)) 1595 { 1596 $delete_reason = $request->variable('delete_reason', '', true); 1597 phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, !$request->is_set_post('delete_permanent'), $delete_reason); 1598 return; 1599 } 1600 1601 // Check the permissions for post approval. 1602 // Moderators must go through post approval like ordinary users. 1603 if ((!$auth->acl_get('f_noapprove', $data['forum_id']) && empty($data['force_approved_state'])) || (isset($data['force_approved_state']) && !$data['force_approved_state'])) 1604 { 1605 meta_refresh(10, $redirect_url); 1606 $message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD']; 1607 $message .= (($user->data['user_id'] == ANONYMOUS) ? '' : ' '. $user->lang['POST_APPROVAL_NOTIFY']); 1608 $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $data['forum_id']) . '">', '</a>'); 1609 trigger_error($message); 1610 } 1611 1612 redirect($redirect_url); 1613 } 1614 } 1615 } 1616 1617 // Preview 1618 if (!count($error) && $preview) 1619 { 1620 $post_data['post_time'] = ($mode == 'edit') ? $post_data['post_time'] : $current_time; 1621 1622 $preview_message = $message_parser->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies'], false); 1623 1624 $preview_signature = ($mode == 'edit') ? $post_data['user_sig'] : $user->data['user_sig']; 1625 $preview_signature_uid = ($mode == 'edit') ? $post_data['user_sig_bbcode_uid'] : $user->data['user_sig_bbcode_uid']; 1626 $preview_signature_bitfield = ($mode == 'edit') ? $post_data['user_sig_bbcode_bitfield'] : $user->data['user_sig_bbcode_bitfield']; 1627 1628 // Signature 1629 if ($post_data['enable_sig'] && $config['allow_sig'] && $preview_signature && $auth->acl_get('f_sigs', $forum_id)) 1630 { 1631 $flags = ($config['allow_sig_bbcode']) ? OPTION_FLAG_BBCODE : 0; 1632 $flags |= ($config['allow_sig_links']) ? OPTION_FLAG_LINKS : 0; 1633 $flags |= ($config['allow_sig_smilies']) ? OPTION_FLAG_SMILIES : 0; 1634 1635 $preview_signature = generate_text_for_display($preview_signature, $preview_signature_uid, $preview_signature_bitfield, $flags, false); 1636 } 1637 else 1638 { 1639 $preview_signature = ''; 1640 } 1641 1642 $preview_subject = censor_text($post_data['post_subject']); 1643 1644 // Poll Preview 1645 if (!$poll_delete && ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/)) 1646 && $auth->acl_get('f_poll', $forum_id)) 1647 { 1648 $parse_poll = new parse_message($post_data['poll_title']); 1649 $parse_poll->bbcode_uid = $message_parser->bbcode_uid; 1650 $parse_poll->bbcode_bitfield = $message_parser->bbcode_bitfield; 1651 1652 $parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']); 1653 1654 if ($post_data['poll_length']) 1655 { 1656 $poll_end = ($post_data['poll_length'] * 86400) + (($post_data['poll_start']) ? $post_data['poll_start'] : time()); 1657 } 1658 1659 $template->assign_vars(array( 1660 'S_HAS_POLL_OPTIONS' => (count($post_data['poll_options'])), 1661 'S_IS_MULTI_CHOICE' => ($post_data['poll_max_options'] > 1) ? true : false, 1662 1663 'POLL_QUESTION' => $parse_poll->message, 1664 1665 'L_POLL_LENGTH' => ($post_data['poll_length']) ? sprintf($user->lang['POLL_RUN_TILL'], $user->format_date($poll_end)) : '', 1666 'L_MAX_VOTES' => $user->lang('MAX_OPTIONS_SELECT', (int) $post_data['poll_max_options']), 1667 )); 1668 1669 $preview_poll_options = array(); 1670 foreach ($post_data['poll_options'] as $poll_option) 1671 { 1672 $parse_poll->message = $poll_option; 1673 $parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']); 1674 $preview_poll_options[] = $parse_poll->message; 1675 } 1676 unset($parse_poll); 1677 1678 foreach ($preview_poll_options as $key => $option) 1679 { 1680 $template->assign_block_vars('poll_option', array( 1681 'POLL_OPTION_CAPTION' => $option, 1682 'POLL_OPTION_ID' => $key + 1) 1683 ); 1684 } 1685 unset($preview_poll_options); 1686 } 1687 1688 // Attachment Preview 1689 if (count($message_parser->attachment_data)) 1690 { 1691 $template->assign_var('S_HAS_ATTACHMENTS', true); 1692 1693 $update_count = array(); 1694 $attachment_data = $message_parser->attachment_data; 1695 1696 parse_attachments($forum_id, $preview_message, $attachment_data, $update_count, true); 1697 1698 foreach ($attachment_data as $i => $attachment) 1699 { 1700 $template->assign_block_vars('attachment', array( 1701 'DISPLAY_ATTACHMENT' => $attachment) 1702 ); 1703 } 1704 unset($attachment_data); 1705 } 1706 1707 if (!count($error)) 1708 { 1709 $template->assign_vars(array( 1710 'PREVIEW_SUBJECT' => $preview_subject, 1711 'PREVIEW_MESSAGE' => $preview_message, 1712 'PREVIEW_SIGNATURE' => $preview_signature, 1713 1714 'S_DISPLAY_PREVIEW' => !empty($preview_message), 1715 )); 1716 } 1717 } 1718 1719 // Remove quotes that would become nested too deep before decoding the text 1720 $generate_quote = ($mode == 'quote' && !$submit && !$preview && !$refresh); 1721 if ($generate_quote && $config['max_quote_depth'] > 0) 1722 { 1723 $tmp_bbcode_uid = $message_parser->bbcode_uid; 1724 $message_parser->bbcode_uid = $post_data['bbcode_uid']; 1725 $message_parser->remove_nested_quotes($config['max_quote_depth'] - 1); 1726 $message_parser->bbcode_uid = $tmp_bbcode_uid; 1727 } 1728 1729 // Decode text for message display 1730 $post_data['bbcode_uid'] = ($mode == 'quote' && !$preview && !$refresh && !count($error)) ? $post_data['bbcode_uid'] : $message_parser->bbcode_uid; 1731 $message_parser->decode_message($post_data['bbcode_uid']); 1732 1733 if ($generate_quote) 1734 { 1735 // Remove attachment bbcode tags from the quoted message to avoid mixing with the new post attachments if any 1736 $message_parser->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#uis', '\\2', $message_parser->message); 1737 1738 $quote_attributes = array( 1739 'author' => $post_data['quote_username'], 1740 'post_id' => $post_data['post_id'], 1741 'time' => $post_data['post_time'], 1742 'user_id' => $post_data['poster_id'], 1743 ); 1744 1745 /** 1746 * This event allows you to modify the quote attributes of the post being quoted 1747 * 1748 * @event core.posting_modify_quote_attributes 1749 * @var array quote_attributes Array with quote attributes 1750 * @var array post_data Array with post data 1751 * @since 3.2.6-RC1 1752 */ 1753 $vars = array( 1754 'quote_attributes', 1755 'post_data', 1756 ); 1757 extract($phpbb_dispatcher->trigger_event('core.posting_modify_quote_attributes', compact($vars))); 1758 1759 /** @var \phpbb\language\language $language */ 1760 $language = $phpbb_container->get('language'); 1761 phpbb_format_quote($language, $message_parser, $bbcode_utils, $bbcode_status, $quote_attributes); 1762 } 1763 1764 if (($mode == 'reply' || $mode == 'quote') && !$submit && !$preview && !$refresh) 1765 { 1766 $post_data['post_subject'] = ((strpos($post_data['post_subject'], 'Re: ') !== 0) ? 'Re: ' : '') . censor_text($post_data['post_subject']); 1767 1768 $post_subject = $post_data['post_subject']; 1769 1770 /** 1771 * This event allows you to modify the post subject of the post being quoted 1772 * 1773 * @event core.posting_modify_post_subject 1774 * @var string post_subject String with the post subject already censored. 1775 * @since 3.2.8-RC1 1776 */ 1777 $vars = array('post_subject'); 1778 extract($phpbb_dispatcher->trigger_event('core.posting_modify_post_subject', compact($vars))); 1779 1780 $post_data['post_subject'] = $post_subject; 1781 } 1782 1783 $attachment_data = $message_parser->attachment_data; 1784 $filename_data = $message_parser->filename_data; 1785 $post_data['post_text'] = $message_parser->message; 1786 1787 if (count($post_data['poll_options']) || (isset($post_data['poll_title']) && !$bbcode_utils->is_empty($post_data['poll_title']))) 1788 { 1789 $message_parser->message = $post_data['poll_title']; 1790 $message_parser->bbcode_uid = $post_data['bbcode_uid']; 1791 1792 $message_parser->decode_message(); 1793 $post_data['poll_title'] = $message_parser->message; 1794 1795 $message_parser->message = implode("\n", $post_data['poll_options']); 1796 $message_parser->decode_message(); 1797 $post_data['poll_options'] = explode("\n", $message_parser->message); 1798 } 1799 1800 // MAIN POSTING PAGE BEGINS HERE 1801 1802 // Forum moderators? 1803 $moderators = array(); 1804 if ($config['load_moderators']) 1805 { 1806 get_moderators($moderators, $forum_id); 1807 } 1808 1809 // Generate smiley listing 1810 generate_smilies('inline', $forum_id); 1811 1812 // Generate inline attachment select box 1813 posting_gen_inline_attachments($attachment_data); 1814 1815 // Do show topic type selection only in first post. 1816 $topic_type_toggle = false; 1817 1818 if ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id'])) 1819 { 1820 $topic_type_toggle = posting_gen_topic_types($forum_id, $post_data['topic_type']); 1821 } 1822 1823 $s_topic_icons = false; 1824 if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id)) 1825 { 1826 $s_topic_icons = posting_gen_topic_icons($mode, $post_data['icon_id']); 1827 } 1828 1829 $bbcode_checked = (isset($post_data['enable_bbcode'])) ? !$post_data['enable_bbcode'] : (($config['allow_bbcode']) ? !$user->optionget('bbcode') : 1); 1830 $smilies_checked = (isset($post_data['enable_smilies'])) ? !$post_data['enable_smilies'] : (($config['allow_smilies']) ? !$user->optionget('smilies') : 1); 1831 $urls_checked = (isset($post_data['enable_urls'])) ? !$post_data['enable_urls'] : 0; 1832 $sig_checked = $post_data['enable_sig']; 1833 $lock_topic_checked = (isset($topic_lock) && $topic_lock) ? $topic_lock : (($post_data['topic_status'] == ITEM_LOCKED) ? 1 : 0); 1834 $lock_post_checked = (isset($post_lock)) ? $post_lock : $post_data['post_edit_locked']; 1835 1836 // If the user is replying or posting and not already watching this topic but set to always being notified we need to overwrite this setting 1837 $notify_set = ($mode != 'edit' && $config['allow_topic_notify'] && $user->data['is_registered'] && !$post_data['notify_set']) ? $user->data['user_notify'] : $post_data['notify_set']; 1838 $notify_checked = (isset($notify)) ? $notify : (($mode == 'post') ? $user->data['user_notify'] : $notify_set); 1839 1840 // Page title & action URL 1841 $s_action = append_sid("{$phpbb_root_path}posting.$phpEx", "mode=$mode"); 1842 1843 switch ($mode) 1844 { 1845 case 'post': 1846 $s_action .= $forum_id ? "&f=$forum_id" : ''; 1847 $page_title = $user->lang['POST_TOPIC']; 1848 break; 1849 1850 case 'reply': 1851 $s_action .= $topic_id ? "&t=$topic_id" : ''; 1852 $page_title = $user->lang['POST_REPLY']; 1853 break; 1854 1855 case 'quote': 1856 $s_action .= $post_id ? "&p=$post_id" : ''; 1857 $page_title = $user->lang['POST_REPLY']; 1858 break; 1859 1860 case 'delete': 1861 case 'edit': 1862 $s_action .= $post_id ? "&p=$post_id" : ''; 1863 $page_title = $user->lang['EDIT_POST']; 1864 break; 1865 } 1866 1867 // Build Navigation Links 1868 generate_forum_nav($post_data); 1869 1870 // Build Forum Rules 1871 generate_forum_rules($post_data); 1872 1873 // Posting uses is_solved for legacy reasons. Plugins have to use is_solved to force themselves to be displayed. 1874 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === false) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote')) 1875 { 1876 1877 $template->assign_vars(array( 1878 'S_CONFIRM_CODE' => true, 1879 'CAPTCHA_TEMPLATE' => $captcha->get_template(), 1880 )); 1881 } 1882 1883 $s_hidden_fields = ($mode == 'reply' || $mode == 'quote') ? '<input type="hidden" name="topic_cur_post_id" value="' . $post_data['topic_last_post_id'] . '" />' : ''; 1884 $s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input type="hidden" name="draft_loaded" value="' . $request->variable('draft_loaded', $draft_id) . '" />' : ''; 1885 1886 if ($mode == 'edit') 1887 { 1888 $s_hidden_fields .= build_hidden_fields(array( 1889 'edit_post_message_checksum' => $post_data['post_checksum'], 1890 'edit_post_subject_checksum' => $post_data['post_subject_md5'], 1891 )); 1892 } 1893 1894 // Add the confirm id/code pair to the hidden fields, else an error is displayed on next submit/preview 1895 if (isset($captcha) && $captcha->is_solved() !== false) 1896 { 1897 $s_hidden_fields .= build_hidden_fields($captcha->get_hidden_fields()); 1898 } 1899 1900 $form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_attachments'] || !$auth->acl_get('u_attach') || !$auth->acl_get('f_attach', $forum_id)) ? '' : ' enctype="multipart/form-data"'; 1901 add_form_key('posting'); 1902 1903 /** @var \phpbb\controller\helper $controller_helper */ 1904 $controller_helper = $phpbb_container->get('controller.helper'); 1905 1906 // Build array of variables for main posting page 1907 $page_data = array( 1908 'L_POST_A' => $page_title, 1909 'L_ICON' => ($mode == 'reply' || $mode == 'quote' || ($mode == 'edit' && $post_id != $post_data['topic_first_post_id'])) ? $user->lang['POST_ICON'] : $user->lang['TOPIC_ICON'], 1910 'L_MESSAGE_BODY_EXPLAIN' => $user->lang('MESSAGE_BODY_EXPLAIN', (int) $config['max_post_chars']), 1911 'L_DELETE_POST_PERMANENTLY' => $user->lang('DELETE_POST_PERMANENTLY', 1), 1912 1913 'FORUM_NAME' => $post_data['forum_name'], 1914 'FORUM_DESC' => ($post_data['forum_desc']) ? generate_text_for_display($post_data['forum_desc'], $post_data['forum_desc_uid'], $post_data['forum_desc_bitfield'], $post_data['forum_desc_options']) : '', 1915 'TOPIC_TITLE' => censor_text($post_data['topic_title']), 1916 'MODERATORS' => (count($moderators)) ? implode($user->lang['COMMA_SEPARATOR'], $moderators[$forum_id]) : '', 1917 'USERNAME' => ((!$preview && $mode != 'quote') || $preview) ? $post_data['username'] : '', 1918 'SUBJECT' => $post_data['post_subject'], 1919 'MESSAGE' => $post_data['post_text'], 1920 'BBCODE_STATUS' => $user->lang(($bbcode_status ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'), 1921 'IMG_STATUS' => ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'], 1922 'FLASH_STATUS' => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'], 1923 'SMILIES_STATUS' => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'], 1924 'URL_STATUS' => ($bbcode_status && $url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'], 1925 'MAX_FONT_SIZE' => (int) $config['max_post_font_size'], 1926 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']), 1927 'POST_DATE' => ($post_data['post_time']) ? $user->format_date($post_data['post_time']) : '', 1928 'ERROR' => (count($error)) ? implode('<br />', $error) : '', 1929 'TOPIC_TIME_LIMIT' => (int) $post_data['topic_time_limit'], 1930 'EDIT_REASON' => $request->variable('edit_reason', '', true), 1931 'SHOW_PANEL' => $request->variable('show_panel', ''), 1932 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"), 1933 'U_VIEW_TOPIC' => ($mode != 'post') ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id") : '', 1934 'U_PROGRESS_BAR' => append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup"), 1935 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup")), 1936 1937 'S_PRIVMSGS' => false, 1938 'S_CLOSE_PROGRESS_WINDOW' => (isset($_POST['add_file'])) ? true : false, 1939 'S_EDIT_POST' => ($mode == 'edit') ? true : false, 1940 'S_EDIT_REASON' => ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false, 1941 'S_DISPLAY_USERNAME' => (!$user->data['is_registered'] || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS)) ? true : false, 1942 'S_SHOW_TOPIC_ICONS' => $s_topic_icons, 1943 'S_DELETE_ALLOWED' => ($mode == 'edit' && (($post_id == $post_data['topic_last_post_id'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id) && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time'])) || $auth->acl_get('m_delete', $forum_id))) ? true : false, 1944 'S_BBCODE_ALLOWED' => ($bbcode_status) ? 1 : 0, 1945 'S_BBCODE_CHECKED' => ($bbcode_checked) ? ' checked="checked"' : '', 1946 'S_SMILIES_ALLOWED' => $smilies_status, 1947 'S_SMILIES_CHECKED' => ($smilies_checked) ? ' checked="checked"' : '', 1948 'S_SIG_ALLOWED' => ($auth->acl_get('f_sigs', $forum_id) && $config['allow_sig'] && $user->data['is_registered']) ? true : false, 1949 'S_SIGNATURE_CHECKED' => ($sig_checked) ? ' checked="checked"' : '', 1950 'S_NOTIFY_ALLOWED' => (!$user->data['is_registered'] || ($mode == 'edit' && $user->data['user_id'] != $post_data['poster_id']) || !$config['allow_topic_notify'] || !$config['email_enable']) ? false : true, 1951 'S_NOTIFY_CHECKED' => ($notify_checked) ? ' checked="checked"' : '', 1952 'S_LOCK_TOPIC_ALLOWED' => (($mode == 'edit' || $mode == 'reply' || $mode == 'quote' || $mode == 'post') && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED))) ? true : false, 1953 'S_LOCK_TOPIC_CHECKED' => ($lock_topic_checked) ? ' checked="checked"' : '', 1954 'S_LOCK_POST_ALLOWED' => ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false, 1955 'S_LOCK_POST_CHECKED' => ($lock_post_checked) ? ' checked="checked"' : '', 1956 'S_SOFTDELETE_CHECKED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? ' checked="checked"' : '', 1957 'S_SOFTDELETE_ALLOWED' => ($mode == 'edit' && $phpbb_content_visibility->can_soft_delete($forum_id, $post_data['poster_id'], $lock_post_checked) && $post_id == $post_data['topic_last_post_id'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time'])) ? true : false, 1958 'S_RESTORE_ALLOWED' => $auth->acl_get('m_approve', $forum_id), 1959 'S_IS_DELETED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? true : false, 1960 'S_LINKS_ALLOWED' => $url_status, 1961 'S_MAGIC_URL_CHECKED' => ($urls_checked) ? ' checked="checked"' : '', 1962 'S_TYPE_TOGGLE' => $topic_type_toggle, 1963 'S_SAVE_ALLOWED' => ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $mode != 'edit') ? true : false, 1964 'S_HAS_DRAFTS' => ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $post_data['drafts']) ? true : false, 1965 'S_FORM_ENCTYPE' => $form_enctype, 1966 1967 'S_BBCODE_IMG' => $img_status, 1968 'S_BBCODE_URL' => $url_status, 1969 'S_BBCODE_FLASH' => $flash_status, 1970 'S_BBCODE_QUOTE' => $quote_status, 1971 1972 'S_POST_ACTION' => $s_action, 1973 'S_HIDDEN_FIELDS' => $s_hidden_fields, 1974 'S_ATTACH_DATA' => json_encode($message_parser->attachment_data), 1975 'S_IN_POSTING' => true, 1976 ); 1977 1978 // Build custom bbcodes array 1979 display_custom_bbcodes(); 1980 1981 // Poll entry 1982 if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/)) 1983 && $auth->acl_get('f_poll', $forum_id)) 1984 { 1985 $page_data = array_merge($page_data, array( 1986 'S_SHOW_POLL_BOX' => true, 1987 'S_POLL_VOTE_CHANGE' => ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id)), 1988 'S_POLL_DELETE' => ($mode == 'edit' && count($post_data['poll_options']) && ((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id))), 1989 'S_POLL_DELETE_CHECKED' => (!empty($poll_delete)) ? true : false, 1990 1991 'L_POLL_OPTIONS_EXPLAIN' => $user->lang('POLL_OPTIONS_' . (($mode == 'edit') ? 'EDIT_' : '') . 'EXPLAIN', (int) $config['max_poll_options']), 1992 1993 'VOTE_CHANGE_CHECKED' => (!empty($post_data['poll_vote_change'])) ? ' checked="checked"' : '', 1994 'POLL_TITLE' => (isset($post_data['poll_title'])) ? $post_data['poll_title'] : '', 1995 'POLL_OPTIONS' => (!empty($post_data['poll_options'])) ? implode("\n", $post_data['poll_options']) : '', 1996 'POLL_MAX_OPTIONS' => (isset($post_data['poll_max_options'])) ? (int) $post_data['poll_max_options'] : 1, 1997 'POLL_LENGTH' => $post_data['poll_length'], 1998 ) 1999 ); 2000 } 2001 2002 /** 2003 * This event allows you to modify template variables for the posting screen 2004 * 2005 * @event core.posting_modify_template_vars 2006 * @var array post_data Array with post data 2007 * @var array moderators Array with forum moderators 2008 * @var string mode What action to take if the form is submitted 2009 * post|reply|quote|edit|delete|bump|smilies|popup 2010 * @var string page_title Title of the mode page 2011 * @var bool s_topic_icons Whether or not to show the topic icons 2012 * @var string form_enctype If attachments are allowed for this form 2013 * "multipart/form-data" or empty string 2014 * @var string s_action The URL to submit the POST data to 2015 * @var string s_hidden_fields Concatenated hidden input tags of posting form 2016 * @var int post_id ID of the post 2017 * @var int topic_id ID of the topic 2018 * @var int forum_id ID of the forum 2019 * @var int draft_id ID of the draft 2020 * @var bool submit Whether or not the form has been submitted 2021 * @var bool preview Whether or not the post is being previewed 2022 * @var bool save Whether or not a draft is being saved 2023 * @var bool load Whether or not a draft is being loaded 2024 * @var bool cancel Whether or not to cancel the form (returns to 2025 * viewtopic or viewforum depending on if the user 2026 * is posting a new topic or editing a post) 2027 * @var array error Any error strings; a non-empty array aborts 2028 * form submission. 2029 * NOTE: Should be actual language strings, NOT 2030 * language keys. 2031 * @var bool refresh Whether or not to retain previously submitted data 2032 * @var array page_data Posting page data that should be passed to the 2033 * posting page via $template->assign_vars() 2034 * @var object message_parser The message parser object 2035 * @since 3.1.0-a1 2036 * @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title, 2037 * s_topic_icons, form_enctype, s_action, s_hidden_fields, 2038 * post_id, topic_id, forum_id, submit, preview, save, load, 2039 * delete, cancel, refresh, error, page_data, message_parser 2040 * @changed 3.1.2-RC1 Removed 'delete' var as it does not exist 2041 * @changed 3.1.5-RC1 Added poll variables to the page_data array 2042 * @changed 3.1.6-RC1 Added 'draft_id' var 2043 */ 2044 $vars = array( 2045 'post_data', 2046 'moderators', 2047 'mode', 2048 'page_title', 2049 's_topic_icons', 2050 'form_enctype', 2051 's_action', 2052 's_hidden_fields', 2053 'post_id', 2054 'topic_id', 2055 'forum_id', 2056 'draft_id', 2057 'submit', 2058 'preview', 2059 'save', 2060 'load', 2061 'cancel', 2062 'refresh', 2063 'error', 2064 'page_data', 2065 'message_parser', 2066 ); 2067 extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', compact($vars))); 2068 2069 // Start assigning vars for main posting page ... 2070 $template->assign_vars($page_data); 2071 2072 // Show attachment box for adding attachments if true 2073 $allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype); 2074 2075 if ($allowed) 2076 { 2077 $max_files = ($auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) ? 0 : (int) $config['max_attachments']; 2078 $plupload->configure($cache, $template, $s_action, $forum_id, $max_files); 2079 } 2080 2081 // Attachment entry 2082 posting_gen_attachment_entry($attachment_data, $filename_data, $allowed, $forum_id); 2083 2084 // Output page ... 2085 page_header($page_title); 2086 2087 $template->set_filenames(array( 2088 'body' => 'posting_body.html') 2089 ); 2090 2091 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx")); 2092 2093 // Topic review 2094 if ($mode == 'reply' || $mode == 'quote') 2095 { 2096 if (topic_review($topic_id, $forum_id)) 2097 { 2098 $template->assign_var('S_DISPLAY_REVIEW', true); 2099 } 2100 } 2101 2102 page_footer();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Nov 4 14:26:03 2023 | Cross-referenced by PHPXref 0.7.1 |