Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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