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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

posting.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 76.93 KiB


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 ? "&amp;f=$forum_id" : '';
1869          $page_title = $user->lang['POST_TOPIC'];
1870      break;
1871   
1872      case 'reply':
1873          $s_action .= $topic_id ? "&amp;t=$topic_id" : '';
1874          $page_title = $user->lang['POST_REPLY'];
1875      break;
1876   
1877      case 'quote':
1878          $s_action .= $post_id ? "&amp;p=$post_id" : '';
1879          $page_title = $user->lang['POST_REPLY'];
1880      break;
1881   
1882      case 'delete':
1883      case 'edit':
1884          $s_action .= $post_id ? "&amp;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&amp;mode=popup"),
1957      'UA_PROGRESS_BAR'        => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&amp;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