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