Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ucp_pm_compose.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 52.28 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  if (!defined('IN_PHPBB'))
0018  {
0019      exit;
0020  }
0021   
0022  /**
0023  * Compose private message
0024  * Called from ucp_pm with mode == 'compose'
0025  */
0026  function compose_pm($id, $mode, $action, $user_folders = array())
0027  {
0028      global $template, $db, $auth, $user, $cache;
0029      global $phpbb_root_path, $phpEx, $config, $language;
0030      global $request, $phpbb_dispatcher, $phpbb_container;
0031   
0032      // Damn php and globals - i know, this is horrible
0033      // Needed for handle_message_list_actions()
0034      global $refresh, $submit, $preview;
0035   
0036      if (!function_exists('generate_smilies'))
0037      {
0038          include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
0039      }
0040   
0041      if (!function_exists('display_custom_bbcodes'))
0042      {
0043          include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0044      }
0045   
0046      if (!class_exists('parse_message'))
0047      {
0048          include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
0049      }
0050   
0051      if (!$action)
0052      {
0053          $action = 'post';
0054      }
0055      add_form_key('ucp_pm_compose');
0056   
0057      // Grab only parameters needed here
0058      $to_user_id        = $request->variable('u', 0);
0059      $to_group_id    = $request->variable('g', 0);
0060      $msg_id            = $request->variable('p', 0);
0061      $draft_id        = $request->variable('d', 0);
0062   
0063      // Reply to all triggered (quote/reply)
0064      $reply_to_all    = $request->variable('reply_to_all', 0);
0065   
0066      $address_list    = $request->variable('address_list', array('' => array(0 => '')));
0067   
0068      $preview    = (isset($_POST['preview'])) ? true : false;
0069      $save        = (isset($_POST['save'])) ? true : false;
0070      $load        = (isset($_POST['load'])) ? true : false;
0071      $cancel        = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;
0072      $delete        = (isset($_POST['delete'])) ? true : false;
0073   
0074      $remove_u    = (isset($_REQUEST['remove_u'])) ? true : false;
0075      $remove_g    = (isset($_REQUEST['remove_g'])) ? true : false;
0076      $add_to        = (isset($_REQUEST['add_to'])) ? true : false;
0077      $add_bcc    = (isset($_REQUEST['add_bcc'])) ? true : false;
0078   
0079      $refresh    = isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load
0080          || $remove_u || $remove_g || $add_to || $add_bcc;
0081      $submit = $request->is_set_post('post') && !$refresh && !$preview;
0082   
0083      $action        = ($delete && !$preview && !$refresh && $submit) ? 'delete' : $action;
0084      $select_single = ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? false : true;
0085   
0086      $error = array();
0087      $current_time = time();
0088   
0089      /** @var \phpbb\group\helper $group_helper */
0090      $group_helper = $phpbb_container->get('group_helper');
0091   
0092      // Was cancel pressed? If so then redirect to the appropriate page
0093      if ($cancel)
0094      {
0095          if ($msg_id)
0096          {
0097              redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;action=view_message&amp;p=' . $msg_id));
0098          }
0099          redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm'));
0100      }
0101   
0102      // Since viewtopic.php language entries are used in several modes,
0103      // we include the language file here
0104      $user->add_lang('viewtopic');
0105   
0106      /**
0107      * Modify the default vars before composing a PM
0108      *
0109      * @event core.ucp_pm_compose_modify_data
0110      * @var    int        msg_id                    post_id in the page request
0111      * @var    int        to_user_id                The id of whom the message is to
0112      * @var    int        to_group_id                The id of the group the message is to
0113      * @var    bool    submit                    Whether the form has been submitted
0114      * @var    bool    preview                    Whether the user is previewing the PM or not
0115      * @var    string    action                    One of: post, reply, quote, forward, quotepost, edit, delete, smilies
0116      * @var    bool    delete                    Whether the user is deleting the PM
0117      * @var    int        reply_to_all            Value of reply_to_all request variable.
0118      * @since 3.1.4-RC1
0119      */
0120      $vars = array(
0121          'msg_id',
0122          'to_user_id',
0123          'to_group_id',
0124          'submit',
0125          'preview',
0126          'action',
0127          'delete',
0128          'reply_to_all',
0129      );
0130      extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_data', compact($vars)));
0131   
0132      // Output PM_TO box if message composing
0133      if ($action != 'edit')
0134      {
0135          // Add groups to PM box
0136          if ($config['allow_mass_pm'] && $auth->acl_get('u_masspm_group'))
0137          {
0138              $sql = 'SELECT g.group_id, g.group_name, g.group_type, g.group_colour
0139                  FROM ' . GROUPS_TABLE . ' g';
0140   
0141              if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel'))
0142              {
0143                  $sql .= ' LEFT JOIN ' . USER_GROUP_TABLE . ' ug
0144                      ON (
0145                          g.group_id = ug.group_id
0146                          AND ug.user_id = ' . $user->data['user_id'] . '
0147                          AND ug.user_pending = 0
0148                      )
0149                      WHERE (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ')';
0150              }
0151   
0152              $sql .= ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? ' WHERE ' : ' AND ';
0153   
0154              $sql .= 'g.group_receive_pm = 1
0155                  ORDER BY g.group_type DESC, g.group_name ASC';
0156              $result = $db->sql_query($sql);
0157   
0158              $group_options = '';
0159              while ($row = $db->sql_fetchrow($result))
0160              {
0161                  $group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . ($row['group_colour'] ? ' style="color: #' . $row['group_colour'] . '"' : '') . '>' . $group_helper->get_name($row['group_name']) . '</option>';
0162              }
0163              $db->sql_freeresult($result);
0164          }
0165   
0166          $template->assign_vars(array(
0167              'S_SHOW_PM_BOX'        => true,
0168              'S_ALLOW_MASS_PM'    => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? true : false,
0169              'S_GROUP_OPTIONS'    => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm_group')) ? $group_options : '',
0170              'U_FIND_USERNAME'    => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=searchuser&amp;form=postform&amp;field=username_list&amp;select_single=" . (int) $select_single),
0171          ));
0172      }
0173   
0174      $sql = '';
0175      $folder_id = 0;
0176   
0177      // What is all this following SQL for? Well, we need to know
0178      // some basic information in all cases before we do anything.
0179      switch ($action)
0180      {
0181          case 'post':
0182              if (!$auth->acl_get('u_sendpm'))
0183              {
0184                  send_status_line(403, 'Forbidden');
0185                  trigger_error('NO_AUTH_SEND_MESSAGE');
0186              }
0187          break;
0188   
0189          case 'reply':
0190          case 'quote':
0191          case 'forward':
0192          case 'quotepost':
0193              if (!$msg_id)
0194              {
0195                  trigger_error('NO_MESSAGE');
0196              }
0197   
0198              if (!$auth->acl_get('u_sendpm'))
0199              {
0200                  send_status_line(403, 'Forbidden');
0201                  trigger_error('NO_AUTH_SEND_MESSAGE');
0202              }
0203   
0204              if ($action == 'quotepost')
0205              {
0206                  $sql = 'SELECT p.post_id as msg_id, p.forum_id, p.post_text as message_text, p.poster_id as author_id, p.post_time as message_time, p.bbcode_bitfield, p.bbcode_uid, p.enable_sig, p.enable_smilies, p.enable_magic_url, t.topic_title as message_subject, u.username as quote_username
0207                      FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . " u
0208                      WHERE p.post_id = $msg_id
0209                          AND t.topic_id = p.topic_id
0210                          AND u.user_id = p.poster_id";
0211              }
0212              else
0213              {
0214                  $sql = 'SELECT t.folder_id, p.*, u.username as quote_username
0215                      FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . ' u
0216                      WHERE t.user_id = ' . $user->data['user_id'] . "
0217                          AND p.author_id = u.user_id
0218                          AND t.msg_id = p.msg_id
0219                          AND p.msg_id = $msg_id";
0220              }
0221          break;
0222   
0223          case 'edit':
0224              if (!$msg_id)
0225              {
0226                  trigger_error('NO_MESSAGE');
0227              }
0228   
0229              // check for outbox (not read) status, we do not allow editing if one user already having the message
0230              $sql = 'SELECT p.*, t.folder_id
0231                  FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
0232                  WHERE t.user_id = ' . $user->data['user_id'] . '
0233                      AND t.folder_id = ' . PRIVMSGS_OUTBOX . "
0234                      AND t.msg_id = $msg_id
0235                      AND t.msg_id = p.msg_id";
0236          break;
0237   
0238          case 'delete':
0239              if (!$auth->acl_get('u_pm_delete'))
0240              {
0241                  send_status_line(403, 'Forbidden');
0242                  trigger_error('NO_AUTH_DELETE_MESSAGE');
0243              }
0244   
0245              if (!$msg_id)
0246              {
0247                  trigger_error('NO_MESSAGE');
0248              }
0249   
0250              $sql = 'SELECT msg_id, pm_unread, pm_new, author_id, folder_id
0251                  FROM ' . PRIVMSGS_TO_TABLE . '
0252                  WHERE user_id = ' . $user->data['user_id'] . "
0253                      AND msg_id = $msg_id";
0254          break;
0255   
0256          case 'smilies':
0257              generate_smilies('window', 0);
0258          break;
0259   
0260          default:
0261              trigger_error('NO_ACTION_MODE', E_USER_ERROR);
0262          break;
0263      }
0264   
0265      if ($action == 'forward' && (!$config['forward_pm'] || !$auth->acl_get('u_pm_forward')))
0266      {
0267          send_status_line(403, 'Forbidden');
0268          trigger_error('NO_AUTH_FORWARD_MESSAGE');
0269      }
0270   
0271      if ($action == 'edit' && !$auth->acl_get('u_pm_edit'))
0272      {
0273          send_status_line(403, 'Forbidden');
0274          trigger_error('NO_AUTH_EDIT_MESSAGE');
0275      }
0276   
0277      if ($sql)
0278      {
0279          /**
0280          * Alter sql query to get message for user to write the PM
0281          *
0282          * @event core.ucp_pm_compose_compose_pm_basic_info_query_before
0283          * @var    string    sql                        String with the query to be executed
0284          * @var    int        msg_id                    topic_id in the page request
0285          * @var    int        to_user_id                The id of whom the message is to
0286          * @var    int        to_group_id                The id of the group whom the message is to
0287          * @var    bool    submit                    Whether the user is sending the PM or not
0288          * @var    bool    preview                    Whether the user is previewing the PM or not
0289          * @var    string    action                    One of: post, reply, quote, forward, quotepost, edit, delete, smilies
0290          * @var    bool    delete                    Whether the user is deleting the PM
0291          * @var    int        reply_to_all            Value of reply_to_all request variable.
0292          * @since 3.1.0-RC5
0293          * @changed 3.2.0-a1 Removed undefined variables
0294          */
0295          $vars = array(
0296              'sql',
0297              'msg_id',
0298              'to_user_id',
0299              'to_group_id',
0300              'submit',
0301              'preview',
0302              'action',
0303              'delete',
0304              'reply_to_all',
0305          );
0306          extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_compose_pm_basic_info_query_before', compact($vars)));
0307   
0308          $result = $db->sql_query($sql);
0309          $post = $db->sql_fetchrow($result);
0310          $db->sql_freeresult($result);
0311   
0312          /**
0313          * Alter the row of the post being quoted when composing a private message
0314          *
0315          * @event core.ucp_pm_compose_compose_pm_basic_info_query_after
0316          * @var    array    post            Array with data of the post being quoted
0317          * @var    int        msg_id            topic_id in the page request
0318          * @var    int        to_user_id        The id of whom the message is to
0319          * @var    int        to_group_id        The id of the group whom the message is to
0320          * @var    bool    submit            Whether the user is sending the PM or not
0321          * @var    bool    preview            Whether the user is previewing the PM or not
0322          * @var    string    action            One of: post, reply, quote, forward, quotepost, edit, delete, smilies
0323          * @var    bool    delete            Whether the user is deleting the PM
0324          * @var    int        reply_to_all    Value of reply_to_all request variable.
0325          * @since 3.2.10-RC1
0326          * @since 3.3.1-RC1
0327          */
0328          $vars = [
0329              'post',
0330              'msg_id',
0331              'to_user_id',
0332              'to_group_id',
0333              'submit',
0334              'preview',
0335              'action',
0336              'delete',
0337              'reply_to_all',
0338          ];
0339          extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_compose_pm_basic_info_query_after', compact($vars)));
0340   
0341          if (!$post)
0342          {
0343              // If editing it could be the recipient already read the message...
0344              if ($action == 'edit')
0345              {
0346                  $sql = 'SELECT p.*, t.folder_id
0347                      FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
0348                      WHERE t.user_id = ' . $user->data['user_id'] . "
0349                          AND t.msg_id = $msg_id
0350                          AND t.msg_id = p.msg_id";
0351                  $result = $db->sql_query($sql);
0352                  $post = $db->sql_fetchrow($result);
0353                  $db->sql_freeresult($result);
0354   
0355                  if ($post)
0356                  {
0357                      trigger_error('NO_EDIT_READ_MESSAGE');
0358                  }
0359              }
0360   
0361              trigger_error('NO_MESSAGE');
0362          }
0363   
0364          if ($action == 'quotepost')
0365          {
0366              if (($post['forum_id'] && !$auth->acl_get('f_read', $post['forum_id'])) || (!$post['forum_id'] && !$auth->acl_getf_global('f_read')))
0367              {
0368                  send_status_line(403, 'Forbidden');
0369                  trigger_error('NOT_AUTHORISED');
0370              }
0371   
0372              /**
0373              * Get the result of querying for the post to be quoted in the pm message
0374              *
0375              * @event core.ucp_pm_compose_quotepost_query_after
0376              * @var    string    sql                    The original SQL used in the query
0377              * @var    array    post                Associative array with the data of the quoted post
0378              * @var    array    msg_id                The post_id that was searched to get the message for quoting
0379              * @var    int        to_user_id            Users the message is sent to
0380              * @var    int        to_group_id            Groups the message is sent to
0381              * @var    bool    submit                Whether the user is sending the PM or not
0382              * @var    bool    preview                Whether the user is previewing the PM or not
0383              * @var    string    action                One of: post, reply, quote, forward, quotepost, edit, delete, smilies
0384              * @var    bool    delete                If deleting message
0385              * @var    int        reply_to_all        Value of reply_to_all request variable.
0386              * @since 3.1.0-RC5
0387              * @changed 3.2.0-a1 Removed undefined variables
0388              */
0389              $vars = array(
0390                  'sql',
0391                  'post',
0392                  'msg_id',
0393                  'to_user_id',
0394                  'to_group_id',
0395                  'submit',
0396                  'preview',
0397                  'action',
0398                  'delete',
0399                  'reply_to_all',
0400              );
0401              extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_quotepost_query_after', compact($vars)));
0402   
0403              // Passworded forum?
0404              if ($post['forum_id'])
0405              {
0406                  $sql = 'SELECT forum_id, forum_name, forum_password
0407                      FROM ' . FORUMS_TABLE . '
0408                      WHERE forum_id = ' . (int) $post['forum_id'];
0409                  $result = $db->sql_query($sql);
0410                  $forum_data = $db->sql_fetchrow($result);
0411                  $db->sql_freeresult($result);
0412   
0413                  if (!empty($forum_data['forum_password']))
0414                  {
0415                      login_forum_box($forum_data);
0416                  }
0417              }
0418          }
0419   
0420          $msg_id            = (int) $post['msg_id'];
0421          $folder_id        = (isset($post['folder_id'])) ? $post['folder_id'] : 0;
0422          $message_text    = (isset($post['message_text'])) ? $post['message_text'] : '';
0423   
0424          if ((!$post['author_id'] || ($post['author_id'] == ANONYMOUS && $action != 'delete')) && $msg_id)
0425          {
0426              trigger_error('NO_AUTHOR');
0427          }
0428   
0429          if ($action == 'quotepost')
0430          {
0431              // Decode text for message display
0432              decode_message($message_text, $post['bbcode_uid']);
0433          }
0434   
0435          if ($action != 'delete')
0436          {
0437              $enable_urls = $post['enable_magic_url'];
0438              $enable_sig = (isset($post['enable_sig'])) ? $post['enable_sig'] : 0;
0439   
0440              $message_attachment = (isset($post['message_attachment'])) ? $post['message_attachment'] : 0;
0441              $message_subject = $post['message_subject'];
0442              $message_time = $post['message_time'];
0443              $bbcode_uid = $post['bbcode_uid'];
0444   
0445              $quote_username = (isset($post['quote_username'])) ? $post['quote_username'] : '';
0446              $icon_id = (isset($post['icon_id'])) ? $post['icon_id'] : 0;
0447   
0448              if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !count($address_list) && !$refresh && !$submit && !$preview)
0449              {
0450                  // Add the original author as the recipient if quoting a post or only replying and not having checked "reply to all"
0451                  if ($action == 'quotepost' || !$reply_to_all)
0452                  {
0453                      $address_list = array('u' => array($post['author_id'] => 'to'));
0454                  }
0455                  else
0456                  {
0457                      // We try to include every previously listed member from the TO Header - Reply to all
0458                      $address_list = rebuild_header(array('to' => $post['to_address']));
0459   
0460                      // Add the author (if he is already listed then this is no shame (it will be overwritten))
0461                      $address_list['u'][$post['author_id']] = 'to';
0462   
0463                      // Now, make sure the user itself is not listed. ;)
0464                      if (isset($address_list['u'][$user->data['user_id']]))
0465                      {
0466                          unset($address_list['u'][$user->data['user_id']]);
0467                      }
0468                  }
0469              }
0470              else if ($action == 'edit' && !count($address_list) && !$refresh && !$submit && !$preview)
0471              {
0472                  // Rebuild TO and BCC Header
0473                  $address_list = rebuild_header(array('to' => $post['to_address'], 'bcc' => $post['bcc_address']));
0474              }
0475   
0476              if ($action == 'quotepost')
0477              {
0478                  $check_value = 0;
0479              }
0480              else
0481              {
0482                  $check_value = (($post['enable_bbcode']+1) << 8) + (($post['enable_smilies']+1) << 4) + (($enable_urls+1) << 2) + (($post['enable_sig']+1) << 1);
0483              }
0484          }
0485      }
0486      else
0487      {
0488          $message_attachment = 0;
0489          $message_text = $message_subject = '';
0490   
0491          /**
0492          * Predefine message text and subject
0493          *
0494          * @event core.ucp_pm_compose_predefined_message
0495          * @var    string    message_text    Message text
0496          * @var    string    message_subject    Messate subject
0497          * @since 3.1.11-RC1
0498          */
0499          $vars = array('message_text', 'message_subject');
0500          extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_predefined_message', compact($vars)));
0501   
0502          if ($to_user_id && $to_user_id != ANONYMOUS && $action == 'post')
0503          {
0504              $address_list['u'][$to_user_id] = 'to';
0505          }
0506          else if ($to_group_id && $action == 'post')
0507          {
0508              $address_list['g'][$to_group_id] = 'to';
0509          }
0510          $check_value = 0;
0511      }
0512   
0513      if (($to_group_id || isset($address_list['g'])) && (!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm_group')))
0514      {
0515          send_status_line(403, 'Forbidden');
0516          trigger_error('NO_AUTH_GROUP_MESSAGE');
0517      }
0518   
0519      if ($action == 'edit' && !$refresh && !$preview && !$submit)
0520      {
0521          if (!($message_time > time() - ($config['pm_edit_time'] * 60) || !$config['pm_edit_time']))
0522          {
0523              trigger_error('CANNOT_EDIT_MESSAGE_TIME');
0524          }
0525      }
0526   
0527      if ($action == 'post')
0528      {
0529          $template->assign_var('S_NEW_MESSAGE', true);
0530      }
0531   
0532      if (!isset($icon_id))
0533      {
0534          $icon_id = 0;
0535      }
0536   
0537      /* @var $plupload \phpbb\plupload\plupload */
0538      $plupload = $phpbb_container->get('plupload');
0539      $message_parser = new parse_message();
0540      $message_parser->set_plupload($plupload);
0541   
0542      $message_parser->message = ($action == 'reply') ? '' : $message_text;
0543      unset($message_text);
0544   
0545      $s_action = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&amp;mode=$mode&amp;action=$action", true, $user->session_id);
0546      $s_action .= (($folder_id) ? "&amp;f=$folder_id" : '') . (($msg_id) ? "&amp;p=$msg_id" : '');
0547   
0548      // Delete triggered ?
0549      if ($action == 'delete')
0550      {
0551          // Folder id has been determined by the SQL Statement
0552          // $folder_id = $request->variable('f', PRIVMSGS_NO_BOX);
0553   
0554          // Do we need to confirm ?
0555          if (confirm_box(true))
0556          {
0557              delete_pm($user->data['user_id'], $msg_id, $folder_id);
0558   
0559              // jump to next message in "history"? nope, not for the moment. But able to be included later.
0560              $meta_info = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&amp;folder=$folder_id");
0561              $message = $user->lang['MESSAGE_DELETED'];
0562   
0563              meta_refresh(3, $meta_info);
0564              $message .= '<br /><br />' . sprintf($user->lang['RETURN_FOLDER'], '<a href="' . $meta_info . '">', '</a>');
0565              trigger_error($message);
0566          }
0567          else
0568          {
0569              $s_hidden_fields = array(
0570                  'p'            => $msg_id,
0571                  'f'            => $folder_id,
0572                  'action'    => 'delete'
0573              );
0574   
0575              // "{$phpbb_root_path}ucp.$phpEx?i=pm&amp;mode=compose"
0576              confirm_box(false, 'DELETE_MESSAGE', build_hidden_fields($s_hidden_fields));
0577          }
0578   
0579          redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;action=view_message&amp;p=' . $msg_id));
0580      }
0581   
0582      // Get maximum number of allowed recipients
0583      $max_recipients = phpbb_get_max_setting_from_group($db, $user->data['user_id'], 'max_recipients');
0584   
0585      // If it is 0, there is no limit set and we use the maximum value within the config.
0586      $max_recipients = (!$max_recipients) ? $config['pm_max_recipients'] : $max_recipients;
0587   
0588      // If this is a quote/reply "to all"... we may increase the max_recpients to the number of original recipients
0589      if (($action == 'reply' || $action == 'quote') && $max_recipients && $reply_to_all)
0590      {
0591          // We try to include every previously listed member from the TO Header
0592          $list = rebuild_header(array('to' => $post['to_address']));
0593   
0594          // Can be an empty array too ;)
0595          $list = (!empty($list['u'])) ? $list['u'] : array();
0596          $list[$post['author_id']] = 'to';
0597   
0598          if (isset($list[$user->data['user_id']]))
0599          {
0600              unset($list[$user->data['user_id']]);
0601          }
0602   
0603          $max_recipients = ($max_recipients < count($list)) ? count($list) : $max_recipients;
0604   
0605          unset($list);
0606      }
0607   
0608      // Handle User/Group adding/removing
0609      handle_message_list_actions($address_list, $error, $remove_u, $remove_g, $add_to, $add_bcc);
0610   
0611      // Check mass pm to group permission
0612      if ((!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm_group')) && !empty($address_list['g']))
0613      {
0614          $address_list = array();
0615          $error[] = $user->lang['NO_AUTH_GROUP_MESSAGE'];
0616      }
0617   
0618      // Check mass pm to users permission
0619      if ((!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm')) && num_recipients($address_list) > 1)
0620      {
0621          $address_list = get_recipients($address_list, 1);
0622          $error[] = $user->lang('TOO_MANY_RECIPIENTS', 1);
0623      }
0624   
0625      // Check for too many recipients
0626      if (!empty($address_list['u']) && $max_recipients && count($address_list['u']) > $max_recipients)
0627      {
0628          $address_list = get_recipients($address_list, $max_recipients);
0629          $error[] = $user->lang('TOO_MANY_RECIPIENTS', $max_recipients);
0630      }
0631   
0632      // Always check if the submitted attachment data is valid and belongs to the user.
0633      // Further down (especially in submit_post()) we do not check this again.
0634      $message_parser->get_submitted_attachment_data();
0635   
0636      if ($message_attachment && !$submit && !$refresh && !$preview && $action == 'edit')
0637      {
0638          // Do not change to SELECT *
0639          $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename, filesize
0640              FROM ' . ATTACHMENTS_TABLE . "
0641              WHERE post_msg_id = $msg_id
0642                  AND in_message = 1
0643                  AND is_orphan = 0
0644              ORDER BY filetime DESC";
0645          $result = $db->sql_query($sql);
0646          $message_parser->attachment_data = array_merge($message_parser->attachment_data, $db->sql_fetchrowset($result));
0647          $db->sql_freeresult($result);
0648      }
0649   
0650      if (!in_array($action, array('quote', 'edit', 'delete', 'forward')))
0651      {
0652          $enable_sig        = ($config['allow_sig'] && $config['allow_sig_pm'] && $auth->acl_get('u_sig') && $user->optionget('attachsig'));
0653          $enable_smilies    = ($config['allow_smilies'] && $auth->acl_get('u_pm_smilies') && $user->optionget('smilies'));
0654          $enable_bbcode    = ($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode') && $user->optionget('bbcode'));
0655          $enable_urls    = true;
0656      }
0657   
0658      $drafts = false;
0659   
0660      // User own some drafts?
0661      if ($auth->acl_get('u_savedrafts') && $action != 'delete')
0662      {
0663          $sql = 'SELECT draft_id
0664              FROM ' . DRAFTS_TABLE . '
0665              WHERE forum_id = 0
0666                  AND topic_id = 0
0667                  AND user_id = ' . $user->data['user_id'] .
0668                  (($draft_id) ? " AND draft_id <> $draft_id" : '');
0669          $result = $db->sql_query_limit($sql, 1);
0670          $row = $db->sql_fetchrow($result);
0671          $db->sql_freeresult($result);
0672   
0673          if ($row)
0674          {
0675              $drafts = true;
0676          }
0677      }
0678   
0679      if ($action == 'edit')
0680      {
0681          $message_parser->bbcode_uid = $bbcode_uid;
0682      }
0683   
0684      $bbcode_status    = ($config['allow_bbcode'] && $config['auth_bbcode_pm'] && $auth->acl_get('u_pm_bbcode')) ? true : false;
0685      $smilies_status    = ($config['allow_smilies'] && $config['auth_smilies_pm'] && $auth->acl_get('u_pm_smilies')) ? true : false;
0686      $img_status        = ($config['auth_img_pm'] && $auth->acl_get('u_pm_img')) ? true : false;
0687      $flash_status    = ($config['auth_flash_pm'] && $auth->acl_get('u_pm_flash')) ? true : false;
0688      $url_status        = ($config['allow_post_links']) ? true : false;
0689   
0690      /**
0691       * Event to override private message BBCode status indications
0692       *
0693       * @event core.ucp_pm_compose_modify_bbcode_status
0694       *
0695       * @var bool    bbcode_status    BBCode status
0696       * @var bool    smilies_status    Smilies status
0697       * @var bool    img_status        Image BBCode status
0698       * @var bool    flash_status    Flash BBCode status
0699       * @var bool    url_status        URL BBCode status
0700       * @since 3.3.3-RC1
0701       */
0702      $vars = [
0703          'bbcode_status',
0704          'smilies_status',
0705          'img_status',
0706          'flash_status',
0707          'url_status',
0708      ];
0709      extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_bbcode_status', compact($vars)));
0710   
0711      // Save Draft
0712      if ($save && $auth->acl_get('u_savedrafts'))
0713      {
0714          $subject = $request->variable('subject', '', true);
0715          $subject = (!$subject && $action != 'post') ? $user->lang['NEW_MESSAGE'] : $subject;
0716          $message = $request->variable('message', '', true);
0717   
0718          /**
0719           * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR.
0720           * Using their Numeric Character Reference's Hexadecimal notation.
0721           */
0722          $subject = utf8_encode_ucr($subject);
0723   
0724          if ($subject && $message)
0725          {
0726              if (confirm_box(true))
0727              {
0728                  $message_parser->message = $message;
0729                  $message_parser->parse($bbcode_status, $url_status, $smilies_status, $img_status, $flash_status, true, $url_status);
0730   
0731                  $sql = 'INSERT INTO ' . DRAFTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
0732                      'user_id'        => $user->data['user_id'],
0733                      'topic_id'        => 0,
0734                      'forum_id'        => 0,
0735                      'save_time'        => $current_time,
0736                      'draft_subject'    => $subject,
0737                      'draft_message'    => $message_parser->message,
0738                      )
0739                  );
0740                  $db->sql_query($sql);
0741   
0742                  /** @var \phpbb\attachment\manager $attachment_manager */
0743                  $attachment_manager = $phpbb_container->get('attachment.manager');
0744                  $attachment_manager->delete('attach', array_column($message_parser->attachment_data, 'attach_id'));
0745   
0746                  $redirect_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&amp;mode=$mode");
0747   
0748                  meta_refresh(3, $redirect_url);
0749                  $message = $user->lang['DRAFT_SAVED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>');
0750   
0751                  trigger_error($message);
0752              }
0753              else
0754              {
0755                  $s_hidden_fields = build_hidden_fields(array(
0756                      'mode'        => $mode,
0757                      'action'    => $action,
0758                      'save'        => true,
0759                      'subject'    => $subject,
0760                      'message'    => $message,
0761                      'u'            => $to_user_id,
0762                      'g'            => $to_group_id,
0763                      'p'            => $msg_id,
0764                      'attachment_data' => $message_parser->attachment_data,
0765                  ));
0766                  $s_hidden_fields .= build_address_field($address_list);
0767   
0768                  confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields);
0769              }
0770          }
0771          else
0772          {
0773              if (utf8_clean_string($subject) === '')
0774              {
0775                  $error[] = $user->lang['EMPTY_MESSAGE_SUBJECT'];
0776              }
0777   
0778              if (utf8_clean_string($message) === '')
0779              {
0780                  $error[] = $user->lang['TOO_FEW_CHARS'];
0781              }
0782          }
0783   
0784          unset($subject, $message);
0785      }
0786   
0787      // Load Draft
0788      if ($draft_id && $auth->acl_get('u_savedrafts'))
0789      {
0790          $sql = 'SELECT draft_subject, draft_message
0791              FROM ' . DRAFTS_TABLE . "
0792              WHERE draft_id = $draft_id
0793                  AND topic_id = 0
0794                  AND forum_id = 0
0795                  AND user_id = " . $user->data['user_id'];
0796          $result = $db->sql_query_limit($sql, 1);
0797   
0798          if ($row = $db->sql_fetchrow($result))
0799          {
0800              $message_parser->message = $row['draft_message'];
0801              $message_subject = $row['draft_subject'];
0802   
0803              $template->assign_var('S_DRAFT_LOADED', true);
0804          }
0805          else
0806          {
0807              $draft_id = 0;
0808          }
0809          $db->sql_freeresult($result);
0810      }
0811   
0812      // Load Drafts
0813      if ($load && $drafts)
0814      {
0815          load_drafts(0, 0, $id, $action, $msg_id);
0816      }
0817   
0818      if ($submit || $preview || $refresh)
0819      {
0820          if (($submit || $preview) && !check_form_key('ucp_pm_compose'))
0821          {
0822              $error[] = $user->lang['FORM_INVALID'];
0823          }
0824          $subject = $request->variable('subject', '', true);
0825          $message_parser->message = $request->variable('message', '', true);
0826   
0827          $icon_id            = $request->variable('icon', 0);
0828   
0829          $enable_bbcode         = (!$bbcode_status || isset($_POST['disable_bbcode'])) ? false : true;
0830          $enable_smilies        = (!$smilies_status || isset($_POST['disable_smilies'])) ? false : true;
0831          $enable_urls         = (isset($_POST['disable_magic_url'])) ? 0 : 1;
0832          $enable_sig            = (!$config['allow_sig'] ||!$config['allow_sig_pm']) ? false : ((isset($_POST['attach_sig'])) ? true : false);
0833   
0834          /**
0835          * Modify private message
0836          *
0837          * @event core.ucp_pm_compose_modify_parse_before
0838          * @var    bool    enable_bbcode        Whether or not bbcode is enabled
0839          * @var    bool    enable_smilies        Whether or not smilies are enabled
0840          * @var    bool    enable_urls            Whether or not urls are enabled
0841          * @var    bool    enable_sig            Whether or not signature is enabled
0842          * @var    string    subject                PM subject text
0843          * @var    object    message_parser        The message parser object
0844          * @var    bool    submit                Whether or not the form has been sumitted
0845          * @var    bool    preview                Whether or not the signature is being previewed
0846          * @var    array    error                Any error strings
0847          * @since 3.1.10-RC1
0848          */
0849          $vars = array(
0850              'enable_bbcode',
0851              'enable_smilies',
0852              'enable_urls',
0853              'enable_sig',
0854              'subject',
0855              'message_parser',
0856              'submit',
0857              'preview',
0858              'error',
0859          );
0860          extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_parse_before', compact($vars)));
0861   
0862          // Parse Attachments - before checksum is calculated
0863          if ($message_parser->check_attachment_form_token($language, $request, 'ucp_pm_compose'))
0864          {
0865              $message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true);
0866          }
0867   
0868          if (count($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc))
0869          {
0870              $error[] = implode('<br />', $message_parser->warn_msg);
0871              $message_parser->warn_msg = array();
0872          }
0873   
0874          // Parse message
0875          $message_parser->parse($enable_bbcode, ($config['allow_post_links']) ? $enable_urls : false, $enable_smilies, $img_status, $flash_status, true, $config['allow_post_links']);
0876   
0877          // On a refresh we do not care about message parsing errors
0878          if (count($message_parser->warn_msg) && !$refresh)
0879          {
0880              $error[] = implode('<br />', $message_parser->warn_msg);
0881          }
0882   
0883          if ($action != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$auth->acl_get('u_ignoreflood'))
0884          {
0885              // Flood check
0886              $last_post_time = $user->data['user_lastpost_time'];
0887   
0888              if ($last_post_time)
0889              {
0890                  if ($last_post_time && ($current_time - $last_post_time) < intval($config['flood_interval']))
0891                  {
0892                      $error[] = $user->lang['FLOOD_ERROR'];
0893                  }
0894              }
0895          }
0896   
0897          // Subject defined
0898          if ($submit)
0899          {
0900              if (utf8_clean_string($subject) === '')
0901              {
0902                  $error[] = $user->lang['EMPTY_MESSAGE_SUBJECT'];
0903              }
0904   
0905              if (!count($address_list))
0906              {
0907                  $error[] = $user->lang['NO_RECIPIENT'];
0908              }
0909          }
0910   
0911          /**
0912          * Modify private message
0913          *
0914          * @event core.ucp_pm_compose_modify_parse_after
0915          * @var    bool    enable_bbcode        Whether or not bbcode is enabled
0916          * @var    bool    enable_smilies        Whether or not smilies are enabled
0917          * @var    bool    enable_urls            Whether or not urls are enabled
0918          * @var    bool    enable_sig            Whether or not signature is enabled
0919          * @var    string    subject                PM subject text
0920          * @var    object    message_parser        The message parser object
0921          * @var    bool    submit                Whether or not the form has been sumitted
0922          * @var    bool    preview                Whether or not the signature is being previewed
0923          * @var    array    error                Any error strings
0924          * @since 3.2.10-RC1
0925          * @since 3.3.1-RC1
0926          */
0927          $vars = [
0928              'enable_bbcode',
0929              'enable_smilies',
0930              'enable_urls',
0931              'enable_sig',
0932              'subject',
0933              'message_parser',
0934              'submit',
0935              'preview',
0936              'error',
0937          ];
0938          extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_parse_after', compact($vars)));
0939   
0940          // Store message, sync counters
0941          if (!count($error) && $submit)
0942          {
0943              $pm_data = array(
0944                  'msg_id'                => (int) $msg_id,
0945                  'from_user_id'            => $user->data['user_id'],
0946                  'from_user_ip'            => $user->ip,
0947                  'from_username'            => $user->data['username'],
0948                  'reply_from_root_level'    => (isset($post['root_level'])) ? (int) $post['root_level'] : 0,
0949                  'reply_from_msg_id'        => (int) $msg_id,
0950                  'icon_id'                => (int) $icon_id,
0951                  'enable_sig'            => (bool) $enable_sig,
0952                  'enable_bbcode'            => (bool) $enable_bbcode,
0953                  'enable_smilies'        => (bool) $enable_smilies,
0954                  'enable_urls'            => (bool) $enable_urls,
0955                  'bbcode_bitfield'        => $message_parser->bbcode_bitfield,
0956                  'bbcode_uid'            => $message_parser->bbcode_uid,
0957                  'message'                => $message_parser->message,
0958                  'attachment_data'        => $message_parser->attachment_data,
0959                  'filename_data'            => $message_parser->filename_data,
0960                  'address_list'            => $address_list
0961              );
0962   
0963              /**
0964               * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR.
0965               * Using their Numeric Character Reference's Hexadecimal notation.
0966               */
0967              $subject = utf8_encode_ucr($subject);
0968   
0969              // ((!$message_subject) ? $subject : $message_subject)
0970              $msg_id = submit_pm($action, $subject, $pm_data);
0971   
0972              $return_message_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;p=' . $msg_id);
0973              $inbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=inbox');
0974              $outbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=outbox');
0975   
0976              $folder_url = '';
0977              if (($folder_id > 0) && isset($user_folders[$folder_id]))
0978              {
0979                  $folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $folder_id);
0980              }
0981   
0982              $return_box_url = ($action === 'post' || $action === 'edit') ? $outbox_folder_url : $inbox_folder_url;
0983              $return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX';
0984   
0985              $save_message = ($action === 'edit') ? $user->lang['MESSAGE_EDITED'] : $user->lang['MESSAGE_STORED'];
0986              $message = $save_message . '<br /><br />' . $user->lang('VIEW_PRIVATE_MESSAGE', '<a href="' . $return_message_url . '">', '</a>');
0987   
0988              $last_click_type = 'CLICK_RETURN_FOLDER';
0989              if ($folder_url)
0990              {
0991                  $message .= '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $folder_url . '">', '</a>', $user_folders[$folder_id]['folder_name']);
0992                  $last_click_type = 'CLICK_GOTO_FOLDER';
0993              }
0994              $message .= '<br /><br />' . sprintf($user->lang[$last_click_type], '<a href="' . $return_box_url . '">', '</a>', $user->lang[$return_box_lang]);
0995   
0996              meta_refresh(3, $return_message_url);
0997              trigger_error($message);
0998          }
0999   
1000          $message_subject = $subject;
1001      }
1002   
1003      // Preview
1004      if (!count($error) && $preview)
1005      {
1006          $preview_message = $message_parser->format_display($enable_bbcode, $enable_urls, $enable_smilies, false);
1007   
1008          $preview_signature = $user->data['user_sig'];
1009          $preview_signature_uid = $user->data['user_sig_bbcode_uid'];
1010          $preview_signature_bitfield = $user->data['user_sig_bbcode_bitfield'];
1011   
1012          // Signature
1013          if ($enable_sig && $config['allow_sig'] && $preview_signature)
1014          {
1015              $bbcode_flags = ($enable_bbcode ? OPTION_FLAG_BBCODE : 0) + ($enable_smilies ? OPTION_FLAG_SMILIES : 0) + ($enable_urls ? OPTION_FLAG_LINKS : 0);
1016              $preview_signature = generate_text_for_display($preview_signature, $preview_signature_uid, $preview_signature_bitfield, $bbcode_flags);
1017          }
1018          else
1019          {
1020              $preview_signature = '';
1021          }
1022   
1023          // Attachment Preview
1024          if (count($message_parser->attachment_data))
1025          {
1026              $template->assign_var('S_HAS_ATTACHMENTS', true);
1027   
1028              $update_count = array();
1029              $attachment_data = $message_parser->attachment_data;
1030   
1031              parse_attachments(false, $preview_message, $attachment_data, $update_count, true);
1032   
1033              foreach ($attachment_data as $i => $attachment)
1034              {
1035                  $template->assign_block_vars('attachment', array(
1036                      'DISPLAY_ATTACHMENT'    => $attachment)
1037                  );
1038              }
1039              unset($attachment_data);
1040          }
1041   
1042          $preview_subject = censor_text($subject);
1043   
1044          if (!count($error))
1045          {
1046              $template->assign_vars(array(
1047                  'PREVIEW_SUBJECT'        => $preview_subject,
1048                  'PREVIEW_MESSAGE'        => $preview_message,
1049                  'PREVIEW_SIGNATURE'        => $preview_signature,
1050   
1051                  'S_DISPLAY_PREVIEW'        => true)
1052              );
1053          }
1054          unset($message_text);
1055      }
1056   
1057      // Decode text for message display
1058      $bbcode_uid = (($action == 'quote' || $action == 'forward') && !$preview && !$refresh && (!count($error) || (count($error) && !$submit))) ? $bbcode_uid : $message_parser->bbcode_uid;
1059   
1060      $message_parser->decode_message($bbcode_uid);
1061   
1062      if (($action == 'quote' || $action == 'quotepost') && !$preview && !$refresh && !$submit)
1063      {
1064          if ($action == 'quotepost')
1065          {
1066              $post_id = $request->variable('p', 0);
1067              if ($config['allow_post_links'])
1068              {
1069                  $message_link = generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id}";
1070                  $message_link_subject = "{$user->lang['SUBJECT']}{$user->lang['COLON']} {$message_subject}";
1071                  if ($bbcode_status)
1072                  {
1073                      $message_link = "[url=" . $message_link . "]" . $message_link_subject . "[/url]\n\n";
1074                  }
1075                  else
1076                  {
1077                      $message_link = $message_link . " - " . $message_link_subject . "\n\n";
1078                  }
1079              }
1080              else
1081              {
1082                  $message_link = $user->lang['SUBJECT'] . $user->lang['COLON'] . ' ' . $message_subject . " (" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id})\n\n";
1083              }
1084          }
1085          else
1086          {
1087              $message_link = '';
1088          }
1089          $quote_attributes = array(
1090              'author'  => $quote_username,
1091              'time'    => $post['message_time'],
1092              'user_id' => $post['author_id'],
1093          );
1094          if ($action === 'quotepost')
1095          {
1096              $quote_attributes['post_id'] = $post['msg_id'];
1097          }
1098          if ($action === 'quote')
1099          {
1100              $quote_attributes['msg_id'] = $post['msg_id'];
1101          }
1102          /** @var \phpbb\language\language $language */
1103          $language = $phpbb_container->get('language');
1104          /** @var \phpbb\textformatter\utils_interface $text_formatter_utils */
1105          $text_formatter_utils = $phpbb_container->get('text_formatter.utils');
1106          phpbb_format_quote($language, $message_parser, $text_formatter_utils, $bbcode_status, $quote_attributes, $message_link);
1107      }
1108   
1109      if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !$preview && !$refresh)
1110      {
1111          $message_subject = ((!preg_match('/^Re:/', $message_subject)) ? 'Re: ' : '') . censor_text($message_subject);
1112   
1113          /**
1114          * This event allows you to modify the PM subject of the PM being quoted
1115          *
1116          * @event core.pm_modify_message_subject
1117          * @var    string        message_subject        String with the PM subject already censored.
1118          * @since 3.2.8-RC1
1119          */
1120          $vars = array('message_subject');
1121          extract($phpbb_dispatcher->trigger_event('core.pm_modify_message_subject', compact($vars)));
1122      }
1123   
1124      if ($action == 'forward' && !$preview && !$refresh && !$submit)
1125      {
1126          $fwd_to_field = write_pm_addresses(array('to' => $post['to_address']), 0, true);
1127   
1128          if ($config['allow_post_links'])
1129          {
1130              $quote_username_text = '[url=' . generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&amp;u={$post['author_id']}]{$quote_username}[/url]";
1131          }
1132          else
1133          {
1134              $quote_username_text = $quote_username . ' (' . generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&amp;u={$post['author_id']})";
1135          }
1136   
1137          $forward_text = array();
1138          $forward_text[] = $user->lang['FWD_ORIGINAL_MESSAGE'];
1139          $forward_text[] = sprintf($user->lang['FWD_SUBJECT'], censor_text($message_subject));
1140          $forward_text[] = sprintf($user->lang['FWD_DATE'], $user->format_date($message_time, false, true));
1141          $forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text);
1142          $forward_text[] = sprintf($user->lang['FWD_TO'], implode($user->lang['COMMA_SEPARATOR'], $fwd_to_field['to']));
1143   
1144          $quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote(
1145              censor_text($message_parser->message),
1146              array('author' => $quote_username)
1147          );
1148          $message_parser->message = implode("\n", $forward_text) . "\n\n" . $quote_text;
1149          $message_subject = ((!preg_match('/^Fwd:/', $message_subject)) ? 'Fwd: ' : '') . censor_text($message_subject);
1150      }
1151   
1152      $attachment_data = $message_parser->attachment_data;
1153      $filename_data = $message_parser->filename_data;
1154      $message_text = $message_parser->message;
1155   
1156      // MAIN PM PAGE BEGINS HERE
1157   
1158      // Generate smiley listing
1159      generate_smilies('inline', 0);
1160   
1161      // Generate PM Icons
1162      $s_pm_icons = false;
1163      if ($config['enable_pm_icons'])
1164      {
1165          $s_pm_icons = posting_gen_topic_icons($action, $icon_id);
1166      }
1167   
1168      // Generate inline attachment select box
1169      posting_gen_inline_attachments($attachment_data);
1170   
1171      // Build address list for display
1172      // array('u' => array($author_id => 'to'));
1173      if (count($address_list))
1174      {
1175          // Get Usernames and Group Names
1176          $result = array();
1177          if (!empty($address_list['u']))
1178          {
1179              $sql = 'SELECT user_id as id, username as name, user_colour as colour
1180                  FROM ' . USERS_TABLE . '
1181                  WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($address_list['u']))) . '
1182                  ORDER BY username_clean ASC';
1183              $result['u'] = $db->sql_query($sql);
1184          }
1185   
1186          if (!empty($address_list['g']))
1187          {
1188              $sql = 'SELECT g.group_id AS id, g.group_name AS name, g.group_colour AS colour, g.group_type
1189                  FROM ' . GROUPS_TABLE . ' g';
1190   
1191              if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel'))
1192              {
1193                  $sql .= ' LEFT JOIN ' . USER_GROUP_TABLE . ' ug
1194                      ON (
1195                          g.group_id = ug.group_id
1196                          AND ug.user_id = ' . $user->data['user_id'] . '
1197                          AND ug.user_pending = 0
1198                      )
1199                      WHERE (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ')';
1200              }
1201   
1202              $sql .= ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? ' WHERE ' : ' AND ';
1203   
1204              $sql .= 'g.group_receive_pm = 1
1205                  AND ' . $db->sql_in_set('g.group_id', array_map('intval', array_keys($address_list['g']))) . '
1206                  ORDER BY g.group_name ASC';
1207   
1208              $result['g'] = $db->sql_query($sql);
1209          }
1210   
1211          $u = $g = array();
1212          $_types = array('u', 'g');
1213          foreach ($_types as $type)
1214          {
1215              if (isset($result[$type]) && $result[$type])
1216              {
1217                  while ($row = $db->sql_fetchrow($result[$type]))
1218                  {
1219                      if ($type == 'g')
1220                      {
1221                          $row['name'] = $group_helper->get_name($row['name']);
1222                      }
1223   
1224                      ${$type}[$row['id']] = array('name' => $row['name'], 'colour' => $row['colour']);
1225                  }
1226                  $db->sql_freeresult($result[$type]);
1227              }
1228          }
1229   
1230          // Now Build the address list
1231          foreach ($address_list as $type => $adr_ary)
1232          {
1233              foreach ($adr_ary as $id => $field)
1234              {
1235                  if (!isset(${$type}[$id]))
1236                  {
1237                      unset($address_list[$type][$id]);
1238                      continue;
1239                  }
1240   
1241                  $field = ($field == 'to') ? 'to' : 'bcc';
1242                  $type = ($type == 'u') ? 'u' : 'g';
1243                  $id = (int) $id;
1244   
1245                  $tpl_ary = array(
1246                      'IS_GROUP'    => ($type == 'g') ? true : false,
1247                      'IS_USER'    => ($type == 'u') ? true : false,
1248                      'UG_ID'        => $id,
1249                      'NAME'        => ${$type}[$id]['name'],
1250                      'COLOUR'    => (${$type}[$id]['colour']) ? '#' . ${$type}[$id]['colour'] : '',
1251                      'TYPE'        => $type,
1252                  );
1253   
1254                  if ($type == 'u')
1255                  {
1256                      $tpl_ary = array_merge($tpl_ary, array(
1257                          'U_VIEW'        => get_username_string('profile', $id, ${$type}[$id]['name'], ${$type}[$id]['colour']),
1258                          'NAME_FULL'        => get_username_string('full', $id, ${$type}[$id]['name'], ${$type}[$id]['colour']),
1259                      ));
1260                  }
1261                  else
1262                  {
1263                      $tpl_ary = array_merge($tpl_ary, array(
1264                          'U_VIEW'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $id),
1265                      ));
1266                  }
1267   
1268                  $template->assign_block_vars($field . '_recipient', $tpl_ary);
1269              }
1270          }
1271      }
1272   
1273      // Build hidden address list
1274      $s_hidden_address_field = build_address_field($address_list);
1275   
1276      $bbcode_checked        = (isset($enable_bbcode)) ? !$enable_bbcode : (($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode')) ? !$user->optionget('bbcode') : 1);
1277      $smilies_checked    = (isset($enable_smilies)) ? !$enable_smilies : (($config['allow_smilies'] && $auth->acl_get('u_pm_smilies')) ? !$user->optionget('smilies') : 1);
1278      $urls_checked        = (isset($enable_urls)) ? !$enable_urls : 0;
1279      $sig_checked        = $enable_sig;
1280   
1281      switch ($action)
1282      {
1283          case 'post':
1284              $page_title = $user->lang['POST_NEW_PM'];
1285          break;
1286   
1287          case 'quote':
1288              $page_title = $user->lang['POST_QUOTE_PM'];
1289          break;
1290   
1291          case 'quotepost':
1292              $page_title = $user->lang['POST_PM_POST'];
1293          break;
1294   
1295          case 'reply':
1296              $page_title = $user->lang['POST_REPLY_PM'];
1297          break;
1298   
1299          case 'edit':
1300              $page_title = $user->lang['POST_EDIT_PM'];
1301          break;
1302   
1303          case 'forward':
1304              $page_title = $user->lang['POST_FORWARD_PM'];
1305          break;
1306   
1307          default:
1308              trigger_error('NO_ACTION_MODE', E_USER_ERROR);
1309          break;
1310      }
1311   
1312      $s_hidden_fields = (isset($check_value)) ? '<input type="hidden" name="status_switch" value="' . $check_value . '" />' : '';
1313      $s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input type="hidden" name="draft_loaded" value="' . ((isset($_REQUEST['draft_loaded'])) ? $request->variable('draft_loaded', 0) : $draft_id) . '" />' : '';
1314   
1315      $form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_pm_attach'] || !$auth->acl_get('u_pm_attach')) ? '' : ' enctype="multipart/form-data"';
1316   
1317      /** @var \phpbb\controller\helper $controller_helper */
1318      $controller_helper = $phpbb_container->get('controller.helper');
1319   
1320      // Start assigning vars for main posting page ...
1321      $template_ary = array(
1322          'L_POST_A'                    => $page_title,
1323          'L_ICON'                    => $user->lang['PM_ICON'],
1324          'L_MESSAGE_BODY_EXPLAIN'    => $user->lang('MESSAGE_BODY_EXPLAIN', (int) $config['max_post_chars']),
1325   
1326          'SUBJECT'                => (isset($message_subject)) ? $message_subject : '',
1327          'MESSAGE'                => $message_text,
1328          'BBCODE_STATUS'            => $user->lang(($bbcode_status ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'),
1329          'IMG_STATUS'            => ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
1330          'FLASH_STATUS'            => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
1331          'SMILIES_STATUS'        => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
1332          'URL_STATUS'            => ($url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
1333          'MAX_FONT_SIZE'            => (int) $config['max_post_font_size'],
1334          'MINI_POST_IMG'            => $user->img('icon_post_target', $user->lang['PM']),
1335          'ERROR'                    => (count($error)) ? implode('<br />', $error) : '',
1336          'MAX_RECIPIENTS'        => ($config['allow_mass_pm'] && ($auth->acl_get('u_masspm') || $auth->acl_get('u_masspm_group'))) ? $max_recipients : 0,
1337   
1338          'S_COMPOSE_PM'            => true,
1339          'S_EDIT_POST'            => ($action == 'edit'),
1340          'S_SHOW_PM_ICONS'        => $s_pm_icons,
1341          'S_BBCODE_ALLOWED'        => ($bbcode_status) ? 1 : 0,
1342          'S_BBCODE_CHECKED'        => ($bbcode_checked) ? ' checked="checked"' : '',
1343          'S_SMILIES_ALLOWED'        => $smilies_status,
1344          'S_SMILIES_CHECKED'        => ($smilies_checked) ? ' checked="checked"' : '',
1345          'S_SIG_ALLOWED'            => ($config['allow_sig'] && $config['allow_sig_pm'] && $auth->acl_get('u_sig')),
1346          'S_SIGNATURE_CHECKED'    => ($sig_checked) ? ' checked="checked"' : '',
1347          'S_LINKS_ALLOWED'        => $url_status,
1348          'S_MAGIC_URL_CHECKED'    => ($urls_checked) ? ' checked="checked"' : '',
1349          'S_SAVE_ALLOWED'        => ($auth->acl_get('u_savedrafts') && $action != 'edit') ? true : false,
1350          'S_HAS_DRAFTS'            => ($auth->acl_get('u_savedrafts') && $drafts),
1351          'S_FORM_ENCTYPE'        => $form_enctype,
1352          'S_ATTACH_DATA'            => json_encode($message_parser->attachment_data),
1353   
1354          'S_BBCODE_IMG'            => $img_status,
1355          'S_BBCODE_FLASH'        => $flash_status,
1356          'S_BBCODE_QUOTE'        => true,
1357          'S_BBCODE_URL'            => $url_status,
1358   
1359          'S_POST_ACTION'                => $s_action,
1360          'S_HIDDEN_ADDRESS_FIELD'    => $s_hidden_address_field,
1361          'S_HIDDEN_FIELDS'            => $s_hidden_fields,
1362   
1363          'S_CLOSE_PROGRESS_WINDOW'    => isset($_POST['add_file']),
1364          'U_PROGRESS_BAR'            => append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&amp;mode=popup'),
1365          'UA_PROGRESS_BAR'            => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&amp;mode=popup')),
1366      );
1367   
1368      /**
1369      * Modify the default template vars
1370      *
1371      * @event core.ucp_pm_compose_template
1372      * @var    array    template_ary    Template variables
1373      * @since 3.2.6-RC1
1374      */
1375      $vars = array('template_ary');
1376      extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_template', compact($vars)));
1377   
1378      $template->assign_vars($template_ary);
1379   
1380      // Build custom bbcodes array
1381      display_custom_bbcodes();
1382   
1383      // Show attachment box for adding attachments if true
1384      $allowed = ($auth->acl_get('u_pm_attach') && $config['allow_pm_attach'] && $form_enctype);
1385   
1386      if ($allowed)
1387      {
1388          $max_files = ($auth->acl_gets('a_', 'm_')) ? 0 : (int) $config['max_attachments_pm'];
1389          $plupload->configure($cache, $template, $s_action, false, $max_files);
1390      }
1391   
1392      // Attachment entry
1393      posting_gen_attachment_entry($attachment_data, $filename_data, $allowed);
1394   
1395      // Message History
1396      if ($action == 'reply' || $action == 'quote' || $action == 'forward')
1397      {
1398          if (message_history($msg_id, $user->data['user_id'], $post, array(), true))
1399          {
1400              $template->assign_var('S_DISPLAY_HISTORY', true);
1401          }
1402      }
1403  }
1404   
1405  /**
1406  * For composing messages, handle list actions
1407  */
1408  function handle_message_list_actions(&$address_list, &$error, $remove_u, $remove_g, $add_to, $add_bcc)
1409  {
1410      global $auth, $db, $user;
1411      global $request, $phpbb_dispatcher;
1412   
1413      // Delete User [TO/BCC]
1414      if ($remove_u && $request->variable('remove_u', array(0 => '')))
1415      {
1416          $remove_user_id = array_keys($request->variable('remove_u', array(0 => '')));
1417   
1418          if (isset($remove_user_id[0]))
1419          {
1420              unset($address_list['u'][(int) $remove_user_id[0]]);
1421          }
1422      }
1423   
1424      // Delete Group [TO/BCC]
1425      if ($remove_g && $request->variable('remove_g', array(0 => '')))
1426      {
1427          $remove_group_id = array_keys($request->variable('remove_g', array(0 => '')));
1428   
1429          if (isset($remove_group_id[0]))
1430          {
1431              unset($address_list['g'][(int) $remove_group_id[0]]);
1432          }
1433      }
1434   
1435      // Add Selected Groups
1436      $group_list = $request->variable('group_list', array(0));
1437   
1438      // Build usernames to add
1439      $usernames = $request->variable('username', '', true);
1440      $usernames = (empty($usernames)) ? array() : array($usernames);
1441   
1442      $username_list = $request->variable('username_list', '', true);
1443      if ($username_list)
1444      {
1445          $usernames = array_merge($usernames, explode("\n", $username_list));
1446      }
1447   
1448      // If add to or add bcc not pressed, users could still have usernames listed they want to add...
1449      if (!$add_to && !$add_bcc && (count($group_list) || count($usernames)))
1450      {
1451          $add_to = true;
1452   
1453          global $refresh, $submit, $preview;
1454   
1455          $refresh = true;
1456          $submit = false;
1457   
1458          // Preview is only true if there was also a message entered
1459          if ($request->variable('message', ''))
1460          {
1461              $preview = true;
1462          }
1463      }
1464   
1465      // Add User/Group [TO]
1466      if ($add_to || $add_bcc)
1467      {
1468          $type = ($add_to) ? 'to' : 'bcc';
1469   
1470          if (count($group_list))
1471          {
1472              foreach ($group_list as $group_id)
1473              {
1474                  $address_list['g'][$group_id] = $type;
1475              }
1476          }
1477   
1478          // User ID's to add...
1479          $user_id_ary = array();
1480   
1481          // Reveal the correct user_ids
1482          if (count($usernames))
1483          {
1484              $user_id_ary = array();
1485              user_get_id_name($user_id_ary, $usernames, array(USER_NORMAL, USER_FOUNDER, USER_INACTIVE));
1486   
1487              // If there are users not existing, we will at least print a notice...
1488              if (!count($user_id_ary))
1489              {
1490                  $error[] = $user->lang['PM_NO_USERS'];
1491              }
1492          }
1493   
1494          // Add Friends if specified
1495          $friend_list = array_keys($request->variable('add_' . $type, array(0)));
1496          $user_id_ary = array_merge($user_id_ary, $friend_list);
1497   
1498          foreach ($user_id_ary as $user_id)
1499          {
1500              if ($user_id == ANONYMOUS)
1501              {
1502                  continue;
1503              }
1504   
1505              $address_list['u'][$user_id] = $type;
1506          }
1507      }
1508   
1509      // Check for disallowed recipients
1510      if (!empty($address_list['u']))
1511      {
1512          $can_ignore_allow_pm = $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_');
1513   
1514          // Administrator deactivated users check and we need to check their
1515          //        PM status (do they want to receive PM's?)
1516          //         Only check PM status if not a moderator or admin, since they
1517          //        are allowed to override this user setting
1518          $sql = 'SELECT user_id, user_allow_pm
1519              FROM ' . USERS_TABLE . '
1520              WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . '
1521                  AND (
1522                          (user_type = ' . USER_INACTIVE . '
1523                          AND user_inactive_reason = ' . INACTIVE_MANUAL . ')
1524                          ' . ($can_ignore_allow_pm ? '' : ' OR user_allow_pm = 0') . '
1525                      )';
1526   
1527          $result = $db->sql_query($sql);
1528   
1529          $removed_no_pm = $removed_no_permission = false;
1530          while ($row = $db->sql_fetchrow($result))
1531          {
1532              if (!$can_ignore_allow_pm && !$row['user_allow_pm'])
1533              {
1534                  $removed_no_pm = true;
1535              }
1536              else
1537              {
1538                  $removed_no_permission = true;
1539              }
1540   
1541              unset($address_list['u'][$row['user_id']]);
1542          }
1543          $db->sql_freeresult($result);
1544   
1545          // print a notice about users not being added who do not want to receive pms
1546          if ($removed_no_pm)
1547          {
1548              $error[] = $user->lang['PM_USERS_REMOVED_NO_PM'];
1549          }
1550   
1551          // print a notice about users not being added who do not have permission to receive PMs
1552          if ($removed_no_permission)
1553          {
1554              $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
1555          }
1556   
1557          if (!count(array_keys($address_list['u'])))
1558          {
1559              return;
1560          }
1561   
1562          // Check if users have permission to read PMs
1563          $can_read = $auth->acl_get_list(array_keys($address_list['u']), 'u_readpm');
1564          $can_read = (empty($can_read) || !isset($can_read[0]['u_readpm'])) ? array() : $can_read[0]['u_readpm'];
1565          $cannot_read_list = array_diff(array_keys($address_list['u']), $can_read);
1566          if (!empty($cannot_read_list))
1567          {
1568              foreach ($cannot_read_list as $cannot_read)
1569              {
1570                  unset($address_list['u'][$cannot_read]);
1571              }
1572   
1573              $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
1574          }
1575   
1576          // Check if users are banned
1577          $banned_user_list = phpbb_get_banned_user_ids(array_keys($address_list['u']), false);
1578          if (!empty($banned_user_list))
1579          {
1580              foreach ($banned_user_list as $banned_user)
1581              {
1582                  unset($address_list['u'][$banned_user]);
1583              }
1584   
1585              $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
1586          }
1587      }
1588   
1589      /**
1590      * Event for additional message list actions
1591      *
1592      * @event core.message_list_actions
1593      * @var    array    address_list        The assoc array with the recipient user/group ids
1594      * @var    array    error                The array containing error data
1595      * @var    bool    remove_u            The variable for removing a user
1596      * @var    bool    remove_g            The variable for removing a group
1597      * @var    bool    add_to                The variable for adding a user to the [TO] field
1598      * @var    bool    add_bcc                The variable for adding a user to the [BCC] field
1599      * @since 3.2.4-RC1
1600      */
1601      $vars = array('address_list', 'error', 'remove_u', 'remove_g', 'add_to', 'add_bcc');
1602      extract($phpbb_dispatcher->trigger_event('core.message_list_actions', compact($vars)));
1603  }
1604   
1605  /**
1606  * Build the hidden field for the recipients. Needed, as the variable is not read via $request->variable().
1607  */
1608  function build_address_field($address_list)
1609  {
1610      $s_hidden_address_field = '';
1611      foreach ($address_list as $type => $adr_ary)
1612      {
1613          foreach ($adr_ary as $id => $field)
1614          {
1615              $s_hidden_address_field .= '<input type="hidden" name="address_list[' . (($type == 'u') ? 'u' : 'g') . '][' . (int) $id . ']" value="' . (($field == 'to') ? 'to' : 'bcc') . '" />';
1616          }
1617      }
1618      return $s_hidden_address_field;
1619  }
1620   
1621  /**
1622  * Return number of private message recipients
1623  */
1624  function num_recipients($address_list)
1625  {
1626      $num_recipients = 0;
1627   
1628      foreach ($address_list as $field => $adr_ary)
1629      {
1630          $num_recipients += count($adr_ary);
1631      }
1632   
1633      return $num_recipients;
1634  }
1635   
1636  /**
1637  * Get number of 'num_recipients' recipients from first position
1638  */
1639  function get_recipients($address_list, $num_recipients = 1)
1640  {
1641      $recipient = array();
1642   
1643      $count = 0;
1644      foreach ($address_list as $field => $adr_ary)
1645      {
1646          foreach ($adr_ary as $id => $type)
1647          {
1648              if ($count >= $num_recipients)
1649              {
1650                  break 2;
1651              }
1652              $recipient[$field][$id] = $type;
1653              $count++;
1654          }
1655      }
1656   
1657      return $recipient;
1658  }
1659