Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
posting.php
0001 <?php
0002 /**
0003 *
0004 * This file is part of the phpBB Forum Software package.
0005 *
0006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007 * @license GNU General Public License, version 2 (GPL-2.0)
0008 *
0009 * For full copyright and license information, please see
0010 * the docs/CREDITS.txt file.
0011 *
0012 */
0013
0014 /**
0015 * @ignore
0016 */
0017 define('IN_PHPBB', true);
0018 $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
0019 $phpEx = substr(strrchr(__FILE__, '.'), 1);
0020 include($phpbb_root_path . 'common.' . $phpEx);
0021 include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
0022 include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0023 include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
0024
0025
0026 // Start session management
0027 $user->session_begin();
0028 $auth->acl($user->data);
0029
0030
0031 // Grab only parameters needed here
0032 $draft_id = $request->variable('d', 0);
0033
0034 $preview = (isset($_POST['preview'])) ? true : false;
0035 $save = (isset($_POST['save'])) ? true : false;
0036 $load = (isset($_POST['load'])) ? true : false;
0037 $confirm = $request->is_set_post('confirm');
0038 $cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;
0039
0040 $refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load || $preview);
0041 $submit = $request->is_set_post('post') && !$refresh && !$preview;
0042 $mode = $request->variable('mode', '');
0043
0044 // Only assign required URL parameters
0045 $forum_id = 0;
0046 $topic_id = 0;
0047 $post_id = 0;
0048
0049 switch ($mode)
0050 {
0051 case 'popup':
0052 case 'smilies':
0053 $forum_id = $request->variable('f', 0);
0054 break;
0055
0056 case 'post':
0057 $forum_id = $request->variable('f', 0);
0058 if (!$forum_id)
0059 {
0060 trigger_error('NO_FORUM');
0061 }
0062 break;
0063
0064 case 'bump':
0065 case 'reply':
0066 $topic_id = $request->variable('t', 0);
0067 if ($topic_id)
0068 {
0069 $sql = 'SELECT forum_id
0070 FROM ' . TOPICS_TABLE . "
0071 WHERE topic_id = $topic_id";
0072 $result = $db->sql_query($sql);
0073 $forum_id = (int) $db->sql_fetchfield('forum_id');
0074 $db->sql_freeresult($result);
0075 }
0076
0077 if (!$topic_id || !$forum_id)
0078 {
0079 trigger_error('NO_TOPIC');
0080 }
0081 break;
0082
0083 case 'edit':
0084 case 'delete':
0085 case 'quote':
0086 case 'soft_delete':
0087 $post_id = $request->variable('p', 0);
0088 if ($post_id)
0089 {
0090 $topic_forum = [];
0091
0092 $sql = 'SELECT t.topic_id, t.forum_id
0093 FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
0094 WHERE p.post_id = ' . $post_id . '
0095 AND t.topic_id = p.topic_id';
0096 $result = $db->sql_query($sql);
0097 $topic_forum = $db->sql_fetchrow($result);
0098 $db->sql_freeresult($result);
0099 }
0100
0101 if (!$post_id || !$topic_forum)
0102 {
0103 $user->setup('posting');
0104 trigger_error('NO_POST');
0105 }
0106
0107 // Need to update session forum_id to valid value for proper viewonline information
0108 if (!$forum_id)
0109 {
0110 $user->page['forum'] = (int) $topic_forum['forum_id'];
0111 $user->update_session_page = true;
0112 $user->update_session_infos();
0113 }
0114
0115 $topic_id = (int) $topic_forum['topic_id'];
0116 $forum_id = (int) $topic_forum['forum_id'];
0117
0118 break;
0119 }
0120
0121 // If the user is not allowed to delete the post, we try to soft delete it, so we overwrite the mode here.
0122 if ($mode == 'delete' && (($confirm && !$request->is_set_post('delete_permanent')) || !$auth->acl_gets('f_delete', 'm_delete', $forum_id)))
0123 {
0124 $mode = 'soft_delete';
0125 }
0126
0127 $error = $post_data = array();
0128 $current_time = time();
0129
0130 /**
0131 * This event allows you to alter the above parameters, such as submit and mode
0132 *
0133 * Note: $refresh must be true to retain previously submitted form data.
0134 *
0135 * Note: The template class will not work properly until $user->setup() is
0136 * called, and it has not been called yet. Extensions requiring template
0137 * assignments should use an event that comes later in this file.
0138 *
0139 * @event core.modify_posting_parameters
0140 * @var int post_id ID of the post
0141 * @var int topic_id ID of the topic
0142 * @var int forum_id ID of the forum
0143 * @var int draft_id ID of the draft
0144 * @var bool submit Whether or not the form has been submitted
0145 * @var bool preview Whether or not the post is being previewed
0146 * @var bool save Whether or not a draft is being saved
0147 * @var bool load Whether or not a draft is being loaded
0148 * @var bool cancel Whether or not to cancel the form (returns to
0149 * viewtopic or viewforum depending on if the user
0150 * is posting a new topic or editing a post)
0151 * @var bool refresh Whether or not to retain previously submitted data
0152 * @var string mode What action to take if the form has been submitted
0153 * post|reply|quote|edit|delete|bump|smilies|popup
0154 * @var array error Any error strings; a non-empty array aborts
0155 * form submission.
0156 * NOTE: Should be actual language strings, NOT
0157 * language keys.
0158 * @since 3.1.0-a1
0159 * @changed 3.1.2-RC1 Removed 'delete' var as it does not exist
0160 * @changed 3.2.4-RC1 Remove unused 'lastclick' var
0161 */
0162 $vars = array(
0163 'post_id',
0164 'topic_id',
0165 'forum_id',
0166 'draft_id',
0167 'submit',
0168 'preview',
0169 'save',
0170 'load',
0171 'cancel',
0172 'refresh',
0173 'mode',
0174 'error',
0175 );
0176 extract($phpbb_dispatcher->trigger_event('core.modify_posting_parameters', compact($vars)));
0177
0178 // Was cancel pressed? If so then redirect to the appropriate page
0179 if ($cancel)
0180 {
0181 $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")));
0182 redirect($redirect);
0183 }
0184
0185 /* @var $phpbb_content_visibility \phpbb\content_visibility */
0186 $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0187
0188 // We need to know some basic information in all cases before we do anything.
0189 switch ($mode)
0190 {
0191 case 'post':
0192 $sql = 'SELECT *
0193 FROM ' . FORUMS_TABLE . "
0194 WHERE forum_id = $forum_id";
0195 break;
0196
0197 case 'bump':
0198 case 'reply':
0199 $sql = 'SELECT f.*, t.*
0200 FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f
0201 WHERE t.topic_id = $topic_id
0202 AND f.forum_id = t.forum_id
0203 AND " . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.');
0204 break;
0205
0206 case 'quote':
0207 case 'edit':
0208 case 'delete':
0209 case 'soft_delete':
0210 $sql = 'SELECT f.*, t.*, p.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_sig_bbcode_bitfield
0211 FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . ' f, ' . USERS_TABLE . " u
0212 WHERE p.post_id = $post_id
0213 AND t.topic_id = p.topic_id
0214 AND u.user_id = p.poster_id
0215 AND f.forum_id = t.forum_id
0216 AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.');
0217 break;
0218
0219 case 'smilies':
0220 $sql = '';
0221 generate_smilies('window', $forum_id);
0222 break;
0223
0224 case 'popup':
0225 if ($forum_id)
0226 {
0227 $sql = 'SELECT forum_style
0228 FROM ' . FORUMS_TABLE . '
0229 WHERE forum_id = ' . $forum_id;
0230 }
0231 else
0232 {
0233 phpbb_upload_popup();
0234 return;
0235 }
0236 break;
0237
0238 default:
0239 $sql = '';
0240 break;
0241 }
0242
0243 if (!$sql)
0244 {
0245 $user->setup('posting');
0246 trigger_error('NO_POST_MODE');
0247 }
0248
0249 $result = $db->sql_query($sql);
0250 $post_data = $db->sql_fetchrow($result);
0251 $db->sql_freeresult($result);
0252
0253 if (!$post_data)
0254 {
0255 if (!($mode == 'post' || $mode == 'bump' || $mode == 'reply'))
0256 {
0257 $user->setup('posting');
0258 }
0259 trigger_error(($mode == 'post' || $mode == 'bump' || $mode == 'reply') ? 'NO_TOPIC' : 'NO_POST');
0260 }
0261
0262 /**
0263 * This event allows you to bypass reply/quote test of an unapproved post.
0264 *
0265 * @event core.posting_modify_row_data
0266 * @var array post_data All post data from database
0267 * @var string mode What action to take if the form has been submitted
0268 * post|reply|quote|edit|delete|bump|smilies|popup
0269 * @var int topic_id ID of the topic
0270 * @var int forum_id ID of the forum
0271 * @since 3.2.8-RC1
0272 */
0273 $vars = array(
0274 'post_data',
0275 'mode',
0276 'topic_id',
0277 'forum_id',
0278 );
0279 extract($phpbb_dispatcher->trigger_event('core.posting_modify_row_data', compact($vars)));
0280
0281 // Not able to reply to unapproved posts/topics
0282 // TODO: add more descriptive language key
0283 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)))
0284 {
0285 trigger_error(($mode == 'reply' || $mode == 'bump') ? 'TOPIC_UNAPPROVED' : 'POST_UNAPPROVED');
0286 }
0287
0288 if ($mode == 'popup')
0289 {
0290 phpbb_upload_popup($post_data['forum_style']);
0291 return;
0292 }
0293
0294 $user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']);
0295
0296 // Need to login to passworded forum first?
0297 if ($post_data['forum_password'])
0298 {
0299 login_forum_box(array(
0300 'forum_id' => $forum_id,
0301 'forum_name' => $post_data['forum_name'],
0302 'forum_password' => $post_data['forum_password'])
0303 );
0304 }
0305
0306 // Check permissions
0307 if ($user->data['is_bot'])
0308 {
0309 redirect(append_sid("{$phpbb_root_path}index.$phpEx"));
0310 }
0311
0312 // Is the user able to read within this forum?
0313 if (!$auth->acl_get('f_read', $forum_id))
0314 {
0315 if ($user->data['user_id'] != ANONYMOUS)
0316 {
0317 trigger_error('USER_CANNOT_READ');
0318 }
0319 $message = $user->lang['LOGIN_EXPLAIN_POST'];
0320
0321 if ($request->is_ajax())
0322 {
0323 $json = new phpbb\json_response();
0324 $json->send(array(
0325 'title' => $user->lang['INFORMATION'],
0326 'message' => $message,
0327 ));
0328 }
0329
0330 login_box('', $message);
0331 }
0332
0333 // Permission to do the action asked?
0334 $is_authed = false;
0335
0336 switch ($mode)
0337 {
0338 case 'post':
0339 if ($auth->acl_get('f_post', $forum_id))
0340 {
0341 $is_authed = true;
0342 }
0343 break;
0344
0345 case 'bump':
0346 if ($auth->acl_get('f_bump', $forum_id))
0347 {
0348 $is_authed = true;
0349 }
0350 break;
0351
0352 case 'quote':
0353
0354 $post_data['post_edit_locked'] = 0;
0355
0356 // no break;
0357
0358 case 'reply':
0359 if ($auth->acl_get('f_reply', $forum_id))
0360 {
0361 $is_authed = true;
0362 }
0363 break;
0364
0365 case 'edit':
0366 if ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id))
0367 {
0368 $is_authed = true;
0369 }
0370 break;
0371
0372 case 'delete':
0373 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))))
0374 {
0375 $is_authed = true;
0376 }
0377
0378 // no break;
0379
0380 case 'soft_delete':
0381 if (!$is_authed && $user->data['is_registered'] && $phpbb_content_visibility->can_soft_delete($forum_id, $post_data['poster_id'], $post_data['post_edit_locked']))
0382 {
0383 // Fall back to soft_delete if we have no permissions to delete posts but to soft delete them
0384 $is_authed = true;
0385 $mode = 'soft_delete';
0386 }
0387 break;
0388 }
0389 /**
0390 * This event allows you to do extra auth checks and verify if the user
0391 * has the required permissions
0392 *
0393 * Extensions should only change the error and is_authed variables.
0394 *
0395 * @event core.modify_posting_auth
0396 * @var int post_id ID of the post
0397 * @var int topic_id ID of the topic
0398 * @var int forum_id ID of the forum
0399 * @var int draft_id ID of the draft
0400 * @var bool submit Whether or not the form has been submitted
0401 * @var bool preview Whether or not the post is being previewed
0402 * @var bool save Whether or not a draft is being saved
0403 * @var bool load Whether or not a draft is being loaded
0404 * @var bool refresh Whether or not to retain previously submitted data
0405 * @var string mode What action to take if the form has been submitted
0406 * post|reply|quote|edit|delete|bump|smilies|popup
0407 * @var array error Any error strings; a non-empty array aborts
0408 * form submission.
0409 * NOTE: Should be actual language strings, NOT
0410 * language keys.
0411 * @var bool is_authed Does the user have the required permissions?
0412 * @var array post_data All post data from database
0413 * @since 3.1.3-RC1
0414 * @changed 3.1.10-RC1 Added post_data
0415 * @changed 3.2.4-RC1 Remove unused 'lastclick' var
0416 */
0417 $vars = array(
0418 'post_id',
0419 'topic_id',
0420 'forum_id',
0421 'draft_id',
0422 'submit',
0423 'preview',
0424 'save',
0425 'load',
0426 'refresh',
0427 'mode',
0428 'error',
0429 'is_authed',
0430 'post_data',
0431 );
0432 extract($phpbb_dispatcher->trigger_event('core.modify_posting_auth', compact($vars)));
0433
0434 if (!$is_authed || !empty($error))
0435 {
0436 $check_auth = ($mode == 'quote') ? 'reply' : (($mode == 'soft_delete') ? 'delete' : $mode);
0437
0438 if ($user->data['is_registered'])
0439 {
0440 trigger_error(empty($error) ? 'USER_CANNOT_' . strtoupper($check_auth) : implode('<br/>', $error));
0441 }
0442 $message = $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)];
0443
0444 if ($request->is_ajax())
0445 {
0446 $json = new phpbb\json_response();
0447 $json->send(array(
0448 'title' => $user->lang['INFORMATION'],
0449 'message' => $message,
0450 ));
0451 }
0452
0453 login_box('', $message);
0454 }
0455
0456 if ($config['enable_post_confirm'] && !$user->data['is_registered'])
0457 {
0458 $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
0459 $captcha->init(CONFIRM_POST);
0460 }
0461
0462 // Is the user able to post within this forum?
0463 if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply')))
0464 {
0465 trigger_error('USER_CANNOT_FORUM_POST');
0466 }
0467
0468 // Forum/Topic locked?
0469 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))
0470 {
0471 trigger_error(($post_data['forum_status'] == ITEM_LOCKED) ? 'FORUM_LOCKED' : 'TOPIC_LOCKED');
0472 }
0473
0474 // Can we edit this post ... if we're a moderator with rights then always yes
0475 // else it depends on editing times, lock status and if we're the correct user
0476 if ($mode == 'edit' && !$auth->acl_get('m_edit', $forum_id))
0477 {
0478 $force_edit_allowed = false;
0479
0480 $s_cannot_edit = $user->data['user_id'] != $post_data['poster_id'];
0481 $s_cannot_edit_time = $config['edit_time'] && $post_data['post_time'] <= time() - ($config['edit_time'] * 60);
0482 $s_cannot_edit_locked = $post_data['post_edit_locked'];
0483
0484 /**
0485 * This event allows you to modify the conditions for the "cannot edit post" checks
0486 *
0487 * @event core.posting_modify_cannot_edit_conditions
0488 * @var array post_data Array with post data
0489 * @var bool force_edit_allowed Allow the user to edit the post (all permissions and conditions are ignored)
0490 * @var bool s_cannot_edit User can not edit the post because it's not his
0491 * @var bool s_cannot_edit_locked User can not edit the post because it's locked
0492 * @var bool s_cannot_edit_time User can not edit the post because edit_time has passed
0493 * @since 3.1.0-b4
0494 */
0495 $vars = array(
0496 'post_data',
0497 'force_edit_allowed',
0498 's_cannot_edit',
0499 's_cannot_edit_locked',
0500 's_cannot_edit_time',
0501 );
0502 extract($phpbb_dispatcher->trigger_event('core.posting_modify_cannot_edit_conditions', compact($vars)));
0503
0504 if (!$force_edit_allowed)
0505 {
0506 if ($s_cannot_edit)
0507 {
0508 trigger_error('USER_CANNOT_EDIT');
0509 }
0510 else if ($s_cannot_edit_time)
0511 {
0512 trigger_error('CANNOT_EDIT_TIME');
0513 }
0514 else if ($s_cannot_edit_locked)
0515 {
0516 trigger_error('CANNOT_EDIT_POST_LOCKED');
0517 }
0518 }
0519 }
0520
0521 // Handle delete mode...
0522 if ($mode == 'delete' || $mode == 'soft_delete')
0523 {
0524 if ($mode == 'soft_delete' && $post_data['post_visibility'] == ITEM_DELETED)
0525 {
0526 $user->setup('posting');
0527 trigger_error('NO_POST');
0528 }
0529
0530 $delete_reason = $request->variable('delete_reason', '', true);
0531 phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, ($mode == 'soft_delete' && !$request->is_set_post('delete_permanent')), $delete_reason);
0532 return;
0533 }
0534
0535 // Handle bump mode...
0536 if ($mode == 'bump')
0537 {
0538 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'])
0539 && check_link_hash($request->variable('hash', ''), "topic_{$post_data['topic_id']}"))
0540 {
0541 $meta_url = phpbb_bump_topic($forum_id, $topic_id, $post_data, $current_time);
0542 meta_refresh(3, $meta_url);
0543 $message = $user->lang['TOPIC_BUMPED'];
0544
0545 if (!$request->is_ajax())
0546 {
0547 $message .= '<br /><br />' . $user->lang('VIEW_MESSAGE', '<a href="' . $meta_url . '">', '</a>');
0548 $message .= '<br /><br />' . $user->lang('RETURN_FORUM', '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
0549 }
0550
0551 trigger_error($message);
0552 }
0553
0554 trigger_error('BUMP_ERROR');
0555 }
0556
0557 // Subject length limiting to 60 characters if first post...
0558 if ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_data['post_id']))
0559 {
0560 $template->assign_var('S_NEW_MESSAGE', true);
0561 }
0562
0563 // Determine some vars
0564 if (isset($post_data['poster_id']) && $post_data['poster_id'] == ANONYMOUS)
0565 {
0566 $post_data['quote_username'] = (!empty($post_data['post_username'])) ? $post_data['post_username'] : $user->lang['GUEST'];
0567 }
0568 else
0569 {
0570 $post_data['quote_username'] = isset($post_data['username']) ? $post_data['username'] : '';
0571 }
0572
0573 $post_data['post_edit_locked'] = (isset($post_data['post_edit_locked'])) ? (int) $post_data['post_edit_locked'] : 0;
0574 $post_data['post_subject_md5'] = (isset($post_data['post_subject']) && $mode == 'edit') ? md5($post_data['post_subject']) : '';
0575 $post_data['post_subject'] = (in_array($mode, array('quote', 'edit'))) ? $post_data['post_subject'] : ((isset($post_data['topic_title'])) ? $post_data['topic_title'] : '');
0576 $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;
0577 $post_data['poll_length'] = (!empty($post_data['poll_length'])) ? (int) $post_data['poll_length'] / 86400 : 0;
0578 $post_data['poll_start'] = (!empty($post_data['poll_start'])) ? (int) $post_data['poll_start'] : 0;
0579 $post_data['icon_id'] = (!isset($post_data['icon_id']) || in_array($mode, array('quote', 'reply'))) ? 0 : (int) $post_data['icon_id'];
0580 $post_data['poll_options'] = array();
0581
0582 // Get Poll Data
0583 if ($post_data['poll_start'])
0584 {
0585 $sql = 'SELECT poll_option_text
0586 FROM ' . POLL_OPTIONS_TABLE . "
0587 WHERE topic_id = $topic_id
0588 ORDER BY poll_option_id";
0589 $result = $db->sql_query($sql);
0590
0591 while ($row = $db->sql_fetchrow($result))
0592 {
0593 $post_data['poll_options'][] = trim($row['poll_option_text']);
0594 }
0595 $db->sql_freeresult($result);
0596 }
0597
0598 /**
0599 * This event allows you to modify the post data before parsing
0600 *
0601 * @event core.posting_modify_post_data
0602 * @var int forum_id ID of the forum
0603 * @var string mode What action to take if the form has been submitted
0604 * post|reply|quote|edit|delete|bump|smilies|popup
0605 * @var array post_data Array with post data
0606 * @var int post_id ID of the post
0607 * @var int topic_id ID of the topic
0608 * @since 3.2.2-RC1
0609 */
0610 $vars = array(
0611 'forum_id',
0612 'mode',
0613 'post_data',
0614 'post_id',
0615 'topic_id',
0616 );
0617 extract($phpbb_dispatcher->trigger_event('core.posting_modify_post_data', compact($vars)));
0618
0619 if ($mode == 'edit')
0620 {
0621 $original_poll_data = array(
0622 'poll_title' => $post_data['poll_title'],
0623 'poll_length' => $post_data['poll_length'],
0624 'poll_max_options' => $post_data['poll_max_options'],
0625 'poll_option_text' => implode("\n", $post_data['poll_options']),
0626 'poll_start' => $post_data['poll_start'],
0627 'poll_last_vote' => $post_data['poll_last_vote'],
0628 'poll_vote_change' => $post_data['poll_vote_change'],
0629 );
0630 }
0631
0632 $orig_poll_options_size = count($post_data['poll_options']);
0633
0634 $message_parser = new parse_message();
0635 /* @var $plupload \phpbb\plupload\plupload */
0636 $plupload = $phpbb_container->get('plupload');
0637
0638 /* @var $mimetype_guesser \phpbb\mimetype\guesser */
0639 $mimetype_guesser = $phpbb_container->get('mimetype.guesser');
0640 $message_parser->set_plupload($plupload);
0641
0642 if (isset($post_data['post_text']))
0643 {
0644 $message_parser->message = &$post_data['post_text'];
0645 unset($post_data['post_text']);
0646 }
0647
0648 // Set some default variables
0649 $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);
0650
0651 /**
0652 * This event allows you to modify the default variables for post_data, and unset them in post_data if needed
0653 *
0654 * @event core.posting_modify_default_variables
0655 * @var array post_data Array with post data
0656 * @var array uninit Array with default vars to put into post_data, if they aren't there
0657 * @since 3.2.5-RC1
0658 */
0659 $vars = array(
0660 'post_data',
0661 'uninit',
0662 );
0663 extract($phpbb_dispatcher->trigger_event('core.posting_modify_default_variables', compact($vars)));
0664
0665 foreach ($uninit as $var_name => $default_value)
0666 {
0667 if (!isset($post_data[$var_name]))
0668 {
0669 $post_data[$var_name] = $default_value;
0670 }
0671 }
0672 unset($uninit);
0673
0674 // Always check if the submitted attachment data is valid and belongs to the user.
0675 // Further down (especially in submit_post()) we do not check this again.
0676 $message_parser->get_submitted_attachment_data($post_data['poster_id']);
0677
0678 if ($post_data['post_attachment'] && !$submit && !$refresh && !$preview && $mode == 'edit')
0679 {
0680 // Do not change to SELECT *
0681 $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename, filesize
0682 FROM ' . ATTACHMENTS_TABLE . "
0683 WHERE post_msg_id = $post_id
0684 AND in_message = 0
0685 AND is_orphan = 0
0686 ORDER BY attach_id DESC";
0687 $result = $db->sql_query($sql);
0688 $message_parser->attachment_data = array_merge($message_parser->attachment_data, $db->sql_fetchrowset($result));
0689 $db->sql_freeresult($result);
0690 }
0691
0692 if ($post_data['poster_id'] == ANONYMOUS)
0693 {
0694 $post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['post_username']) : '';
0695 }
0696 else
0697 {
0698 $post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['username']) : '';
0699 }
0700
0701 $post_data['enable_urls'] = $post_data['enable_magic_url'];
0702
0703 if ($mode != 'edit')
0704 {
0705 $post_data['enable_sig'] = ($config['allow_sig'] && $user->optionget('attachsig')) ? true: false;
0706 $post_data['enable_smilies'] = ($config['allow_smilies'] && $user->optionget('smilies')) ? true : false;
0707 $post_data['enable_bbcode'] = ($config['allow_bbcode'] && $user->optionget('bbcode')) ? true : false;
0708 $post_data['enable_urls'] = true;
0709 }
0710
0711 if ($mode == 'post')
0712 {
0713 $post_data['topic_status'] = ($request->is_set_post('lock_topic') && $auth->acl_gets('m_lock', 'f_user_lock', $forum_id)) ? ITEM_LOCKED : ITEM_UNLOCKED;
0714 }
0715
0716 $post_data['enable_magic_url'] = $post_data['drafts'] = false;
0717
0718 // User own some drafts?
0719 if ($user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote'))
0720 {
0721 $sql = 'SELECT draft_id
0722 FROM ' . DRAFTS_TABLE . '
0723 WHERE user_id = ' . $user->data['user_id'] .
0724 (($forum_id) ? ' AND forum_id = ' . (int) $forum_id : '') .
0725 (($topic_id) ? ' AND topic_id = ' . (int) $topic_id : '') .
0726 (($draft_id) ? " AND draft_id <> $draft_id" : '');
0727 $result = $db->sql_query_limit($sql, 1);
0728
0729 if ($db->sql_fetchrow($result))
0730 {
0731 $post_data['drafts'] = true;
0732 }
0733 $db->sql_freeresult($result);
0734 }
0735
0736 $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);
0737
0738 // Check if user is watching this topic
0739 if ($mode != 'post' && $config['allow_topic_notify'] && $user->data['is_registered'])
0740 {
0741 $sql = 'SELECT topic_id
0742 FROM ' . TOPICS_WATCH_TABLE . '
0743 WHERE topic_id = ' . $topic_id . '
0744 AND user_id = ' . $user->data['user_id'];
0745 $result = $db->sql_query($sql);
0746 $post_data['notify_set'] = (int) $db->sql_fetchfield('topic_id');
0747 $db->sql_freeresult($result);
0748 }
0749
0750 // Do we want to edit our post ?
0751 if ($mode == 'edit' && $post_data['bbcode_uid'])
0752 {
0753 $message_parser->bbcode_uid = $post_data['bbcode_uid'];
0754 }
0755
0756 // HTML, BBCode, Smilies, Images and Flash status
0757 $bbcode_status = ($config['allow_bbcode'] && $auth->acl_get('f_bbcode', $forum_id)) ? true : false;
0758 $smilies_status = ($config['allow_smilies'] && $auth->acl_get('f_smilies', $forum_id)) ? true : false;
0759 $img_status = ($bbcode_status && $auth->acl_get('f_img', $forum_id)) ? true : false;
0760 $url_status = ($config['allow_post_links']) ? true : false;
0761 $flash_status = ($bbcode_status && $auth->acl_get('f_flash', $forum_id) && $config['allow_post_flash']) ? true : false;
0762 $quote_status = true;
0763
0764 /**
0765 * Event to override message BBCode status indications
0766 *
0767 * @event core.posting_modify_bbcode_status
0768 *
0769 * @var bool bbcode_status BBCode status
0770 * @var bool smilies_status Smilies status
0771 * @var bool img_status Image BBCode status
0772 * @var bool url_status URL BBCode status
0773 * @var bool flash_status Flash BBCode status
0774 * @var bool quote_status Quote BBCode status
0775 * @since 3.3.3-RC1
0776 */
0777 $vars = [
0778 'bbcode_status',
0779 'smilies_status',
0780 'img_status',
0781 'url_status',
0782 'flash_status',
0783 'quote_status',
0784 ];
0785 extract($phpbb_dispatcher->trigger_event('core.posting_modify_bbcode_status', compact($vars)));
0786
0787 // Save Draft
0788 if ($save && $user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote'))
0789 {
0790 $subject = $request->variable('subject', '', true);
0791 $subject = (!$subject && $mode != 'post') ? $post_data['topic_title'] : $subject;
0792 $message = $request->variable('message', '', true);
0793
0794 /**
0795 * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR.
0796 * Using their Numeric Character Reference's Hexadecimal notation.
0797 */
0798 $subject = utf8_encode_ucr($subject);
0799
0800 if ($subject && $message)
0801 {
0802 if (confirm_box(true))
0803 {
0804 $message_parser->message = $message;
0805 $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']);
0806
0807 $sql = 'INSERT INTO ' . DRAFTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
0808 'user_id' => (int) $user->data['user_id'],
0809 'topic_id' => (int) $topic_id,
0810 'forum_id' => (int) $forum_id,
0811 'save_time' => (int) $current_time,
0812 'draft_subject' => (string) $subject,
0813 'draft_message' => (string) $message_parser->message)
0814 );
0815 $db->sql_query($sql);
0816
0817 /** @var \phpbb\attachment\manager $attachment_manager */
0818 $attachment_manager = $phpbb_container->get('attachment.manager');
0819 $attachment_manager->delete('attach', array_column($message_parser->attachment_data, 'attach_id'));
0820
0821 $meta_info = ($mode == 'post') ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) : append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id");
0822
0823 meta_refresh(3, $meta_info);
0824
0825 $message = $user->lang['DRAFT_SAVED'] . '<br /><br />';
0826 $message .= ($mode != 'post') ? sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>') . '<br /><br />' : '';
0827 $message .= sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
0828
0829 trigger_error($message);
0830 }
0831 else
0832 {
0833 $s_hidden_fields = build_hidden_fields(array(
0834 'mode' => $mode,
0835 'save' => true,
0836 'f' => $forum_id,
0837 't' => $topic_id,
0838 'subject' => $subject,
0839 'message' => $message,
0840 'attachment_data' => $message_parser->attachment_data,
0841 )
0842 );
0843
0844 $hidden_fields = array(
0845 'icon_id' => 0,
0846
0847 'disable_bbcode' => false,
0848 'disable_smilies' => false,
0849 'disable_magic_url' => false,
0850 'attach_sig' => true,
0851 'notify' => false,
0852 'lock_topic' => false,
0853
0854 'topic_type' => POST_NORMAL,
0855 'topic_time_limit' => 0,
0856
0857 'poll_title' => '',
0858 'poll_option_text' => '',
0859 'poll_max_options' => 1,
0860 'poll_length' => 0,
0861 'poll_vote_change' => false,
0862 );
0863
0864 foreach ($hidden_fields as $name => $default)
0865 {
0866 if (!isset($_POST[$name]))
0867 {
0868 // Don't include it, if its not available
0869 unset($hidden_fields[$name]);
0870 continue;
0871 }
0872
0873 if (is_bool($default))
0874 {
0875 // Use the string representation
0876 $hidden_fields[$name] = $request->variable($name, '');
0877 }
0878 else
0879 {
0880 $hidden_fields[$name] = $request->variable($name, $default);
0881 }
0882 }
0883
0884 $s_hidden_fields .= build_hidden_fields($hidden_fields);
0885
0886 confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields);
0887 }
0888 }
0889 else
0890 {
0891 if (utf8_clean_string($subject) === '')
0892 {
0893 $error[] = $user->lang['EMPTY_SUBJECT'];
0894 }
0895
0896 if (utf8_clean_string($message) === '')
0897 {
0898 $error[] = $user->lang['TOO_FEW_CHARS'];
0899 }
0900 }
0901 unset($subject, $message);
0902 }
0903
0904 // Load requested Draft
0905 if ($draft_id && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $user->data['is_registered'] && $auth->acl_get('u_savedrafts'))
0906 {
0907 $sql = 'SELECT draft_subject, draft_message
0908 FROM ' . DRAFTS_TABLE . "
0909 WHERE draft_id = $draft_id
0910 AND user_id = " . $user->data['user_id'];
0911 $result = $db->sql_query_limit($sql, 1);
0912 $row = $db->sql_fetchrow($result);
0913 $db->sql_freeresult($result);
0914
0915 if ($row)
0916 {
0917 $post_data['post_subject'] = $row['draft_subject'];
0918 $message_parser->message = $row['draft_message'];
0919
0920 $template->assign_var('S_DRAFT_LOADED', true);
0921 }
0922 else
0923 {
0924 $draft_id = 0;
0925 }
0926 }
0927
0928 // Load draft overview
0929 if ($load && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_data['drafts'])
0930 {
0931 load_drafts($topic_id, $forum_id);
0932 }
0933
0934 /** @var \phpbb\textformatter\utils_interface $bbcode_utils */
0935 $bbcode_utils = $phpbb_container->get('text_formatter.utils');
0936
0937 if ($submit || $preview || $refresh)
0938 {
0939 $post_data['topic_cur_post_id'] = $request->variable('topic_cur_post_id', 0);
0940 $post_data['post_subject'] = $request->variable('subject', '', true);
0941 $message_parser->message = $request->variable('message', '', true);
0942
0943 $post_data['username'] = $request->variable('username', $post_data['username'], true);
0944 $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) : '';
0945
0946 $post_data['orig_topic_type'] = $post_data['topic_type'];
0947 $post_data['topic_type'] = $request->variable('topic_type', (($mode != 'post') ? (int) $post_data['topic_type'] : POST_NORMAL));
0948 $post_data['topic_time_limit'] = $request->variable('topic_time_limit', (($mode != 'post') ? (int) $post_data['topic_time_limit'] : 0));
0949
0950 if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id))
0951 {
0952 $post_data['icon_id'] = $request->variable('icon', (int) $post_data['icon_id']);
0953 }
0954
0955 $post_data['enable_bbcode'] = (!$bbcode_status || isset($_POST['disable_bbcode'])) ? false : true;
0956 $post_data['enable_smilies'] = (!$smilies_status || isset($_POST['disable_smilies'])) ? false : true;
0957 $post_data['enable_urls'] = (isset($_POST['disable_magic_url'])) ? 0 : 1;
0958 $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);
0959
0960 if ($config['allow_topic_notify'] && $user->data['is_registered'])
0961 {
0962 $notify = (isset($_POST['notify'])) ? true : false;
0963 }
0964 else
0965 {
0966 $notify = false;
0967 }
0968
0969 $topic_lock = (isset($_POST['lock_topic'])) ? true : false;
0970 $post_lock = (isset($_POST['lock_post'])) ? true : false;
0971 $poll_delete = (isset($_POST['poll_delete'])) ? true : false;
0972
0973 if ($submit)
0974 {
0975 $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);
0976 $status_switch = ($status_switch != $check_value);
0977 }
0978 else
0979 {
0980 $status_switch = 1;
0981 }
0982
0983 // Delete Poll
0984 if ($poll_delete && $mode == 'edit' && count($post_data['poll_options']) &&
0985 ((!$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)))
0986 {
0987 if ($submit && check_form_key('posting'))
0988 {
0989 $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . "
0990 WHERE topic_id = $topic_id";
0991 $db->sql_query($sql);
0992
0993 $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . "
0994 WHERE topic_id = $topic_id";
0995 $db->sql_query($sql);
0996
0997 $topic_sql = array(
0998 'poll_title' => '',
0999 'poll_start' => 0,
1000 'poll_length' => 0,
1001 'poll_last_vote' => 0,
1002 'poll_max_options' => 0,
1003 'poll_vote_change' => 0
1004 );
1005
1006 $sql = 'UPDATE ' . TOPICS_TABLE . '
1007 SET ' . $db->sql_build_array('UPDATE', $topic_sql) . "
1008 WHERE topic_id = $topic_id";
1009 $db->sql_query($sql);
1010 }
1011
1012 $post_data['poll_title'] = $post_data['poll_option_text'] = '';
1013 $post_data['poll_vote_change'] = $post_data['poll_max_options'] = $post_data['poll_length'] = 0;
1014 }
1015 else
1016 {
1017 $post_data['poll_title'] = $request->variable('poll_title', '', true);
1018 $post_data['poll_length'] = $request->variable('poll_length', 0);
1019 $post_data['poll_option_text'] = $request->variable('poll_option_text', '', true);
1020 $post_data['poll_max_options'] = $request->variable('poll_max_options', 1);
1021 $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;
1022 }
1023
1024 // If replying/quoting and last post id has changed
1025 // give user option to continue submit or return to post
1026 // notify and show user the post made between his request and the final submit
1027 if (($mode == 'reply' || $mode == 'quote') && $post_data['topic_cur_post_id'] && $post_data['topic_cur_post_id'] != $post_data['topic_last_post_id'])
1028 {
1029 // Only do so if it is allowed forum-wide
1030 if ($post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW)
1031 {
1032 if (topic_review($topic_id, $forum_id, 'post_review', $post_data['topic_cur_post_id']))
1033 {
1034 $template->assign_var('S_POST_REVIEW', true);
1035 }
1036
1037 $submit = false;
1038 $refresh = true;
1039 }
1040 }
1041
1042 // Parse Attachments - before checksum is calculated
1043 if ($message_parser->check_attachment_form_token($language, $request, 'posting'))
1044 {
1045 $message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh);
1046 }
1047
1048 /**
1049 * This event allows you to modify message text before parsing
1050 *
1051 * @event core.posting_modify_message_text
1052 * @var array post_data Array with post data
1053 * @var string mode What action to take if the form is submitted
1054 * post|reply|quote|edit|delete|bump|smilies|popup
1055 * @var int post_id ID of the post
1056 * @var int topic_id ID of the topic
1057 * @var int forum_id ID of the forum
1058 * @var bool submit Whether or not the form has been submitted
1059 * @var bool preview Whether or not the post is being previewed
1060 * @var bool save Whether or not a draft is being saved
1061 * @var bool load Whether or not a draft is being loaded
1062 * @var bool cancel Whether or not to cancel the form (returns to
1063 * viewtopic or viewforum depending on if the user
1064 * is posting a new topic or editing a post)
1065 * @var bool refresh Whether or not to retain previously submitted data
1066 * @var object message_parser The message parser object
1067 * @var array error Array of errors
1068 * @since 3.1.2-RC1
1069 * @changed 3.1.11-RC1 Added error
1070 */
1071 $vars = array(
1072 'post_data',
1073 'mode',
1074 'post_id',
1075 'topic_id',
1076 'forum_id',
1077 'submit',
1078 'preview',
1079 'save',
1080 'load',
1081 'cancel',
1082 'refresh',
1083 'message_parser',
1084 'error',
1085 );
1086 extract($phpbb_dispatcher->trigger_event('core.posting_modify_message_text', compact($vars)));
1087
1088 // Grab md5 'checksum' of new message
1089 $message_md5 = md5($message_parser->message);
1090
1091 // If editing and checksum has changed we know the post was edited while we're editing
1092 // Notify and show user the changed post
1093 if ($mode == 'edit' && $post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW)
1094 {
1095 $edit_post_message_checksum = $request->variable('edit_post_message_checksum', '');
1096 $edit_post_subject_checksum = $request->variable('edit_post_subject_checksum', '');
1097
1098 // $post_data['post_checksum'] is the checksum of the post submitted in the meantime
1099 // $message_md5 is the checksum of the post we're about to submit
1100 // $edit_post_message_checksum is the checksum of the post we're editing
1101 // ...
1102
1103 // We make sure nobody else made exactly the same change
1104 // we're about to submit by also checking $message_md5 != $post_data['post_checksum']
1105 if ($edit_post_message_checksum !== '' &&
1106 $edit_post_message_checksum != $post_data['post_checksum'] &&
1107 $message_md5 != $post_data['post_checksum']
1108 ||
1109 $edit_post_subject_checksum !== '' &&
1110 $edit_post_subject_checksum != $post_data['post_subject_md5'] &&
1111 md5($post_data['post_subject']) != $post_data['post_subject_md5'])
1112 {
1113 if (topic_review($topic_id, $forum_id, 'post_review_edit', $post_id))
1114 {
1115 $template->assign_vars(array(
1116 'S_POST_REVIEW' => true,
1117
1118 'L_POST_REVIEW' => $user->lang['POST_REVIEW_EDIT'],
1119 'L_POST_REVIEW_EXPLAIN' => $user->lang['POST_REVIEW_EDIT_EXPLAIN'],
1120 ));
1121 }
1122
1123 $submit = false;
1124 $refresh = true;
1125 }
1126 }
1127
1128 // Check checksum ... don't re-parse message if the same
1129 $update_message = ($mode != 'edit' || $message_md5 != $post_data['post_checksum'] || $status_switch || strlen($post_data['bbcode_uid']) < BBCODE_UID_LEN) ? true : false;
1130
1131 // Also check if subject got updated...
1132 $update_subject = $mode != 'edit' || ($post_data['post_subject_md5'] && $post_data['post_subject_md5'] != md5($post_data['post_subject']));
1133
1134 // Parse message
1135 if ($update_message)
1136 {
1137 if (count($message_parser->warn_msg))
1138 {
1139 $error[] = implode('<br />', $message_parser->warn_msg);
1140 $message_parser->warn_msg = array();
1141 }
1142
1143 if (!$preview || !empty($message_parser->message))
1144 {
1145 $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']);
1146 }
1147
1148 // On a refresh we do not care about message parsing errors
1149 if (count($message_parser->warn_msg) && $refresh && !$preview)
1150 {
1151 $message_parser->warn_msg = array();
1152 }
1153 }
1154 else
1155 {
1156 $message_parser->bbcode_bitfield = $post_data['bbcode_bitfield'];
1157 }
1158
1159 $ignore_flood = $auth->acl_get('u_ignoreflood') ? true : $auth->acl_get('f_ignoreflood', $forum_id);
1160 if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$ignore_flood)
1161 {
1162 // Flood check
1163 $last_post_time = 0;
1164
1165 if ($user->data['is_registered'])
1166 {
1167 $last_post_time = $user->data['user_lastpost_time'];
1168 }
1169 else
1170 {
1171 $sql = 'SELECT post_time AS last_post_time
1172 FROM ' . POSTS_TABLE . "
1173 WHERE poster_ip = '" . $user->ip . "'
1174 AND post_time > " . ($current_time - $config['flood_interval']);
1175 $result = $db->sql_query_limit($sql, 1);
1176 if ($row = $db->sql_fetchrow($result))
1177 {
1178 $last_post_time = $row['last_post_time'];
1179 }
1180 $db->sql_freeresult($result);
1181 }
1182
1183 if ($last_post_time && ($current_time - $last_post_time) < intval($config['flood_interval']))
1184 {
1185 $error[] = $user->lang['FLOOD_ERROR'];
1186 }
1187 }
1188
1189 // Validate username
1190 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']))
1191 {
1192 if (!function_exists('validate_username'))
1193 {
1194 include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1195 }
1196
1197 $user->add_lang('ucp');
1198
1199 if (($result = validate_username($post_data['username'], (!empty($post_data['post_username'])) ? $post_data['post_username'] : '')) !== false)
1200 {
1201 $error[] = $user->lang[$result . '_USERNAME'];
1202 }
1203
1204 if (($result = validate_string($post_data['username'], false, $config['min_name_chars'], $config['max_name_chars'])) !== false)
1205 {
1206 $min_max_amount = ($result == 'TOO_SHORT') ? $config['min_name_chars'] : $config['max_name_chars'];
1207 $error[] = $user->lang('FIELD_' . $result, $min_max_amount, $user->lang['USERNAME']);
1208 }
1209 }
1210
1211 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply')))
1212 {
1213 $captcha_data = array(
1214 'message' => $request->variable('message', '', true),
1215 'subject' => $request->variable('subject', '', true),
1216 'username' => $request->variable('username', '', true),
1217 );
1218 $vc_response = $captcha->validate($captcha_data);
1219 if ($vc_response)
1220 {
1221 $error[] = $vc_response;
1222 }
1223 }
1224
1225 // check form
1226 if (($submit || $preview) && !check_form_key('posting'))
1227 {
1228 $error[] = $user->lang['FORM_INVALID'];
1229 }
1230
1231 if ($submit && $mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED && !$request->is_set_post('delete') && $auth->acl_get('m_approve', $forum_id))
1232 {
1233 $is_first_post = ($post_id <= $post_data['topic_first_post_id'] || !$post_data['topic_posts_approved']);
1234 $is_last_post = ($post_id >= $post_data['topic_last_post_id'] || !$post_data['topic_posts_approved']);
1235 $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);
1236
1237 if (!empty($updated_post_data))
1238 {
1239 // Update the post_data, so we don't need to refetch it.
1240 $post_data = array_merge($post_data, $updated_post_data);
1241 }
1242 }
1243
1244 // Parse subject
1245 if (!$preview && !$refresh && utf8_clean_string($post_data['post_subject']) === '' && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id)))
1246 {
1247 $error[] = $user->lang['EMPTY_SUBJECT'];
1248 }
1249
1250 /**
1251 * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR.
1252 * Using their Numeric Character Reference's Hexadecimal notation.
1253 * Check the permissions for posting Emojis first.
1254 */
1255 if ($auth->acl_get('u_emoji'))
1256 {
1257 $post_data['post_subject'] = utf8_encode_ucr($post_data['post_subject']);
1258 }
1259 else
1260 {
1261 /**
1262 * Check for out-of-bounds characters that are currently
1263 * not supported by utf8_bin in MySQL
1264 */
1265 if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $post_data['post_subject'], $matches))
1266 {
1267 $character_list = implode('<br>', $matches[0]);
1268
1269 $error[] = $user->lang('UNSUPPORTED_CHARACTERS_SUBJECT', $character_list);
1270 }
1271 }
1272
1273 $post_data['poll_last_vote'] = (isset($post_data['poll_last_vote'])) ? $post_data['poll_last_vote'] : 0;
1274
1275 if ($post_data['poll_option_text'] &&
1276 ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
1277 && $auth->acl_get('f_poll', $forum_id))
1278 {
1279 $poll = array(
1280 'poll_title' => $post_data['poll_title'],
1281 'poll_length' => $post_data['poll_length'],
1282 'poll_max_options' => $post_data['poll_max_options'],
1283 'poll_option_text' => $post_data['poll_option_text'],
1284 'poll_start' => $post_data['poll_start'],
1285 'poll_last_vote' => $post_data['poll_last_vote'],
1286 'poll_vote_change' => $post_data['poll_vote_change'],
1287 'enable_bbcode' => $post_data['enable_bbcode'],
1288 'enable_urls' => $post_data['enable_urls'],
1289 'enable_smilies' => $post_data['enable_smilies'],
1290 'img_status' => $img_status
1291 );
1292
1293 $message_parser->parse_poll($poll);
1294
1295 $post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array();
1296 $post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : '';
1297
1298 /* We reset votes, therefore also allow removing options
1299 if ($post_data['poll_last_vote'] && ($poll['poll_options_size'] < $orig_poll_options_size))
1300 {
1301 $message_parser->warn_msg[] = $user->lang['NO_DELETE_POLL_OPTIONS'];
1302 }*/
1303 }
1304 else if ($mode == 'edit' && $post_id == $post_data['topic_first_post_id'] && $auth->acl_get('f_poll', $forum_id))
1305 {
1306 // The user removed all poll options, this is equal to deleting the poll.
1307 $poll = array(
1308 'poll_title' => '',
1309 'poll_length' => 0,
1310 'poll_max_options' => 0,
1311 'poll_option_text' => '',
1312 'poll_start' => 0,
1313 'poll_last_vote' => 0,
1314 'poll_vote_change' => 0,
1315 'poll_options' => array(),
1316 );
1317
1318 $post_data['poll_options'] = array();
1319 $post_data['poll_title'] = '';
1320 $post_data['poll_start'] = $post_data['poll_length'] = $post_data['poll_max_options'] = $post_data['poll_last_vote'] = $post_data['poll_vote_change'] = 0;
1321 }
1322 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']))
1323 {
1324 // We have a poll but the editing user is not permitted to create/edit it.
1325 // So we just keep the original poll-data.
1326 // Decode the poll title and options text fisrt.
1327 $original_poll_data['poll_title'] = $bbcode_utils->unparse($original_poll_data['poll_title']);
1328 $original_poll_data['poll_option_text'] = $bbcode_utils->unparse($original_poll_data['poll_option_text']);
1329 $original_poll_data['poll_options'] = explode("\n", $original_poll_data['poll_option_text']);
1330
1331 $poll = array_merge($original_poll_data, array(
1332 'enable_bbcode' => $post_data['enable_bbcode'],
1333 'enable_urls' => $post_data['enable_urls'],
1334 'enable_smilies' => $post_data['enable_smilies'],
1335 'img_status' => $img_status,
1336 ));
1337
1338 $message_parser->parse_poll($poll);
1339
1340 $post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array();
1341 $post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : '';
1342 }
1343 else
1344 {
1345 $poll = array();
1346 }
1347
1348 // Check topic type
1349 if ($post_data['topic_type'] != POST_NORMAL && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id)))
1350 {
1351 switch ($post_data['topic_type'])
1352 {
1353 case POST_GLOBAL:
1354 $auth_option = 'f_announce_global';
1355 break;
1356
1357 case POST_ANNOUNCE:
1358 $auth_option = 'f_announce';
1359 break;
1360
1361 case POST_STICKY:
1362 $auth_option = 'f_sticky';
1363 break;
1364
1365 default:
1366 $auth_option = '';
1367 break;
1368 }
1369
1370 if ($auth_option != '' && !$auth->acl_get($auth_option, $forum_id))
1371 {
1372 // There is a special case where a user edits his post whereby the topic type got changed by an admin/mod.
1373 // Another case would be a mod not having sticky permissions for example but edit permissions.
1374 if ($mode == 'edit')
1375 {
1376 // To prevent non-authed users messing around with the topic type we reset it to the original one.
1377 $post_data['topic_type'] = $post_data['orig_topic_type'];
1378 }
1379 else
1380 {
1381 $error[] = $user->lang['CANNOT_POST_' . str_replace('F_', '', strtoupper($auth_option))];
1382 }
1383 }
1384 }
1385
1386 if (count($message_parser->warn_msg))
1387 {
1388 $error[] = implode('<br />', $message_parser->warn_msg);
1389 }
1390
1391 // DNSBL check
1392 if ($config['check_dnsbl'] && !$refresh)
1393 {
1394 if (($dnsbl = $user->check_dnsbl('post')) !== false)
1395 {
1396 $error[] = sprintf($user->lang['IP_BLACKLISTED'], $user->ip, $dnsbl[1]);
1397 }
1398 }
1399
1400 /**
1401 * This event allows you to define errors before the post action is performed
1402 *
1403 * @event core.posting_modify_submission_errors
1404 * @var array post_data Array with post data
1405 * @var array poll Array with poll data from post (must be used instead of the post_data equivalent)
1406 * @var string mode What action to take if the form is submitted
1407 * post|reply|quote|edit|delete|bump|smilies|popup
1408 * @var int post_id ID of the post
1409 * @var int topic_id ID of the topic
1410 * @var int forum_id ID of the forum
1411 * @var bool submit Whether or not the form has been submitted
1412 * @var array error Any error strings; a non-empty array aborts form submission.
1413 * NOTE: Should be actual language strings, NOT language keys.
1414 * @since 3.1.0-RC5
1415 * @changed 3.1.5-RC1 Added poll array to the event
1416 * @changed 3.2.0-a1 Removed undefined page_title
1417 */
1418 $vars = array(
1419 'post_data',
1420 'poll',
1421 'mode',
1422 'post_id',
1423 'topic_id',
1424 'forum_id',
1425 'submit',
1426 'error',
1427 );
1428 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submission_errors', compact($vars)));
1429
1430 // Store message, sync counters
1431 if (!count($error) && $submit)
1432 {
1433 /** @var \phpbb\lock\posting $posting_lock */
1434 $posting_lock = $phpbb_container->get('posting.lock');
1435
1436 // Get creation time and form token, must be already checked at this point
1437 $creation_time = abs($request->variable('creation_time', 0));
1438 $form_token = $request->variable('form_token', '');
1439
1440 if ($posting_lock->acquire($creation_time, $form_token))
1441 {
1442 // Lock/Unlock Topic
1443 $change_topic_status = $post_data['topic_status'];
1444 $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;
1445
1446 if ($post_data['topic_status'] == ITEM_LOCKED && !$topic_lock && $perm_lock_unlock)
1447 {
1448 $change_topic_status = ITEM_UNLOCKED;
1449 }
1450 else if ($post_data['topic_status'] == ITEM_UNLOCKED && $topic_lock && $perm_lock_unlock)
1451 {
1452 $change_topic_status = ITEM_LOCKED;
1453 }
1454
1455 if ($change_topic_status != $post_data['topic_status'])
1456 {
1457 $sql = 'UPDATE ' . TOPICS_TABLE . "
1458 SET topic_status = $change_topic_status
1459 WHERE topic_id = $topic_id
1460 AND topic_moved_id = 0";
1461 $db->sql_query($sql);
1462
1463 $user_lock = ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $post_data['topic_poster']) ? 'USER_' : '';
1464
1465 $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_' . $user_lock . (($change_topic_status == ITEM_LOCKED) ? 'LOCK' : 'UNLOCK'), false, array(
1466 'forum_id' => $forum_id,
1467 'topic_id' => $topic_id,
1468 $post_data['topic_title']
1469 ));
1470 }
1471
1472 // Lock/Unlock Post Edit
1473 if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_LOCKED && !$post_lock && $auth->acl_get('m_edit', $forum_id))
1474 {
1475 $post_data['post_edit_locked'] = ITEM_UNLOCKED;
1476 }
1477 else if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_UNLOCKED && $post_lock && $auth->acl_get('m_edit', $forum_id))
1478 {
1479 $post_data['post_edit_locked'] = ITEM_LOCKED;
1480 }
1481
1482 $data = array(
1483 'topic_title' => (empty($post_data['topic_title'])) ? $post_data['post_subject'] : $post_data['topic_title'],
1484 'topic_first_post_id' => (isset($post_data['topic_first_post_id'])) ? (int) $post_data['topic_first_post_id'] : 0,
1485 'topic_last_post_id' => (isset($post_data['topic_last_post_id'])) ? (int) $post_data['topic_last_post_id'] : 0,
1486 'topic_time_limit' => (int) $post_data['topic_time_limit'],
1487 'topic_attachment' => (isset($post_data['topic_attachment'])) ? (int) $post_data['topic_attachment'] : 0,
1488 'post_id' => (int) $post_id,
1489 'topic_id' => (int) $topic_id,
1490 'forum_id' => (int) $forum_id,
1491 'icon_id' => (int) $post_data['icon_id'],
1492 'poster_id' => (int) $post_data['poster_id'],
1493 'enable_sig' => (bool) $post_data['enable_sig'],
1494 'enable_bbcode' => (bool) $post_data['enable_bbcode'],
1495 'enable_smilies' => (bool) $post_data['enable_smilies'],
1496 'enable_urls' => (bool) $post_data['enable_urls'],
1497 'enable_indexing' => (bool) $post_data['enable_indexing'],
1498 'message_md5' => (string) $message_md5,
1499 'post_checksum' => (isset($post_data['post_checksum'])) ? (string) $post_data['post_checksum'] : '',
1500 'post_edit_reason' => $post_data['post_edit_reason'],
1501 'post_edit_user' => ($mode == 'edit') ? $user->data['user_id'] : ((isset($post_data['post_edit_user'])) ? (int) $post_data['post_edit_user'] : 0),
1502 'forum_parents' => $post_data['forum_parents'],
1503 'forum_name' => $post_data['forum_name'],
1504 'notify' => $notify,
1505 'notify_set' => $post_data['notify_set'],
1506 'poster_ip' => (isset($post_data['poster_ip'])) ? $post_data['poster_ip'] : $user->ip,
1507 'post_edit_locked' => (int) $post_data['post_edit_locked'],
1508 'bbcode_bitfield' => $message_parser->bbcode_bitfield,
1509 'bbcode_uid' => $message_parser->bbcode_uid,
1510 'message' => $message_parser->message,
1511 'attachment_data' => $message_parser->attachment_data,
1512 'filename_data' => $message_parser->filename_data,
1513 'topic_status' => $post_data['topic_status'],
1514
1515 'topic_visibility' => (isset($post_data['topic_visibility'])) ? $post_data['topic_visibility'] : false,
1516 'post_visibility' => (isset($post_data['post_visibility'])) ? $post_data['post_visibility'] : false,
1517 );
1518
1519 if ($mode == 'edit')
1520 {
1521 $data['topic_posts_approved'] = $post_data['topic_posts_approved'];
1522 $data['topic_posts_unapproved'] = $post_data['topic_posts_unapproved'];
1523 $data['topic_posts_softdeleted'] = $post_data['topic_posts_softdeleted'];
1524 }
1525
1526 // Only return the username when it is either a guest posting or we are editing a post and
1527 // the username was supplied; otherwise post_data might hold the data of the post that is
1528 // being quoted (which could result in the username being returned being that of the quoted
1529 // post's poster, not the poster of the current post). See: PHPBB3-11769 for more information.
1530 $post_author_name = ((!$user->data['is_registered'] || $mode == 'edit') && $post_data['username'] !== '') ? $post_data['username'] : '';
1531
1532 /**
1533 * This event allows you to define errors before the post action is performed
1534 *
1535 * @event core.posting_modify_submit_post_before
1536 * @var array post_data Array with post data
1537 * @var array poll Array with poll data
1538 * @var array data Array with post data going to be stored in the database
1539 * @var string mode What action to take if the form is submitted
1540 * post|reply|quote|edit|delete
1541 * @var int post_id ID of the post
1542 * @var int topic_id ID of the topic
1543 * @var int forum_id ID of the forum
1544 * @var string post_author_name Author name for guest posts
1545 * @var bool update_message Boolean if the post message was changed
1546 * @var bool update_subject Boolean if the post subject was changed
1547 * NOTE: Should be actual language strings, NOT language keys.
1548 * @since 3.1.0-RC5
1549 * @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event
1550 * @change 3.2.0-a1 Removed undefined page_title
1551 */
1552 $vars = array(
1553 'post_data',
1554 'poll',
1555 'data',
1556 'mode',
1557 'post_id',
1558 'topic_id',
1559 'forum_id',
1560 'post_author_name',
1561 'update_message',
1562 'update_subject',
1563 );
1564 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_before', compact($vars)));
1565
1566 // The last parameter tells submit_post if search indexer has to be run
1567 $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);
1568
1569 /**
1570 * This event allows you to define errors after the post action is performed
1571 *
1572 * @event core.posting_modify_submit_post_after
1573 * @var array post_data Array with post data
1574 * @var array poll Array with poll data
1575 * @var array data Array with post data going to be stored in the database
1576 * @var string mode What action to take if the form is submitted
1577 * post|reply|quote|edit|delete
1578 * @var int post_id ID of the post
1579 * @var int topic_id ID of the topic
1580 * @var int forum_id ID of the forum
1581 * @var string post_author_name Author name for guest posts
1582 * @var bool update_message Boolean if the post message was changed
1583 * @var bool update_subject Boolean if the post subject was changed
1584 * @var string redirect_url URL the user is going to be redirected to
1585 * NOTE: Should be actual language strings, NOT language keys.
1586 * @since 3.1.0-RC5
1587 * @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event
1588 * @change 3.2.0-a1 Removed undefined page_title
1589 */
1590 $vars = array(
1591 'post_data',
1592 'poll',
1593 'data',
1594 'mode',
1595 'post_id',
1596 'topic_id',
1597 'forum_id',
1598 'post_author_name',
1599 'update_message',
1600 'update_subject',
1601 'redirect_url',
1602 );
1603 extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_after', compact($vars)));
1604
1605 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === true) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
1606 {
1607 $captcha->reset();
1608 }
1609
1610 // Handle delete mode...
1611 if ($request->is_set_post('delete_permanent') || ($request->is_set_post('delete') && $post_data['post_visibility'] != ITEM_DELETED))
1612 {
1613 $delete_reason = $request->variable('delete_reason', '', true);
1614 phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, !$request->is_set_post('delete_permanent'), $delete_reason);
1615 return;
1616 }
1617
1618 // Check the permissions for post approval.
1619 // Moderators must go through post approval like ordinary users.
1620 if ((!$auth->acl_get('f_noapprove', $data['forum_id']) && empty($data['force_approved_state'])) || (isset($data['force_approved_state']) && !$data['force_approved_state']))
1621 {
1622 meta_refresh(10, $redirect_url);
1623 $message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD'];
1624 $message .= (($user->data['user_id'] == ANONYMOUS) ? '' : ' '. $user->lang['POST_APPROVAL_NOTIFY']);
1625 $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $data['forum_id']) . '">', '</a>');
1626 trigger_error($message);
1627 }
1628
1629 redirect($redirect_url);
1630 }
1631 else
1632 {
1633 // Posting was already locked before, hence form submission was already attempted once and is now invalid
1634 $error[] = $language->lang('FORM_INVALID');
1635 }
1636 }
1637 }
1638
1639 // Preview
1640 if (!count($error) && $preview)
1641 {
1642 $post_data['post_time'] = ($mode == 'edit') ? $post_data['post_time'] : $current_time;
1643
1644 $preview_message = $message_parser->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies'], false);
1645
1646 $preview_signature = ($mode == 'edit') ? $post_data['user_sig'] : $user->data['user_sig'];
1647 $preview_signature_uid = ($mode == 'edit') ? $post_data['user_sig_bbcode_uid'] : $user->data['user_sig_bbcode_uid'];
1648 $preview_signature_bitfield = ($mode == 'edit') ? $post_data['user_sig_bbcode_bitfield'] : $user->data['user_sig_bbcode_bitfield'];
1649
1650 // Signature
1651 if ($post_data['enable_sig'] && $config['allow_sig'] && $preview_signature && $auth->acl_get('f_sigs', $forum_id))
1652 {
1653 $flags = ($config['allow_sig_bbcode']) ? OPTION_FLAG_BBCODE : 0;
1654 $flags |= ($config['allow_sig_links']) ? OPTION_FLAG_LINKS : 0;
1655 $flags |= ($config['allow_sig_smilies']) ? OPTION_FLAG_SMILIES : 0;
1656
1657 $preview_signature = generate_text_for_display($preview_signature, $preview_signature_uid, $preview_signature_bitfield, $flags, false);
1658 }
1659 else
1660 {
1661 $preview_signature = '';
1662 }
1663
1664 $preview_subject = censor_text($post_data['post_subject']);
1665
1666 // Poll Preview
1667 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))*/))
1668 && $auth->acl_get('f_poll', $forum_id))
1669 {
1670 $parse_poll = new parse_message($post_data['poll_title']);
1671 $parse_poll->bbcode_uid = $message_parser->bbcode_uid;
1672 $parse_poll->bbcode_bitfield = $message_parser->bbcode_bitfield;
1673
1674 $parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']);
1675
1676 if ($post_data['poll_length'])
1677 {
1678 $poll_end = ($post_data['poll_length'] * 86400) + (($post_data['poll_start']) ? $post_data['poll_start'] : time());
1679 }
1680
1681 $template->assign_vars(array(
1682 'S_HAS_POLL_OPTIONS' => (count($post_data['poll_options'])),
1683 'S_IS_MULTI_CHOICE' => ($post_data['poll_max_options'] > 1) ? true : false,
1684
1685 'POLL_QUESTION' => $parse_poll->message,
1686
1687 'L_POLL_LENGTH' => ($post_data['poll_length']) ? sprintf($user->lang['POLL_RUN_TILL'], $user->format_date($poll_end)) : '',
1688 'L_MAX_VOTES' => $user->lang('MAX_OPTIONS_SELECT', (int) $post_data['poll_max_options']),
1689 ));
1690
1691 $preview_poll_options = array();
1692 foreach ($post_data['poll_options'] as $poll_option)
1693 {
1694 $parse_poll->message = $poll_option;
1695 $parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']);
1696 $preview_poll_options[] = $parse_poll->message;
1697 }
1698 unset($parse_poll);
1699
1700 foreach ($preview_poll_options as $key => $option)
1701 {
1702 $template->assign_block_vars('poll_option', array(
1703 'POLL_OPTION_CAPTION' => $option,
1704 'POLL_OPTION_ID' => $key + 1)
1705 );
1706 }
1707 unset($preview_poll_options);
1708 }
1709
1710 // Attachment Preview
1711 if (count($message_parser->attachment_data))
1712 {
1713 $template->assign_var('S_HAS_ATTACHMENTS', true);
1714
1715 $update_count = array();
1716 $attachment_data = $message_parser->attachment_data;
1717
1718 parse_attachments($forum_id, $preview_message, $attachment_data, $update_count, true);
1719
1720 foreach ($attachment_data as $i => $attachment)
1721 {
1722 $template->assign_block_vars('attachment', array(
1723 'DISPLAY_ATTACHMENT' => $attachment)
1724 );
1725 }
1726 unset($attachment_data);
1727 }
1728
1729 if (!count($error))
1730 {
1731 $template->assign_vars(array(
1732 'PREVIEW_SUBJECT' => $preview_subject,
1733 'PREVIEW_MESSAGE' => $preview_message,
1734 'PREVIEW_SIGNATURE' => $preview_signature,
1735
1736 'S_DISPLAY_PREVIEW' => !empty($preview_message),
1737 ));
1738 }
1739 }
1740
1741 // Remove quotes that would become nested too deep before decoding the text
1742 $generate_quote = ($mode == 'quote' && !$submit && !$preview && !$refresh);
1743 if ($generate_quote && $config['max_quote_depth'] > 0)
1744 {
1745 $tmp_bbcode_uid = $message_parser->bbcode_uid;
1746 $message_parser->bbcode_uid = $post_data['bbcode_uid'];
1747 $message_parser->remove_nested_quotes($config['max_quote_depth'] - 1);
1748 $message_parser->bbcode_uid = $tmp_bbcode_uid;
1749 }
1750
1751 // Decode text for message display
1752 $post_data['bbcode_uid'] = ($mode == 'quote' && !$preview && !$refresh && !count($error)) ? $post_data['bbcode_uid'] : $message_parser->bbcode_uid;
1753 $message_parser->decode_message($post_data['bbcode_uid']);
1754
1755 if ($generate_quote)
1756 {
1757 // Remove attachment bbcode tags from the quoted message to avoid mixing with the new post attachments if any
1758 $message_parser->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#uis', '\\2', $message_parser->message);
1759
1760 $quote_attributes = array(
1761 'author' => $post_data['quote_username'],
1762 'post_id' => $post_data['post_id'],
1763 'time' => $post_data['post_time'],
1764 'user_id' => $post_data['poster_id'],
1765 );
1766
1767 /**
1768 * This event allows you to modify the quote attributes of the post being quoted
1769 *
1770 * @event core.posting_modify_quote_attributes
1771 * @var array quote_attributes Array with quote attributes
1772 * @var array post_data Array with post data
1773 * @since 3.2.6-RC1
1774 */
1775 $vars = array(
1776 'quote_attributes',
1777 'post_data',
1778 );
1779 extract($phpbb_dispatcher->trigger_event('core.posting_modify_quote_attributes', compact($vars)));
1780
1781 /** @var \phpbb\language\language $language */
1782 $language = $phpbb_container->get('language');
1783 phpbb_format_quote($language, $message_parser, $bbcode_utils, $bbcode_status, $quote_attributes);
1784 }
1785
1786 if (($mode == 'reply' || $mode == 'quote') && !$submit && !$preview && !$refresh)
1787 {
1788 $post_data['post_subject'] = ((strpos($post_data['post_subject'], 'Re: ') !== 0) ? 'Re: ' : '') . censor_text($post_data['post_subject']);
1789
1790 $post_subject = $post_data['post_subject'];
1791
1792 /**
1793 * This event allows you to modify the post subject of the post being quoted
1794 *
1795 * @event core.posting_modify_post_subject
1796 * @var string post_subject String with the post subject already censored.
1797 * @since 3.2.8-RC1
1798 */
1799 $vars = array('post_subject');
1800 extract($phpbb_dispatcher->trigger_event('core.posting_modify_post_subject', compact($vars)));
1801
1802 $post_data['post_subject'] = $post_subject;
1803 }
1804
1805 $attachment_data = $message_parser->attachment_data;
1806 $filename_data = $message_parser->filename_data;
1807 $post_data['post_text'] = $message_parser->message;
1808
1809 if (count($post_data['poll_options']) || (isset($post_data['poll_title']) && !$bbcode_utils->is_empty($post_data['poll_title'])))
1810 {
1811 $message_parser->message = $post_data['poll_title'];
1812 $message_parser->bbcode_uid = $post_data['bbcode_uid'];
1813
1814 $message_parser->decode_message();
1815 $post_data['poll_title'] = $message_parser->message;
1816
1817 $message_parser->message = implode("\n", $post_data['poll_options']);
1818 $message_parser->decode_message();
1819 $post_data['poll_options'] = explode("\n", $message_parser->message);
1820 }
1821
1822 // MAIN POSTING PAGE BEGINS HERE
1823
1824 // Forum moderators?
1825 $moderators = array();
1826 if ($config['load_moderators'])
1827 {
1828 get_moderators($moderators, $forum_id);
1829 }
1830
1831 // Generate smiley listing
1832 generate_smilies('inline', $forum_id);
1833
1834 // Generate inline attachment select box
1835 posting_gen_inline_attachments($attachment_data);
1836
1837 // Do show topic type selection only in first post.
1838 $topic_type_toggle = false;
1839
1840 if ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']))
1841 {
1842 $topic_type_toggle = posting_gen_topic_types($forum_id, $post_data['topic_type']);
1843 }
1844
1845 $s_topic_icons = false;
1846 if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id))
1847 {
1848 $s_topic_icons = posting_gen_topic_icons($mode, $post_data['icon_id']);
1849 }
1850
1851 $bbcode_checked = (isset($post_data['enable_bbcode'])) ? !$post_data['enable_bbcode'] : (($config['allow_bbcode']) ? !$user->optionget('bbcode') : 1);
1852 $smilies_checked = (isset($post_data['enable_smilies'])) ? !$post_data['enable_smilies'] : (($config['allow_smilies']) ? !$user->optionget('smilies') : 1);
1853 $urls_checked = (isset($post_data['enable_urls'])) ? !$post_data['enable_urls'] : 0;
1854 $sig_checked = $post_data['enable_sig'];
1855 $lock_topic_checked = (isset($topic_lock) && $topic_lock) ? $topic_lock : (($post_data['topic_status'] == ITEM_LOCKED) ? 1 : 0);
1856 $lock_post_checked = (isset($post_lock)) ? $post_lock : $post_data['post_edit_locked'];
1857
1858 // 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
1859 $notify_set = ($mode != 'edit' && $config['allow_topic_notify'] && $user->data['is_registered'] && !$post_data['notify_set']) ? $user->data['user_notify'] : $post_data['notify_set'];
1860 $notify_checked = (isset($notify)) ? $notify : (($mode == 'post') ? $user->data['user_notify'] : $notify_set);
1861
1862 // Page title & action URL
1863 $s_action = append_sid("{$phpbb_root_path}posting.$phpEx", "mode=$mode");
1864
1865 switch ($mode)
1866 {
1867 case 'post':
1868 $s_action .= $forum_id ? "&f=$forum_id" : '';
1869 $page_title = $user->lang['POST_TOPIC'];
1870 break;
1871
1872 case 'reply':
1873 $s_action .= $topic_id ? "&t=$topic_id" : '';
1874 $page_title = $user->lang['POST_REPLY'];
1875 break;
1876
1877 case 'quote':
1878 $s_action .= $post_id ? "&p=$post_id" : '';
1879 $page_title = $user->lang['POST_REPLY'];
1880 break;
1881
1882 case 'delete':
1883 case 'edit':
1884 $s_action .= $post_id ? "&p=$post_id" : '';
1885 $page_title = $user->lang['EDIT_POST'];
1886 break;
1887 }
1888
1889 // Build Navigation Links
1890 generate_forum_nav($post_data);
1891
1892 // Build Forum Rules
1893 generate_forum_rules($post_data);
1894
1895 // Posting uses is_solved for legacy reasons. Plugins have to use is_solved to force themselves to be displayed.
1896 if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === false) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
1897 {
1898
1899 $template->assign_vars(array(
1900 'S_CONFIRM_CODE' => true,
1901 'CAPTCHA_TEMPLATE' => $captcha->get_template(),
1902 ));
1903 }
1904
1905 $s_hidden_fields = ($mode == 'reply' || $mode == 'quote') ? '<input type="hidden" name="topic_cur_post_id" value="' . $post_data['topic_last_post_id'] . '" />' : '';
1906 $s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input type="hidden" name="draft_loaded" value="' . $request->variable('draft_loaded', $draft_id) . '" />' : '';
1907
1908 if ($mode == 'edit')
1909 {
1910 $s_hidden_fields .= build_hidden_fields(array(
1911 'edit_post_message_checksum' => $post_data['post_checksum'],
1912 'edit_post_subject_checksum' => $post_data['post_subject_md5'],
1913 ));
1914 }
1915
1916 // Add the confirm id/code pair to the hidden fields, else an error is displayed on next submit/preview
1917 if (isset($captcha) && $captcha->is_solved() !== false)
1918 {
1919 $s_hidden_fields .= build_hidden_fields($captcha->get_hidden_fields());
1920 }
1921
1922 $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"';
1923 add_form_key('posting');
1924
1925 /** @var \phpbb\controller\helper $controller_helper */
1926 $controller_helper = $phpbb_container->get('controller.helper');
1927
1928 // Build array of variables for main posting page
1929 $page_data = array(
1930 'L_POST_A' => $page_title,
1931 'L_ICON' => ($mode == 'reply' || $mode == 'quote' || ($mode == 'edit' && $post_id != $post_data['topic_first_post_id'])) ? $user->lang['POST_ICON'] : $user->lang['TOPIC_ICON'],
1932 'L_MESSAGE_BODY_EXPLAIN' => $user->lang('MESSAGE_BODY_EXPLAIN', (int) $config['max_post_chars']),
1933 'L_DELETE_POST_PERMANENTLY' => $user->lang('DELETE_POST_PERMANENTLY', 1),
1934
1935 'FORUM_NAME' => $post_data['forum_name'],
1936 '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']) : '',
1937 'TOPIC_TITLE' => censor_text($post_data['topic_title']),
1938 'MODERATORS' => (count($moderators)) ? implode($user->lang['COMMA_SEPARATOR'], $moderators[$forum_id]) : '',
1939 'USERNAME' => ((!$preview && $mode != 'quote') || $preview) ? $post_data['username'] : '',
1940 'SUBJECT' => $post_data['post_subject'],
1941 'MESSAGE' => $post_data['post_text'],
1942 'BBCODE_STATUS' => $user->lang(($bbcode_status ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'),
1943 'IMG_STATUS' => ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
1944 'FLASH_STATUS' => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
1945 'SMILIES_STATUS' => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
1946 'URL_STATUS' => ($bbcode_status && $url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
1947 'MAX_FONT_SIZE' => (int) $config['max_post_font_size'],
1948 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']),
1949 'POST_DATE' => ($post_data['post_time']) ? $user->format_date($post_data['post_time']) : '',
1950 'ERROR' => (count($error)) ? implode('<br />', $error) : '',
1951 'TOPIC_TIME_LIMIT' => (int) $post_data['topic_time_limit'],
1952 'EDIT_REASON' => $request->variable('edit_reason', '', true),
1953 'SHOW_PANEL' => $request->variable('show_panel', ''),
1954 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"),
1955 'U_VIEW_TOPIC' => ($mode != 'post') ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id") : '',
1956 'U_PROGRESS_BAR' => append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup"),
1957 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup")),
1958
1959 'S_PRIVMSGS' => false,
1960 'S_CLOSE_PROGRESS_WINDOW' => (isset($_POST['add_file'])) ? true : false,
1961 'S_EDIT_POST' => ($mode == 'edit') ? true : false,
1962 'S_EDIT_REASON' => ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false,
1963 'S_DISPLAY_USERNAME' => (!$user->data['is_registered'] || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS)) ? true : false,
1964 'S_SHOW_TOPIC_ICONS' => $s_topic_icons,
1965 '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,
1966 'S_BBCODE_ALLOWED' => ($bbcode_status) ? 1 : 0,
1967 'S_BBCODE_CHECKED' => ($bbcode_checked) ? ' checked="checked"' : '',
1968 'S_SMILIES_ALLOWED' => $smilies_status,
1969 'S_SMILIES_CHECKED' => ($smilies_checked) ? ' checked="checked"' : '',
1970 'S_SIG_ALLOWED' => ($user->data['is_registered'] && $config['allow_sig'] && $auth->acl_get('f_sigs', $forum_id) && $auth->acl_get('u_sig')) ? true : false,
1971 'S_SIGNATURE_CHECKED' => ($sig_checked) ? ' checked="checked"' : '',
1972 '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,
1973 'S_NOTIFY_CHECKED' => ($notify_checked) ? ' checked="checked"' : '',
1974 '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,
1975 'S_LOCK_TOPIC_CHECKED' => ($lock_topic_checked) ? ' checked="checked"' : '',
1976 'S_LOCK_POST_ALLOWED' => ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false,
1977 'S_LOCK_POST_CHECKED' => ($lock_post_checked) ? ' checked="checked"' : '',
1978 'S_SOFTDELETE_CHECKED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? ' checked="checked"' : '',
1979 '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,
1980 'S_RESTORE_ALLOWED' => $auth->acl_get('m_approve', $forum_id),
1981 'S_IS_DELETED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? true : false,
1982 'S_LINKS_ALLOWED' => $url_status,
1983 'S_MAGIC_URL_CHECKED' => ($urls_checked) ? ' checked="checked"' : '',
1984 'S_TYPE_TOGGLE' => $topic_type_toggle,
1985 'S_SAVE_ALLOWED' => ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $mode != 'edit') ? true : false,
1986 'S_HAS_DRAFTS' => ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $post_data['drafts']) ? true : false,
1987 'S_FORM_ENCTYPE' => $form_enctype,
1988
1989 'S_BBCODE_IMG' => $img_status,
1990 'S_BBCODE_URL' => $url_status,
1991 'S_BBCODE_FLASH' => $flash_status,
1992 'S_BBCODE_QUOTE' => $quote_status,
1993
1994 'S_POST_ACTION' => $s_action,
1995 'S_HIDDEN_FIELDS' => $s_hidden_fields,
1996 'S_ATTACH_DATA' => json_encode($message_parser->attachment_data),
1997 'S_IN_POSTING' => true,
1998 );
1999
2000 // Build custom bbcodes array
2001 display_custom_bbcodes();
2002
2003 // Poll entry
2004 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))*/))
2005 && $auth->acl_get('f_poll', $forum_id))
2006 {
2007 $page_data = array_merge($page_data, array(
2008 'S_SHOW_POLL_BOX' => true,
2009 'S_POLL_VOTE_CHANGE' => ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id)),
2010 '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))),
2011 'S_POLL_DELETE_CHECKED' => (!empty($poll_delete)) ? true : false,
2012
2013 'L_POLL_OPTIONS_EXPLAIN' => $user->lang('POLL_OPTIONS_' . (($mode == 'edit') ? 'EDIT_' : '') . 'EXPLAIN', (int) $config['max_poll_options']),
2014
2015 'VOTE_CHANGE_CHECKED' => (!empty($post_data['poll_vote_change'])) ? ' checked="checked"' : '',
2016 'POLL_TITLE' => (isset($post_data['poll_title'])) ? $post_data['poll_title'] : '',
2017 'POLL_OPTIONS' => (!empty($post_data['poll_options'])) ? implode("\n", $post_data['poll_options']) : '',
2018 'POLL_MAX_OPTIONS' => (isset($post_data['poll_max_options'])) ? (int) $post_data['poll_max_options'] : 1,
2019 'POLL_LENGTH' => $post_data['poll_length'],
2020 )
2021 );
2022 }
2023
2024 /**
2025 * This event allows you to modify template variables for the posting screen
2026 *
2027 * @event core.posting_modify_template_vars
2028 * @var array post_data Array with post data
2029 * @var array moderators Array with forum moderators
2030 * @var string mode What action to take if the form is submitted
2031 * post|reply|quote|edit|delete|bump|smilies|popup
2032 * @var string page_title Title of the mode page
2033 * @var bool s_topic_icons Whether or not to show the topic icons
2034 * @var string form_enctype If attachments are allowed for this form
2035 * "multipart/form-data" or empty string
2036 * @var string s_action The URL to submit the POST data to
2037 * @var string s_hidden_fields Concatenated hidden input tags of posting form
2038 * @var int post_id ID of the post
2039 * @var int topic_id ID of the topic
2040 * @var int forum_id ID of the forum
2041 * @var int draft_id ID of the draft
2042 * @var bool submit Whether or not the form has been submitted
2043 * @var bool preview Whether or not the post is being previewed
2044 * @var bool save Whether or not a draft is being saved
2045 * @var bool load Whether or not a draft is being loaded
2046 * @var bool cancel Whether or not to cancel the form (returns to
2047 * viewtopic or viewforum depending on if the user
2048 * is posting a new topic or editing a post)
2049 * @var array error Any error strings; a non-empty array aborts
2050 * form submission.
2051 * NOTE: Should be actual language strings, NOT
2052 * language keys.
2053 * @var bool refresh Whether or not to retain previously submitted data
2054 * @var array page_data Posting page data that should be passed to the
2055 * posting page via $template->assign_vars()
2056 * @var object message_parser The message parser object
2057 * @since 3.1.0-a1
2058 * @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title,
2059 * s_topic_icons, form_enctype, s_action, s_hidden_fields,
2060 * post_id, topic_id, forum_id, submit, preview, save, load,
2061 * delete, cancel, refresh, error, page_data, message_parser
2062 * @changed 3.1.2-RC1 Removed 'delete' var as it does not exist
2063 * @changed 3.1.5-RC1 Added poll variables to the page_data array
2064 * @changed 3.1.6-RC1 Added 'draft_id' var
2065 */
2066 $vars = array(
2067 'post_data',
2068 'moderators',
2069 'mode',
2070 'page_title',
2071 's_topic_icons',
2072 'form_enctype',
2073 's_action',
2074 's_hidden_fields',
2075 'post_id',
2076 'topic_id',
2077 'forum_id',
2078 'draft_id',
2079 'submit',
2080 'preview',
2081 'save',
2082 'load',
2083 'cancel',
2084 'refresh',
2085 'error',
2086 'page_data',
2087 'message_parser',
2088 );
2089 extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', compact($vars)));
2090
2091 // Start assigning vars for main posting page ...
2092 $template->assign_vars($page_data);
2093
2094 // Show attachment box for adding attachments if true
2095 $allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype);
2096
2097 if ($allowed)
2098 {
2099 $max_files = ($auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) ? 0 : (int) $config['max_attachments'];
2100 $plupload->configure($cache, $template, $s_action, $forum_id, $max_files);
2101 }
2102
2103 // Attachment entry
2104 posting_gen_attachment_entry($attachment_data, $filename_data, $allowed, $forum_id);
2105
2106 // Output page ...
2107 page_header($page_title);
2108
2109 $template->set_filenames(array(
2110 'body' => 'posting_body.html')
2111 );
2112
2113 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
2114
2115 // Topic review
2116 if ($mode == 'reply' || $mode == 'quote')
2117 {
2118 if (topic_review($topic_id, $forum_id))
2119 {
2120 $template->assign_var('S_DISPLAY_REVIEW', true);
2121 }
2122 }
2123
2124 page_footer();
2125