Guest User

Untitled

a guest
Nov 16th, 2015
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 86.36 KB | None | 0 0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13.  
  14. /**
  15. * @ignore
  16. */
  17. if (!defined('IN_PHPBB'))
  18. {
  19.     exit;
  20. }
  21.  
  22. /**
  23. * Fill smiley templates (or just the variables) with smilies, either in a window or inline
  24. */
  25. function generate_smilies($mode, $forum_id)
  26. {
  27.     global $db, $user, $config, $template, $phpbb_dispatcher;
  28.     global $phpEx, $phpbb_root_path, $phpbb_container, $phpbb_path_helper;
  29.  
  30.     $base_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&amp;f=' . $forum_id);
  31.     $pagination = $phpbb_container->get('pagination');
  32.     $start = request_var('start', 0);
  33.  
  34.     if ($mode == 'window')
  35.     {
  36.         if ($forum_id)
  37.         {
  38.             $sql = 'SELECT forum_style
  39.                 FROM ' . FORUMS_TABLE . "
  40.                 WHERE forum_id = $forum_id";
  41.             $result = $db->sql_query_limit($sql, 1);
  42.             $row = $db->sql_fetchrow($result);
  43.             $db->sql_freeresult($result);
  44.  
  45.             $user->setup('posting', (int) $row['forum_style']);
  46.         }
  47.         else
  48.         {
  49.             $user->setup('posting');
  50.         }
  51.  
  52.         page_header($user->lang['SMILIES']);
  53.  
  54.         $sql = 'SELECT COUNT(smiley_id) AS item_count
  55.             FROM ' . SMILIES_TABLE . '
  56.             GROUP BY smiley_url';
  57.         $result = $db->sql_query($sql, 3600);
  58.  
  59.         $smiley_count = 0;
  60.         while ($row = $db->sql_fetchrow($result))
  61.         {
  62.             ++$smiley_count;
  63.         }
  64.         $db->sql_freeresult($result);
  65.  
  66.         $template->set_filenames(array(
  67.             'body' => 'posting_smilies.html')
  68.         );
  69.  
  70.         $start = $pagination->validate_start($start, $config['smilies_per_page'], $smiley_count);
  71.         $pagination->generate_template_pagination($base_url, 'pagination', 'start', $smiley_count, $config['smilies_per_page'], $start);
  72.     }
  73.  
  74.     $display_link = false;
  75.     if ($mode == 'inline')
  76.     {
  77.         $sql = 'SELECT smiley_id
  78.             FROM ' . SMILIES_TABLE . '
  79.             WHERE display_on_posting = 0';
  80.         $result = $db->sql_query_limit($sql, 1, 0, 3600);
  81.  
  82.         if ($row = $db->sql_fetchrow($result))
  83.         {
  84.             $display_link = true;
  85.         }
  86.         $db->sql_freeresult($result);
  87.     }
  88.  
  89.     if ($mode == 'window')
  90.     {
  91.         $sql = 'SELECT smiley_url, MIN(emotion) as emotion, MIN(code) AS code, smiley_width, smiley_height, MIN(smiley_order) AS min_smiley_order
  92.             FROM ' . SMILIES_TABLE . '
  93.             GROUP BY smiley_url, smiley_width, smiley_height
  94.             ORDER BY min_smiley_order';
  95.         $result = $db->sql_query_limit($sql, $config['smilies_per_page'], $start, 3600);
  96.     }
  97.     else
  98.     {
  99.         $sql = 'SELECT *
  100.             FROM ' . SMILIES_TABLE . '
  101.             WHERE display_on_posting = 1
  102.             ORDER BY smiley_order';
  103.         $result = $db->sql_query($sql, 3600);
  104.     }
  105.  
  106.     $smilies = array();
  107.     while ($row = $db->sql_fetchrow($result))
  108.     {
  109.         if (empty($smilies[$row['smiley_url']]))
  110.         {
  111.             $smilies[$row['smiley_url']] = $row;
  112.         }
  113.     }
  114.     $db->sql_freeresult($result);
  115.  
  116.     if (sizeof($smilies))
  117.     {
  118.         $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_path_helper->get_web_root_path();
  119.  
  120.         foreach ($smilies as $row)
  121.         {
  122.             $template->assign_block_vars('smiley', array(
  123.                 'SMILEY_CODE'   => $row['code'],
  124.                 'A_SMILEY_CODE' => addslashes($row['code']),
  125.                 'SMILEY_IMG'    => $root_path . $config['smilies_path'] . '/' . $row['smiley_url'],
  126.                 'SMILEY_WIDTH'  => $row['smiley_width'],
  127.                 'SMILEY_HEIGHT' => $row['smiley_height'],
  128.                 'SMILEY_DESC'   => $row['emotion'])
  129.             );
  130.         }
  131.     }
  132.  
  133.     /**
  134.     * This event is called after the smilies are populated
  135.     *
  136.     * @event core.generate_smilies_after
  137.     * @var  string  mode            Mode of the smilies: window|inline
  138.     * @var  int     forum_id        The forum ID we are currently in
  139.     * @var  bool    display_link    Shall we display the "more smilies" link?
  140.     * @since 3.1.0-a1
  141.     */
  142.     $vars = array('mode', 'forum_id', 'display_link');
  143.     extract($phpbb_dispatcher->trigger_event('core.generate_smilies_after', compact($vars)));
  144.  
  145.     if ($mode == 'inline' && $display_link)
  146.     {
  147.         $template->assign_vars(array(
  148.             'S_SHOW_SMILEY_LINK'    => true,
  149.             'U_MORE_SMILIES'        => $base_url,
  150.         ));
  151.     }
  152.  
  153.     if ($mode == 'window')
  154.     {
  155.         page_footer();
  156.     }
  157. }
  158.  
  159. /**
  160. * Update last post information
  161. * Should be used instead of sync() if only the last post information are out of sync... faster
  162. *
  163. * @param    string  $type               Can be forum|topic
  164. * @param    mixed   $ids                topic/forum ids
  165. * @param    bool    $return_update_sql  true: SQL query shall be returned, false: execute SQL
  166. */
  167. function update_post_information($type, $ids, $return_update_sql = false)
  168. {
  169.     global $db;
  170.  
  171.     if (empty($ids))
  172.     {
  173.         return;
  174.     }
  175.     if (!is_array($ids))
  176.     {
  177.         $ids = array($ids);
  178.     }
  179.  
  180.     $update_sql = $empty_forums = $not_empty_forums = array();
  181.  
  182.     if ($type != 'topic')
  183.     {
  184.         $topic_join = ', ' . TOPICS_TABLE . ' t';
  185.         $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_visibility = ' . ITEM_APPROVED;
  186.     }
  187.     else
  188.     {
  189.         $topic_join = '';
  190.         $topic_condition = '';
  191.     }
  192.  
  193.     if (sizeof($ids) == 1)
  194.     {
  195.         $sql = 'SELECT MAX(p.post_id) as last_post_id
  196.             FROM ' . POSTS_TABLE . " p $topic_join
  197.             WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
  198.                 $topic_condition
  199.                 AND p.post_visibility = " . ITEM_APPROVED;
  200.     }
  201.     else
  202.     {
  203.         $sql = 'SELECT p.' . $type . '_id, MAX(p.post_id) as last_post_id
  204.             FROM ' . POSTS_TABLE . " p $topic_join
  205.             WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
  206.                 $topic_condition
  207.                 AND p.post_visibility = " . ITEM_APPROVED . "
  208.             GROUP BY p.{$type}_id";
  209.     }
  210.     $result = $db->sql_query($sql);
  211.  
  212.     $last_post_ids = array();
  213.     while ($row = $db->sql_fetchrow($result))
  214.     {
  215.         if (sizeof($ids) == 1)
  216.         {
  217.             $row[$type . '_id'] = $ids[0];
  218.         }
  219.  
  220.         if ($type == 'forum')
  221.         {
  222.             $not_empty_forums[] = $row['forum_id'];
  223.  
  224.             if (empty($row['last_post_id']))
  225.             {
  226.                 $empty_forums[] = $row['forum_id'];
  227.             }
  228.         }
  229.  
  230.         $last_post_ids[] = $row['last_post_id'];
  231.     }
  232.     $db->sql_freeresult($result);
  233.  
  234.     if ($type == 'forum')
  235.     {
  236.         $empty_forums = array_merge($empty_forums, array_diff($ids, $not_empty_forums));
  237.  
  238.         foreach ($empty_forums as $void => $forum_id)
  239.         {
  240.             $update_sql[$forum_id][] = 'forum_last_post_id = 0';
  241.             $update_sql[$forum_id][] = "forum_last_post_subject = ''";
  242.             $update_sql[$forum_id][] = 'forum_last_post_time = 0';
  243.             $update_sql[$forum_id][] = 'forum_last_poster_id = 0';
  244.             $update_sql[$forum_id][] = "forum_last_poster_name = ''";
  245.             $update_sql[$forum_id][] = "forum_last_poster_colour = ''";
  246.         }
  247.     }
  248.  
  249.     if (sizeof($last_post_ids))
  250.     {
  251.         $sql = 'SELECT p.' . $type . '_id, p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
  252.             FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
  253.             WHERE p.poster_id = u.user_id
  254.                 AND ' . $db->sql_in_set('p.post_id', $last_post_ids);
  255.         $result = $db->sql_query($sql);
  256.  
  257.         while ($row = $db->sql_fetchrow($result))
  258.         {
  259.             $update_sql[$row["{$type}_id"]][] = $type . '_last_post_id = ' . (int) $row['post_id'];
  260.             $update_sql[$row["{$type}_id"]][] = "{$type}_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
  261.             $update_sql[$row["{$type}_id"]][] = $type . '_last_post_time = ' . (int) $row['post_time'];
  262.             $update_sql[$row["{$type}_id"]][] = $type . '_last_poster_id = ' . (int) $row['poster_id'];
  263.             $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
  264.             $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'";
  265.         }
  266.         $db->sql_freeresult($result);
  267.     }
  268.     unset($empty_forums, $ids, $last_post_ids);
  269.  
  270.     if ($return_update_sql || !sizeof($update_sql))
  271.     {
  272.         return $update_sql;
  273.     }
  274.  
  275.     $table = ($type == 'forum') ? FORUMS_TABLE : TOPICS_TABLE;
  276.  
  277.     foreach ($update_sql as $update_id => $update_sql_ary)
  278.     {
  279.         $sql = "UPDATE $table
  280.             SET " . implode(', ', $update_sql_ary) . "
  281.             WHERE {$type}_id = $update_id";
  282.         $db->sql_query($sql);
  283.     }
  284.  
  285.     return;
  286. }
  287.  
  288. /**
  289. * Generate Topic Icons for display
  290. */
  291. function posting_gen_topic_icons($mode, $icon_id)
  292. {
  293.     global $phpbb_root_path, $config, $template, $cache;
  294.  
  295.     // Grab icons
  296.     $icons = $cache->obtain_icons();
  297.  
  298.     if (!$icon_id)
  299.     {
  300.         $template->assign_var('S_NO_ICON_CHECKED', ' checked="checked"');
  301.     }
  302.  
  303.     if (sizeof($icons))
  304.     {
  305.         $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path;
  306.  
  307.         foreach ($icons as $id => $data)
  308.         {
  309.             if ($data['display'])
  310.             {
  311.                 $template->assign_block_vars('topic_icon', array(
  312.                     'ICON_ID'       => $id,
  313.                     'ICON_IMG'      => $root_path . $config['icons_path'] . '/' . $data['img'],
  314.                     'ICON_WIDTH'    => $data['width'],
  315.                     'ICON_HEIGHT'   => $data['height'],
  316.  
  317.                     'S_CHECKED'         => ($id == $icon_id) ? true : false,
  318.                     'S_ICON_CHECKED'    => ($id == $icon_id) ? ' checked="checked"' : '')
  319.                 );
  320.             }
  321.         }
  322.  
  323.         return true;
  324.     }
  325.  
  326.     return false;
  327. }
  328.  
  329. /**
  330. * Build topic types able to be selected
  331. */
  332. function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
  333. {
  334.     global $auth, $user, $template, $topic_type;
  335.  
  336.     $toggle = false;
  337.  
  338.     $topic_types = array(
  339.         'sticky'    => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
  340.         'announce'  => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
  341.         'global'    => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
  342.     );
  343.  
  344.     $topic_type_array = array();
  345.  
  346.     foreach ($topic_types as $auth_key => $topic_value)
  347.     {
  348.         // We do not have a special post global announcement permission
  349.         $auth_key = ($auth_key == 'global') ? 'announce' : $auth_key;
  350.  
  351.         if ($auth->acl_get('f_' . $auth_key, $forum_id))
  352.         {
  353.             $toggle = true;
  354.  
  355.             $topic_type_array[] = array(
  356.                 'VALUE'         => $topic_value['const'],
  357.                 'S_CHECKED'     => ($cur_topic_type == $topic_value['const']) ? ' checked="checked"' : '',
  358.                 'L_TOPIC_TYPE'  => $user->lang[$topic_value['lang']]
  359.             );
  360.         }
  361.     }
  362.  
  363.     if ($toggle)
  364.     {
  365.         $topic_type_array = array_merge(array(0 => array(
  366.             'VALUE'         => POST_NORMAL,
  367.             'S_CHECKED'     => ($cur_topic_type == POST_NORMAL) ? ' checked="checked"' : '',
  368.             'L_TOPIC_TYPE'  => $user->lang['POST_NORMAL'])),
  369.  
  370.             $topic_type_array
  371.         );
  372.  
  373.         foreach ($topic_type_array as $array)
  374.         {
  375.             $template->assign_block_vars('topic_type', $array);
  376.         }
  377.  
  378.         $template->assign_vars(array(
  379.             'S_TOPIC_TYPE_STICKY'   => ($auth->acl_get('f_sticky', $forum_id)),
  380.             'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_get('f_announce', $forum_id)))
  381.         );
  382.     }
  383.  
  384.     return $toggle;
  385. }
  386.  
  387. //
  388. // Attachment related functions
  389. //
  390.  
  391. /**
  392. * Upload Attachment - filedata is generated here
  393. * Uses upload class
  394. *
  395. * @param string         $form_name      The form name of the file upload input
  396. * @param int            $forum_id       The id of the forum
  397. * @param bool           $local          Whether the file is local or not
  398. * @param string         $local_storage  The path to the local file
  399. * @param bool           $is_message     Whether it is a PM or not
  400. * @param \filespec      $local_filedata A filespec object created for the local file
  401. * @param \phpbb\mimetype\guesser    $mimetype_guesser   The mimetype guesser object if used
  402. * @param \phpbb\plupload\plupload   $plupload       The plupload object if one is being used
  403. *
  404. * @return object filespec
  405. */
  406. function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
  407. {
  408.     global $auth, $user, $config, $db, $cache;
  409.     global $phpbb_root_path, $phpEx, $phpbb_dispatcher;
  410.  
  411.     $filedata = array(
  412.         'error' => array()
  413.     );
  414.  
  415.     include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
  416.     $upload = new fileupload();
  417.  
  418.     if ($config['check_attachment_content'] && isset($config['mime_triggers']))
  419.     {
  420.         $upload->set_disallowed_content(explode('|', $config['mime_triggers']));
  421.     }
  422.     else if (!$config['check_attachment_content'])
  423.     {
  424.         $upload->set_disallowed_content(array());
  425.     }
  426.  
  427.     $filedata['post_attach'] = $local || $upload->is_valid($form_name);
  428.  
  429.     if (!$filedata['post_attach'])
  430.     {
  431.         $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
  432.         return $filedata;
  433.     }
  434.  
  435.     $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
  436.     $upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
  437.  
  438.     $file = ($local) ? $upload->local_upload($local_storage, $local_filedata, $mimetype_guesser) : $upload->form_upload($form_name, $mimetype_guesser, $plupload);
  439.  
  440.     if ($file->init_error)
  441.     {
  442.         $filedata['post_attach'] = false;
  443.         return $filedata;
  444.     }
  445.  
  446.     // Whether the uploaded file is in the image category
  447.     $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
  448.  
  449.     if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
  450.     {
  451.         // Check Image Size, if it is an image
  452.         if ($is_image)
  453.         {
  454.             $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
  455.         }
  456.  
  457.         // Admins and mods are allowed to exceed the allowed filesize
  458.         if (!empty($extensions[$file->get('extension')]['max_filesize']))
  459.         {
  460.             $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
  461.         }
  462.         else
  463.         {
  464.             $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
  465.         }
  466.  
  467.         $file->upload->set_max_filesize($allowed_filesize);
  468.     }
  469.  
  470.     $file->clean_filename('unique', $user->data['user_id'] . '_');
  471.  
  472.     // Are we uploading an image *and* this image being within the image category?
  473.     // Only then perform additional image checks.
  474.     $file->move_file($config['upload_path'], false, !$is_image);
  475.  
  476.     // Do we have to create a thumbnail?
  477.     $filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
  478.  
  479.     if (sizeof($file->error))
  480.     {
  481.         $file->remove();
  482.         $filedata['error'] = array_merge($filedata['error'], $file->error);
  483.         $filedata['post_attach'] = false;
  484.  
  485.         return $filedata;
  486.     }
  487.  
  488.     // Make sure the image category only holds valid images...
  489.     if ($is_image && !$file->is_image())
  490.     {
  491.         $file->remove();
  492.  
  493.         if ($plupload && $plupload->is_active())
  494.         {
  495.             $plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
  496.         }
  497.  
  498.         // If this error occurs a user tried to exploit an IE Bug by renaming extensions
  499.         // Since the image category is displaying content inline we need to catch this.
  500.         trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
  501.     }
  502.  
  503.     $filedata['filesize'] = $file->get('filesize');
  504.     $filedata['mimetype'] = $file->get('mimetype');
  505.     $filedata['extension'] = $file->get('extension');
  506.     $filedata['physical_filename'] = $file->get('realname');
  507.     $filedata['real_filename'] = $file->get('uploadname');
  508.     $filedata['filetime'] = time();
  509.  
  510.     /**
  511.     * Event to modify uploaded file before submit to the post
  512.     *
  513.     * @event core.modify_uploaded_file
  514.     * @var  array   filedata    Array containing uploaded file data
  515.     * @var  bool    is_image    Flag indicating if the file is an image
  516.     * @since 3.1.0-RC3
  517.     */
  518.     $vars = array(
  519.         'filedata',
  520.         'is_image',
  521.     );
  522.     extract($phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
  523.  
  524.     // Check our complete quota
  525.     if ($config['attachment_quota'])
  526.     {
  527.         if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
  528.         {
  529.             $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
  530.             $filedata['post_attach'] = false;
  531.  
  532.             $file->remove();
  533.  
  534.             return $filedata;
  535.         }
  536.     }
  537.  
  538.     // Check free disk space
  539.     if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
  540.     {
  541.         if ($free_space <= $file->get('filesize'))
  542.         {
  543.             if ($auth->acl_get('a_'))
  544.             {
  545.                 $filedata['error'][] = $user->lang['ATTACH_DISK_FULL'];
  546.             }
  547.             else
  548.             {
  549.                 $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
  550.             }
  551.             $filedata['post_attach'] = false;
  552.  
  553.             $file->remove();
  554.  
  555.             return $filedata;
  556.         }
  557.     }
  558.  
  559.     // Create Thumbnail
  560.     if ($filedata['thumbnail'])
  561.     {
  562.         $source = $file->get('destination_file');
  563.         $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
  564.  
  565.         if (!create_thumbnail($source, $destination, $file->get('mimetype')))
  566.         {
  567.             $filedata['thumbnail'] = 0;
  568.         }
  569.     }
  570.  
  571.     return $filedata;
  572. }
  573.  
  574. /**
  575. * Calculate the needed size for Thumbnail
  576. */
  577. function get_img_size_format($width, $height)
  578. {
  579.     global $config;
  580.  
  581.     // Maximum Width the Image can take
  582.     $max_width = ($config['img_max_thumb_width']) ? $config['img_max_thumb_width'] : 400;
  583.  
  584.     if ($width > $height)
  585.     {
  586.         return array(
  587.             round($width * ($max_width / $width)),
  588.             round($height * ($max_width / $width))
  589.         );
  590.     }
  591.     else
  592.     {
  593.         return array(
  594.             round($width * ($max_width / $height)),
  595.             round($height * ($max_width / $height))
  596.         );
  597.     }
  598. }
  599.  
  600. /**
  601. * Return supported image types
  602. */
  603. function get_supported_image_types($type = false)
  604. {
  605.     if (@extension_loaded('gd'))
  606.     {
  607.         $format = imagetypes();
  608.         $new_type = 0;
  609.  
  610.         if ($type !== false)
  611.         {
  612.             // Type is one of the IMAGETYPE constants - it is fetched from getimagesize()
  613.             switch ($type)
  614.             {
  615.                 // GIF
  616.                 case IMAGETYPE_GIF:
  617.                     $new_type = ($format & IMG_GIF) ? IMG_GIF : false;
  618.                 break;
  619.  
  620.                 // JPG, JPC, JP2
  621.                 case IMAGETYPE_JPEG:
  622.                 case IMAGETYPE_JPC:
  623.                 case IMAGETYPE_JPEG2000:
  624.                 case IMAGETYPE_JP2:
  625.                 case IMAGETYPE_JPX:
  626.                 case IMAGETYPE_JB2:
  627.                     $new_type = ($format & IMG_JPG) ? IMG_JPG : false;
  628.                 break;
  629.  
  630.                 // PNG
  631.                 case IMAGETYPE_PNG:
  632.                     $new_type = ($format & IMG_PNG) ? IMG_PNG : false;
  633.                 break;
  634.  
  635.                 // WBMP
  636.                 case IMAGETYPE_WBMP:
  637.                     $new_type = ($format & IMG_WBMP) ? IMG_WBMP : false;
  638.                 break;
  639.             }
  640.         }
  641.         else
  642.         {
  643.             $new_type = array();
  644.             $go_through_types = array(IMG_GIF, IMG_JPG, IMG_PNG, IMG_WBMP);
  645.  
  646.             foreach ($go_through_types as $check_type)
  647.             {
  648.                 if ($format & $check_type)
  649.                 {
  650.                     $new_type[] = $check_type;
  651.                 }
  652.             }
  653.         }
  654.  
  655.         return array(
  656.             'gd'        => ($new_type) ? true : false,
  657.             'format'    => $new_type,
  658.             'version'   => (function_exists('imagecreatetruecolor')) ? 2 : 1
  659.         );
  660.     }
  661.  
  662.     return array('gd' => false);
  663. }
  664.  
  665. /**
  666. * Create Thumbnail
  667. */
  668. function create_thumbnail($source, $destination, $mimetype)
  669. {
  670.     global $config;
  671.  
  672.     $min_filesize = (int) $config['img_min_thumb_filesize'];
  673.     $img_filesize = (file_exists($source)) ? @filesize($source) : false;
  674.  
  675.     if (!$img_filesize || $img_filesize <= $min_filesize)
  676.     {
  677.         return false;
  678.     }
  679.  
  680.     $dimension = @getimagesize($source);
  681.  
  682.     if ($dimension === false)
  683.     {
  684.         return false;
  685.     }
  686.  
  687.     list($width, $height, $type, ) = $dimension;
  688.  
  689.     if (empty($width) || empty($height))
  690.     {
  691.         return false;
  692.     }
  693.  
  694.     list($new_width, $new_height) = get_img_size_format($width, $height);
  695.  
  696.     // Do not create a thumbnail if the resulting width/height is bigger than the original one
  697.     if ($new_width >= $width && $new_height >= $height)
  698.     {
  699.         return false;
  700.     }
  701.  
  702.     $used_imagick = false;
  703.  
  704.     // Only use imagemagick if defined and the passthru function not disabled
  705.     if ($config['img_imagick'] && function_exists('passthru'))
  706.     {
  707.         if (substr($config['img_imagick'], -1) !== '/')
  708.         {
  709.             $config['img_imagick'] .= '/';
  710.         }
  711.  
  712.         @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -geometry ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" "' . str_replace('\\', '/', $destination) . '"');
  713.  
  714.         if (file_exists($destination))
  715.         {
  716.             $used_imagick = true;
  717.         }
  718.     }
  719.  
  720.     if (!$used_imagick)
  721.     {
  722.         $type = get_supported_image_types($type);
  723.  
  724.         if ($type['gd'])
  725.         {
  726.             // If the type is not supported, we are not able to create a thumbnail
  727.             if ($type['format'] === false)
  728.             {
  729.                 return false;
  730.             }
  731.  
  732.             switch ($type['format'])
  733.             {
  734.                 case IMG_GIF:
  735.                     $image = @imagecreatefromgif($source);
  736.                 break;
  737.  
  738.                 case IMG_JPG:
  739.                     @ini_set('gd.jpeg_ignore_warning', 1);
  740.                     $image = @imagecreatefromjpeg($source);
  741.                 break;
  742.  
  743.                 case IMG_PNG:
  744.                     $image = @imagecreatefrompng($source);
  745.                 break;
  746.  
  747.                 case IMG_WBMP:
  748.                     $image = @imagecreatefromwbmp($source);
  749.                 break;
  750.             }
  751.  
  752.             if (empty($image))
  753.             {
  754.                 return false;
  755.             }
  756.  
  757.             if ($type['version'] == 1)
  758.             {
  759.                 $new_image = imagecreate($new_width, $new_height);
  760.  
  761.                 if ($new_image === false)
  762.                 {
  763.                     return false;
  764.                 }
  765.  
  766.                 imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
  767.             }
  768.             else
  769.             {
  770.                 $new_image = imagecreatetruecolor($new_width, $new_height);
  771.  
  772.                 if ($new_image === false)
  773.                 {
  774.                     return false;
  775.                 }
  776.  
  777.                 // Preserve alpha transparency (png for example)
  778.                 @imagealphablending($new_image, false);
  779.                 @imagesavealpha($new_image, true);
  780.  
  781.                 imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
  782.             }
  783.  
  784.             // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug
  785.             if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on')
  786.             {
  787.                 @touch($destination);
  788.             }
  789.  
  790.             switch ($type['format'])
  791.             {
  792.                 case IMG_GIF:
  793.                     imagegif($new_image, $destination);
  794.                 break;
  795.  
  796.                 case IMG_JPG:
  797.                     imagejpeg($new_image, $destination, 90);
  798.                 break;
  799.  
  800.                 case IMG_PNG:
  801.                     imagepng($new_image, $destination);
  802.                 break;
  803.  
  804.                 case IMG_WBMP:
  805.                     imagewbmp($new_image, $destination);
  806.                 break;
  807.             }
  808.  
  809.             imagedestroy($new_image);
  810.         }
  811.         else
  812.         {
  813.             return false;
  814.         }
  815.     }
  816.  
  817.     if (!file_exists($destination))
  818.     {
  819.         return false;
  820.     }
  821.  
  822.     phpbb_chmod($destination, CHMOD_READ | CHMOD_WRITE);
  823.  
  824.     return true;
  825. }
  826.  
  827. /**
  828. * Assign Inline attachments (build option fields)
  829. */
  830. function posting_gen_inline_attachments(&$attachment_data)
  831. {
  832.     global $template;
  833.  
  834.     if (sizeof($attachment_data))
  835.     {
  836.         $s_inline_attachment_options = '';
  837.  
  838.         foreach ($attachment_data as $i => $attachment)
  839.         {
  840.             $s_inline_attachment_options .= '<option value="' . $i . '">' . utf8_basename($attachment['real_filename']) . '</option>';
  841.         }
  842.  
  843.         $template->assign_var('S_INLINE_ATTACHMENT_OPTIONS', $s_inline_attachment_options);
  844.  
  845.         return true;
  846.     }
  847.  
  848.     return false;
  849. }
  850.  
  851. /**
  852. * Generate inline attachment entry
  853. */
  854. function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_attach_box = true)
  855. {
  856.     global $template, $config, $phpbb_root_path, $phpEx, $user;
  857.  
  858.     // Some default template variables
  859.     $template->assign_vars(array(
  860.         'S_SHOW_ATTACH_BOX' => $show_attach_box,
  861.         'S_HAS_ATTACHMENTS' => sizeof($attachment_data),
  862.         'FILESIZE'          => $config['max_filesize'],
  863.         'FILE_COMMENT'      => (isset($filename_data['filecomment'])) ? $filename_data['filecomment'] : '',
  864.     ));
  865.  
  866.     if (sizeof($attachment_data))
  867.     {
  868.         // We display the posted attachments within the desired order.
  869.         ($config['display_order']) ? krsort($attachment_data) : ksort($attachment_data);
  870.  
  871.         foreach ($attachment_data as $count => $attach_row)
  872.         {
  873.             $hidden = '';
  874.             $attach_row['real_filename'] = utf8_basename($attach_row['real_filename']);
  875.  
  876.             foreach ($attach_row as $key => $value)
  877.             {
  878.                 $hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />';
  879.             }
  880.  
  881.             $download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&amp;id=' . (int) $attach_row['attach_id'], true, ($attach_row['is_orphan']) ? $user->session_id : false);
  882.  
  883.             $template->assign_block_vars('attach_row', array(
  884.                 'FILENAME'          => utf8_basename($attach_row['real_filename']),
  885.                 'A_FILENAME'        => addslashes(utf8_basename($attach_row['real_filename'])),
  886.                 'FILE_COMMENT'      => $attach_row['attach_comment'],
  887.                 'ATTACH_ID'         => $attach_row['attach_id'],
  888.                 'S_IS_ORPHAN'       => $attach_row['is_orphan'],
  889.                 'ASSOC_INDEX'       => $count,
  890.                 'FILESIZE'          => get_formatted_filesize($attach_row['filesize']),
  891.  
  892.                 'U_VIEW_ATTACHMENT' => $download_link,
  893.                 'S_HIDDEN'          => $hidden)
  894.             );
  895.         }
  896.     }
  897.  
  898.     return sizeof($attachment_data);
  899. }
  900.  
  901. //
  902. // General Post functions
  903. //
  904.  
  905. /**
  906. * Load Drafts
  907. */
  908. function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $msg_id = 0)
  909. {
  910.     global $user, $db, $template, $auth;
  911.     global $phpbb_root_path, $phpbb_dispatcher, $phpEx;
  912.  
  913.     $topic_ids = $forum_ids = $draft_rows = array();
  914.  
  915.     // Load those drafts not connected to forums/topics
  916.     // If forum_id == 0 AND topic_id == 0 then this is a PM draft
  917.     if (!$topic_id && !$forum_id)
  918.     {
  919.         $sql_and = ' AND d.forum_id = 0 AND d.topic_id = 0';
  920.     }
  921.     else
  922.     {
  923.         $sql_and = '';
  924.         $sql_and .= ($forum_id) ? ' AND d.forum_id = ' . (int) $forum_id : '';
  925.         $sql_and .= ($topic_id) ? ' AND d.topic_id = ' . (int) $topic_id : '';
  926.     }
  927.  
  928.     $sql = 'SELECT d.*, f.forum_id, f.forum_name
  929.         FROM ' . DRAFTS_TABLE . ' d
  930.         LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = d.forum_id)
  931.             WHERE d.user_id = ' . $user->data['user_id'] . "
  932.             $sql_and
  933.         ORDER BY d.save_time DESC";
  934.     $result = $db->sql_query($sql);
  935.  
  936.     while ($row = $db->sql_fetchrow($result))
  937.     {
  938.         if ($row['topic_id'])
  939.         {
  940.             $topic_ids[] = (int) $row['topic_id'];
  941.         }
  942.         $draft_rows[] = $row;
  943.     }
  944.     $db->sql_freeresult($result);
  945.  
  946.     if (!sizeof($draft_rows))
  947.     {
  948.         return;
  949.     }
  950.  
  951.     $topic_rows = array();
  952.     if (sizeof($topic_ids))
  953.     {
  954.         $sql = 'SELECT topic_id, forum_id, topic_title, topic_poster
  955.             FROM ' . TOPICS_TABLE . '
  956.             WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids));
  957.         $result = $db->sql_query($sql);
  958.  
  959.         while ($row = $db->sql_fetchrow($result))
  960.         {
  961.             $topic_rows[$row['topic_id']] = $row;
  962.         }
  963.         $db->sql_freeresult($result);
  964.     }
  965.  
  966.     /**
  967.     * Drafts found and their topics
  968.     * Edit $draft_rows in order to add or remove drafts loaded
  969.     *
  970.     * @event core.load_drafts_draft_list_result
  971.     * @var  array   draft_rows          The drafts query result. Includes its forum id and everything about the draft
  972.     * @var  array   topic_ids           The list of topics got from the topics table
  973.     * @var  array   topic_rows          The topics that draft_rows references
  974.     * @since 3.1.0-RC3
  975.     */
  976.     $vars = array('draft_rows', 'topic_ids', 'topic_rows');
  977.     extract($phpbb_dispatcher->trigger_event('core.load_drafts_draft_list_result', compact($vars)));
  978.  
  979.     unset($topic_ids);
  980.  
  981.     $template->assign_var('S_SHOW_DRAFTS', true);
  982.  
  983.     foreach ($draft_rows as $draft)
  984.     {
  985.         $link_topic = $link_forum = $link_pm = false;
  986.         $insert_url = $view_url = $title = '';
  987.  
  988.         if (isset($topic_rows[$draft['topic_id']])
  989.             && (
  990.                 ($topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_get('f_read', $topic_rows[$draft['topic_id']]['forum_id']))
  991.                 ||
  992.                 (!$topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_getf_global('f_read'))
  993.             ))
  994.         {
  995.             $topic_forum_id = ($topic_rows[$draft['topic_id']]['forum_id']) ? $topic_rows[$draft['topic_id']]['forum_id'] : $forum_id;
  996.  
  997.             $link_topic = true;
  998.             $view_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_forum_id . '&amp;t=' . $draft['topic_id']);
  999.             $title = $topic_rows[$draft['topic_id']]['topic_title'];
  1000.  
  1001.             $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $topic_forum_id . '&amp;t=' . $draft['topic_id'] . '&amp;mode=reply&amp;d=' . $draft['draft_id']);
  1002.         }
  1003.         else if ($draft['forum_id'] && $auth->acl_get('f_read', $draft['forum_id']))
  1004.         {
  1005.             $link_forum = true;
  1006.             $view_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $draft['forum_id']);
  1007.             $title = $draft['forum_name'];
  1008.  
  1009.             $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $draft['forum_id'] . '&amp;mode=post&amp;d=' . $draft['draft_id']);
  1010.         }
  1011.         else
  1012.         {
  1013.             // Either display as PM draft if forum_id and topic_id are empty or if access to the forums has been denied afterwards...
  1014.             $link_pm = true;
  1015.             $insert_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&amp;mode=compose&amp;d={$draft['draft_id']}" . (($pm_action) ? "&amp;action=$pm_action" : '') . (($msg_id) ? "&amp;p=$msg_id" : ''));
  1016.         }
  1017.  
  1018.         $template->assign_block_vars('draftrow', array(
  1019.             'DRAFT_ID'      => $draft['draft_id'],
  1020.             'DATE'          => $user->format_date($draft['save_time']),
  1021.             'DRAFT_SUBJECT' => $draft['draft_subject'],
  1022.  
  1023.             'TITLE'         => $title,
  1024.             'U_VIEW'        => $view_url,
  1025.             'U_INSERT'      => $insert_url,
  1026.  
  1027.             'S_LINK_PM'     => $link_pm,
  1028.             'S_LINK_TOPIC'  => $link_topic,
  1029.             'S_LINK_FORUM'  => $link_forum)
  1030.         );
  1031.     }
  1032. }
  1033.  
  1034. /**
  1035. * Topic Review
  1036. */
  1037. function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true)
  1038. {
  1039.     global $user, $auth, $db, $template, $cache;
  1040.     global $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
  1041.  
  1042.     $phpbb_content_visibility = $phpbb_container->get('content.visibility');
  1043.     $sql_sort = ($mode == 'post_review') ? 'ASC' : 'DESC';
  1044.  
  1045.     // Go ahead and pull all data for this topic
  1046.     $sql = 'SELECT p.post_id
  1047.         FROM ' . POSTS_TABLE . ' p' . "
  1048.         WHERE p.topic_id = $topic_id
  1049.             AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.') . '
  1050.             ' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
  1051.             ' . (($mode == 'post_review_edit') ? " AND p.post_id = $cur_post_id" : '') . '
  1052.         ORDER BY p.post_time ' . $sql_sort . ', p.post_id ' . $sql_sort;
  1053.     $result = $db->sql_query_limit($sql, $config['posts_per_page']);
  1054.  
  1055.     $post_list = array();
  1056.  
  1057.     while ($row = $db->sql_fetchrow($result))
  1058.     {
  1059.         $post_list[] = $row['post_id'];
  1060.     }
  1061.  
  1062.     $db->sql_freeresult($result);
  1063.  
  1064.     if (!sizeof($post_list))
  1065.     {
  1066.         return false;
  1067.     }
  1068.  
  1069.     // Handle 'post_review_edit' like 'post_review' from now on
  1070.     if ($mode == 'post_review_edit')
  1071.     {
  1072.         $mode = 'post_review';
  1073.     }
  1074.  
  1075.     $sql_ary = array(
  1076.         'SELECT'    => 'u.username, u.user_id, u.user_colour, p.*, z.friend, z.foe',
  1077.  
  1078.         'FROM'      => array(
  1079.             USERS_TABLE     => 'u',
  1080.             POSTS_TABLE     => 'p',
  1081.         ),
  1082.  
  1083.         'LEFT_JOIN' => array(
  1084.             array(
  1085.                 'FROM'  => array(ZEBRA_TABLE => 'z'),
  1086.                 'ON'    => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id',
  1087.             ),
  1088.         ),
  1089.  
  1090.         'WHERE'     => $db->sql_in_set('p.post_id', $post_list) . '
  1091.             AND u.user_id = p.poster_id',
  1092.     );
  1093.  
  1094.     $sql = $db->sql_build_query('SELECT', $sql_ary);
  1095.     $result = $db->sql_query($sql);
  1096.  
  1097.     $rowset = array();
  1098.     $has_attachments = false;
  1099.     while ($row = $db->sql_fetchrow($result))
  1100.     {
  1101.         $rowset[$row['post_id']] = $row;
  1102.  
  1103.         if ($row['post_attachment'])
  1104.         {
  1105.             $has_attachments = true;
  1106.         }
  1107.     }
  1108.     $db->sql_freeresult($result);
  1109.  
  1110.     // Grab extensions
  1111.     $extensions = $attachments = array();
  1112.     if ($has_attachments && $auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
  1113.     {
  1114.         $extensions = $cache->obtain_attach_extensions($forum_id);
  1115.  
  1116.         // Get attachments...
  1117.         $sql = 'SELECT *
  1118.             FROM ' . ATTACHMENTS_TABLE . '
  1119.             WHERE ' . $db->sql_in_set('post_msg_id', $post_list) . '
  1120.                 AND in_message = 0
  1121.             ORDER BY filetime DESC, post_msg_id ASC';
  1122.         $result = $db->sql_query($sql);
  1123.  
  1124.         while ($row = $db->sql_fetchrow($result))
  1125.         {
  1126.             $attachments[$row['post_msg_id']][] = $row;
  1127.         }
  1128.         $db->sql_freeresult($result);
  1129.     }
  1130.  
  1131.     for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
  1132.     {
  1133.         // A non-existing rowset only happens if there was no user present for the entered poster_id
  1134.         // This could be a broken posts table.
  1135.         if (!isset($rowset[$post_list[$i]]))
  1136.         {
  1137.             continue;
  1138.         }
  1139.  
  1140.         $row = $rowset[$post_list[$i]];
  1141.  
  1142.         $poster_id      = $row['user_id'];
  1143.         $post_subject   = $row['post_subject'];
  1144.  
  1145.         $decoded_message = false;
  1146.  
  1147.         if ($show_quote_button && $auth->acl_get('f_reply', $forum_id))
  1148.         {
  1149.             $decoded_message = censor_text($row['post_text']);
  1150.             decode_message($decoded_message, $row['bbcode_uid']);
  1151.  
  1152.             $decoded_message = bbcode_nl2br($decoded_message);
  1153.         }
  1154.  
  1155.         $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0);
  1156.         $parse_flags |= ($row['enable_smilies'] ? OPTION_FLAG_SMILIES : 0);
  1157.         $message = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, true);
  1158.  
  1159.         if (!empty($attachments[$row['post_id']]))
  1160.         {
  1161.             $update_count = array();
  1162.             parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count);
  1163.         }
  1164.  
  1165.         $post_subject = censor_text($post_subject);
  1166.  
  1167.         $post_anchor = ($mode == 'post_review') ? 'ppr' . $row['post_id'] : 'pr' . $row['post_id'];
  1168.         $u_show_post = append_sid($phpbb_root_path . 'viewtopic.' . $phpEx, "f=$forum_id&amp;t=$topic_id&amp;p={$row['post_id']}&amp;view=show#p{$row['post_id']}");
  1169.  
  1170.         $post_row = array(
  1171.             'POST_AUTHOR_FULL'      => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1172.             'POST_AUTHOR_COLOUR'    => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1173.             'POST_AUTHOR'           => get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1174.             'U_POST_AUTHOR'         => get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1175.  
  1176.             'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
  1177.             'S_FRIEND'          => ($row['friend']) ? true : false,
  1178.             'S_IGNORE_POST'     => ($row['foe']) ? true : false,
  1179.             'L_IGNORE_POST'     => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), "<a href=\"{$u_show_post}\" onclick=\"phpbb.toggleDisplay('{$post_anchor}', 1); return false;\">", '</a>') : '',
  1180.  
  1181.             'POST_SUBJECT'      => $post_subject,
  1182.             'MINI_POST_IMG'     => $user->img('icon_post_target', $user->lang['POST']),
  1183.             'POST_DATE'         => $user->format_date($row['post_time']),
  1184.             'MESSAGE'           => $message,
  1185.             'DECODED_MESSAGE'   => $decoded_message,
  1186.             'POST_ID'           => $row['post_id'],
  1187.             'U_MINI_POST'       => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
  1188.             'U_MCP_DETAILS'     => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&amp;mode=post_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
  1189.             'POSTER_QUOTE'      => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '',
  1190.         );
  1191.  
  1192.         $current_row_number = $i;
  1193.  
  1194.         /**
  1195.         * Event to modify the template data block for topic reviews
  1196.         *
  1197.         * @event core.topic_review_modify_row
  1198.         * @var  string  mode                The review mode
  1199.         * @var  int     topic_id            The topic that is being reviewed
  1200.         * @var  int     forum_id            The topic's forum
  1201.         * @var  int     cur_post_id         Post offset id
  1202.         * @var  int     current_row_number  Number of the current row being iterated
  1203.         * @var  array   post_row            Template block array of the current post
  1204.         * @var  array   row                 Array with original post and user data
  1205.         * @since 3.1.4-RC1
  1206.         */
  1207.         $vars = array(
  1208.             'mode',
  1209.             'topic_id',
  1210.             'forum_id',
  1211.             'cur_post_id',
  1212.             'current_row_number',
  1213.             'post_row',
  1214.             'row',
  1215.         );
  1216.         extract($phpbb_dispatcher->trigger_event('core.topic_review_modify_row', compact($vars)));
  1217.  
  1218.         $template->assign_block_vars($mode . '_row', $post_row);
  1219.  
  1220.         // Display not already displayed Attachments for this post, we already parsed them. ;)
  1221.         if (!empty($attachments[$row['post_id']]))
  1222.         {
  1223.             foreach ($attachments[$row['post_id']] as $attachment)
  1224.             {
  1225.                 $template->assign_block_vars($mode . '_row.attachment', array(
  1226.                     'DISPLAY_ATTACHMENT'    => $attachment)
  1227.                 );
  1228.             }
  1229.         }
  1230.  
  1231.         unset($rowset[$post_list[$i]]);
  1232.     }
  1233.  
  1234.     if ($mode == 'topic_review')
  1235.     {
  1236.         $template->assign_var('QUOTE_IMG', $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']));
  1237.     }
  1238.  
  1239.     return true;
  1240. }
  1241.  
  1242. //
  1243. // Post handling functions
  1244. //
  1245.  
  1246. /**
  1247. * Delete Post
  1248. */
  1249. function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $softdelete_reason = '')
  1250. {
  1251.     global $db, $user, $auth, $phpbb_container;
  1252.     global $config, $phpEx, $phpbb_root_path;
  1253.  
  1254.     // Specify our post mode
  1255.     $post_mode = 'delete';
  1256.     if (($data['topic_first_post_id'] === $data['topic_last_post_id']) && ($data['topic_posts_approved'] + $data['topic_posts_unapproved'] + $data['topic_posts_softdeleted'] == 1))
  1257.     {
  1258.         $post_mode = 'delete_topic';
  1259.     }
  1260.     else if ($data['topic_first_post_id'] == $post_id)
  1261.     {
  1262.         $post_mode = 'delete_first_post';
  1263.     }
  1264.     else if ($data['topic_last_post_id'] == $post_id)
  1265.     {
  1266.         $post_mode = 'delete_last_post';
  1267.     }
  1268.     $sql_data = array();
  1269.     $next_post_id = false;
  1270.  
  1271.     include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
  1272.  
  1273.     $db->sql_transaction('begin');
  1274.  
  1275.     // we must make sure to update forums that contain the shadow'd topic
  1276.     if ($post_mode == 'delete_topic')
  1277.     {
  1278.         $shadow_forum_ids = array();
  1279.  
  1280.         $sql = 'SELECT forum_id
  1281.             FROM ' . TOPICS_TABLE . '
  1282.             WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id);
  1283.         $result = $db->sql_query($sql);
  1284.         while ($row = $db->sql_fetchrow($result))
  1285.         {
  1286.             if (!isset($shadow_forum_ids[(int) $row['forum_id']]))
  1287.             {
  1288.                 $shadow_forum_ids[(int) $row['forum_id']] = 1;
  1289.             }
  1290.             else
  1291.             {
  1292.                 $shadow_forum_ids[(int) $row['forum_id']]++;
  1293.             }
  1294.         }
  1295.         $db->sql_freeresult($result);
  1296.     }
  1297.  
  1298.     $phpbb_content_visibility = $phpbb_container->get('content.visibility');
  1299.  
  1300.     // (Soft) delete the post
  1301.     if ($is_soft && ($post_mode != 'delete_topic'))
  1302.     {
  1303.         $phpbb_content_visibility->set_post_visibility(ITEM_DELETED, $post_id, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason, ($data['topic_first_post_id'] == $post_id), ($data['topic_last_post_id'] == $post_id));
  1304.     }
  1305.     else if (!$is_soft)
  1306.     {
  1307.         if (!delete_posts('post_id', array($post_id), false, false, false))
  1308.         {
  1309.             // Try to delete topic, we may had an previous error causing inconsistency
  1310.             if ($post_mode == 'delete_topic')
  1311.             {
  1312.                 delete_topics('topic_id', array($topic_id), false);
  1313.             }
  1314.             trigger_error('ALREADY_DELETED');
  1315.         }
  1316.     }
  1317.  
  1318.     $db->sql_transaction('commit');
  1319.  
  1320.     // Collect the necessary information for updating the tables
  1321.     $sql_data[FORUMS_TABLE] = $sql_data[TOPICS_TABLE] = '';
  1322.     switch ($post_mode)
  1323.     {
  1324.         case 'delete_topic':
  1325.  
  1326.             foreach ($shadow_forum_ids as $updated_forum => $topic_count)
  1327.             {
  1328.                 // counting is fun! we only have to do sizeof($forum_ids) number of queries,
  1329.                 // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum)
  1330.                 $sql = 'UPDATE ' . FORUMS_TABLE . '
  1331.                     SET forum_topics_approved = forum_topics_approved - ' . $topic_count . '
  1332.                     WHERE forum_id = ' . $updated_forum;
  1333.                 $db->sql_query($sql);
  1334.                 update_post_information('forum', $updated_forum);
  1335.             }
  1336.  
  1337.             if ($is_soft)
  1338.             {
  1339.                 $topic_row = array();
  1340.                 $phpbb_content_visibility->set_topic_visibility(ITEM_DELETED, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason);
  1341.             }
  1342.             else
  1343.             {
  1344.                 delete_topics('topic_id', array($topic_id), false);
  1345.  
  1346.                 $phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data);
  1347.  
  1348.                 $update_sql = update_post_information('forum', $forum_id, true);
  1349.                 if (sizeof($update_sql))
  1350.                 {
  1351.                     $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
  1352.                     $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
  1353.                 }
  1354.             }
  1355.  
  1356.         break;
  1357.  
  1358.         case 'delete_first_post':
  1359.             $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour
  1360.                 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
  1361.                 WHERE p.topic_id = $topic_id
  1362.                     AND p.poster_id = u.user_id
  1363.                     AND p.post_visibility = " . ITEM_APPROVED . '
  1364.                 ORDER BY p.post_time ASC, p.post_id ASC';
  1365.             $result = $db->sql_query_limit($sql, 1);
  1366.             $row = $db->sql_fetchrow($result);
  1367.             $db->sql_freeresult($result);
  1368.  
  1369.             if (!$row)
  1370.             {
  1371.                 // No approved post, so the first is a not-approved post (unapproved or soft deleted)
  1372.                 $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour
  1373.                     FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
  1374.                     WHERE p.topic_id = $topic_id
  1375.                         AND p.poster_id = u.user_id
  1376.                     ORDER BY p.post_time ASC, p.post_id ASC";
  1377.                 $result = $db->sql_query_limit($sql, 1);
  1378.                 $row = $db->sql_fetchrow($result);
  1379.                 $db->sql_freeresult($result);
  1380.             }
  1381.  
  1382.             $next_post_id = (int) $row['post_id'];
  1383.  
  1384.             $sql_data[TOPICS_TABLE] = $db->sql_build_array('UPDATE', array(
  1385.                 'topic_poster'              => (int) $row['poster_id'],
  1386.                 'topic_first_post_id'       => (int) $row['post_id'],
  1387.                 'topic_first_poster_colour' => $row['user_colour'],
  1388.                 'topic_first_poster_name'   => ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'],
  1389.                 'topic_time'                => (int) $row['post_time'],
  1390.             ));
  1391.         break;
  1392.  
  1393.         case 'delete_last_post':
  1394.             if (!$is_soft)
  1395.             {
  1396.                 // Update last post information when hard deleting. Soft delete already did that by itself.
  1397.                 $update_sql = update_post_information('forum', $forum_id, true);
  1398.                 if (sizeof($update_sql))
  1399.                 {
  1400.                     $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . implode(', ', $update_sql[$forum_id]);
  1401.                 }
  1402.  
  1403.                 $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_bumped = 0, topic_bumper = 0';
  1404.  
  1405.                 $update_sql = update_post_information('topic', $topic_id, true);
  1406.                 if (!empty($update_sql))
  1407.                 {
  1408.                     $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]);
  1409.                     $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]);
  1410.                 }
  1411.             }
  1412.  
  1413.             if (!$next_post_id)
  1414.             {
  1415.                 $sql = 'SELECT MAX(post_id) as last_post_id
  1416.                     FROM ' . POSTS_TABLE . "
  1417.                     WHERE topic_id = $topic_id
  1418.                         AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id);
  1419.                 $result = $db->sql_query($sql);
  1420.                 $next_post_id = (int) $db->sql_fetchfield('last_post_id');
  1421.                 $db->sql_freeresult($result);
  1422.             }
  1423.         break;
  1424.  
  1425.         case 'delete':
  1426.             $sql = 'SELECT post_id
  1427.                 FROM ' . POSTS_TABLE . "
  1428.                 WHERE topic_id = $topic_id
  1429.                     AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . '
  1430.                     AND post_time > ' . $data['post_time'] . '
  1431.                 ORDER BY post_time ASC, post_id ASC';
  1432.             $result = $db->sql_query_limit($sql, 1);
  1433.             $next_post_id = (int) $db->sql_fetchfield('post_id');
  1434.             $db->sql_freeresult($result);
  1435.         break;
  1436.     }
  1437.  
  1438.     if (($post_mode == 'delete') || ($post_mode == 'delete_last_post') || ($post_mode == 'delete_first_post'))
  1439.     {
  1440.         if (!$is_soft)
  1441.         {
  1442.             $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data);
  1443.         }
  1444.  
  1445.         $sql = 'SELECT 1 AS has_attachments
  1446.             FROM ' . ATTACHMENTS_TABLE . '
  1447.             WHERE topic_id = ' . $topic_id;
  1448.         $result = $db->sql_query_limit($sql, 1);
  1449.         $has_attachments = (int) $db->sql_fetchfield('has_attachments');
  1450.         $db->sql_freeresult($result);
  1451.  
  1452.         if (!$has_attachments)
  1453.         {
  1454.             $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_attachment = 0';
  1455.         }
  1456.     }
  1457.  
  1458.     $db->sql_transaction('begin');
  1459.  
  1460.     $where_sql = array(
  1461.         FORUMS_TABLE    => "forum_id = $forum_id",
  1462.         TOPICS_TABLE    => "topic_id = $topic_id",
  1463.         USERS_TABLE     => 'user_id = ' . $data['poster_id'],
  1464.     );
  1465.  
  1466.     foreach ($sql_data as $table => $update_sql)
  1467.     {
  1468.         if ($update_sql)
  1469.         {
  1470.             $db->sql_query("UPDATE $table SET $update_sql WHERE " . $where_sql[$table]);
  1471.         }
  1472.     }
  1473.  
  1474.     // Adjust posted info for this user by looking for a post by him/her within this topic...
  1475.     if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS)
  1476.     {
  1477.         $sql = 'SELECT poster_id
  1478.             FROM ' . POSTS_TABLE . '
  1479.             WHERE topic_id = ' . $topic_id . '
  1480.                 AND poster_id = ' . $data['poster_id'];
  1481.         $result = $db->sql_query_limit($sql, 1);
  1482.         $poster_id = (int) $db->sql_fetchfield('poster_id');
  1483.         $db->sql_freeresult($result);
  1484.  
  1485.         // The user is not having any more posts within this topic
  1486.         if (!$poster_id)
  1487.         {
  1488.             $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
  1489.                 WHERE topic_id = ' . $topic_id . '
  1490.                     AND user_id = ' . $data['poster_id'];
  1491.             $db->sql_query($sql);
  1492.         }
  1493.     }
  1494.  
  1495.     $db->sql_transaction('commit');
  1496.  
  1497.     if ($data['post_reported'] && ($post_mode != 'delete_topic'))
  1498.     {
  1499.         sync('topic_reported', 'topic_id', array($topic_id));
  1500.     }
  1501.  
  1502.     return $next_post_id;
  1503. }
  1504.  
  1505. /**
  1506. * Submit Post
  1507. * @todo Split up and create lightweight, simple API for this.
  1508. */
  1509. function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true, $update_search_index = true)
  1510. {
  1511.     global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher;
  1512.  
  1513.     /**
  1514.     * Modify the data for post submitting
  1515.     *
  1516.     * @event core.modify_submit_post_data
  1517.     * @var  string  mode                Variable containing posting mode value
  1518.     * @var  string  subject             Variable containing post subject value
  1519.     * @var  string  username            Variable containing post author name
  1520.     * @var  int     topic_type          Variable containing topic type value
  1521.     * @var  array   poll                Array with the poll data for the post
  1522.     * @var  array   data                Array with the data for the post
  1523.     * @var  bool    update_message      Flag indicating if the post will be updated
  1524.     * @var  bool    update_search_index Flag indicating if the search index will be updated
  1525.     * @since 3.1.0-a4
  1526.     */
  1527.     $vars = array(
  1528.         'mode',
  1529.         'subject',
  1530.         'username',
  1531.         'topic_type',
  1532.         'poll',
  1533.         'data',
  1534.         'update_message',
  1535.         'update_search_index',
  1536.     );
  1537.     extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact($vars)));
  1538.  
  1539.     // We do not handle erasing posts here
  1540.     if ($mode == 'delete')
  1541.     {
  1542.         return false;
  1543.     }
  1544.  
  1545.     if (!empty($data['post_time']))
  1546.     {
  1547.         $current_time = $data['post_time'];
  1548.     }
  1549.     else
  1550.     {
  1551.         $current_time = time();
  1552.     }
  1553.  
  1554.     if ($mode == 'post')
  1555.     {
  1556.         $post_mode = 'post';
  1557.         $update_message = true;
  1558.     }
  1559.     else if ($mode != 'edit')
  1560.     {
  1561.         $post_mode = 'reply';
  1562.         $update_message = true;
  1563.     }
  1564.     else if ($mode == 'edit')
  1565.     {
  1566.         $post_mode = ($data['topic_posts_approved'] + $data['topic_posts_unapproved'] + $data['topic_posts_softdeleted'] == 1) ? 'edit_topic' : (($data['topic_first_post_id'] == $data['post_id']) ? 'edit_first_post' : (($data['topic_last_post_id'] == $data['post_id']) ? 'edit_last_post' : 'edit'));
  1567.     }
  1568.  
  1569.     // First of all make sure the subject and topic title are having the correct length.
  1570.     // To achieve this without cutting off between special chars we convert to an array and then count the elements.
  1571.     $subject = truncate_string($subject, 120);
  1572.     $data['topic_title'] = truncate_string($data['topic_title'], 120);
  1573.  
  1574.     // Collect some basic information about which tables and which rows to update/insert
  1575.     $sql_data = $topic_row = array();
  1576.     $poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id'];
  1577.  
  1578.     // Retrieve some additional information if not present
  1579.     if ($mode == 'edit' && (!isset($data['post_visibility']) || !isset($data['topic_visibility']) || $data['post_visibility'] === false || $data['topic_visibility'] === false))
  1580.     {
  1581.         $sql = 'SELECT p.post_visibility, t.topic_type, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_visibility
  1582.             FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
  1583.             WHERE t.topic_id = p.topic_id
  1584.                 AND p.post_id = ' . $data['post_id'];
  1585.         $result = $db->sql_query($sql);
  1586.         $topic_row = $db->sql_fetchrow($result);
  1587.         $db->sql_freeresult($result);
  1588.  
  1589.         $data['topic_visibility'] = $topic_row['topic_visibility'];
  1590.         $data['post_visibility'] = $topic_row['post_visibility'];
  1591.     }
  1592.  
  1593.     // This variable indicates if the user is able to post or put into the queue
  1594.     $post_visibility = ITEM_APPROVED;
  1595.  
  1596.     // Check the permissions for post approval.
  1597.     // Moderators must go through post approval like ordinary users.
  1598.     if (!$auth->acl_get('f_noapprove', $data['forum_id']))
  1599.     {
  1600.         // Post not approved, but in queue
  1601.         $post_visibility = ITEM_UNAPPROVED;
  1602.         switch ($post_mode)
  1603.         {
  1604.             case 'edit_first_post':
  1605.             case 'edit':
  1606.             case 'edit_last_post':
  1607.             case 'edit_topic':
  1608.                 $post_visibility = ITEM_REAPPROVE;
  1609.             break;
  1610.         }
  1611.     }
  1612.  
  1613.     // MODs/Extensions are able to force any visibility on posts
  1614.     if (isset($data['force_approved_state']))
  1615.     {
  1616.         $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_approved_state'] : $post_visibility;
  1617.     }
  1618.     if (isset($data['force_visibility']))
  1619.     {
  1620.         $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_visibility'] : $post_visibility;
  1621.     }
  1622.  
  1623.     // Start the transaction here
  1624.     $db->sql_transaction('begin');
  1625.  
  1626.     // Collect Information
  1627.     switch ($post_mode)
  1628.     {
  1629.         case 'post':
  1630.         case 'reply':
  1631.             $sql_data[POSTS_TABLE]['sql'] = array(
  1632.                 'forum_id'          => $data['forum_id'],
  1633.                 'poster_id'         => (int) $user->data['user_id'],
  1634.                 'icon_id'           => $data['icon_id'],
  1635.                 'poster_ip'         => $user->ip,
  1636.                 'post_time'         => $current_time,
  1637.                 'post_visibility'   => $post_visibility,
  1638.                 'enable_bbcode'     => $data['enable_bbcode'],
  1639.                 'enable_smilies'    => $data['enable_smilies'],
  1640.                 'enable_magic_url'  => $data['enable_urls'],
  1641.                 'enable_sig'        => $data['enable_sig'],
  1642.                 'post_username'     => (!$user->data['is_registered']) ? $username : '',
  1643.                 'post_subject'      => $subject,
  1644.                 'post_text'         => $data['message'],
  1645.                 'post_checksum'     => $data['message_md5'],
  1646.                 'post_attachment'   => (!empty($data['attachment_data'])) ? 1 : 0,
  1647.                 'bbcode_bitfield'   => $data['bbcode_bitfield'],
  1648.                 'bbcode_uid'        => $data['bbcode_uid'],
  1649.                 'post_postcount'    => ($auth->acl_get('f_postcount', $data['forum_id'])) ? 1 : 0,
  1650.                 'post_edit_locked'  => $data['post_edit_locked']
  1651.             );
  1652.         break;
  1653.  
  1654.         case 'edit_first_post':
  1655.         case 'edit':
  1656.  
  1657.         case 'edit_last_post':
  1658.         case 'edit_topic':
  1659.  
  1660.             // If edit reason is given always display edit info
  1661.  
  1662.             // If editing last post then display no edit info
  1663.             // If m_edit permission then display no edit info
  1664.             // If normal edit display edit info
  1665.  
  1666.             // Display edit info if edit reason given or user is editing his post, which is not the last within the topic.
  1667.             if ($data['post_edit_reason'] || (!$auth->acl_get('m_edit', $data['forum_id']) && ($post_mode == 'edit' || $post_mode == 'edit_first_post')))
  1668.             {
  1669.                 $data['post_edit_reason']       = truncate_string($data['post_edit_reason'], 255, 255, false);
  1670.  
  1671.                 $sql_data[POSTS_TABLE]['sql']   = array(
  1672.                     'post_edit_time'    => $current_time,
  1673.                     'post_edit_reason'  => $data['post_edit_reason'],
  1674.                     'post_edit_user'    => (int) $data['post_edit_user'],
  1675.                 );
  1676.  
  1677.                 $sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
  1678.             }
  1679.             else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id']))
  1680.             {
  1681.                 $sql_data[POSTS_TABLE]['sql'] = array(
  1682.                     'post_edit_reason'  => '',
  1683.                 );
  1684.             }
  1685.  
  1686.             // If the person editing this post is different to the one having posted then we will add a log entry stating the edit
  1687.             // Could be simplified by only adding to the log if the edit is not tracked - but this may confuse admins/mods
  1688.             if ($user->data['user_id'] != $poster_id)
  1689.             {
  1690.                 $log_subject = ($subject) ? $subject : $data['topic_title'];
  1691.                 add_log('mod', $data['forum_id'], $data['topic_id'], 'LOG_POST_EDITED', $log_subject, (!empty($username)) ? $username : $user->lang['GUEST'], $data['post_edit_reason']);
  1692.             }
  1693.  
  1694.             if (!isset($sql_data[POSTS_TABLE]['sql']))
  1695.             {
  1696.                 $sql_data[POSTS_TABLE]['sql'] = array();
  1697.             }
  1698.  
  1699.             $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
  1700.                 'forum_id'          => $data['forum_id'],
  1701.                 'poster_id'         => $data['poster_id'],
  1702.                 'icon_id'           => $data['icon_id'],
  1703.                 // We will change the visibility later
  1704.                 //'post_visibility' => $post_visibility,
  1705.                 'enable_bbcode'     => $data['enable_bbcode'],
  1706.                 'enable_smilies'    => $data['enable_smilies'],
  1707.                 'enable_magic_url'  => $data['enable_urls'],
  1708.                 'enable_sig'        => $data['enable_sig'],
  1709.                 'post_username'     => ($username && $data['poster_id'] == ANONYMOUS) ? $username : '',
  1710.                 'post_subject'      => $subject,
  1711.                 'post_checksum'     => $data['message_md5'],
  1712.                 'post_attachment'   => (!empty($data['attachment_data'])) ? 1 : 0,
  1713.                 'bbcode_bitfield'   => $data['bbcode_bitfield'],
  1714.                 'bbcode_uid'        => $data['bbcode_uid'],
  1715.                 'post_edit_locked'  => $data['post_edit_locked'])
  1716.             );
  1717.  
  1718.             if ($update_message)
  1719.             {
  1720.                 $sql_data[POSTS_TABLE]['sql']['post_text'] = $data['message'];
  1721.             }
  1722.  
  1723.         break;
  1724.     }
  1725.     $topic_row = array();
  1726.  
  1727.     // And the topic ladies and gentlemen
  1728.     switch ($post_mode)
  1729.     {
  1730.         case 'post':
  1731.             $sql_data[TOPICS_TABLE]['sql'] = array(
  1732.                 'topic_poster'              => (int) $user->data['user_id'],
  1733.                 'topic_time'                => $current_time,
  1734.                 'topic_last_view_time'      => $current_time,
  1735.                 'forum_id'                  => $data['forum_id'],
  1736.                 'icon_id'                   => $data['icon_id'],
  1737.                 'topic_posts_approved'      => ($post_visibility == ITEM_APPROVED) ? 1 : 0,
  1738.                 'topic_posts_softdeleted'   => ($post_visibility == ITEM_DELETED) ? 1 : 0,
  1739.                 'topic_posts_unapproved'    => ($post_visibility == ITEM_UNAPPROVED) ? 1 : 0,
  1740.                 'topic_visibility'          => $post_visibility,
  1741.                 'topic_delete_user'         => ($post_visibility != ITEM_APPROVED) ? (int) $user->data['user_id'] : 0,
  1742.                 'topic_title'               => $subject,
  1743.                 'topic_first_poster_name'   => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
  1744.                 'topic_first_poster_colour' => $user->data['user_colour'],
  1745.                 'topic_type'                => $topic_type,
  1746.                 'topic_time_limit'          => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
  1747.                 'topic_attachment'          => (!empty($data['attachment_data'])) ? 1 : 0,
  1748.                 'topic_status'              => (isset($data['topic_status'])) ? $data['topic_status'] : ITEM_UNLOCKED,
  1749.             );
  1750.  
  1751.             if (isset($poll['poll_options']) && !empty($poll['poll_options']))
  1752.             {
  1753.                 $poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time;
  1754.                 $poll_length = $poll['poll_length'] * 86400;
  1755.                 if ($poll_length < 0)
  1756.                 {
  1757.                     $poll_start = $poll_start + $poll_length;
  1758.                     if ($poll_start < 0)
  1759.                     {
  1760.                         $poll_start = 0;
  1761.                     }
  1762.                     $poll_length = 1;
  1763.                 }
  1764.  
  1765.                 $sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array(
  1766.                     'poll_title'        => $poll['poll_title'],
  1767.                     'poll_start'        => $poll_start,
  1768.                     'poll_max_options'  => $poll['poll_max_options'],
  1769.                     'poll_length'       => $poll_length,
  1770.                     'poll_vote_change'  => $poll['poll_vote_change'])
  1771.                 );
  1772.             }
  1773.  
  1774.             $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_visibility == ITEM_APPROVED) ? ', user_posts = user_posts + 1' : '');
  1775.  
  1776.             if ($post_visibility == ITEM_APPROVED)
  1777.             {
  1778.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_approved = forum_topics_approved + 1';
  1779.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_approved = forum_posts_approved + 1';
  1780.             }
  1781.             else if ($post_visibility == ITEM_UNAPPROVED)
  1782.             {
  1783.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_unapproved = forum_topics_unapproved + 1';
  1784.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_unapproved = forum_posts_unapproved + 1';
  1785.             }
  1786.             else if ($post_visibility == ITEM_DELETED)
  1787.             {
  1788.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_softdeleted = forum_topics_softdeleted + 1';
  1789.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_softdeleted = forum_posts_softdeleted + 1';
  1790.             }
  1791.         break;
  1792.  
  1793.         case 'reply':
  1794.             $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_view_time = ' . $current_time . ',
  1795.                 topic_bumped = 0,
  1796.                 topic_bumper = 0' .
  1797.                 (($post_visibility == ITEM_APPROVED) ? ', topic_posts_approved = topic_posts_approved + 1' : '') .
  1798.                 (($post_visibility == ITEM_UNAPPROVED) ? ', topic_posts_unapproved = topic_posts_unapproved + 1' : '') .
  1799.                 (($post_visibility == ITEM_DELETED) ? ', topic_posts_softdeleted = topic_posts_softdeleted + 1' : '') .
  1800.                 ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : '');
  1801.  
  1802.             $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_visibility == ITEM_APPROVED) ? ', user_posts = user_posts + 1' : '');
  1803.  
  1804.             if ($post_visibility == ITEM_APPROVED)
  1805.             {
  1806.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_approved = forum_posts_approved + 1';
  1807.             }
  1808.             else if ($post_visibility == ITEM_UNAPPROVED)
  1809.             {
  1810.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_unapproved = forum_posts_unapproved + 1';
  1811.             }
  1812.             else if ($post_visibility == ITEM_DELETED)
  1813.             {
  1814.                 $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_softdeleted = forum_posts_softdeleted + 1';
  1815.             }
  1816.         break;
  1817.  
  1818.         case 'edit_topic':
  1819.         case 'edit_first_post':
  1820.             if (isset($poll['poll_options']))
  1821.             {
  1822.                 $poll_start = ($poll['poll_start'] || empty($poll['poll_options'])) ? $poll['poll_start'] : $current_time;
  1823.                 $poll_length = $poll['poll_length'] * 86400;
  1824.                 if ($poll_length < 0)
  1825.                 {
  1826.                     $poll_start = $poll_start + $poll_length;
  1827.                     if ($poll_start < 0)
  1828.                     {
  1829.                         $poll_start = 0;
  1830.                     }
  1831.                     $poll_length = 1;
  1832.                 }
  1833.             }
  1834.  
  1835.             $sql_data[TOPICS_TABLE]['sql'] = array(
  1836.                 'forum_id'                  => $data['forum_id'],
  1837.                 'icon_id'                   => $data['icon_id'],
  1838.                 'topic_title'               => $subject,
  1839.                 'topic_first_poster_name'   => $username,
  1840.                 'topic_type'                => $topic_type,
  1841.                 'topic_time_limit'          => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
  1842.                 'poll_title'                => (isset($poll['poll_options'])) ? $poll['poll_title'] : '',
  1843.                 'poll_start'                => (isset($poll['poll_options'])) ? $poll_start : 0,
  1844.                 'poll_max_options'          => (isset($poll['poll_options'])) ? $poll['poll_max_options'] : 1,
  1845.                 'poll_length'               => (isset($poll['poll_options'])) ? $poll_length : 0,
  1846.                 'poll_vote_change'          => (isset($poll['poll_vote_change'])) ? $poll['poll_vote_change'] : 0,
  1847.                 'topic_last_view_time'      => $current_time,
  1848.  
  1849.                 'topic_attachment'          => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0),
  1850.             );
  1851.  
  1852.         break;
  1853.     }
  1854.  
  1855.     /**
  1856.     * Modify sql query data for post submitting
  1857.     *
  1858.     * @event core.submit_post_modify_sql_data
  1859.     * @var  array   data                Array with the data for the post
  1860.     * @var  array   poll                Array with the poll data for the post
  1861.     * @var  string  post_mode           Variable containing posting mode value
  1862.     * @var  bool    sql_data            Array with the data for the posting SQL query
  1863.     * @var  string  subject             Variable containing post subject value
  1864.     * @var  int     topic_type          Variable containing topic type value
  1865.     * @var  string  username            Variable containing post author name
  1866.     * @since 3.1.3-RC1
  1867.     */
  1868.     $vars = array(
  1869.         'data',
  1870.         'poll',
  1871.         'post_mode',
  1872.         'sql_data',
  1873.         'subject',
  1874.         'topic_type',
  1875.         'username',
  1876.     );
  1877.     extract($phpbb_dispatcher->trigger_event('core.submit_post_modify_sql_data', compact($vars)));
  1878.  
  1879.     // Submit new topic
  1880.     if ($post_mode == 'post')
  1881.     {
  1882.         $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
  1883.             $db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
  1884.         $db->sql_query($sql);
  1885.  
  1886.         $data['topic_id'] = $db->sql_nextid();
  1887.  
  1888.         $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
  1889.             'topic_id' => $data['topic_id'])
  1890.         );
  1891.         unset($sql_data[TOPICS_TABLE]['sql']);
  1892.     }
  1893.  
  1894.     // Submit new post
  1895.     if ($post_mode == 'post' || $post_mode == 'reply')
  1896.     {
  1897.         if ($post_mode == 'reply')
  1898.         {
  1899.             $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
  1900.                 'topic_id' => $data['topic_id'],
  1901.             ));
  1902.         }
  1903.  
  1904.         $sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']);
  1905.         $db->sql_query($sql);
  1906.         $data['post_id'] = $db->sql_nextid();
  1907.  
  1908.         if ($post_mode == 'post' || $post_visibility == ITEM_APPROVED)
  1909.         {
  1910.             $sql_data[TOPICS_TABLE]['sql'] = array(
  1911.                 'topic_last_post_id'        => $data['post_id'],
  1912.                 'topic_last_post_time'      => $current_time,
  1913.                 'topic_last_poster_id'      => $sql_data[POSTS_TABLE]['sql']['poster_id'],
  1914.                 'topic_last_poster_name'    => ($user->data['user_id'] == ANONYMOUS) ? $sql_data[POSTS_TABLE]['sql']['post_username'] : $user->data['username'],
  1915.                 'topic_last_poster_colour'  => $user->data['user_colour'],
  1916.                 'topic_last_post_subject'   => (string) $subject,
  1917.             );
  1918.         }
  1919.  
  1920.         if ($post_mode == 'post')
  1921.         {
  1922.             $sql_data[TOPICS_TABLE]['sql']['topic_first_post_id'] = $data['post_id'];
  1923.         }
  1924.  
  1925.         // Update total post count and forum information
  1926.         if ($post_visibility == ITEM_APPROVED)
  1927.         {
  1928.             if ($post_mode == 'post')
  1929.             {
  1930.                 set_config_count('num_topics', 1, true);
  1931.             }
  1932.             set_config_count('num_posts', 1, true);
  1933.  
  1934.             $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id'];
  1935.             $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'";
  1936.             $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time;
  1937.             $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id'];
  1938.             $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'";
  1939.             $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'";
  1940.         }
  1941.  
  1942.         unset($sql_data[POSTS_TABLE]['sql']);
  1943.     }
  1944.  
  1945.     // Update the topics table
  1946.     if (isset($sql_data[TOPICS_TABLE]['sql']))
  1947.     {
  1948.         $sql = 'UPDATE ' . TOPICS_TABLE . '
  1949.             SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . '
  1950.             WHERE topic_id = ' . $data['topic_id'];
  1951.         $db->sql_query($sql);
  1952.  
  1953.         unset($sql_data[TOPICS_TABLE]['sql']);
  1954.     }
  1955.  
  1956.     // Update the posts table
  1957.     if (isset($sql_data[POSTS_TABLE]['sql']))
  1958.     {
  1959.         $sql = 'UPDATE ' . POSTS_TABLE . '
  1960.             SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . '
  1961.             WHERE post_id = ' . $data['post_id'];
  1962.         $db->sql_query($sql);
  1963.  
  1964.         unset($sql_data[POSTS_TABLE]['sql']);
  1965.     }
  1966.  
  1967.     // Update Poll Tables
  1968.     if (isset($poll['poll_options']))
  1969.     {
  1970.         $cur_poll_options = array();
  1971.  
  1972.         if ($mode == 'edit')
  1973.         {
  1974.             $sql = 'SELECT *
  1975.                 FROM ' . POLL_OPTIONS_TABLE . '
  1976.                 WHERE topic_id = ' . $data['topic_id'] . '
  1977.                 ORDER BY poll_option_id';
  1978.             $result = $db->sql_query($sql);
  1979.  
  1980.             $cur_poll_options = array();
  1981.             while ($row = $db->sql_fetchrow($result))
  1982.             {
  1983.                 $cur_poll_options[] = $row;
  1984.             }
  1985.             $db->sql_freeresult($result);
  1986.         }
  1987.  
  1988.         $sql_insert_ary = array();
  1989.  
  1990.         for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++)
  1991.         {
  1992.             if (strlen(trim($poll['poll_options'][$i])))
  1993.             {
  1994.                 if (empty($cur_poll_options[$i]))
  1995.                 {
  1996.                     // If we add options we need to put them to the end to be able to preserve votes...
  1997.                     $sql_insert_ary[] = array(
  1998.                         'poll_option_id'    => (int) sizeof($cur_poll_options) + 1 + sizeof($sql_insert_ary),
  1999.                         'topic_id'          => (int) $data['topic_id'],
  2000.                         'poll_option_text'  => (string) $poll['poll_options'][$i]
  2001.                     );
  2002.                 }
  2003.                 else if ($poll['poll_options'][$i] != $cur_poll_options[$i])
  2004.                 {
  2005.                     $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
  2006.                         SET poll_option_text = '" . $db->sql_escape($poll['poll_options'][$i]) . "'
  2007.                         WHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . '
  2008.                             AND topic_id = ' . $data['topic_id'];
  2009.                     $db->sql_query($sql);
  2010.                 }
  2011.             }
  2012.         }
  2013.  
  2014.         $db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);
  2015.  
  2016.         if (sizeof($poll['poll_options']) < sizeof($cur_poll_options))
  2017.         {
  2018.             $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
  2019.                 WHERE poll_option_id > ' . sizeof($poll['poll_options']) . '
  2020.                     AND topic_id = ' . $data['topic_id'];
  2021.             $db->sql_query($sql);
  2022.         }
  2023.  
  2024.         // If edited, we would need to reset votes (since options can be re-ordered above, you can't be sure if the change is for changing the text or adding an option
  2025.         if ($mode == 'edit' && sizeof($poll['poll_options']) != sizeof($cur_poll_options))
  2026.         {
  2027.             $db->sql_query('DELETE FROM ' . POLL_VOTES_TABLE . ' WHERE topic_id = ' . $data['topic_id']);
  2028.             $db->sql_query('UPDATE ' . POLL_OPTIONS_TABLE . ' SET poll_option_total = 0 WHERE topic_id = ' . $data['topic_id']);
  2029.         }
  2030.     }
  2031.  
  2032.     // Submit Attachments
  2033.     if (!empty($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit')))
  2034.     {
  2035.         $space_taken = $files_added = 0;
  2036.         $orphan_rows = array();
  2037.  
  2038.         foreach ($data['attachment_data'] as $pos => $attach_row)
  2039.         {
  2040.             $orphan_rows[(int) $attach_row['attach_id']] = array();
  2041.         }
  2042.  
  2043.         if (sizeof($orphan_rows))
  2044.         {
  2045.             $sql = 'SELECT attach_id, filesize, physical_filename
  2046.                 FROM ' . ATTACHMENTS_TABLE . '
  2047.                 WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
  2048.                     AND is_orphan = 1
  2049.                     AND poster_id = ' . $user->data['user_id'];
  2050.             $result = $db->sql_query($sql);
  2051.  
  2052.             $orphan_rows = array();
  2053.             while ($row = $db->sql_fetchrow($result))
  2054.             {
  2055.                 $orphan_rows[$row['attach_id']] = $row;
  2056.             }
  2057.             $db->sql_freeresult($result);
  2058.         }
  2059.  
  2060.         foreach ($data['attachment_data'] as $pos => $attach_row)
  2061.         {
  2062.             if ($attach_row['is_orphan'] && !isset($orphan_rows[$attach_row['attach_id']]))
  2063.             {
  2064.                 continue;
  2065.             }
  2066.  
  2067.             if (!$attach_row['is_orphan'])
  2068.             {
  2069.                 // update entry in db if attachment already stored in db and filespace
  2070.                 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
  2071.                     SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
  2072.                     WHERE attach_id = " . (int) $attach_row['attach_id'] . '
  2073.                         AND is_orphan = 0';
  2074.                 $db->sql_query($sql);
  2075.             }
  2076.             else
  2077.             {
  2078.                 // insert attachment into db
  2079.                 if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
  2080.                 {
  2081.                     continue;
  2082.                 }
  2083.  
  2084.                 $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
  2085.                 $files_added++;
  2086.  
  2087.                 $attach_sql = array(
  2088.                     'post_msg_id'       => $data['post_id'],
  2089.                     'topic_id'          => $data['topic_id'],
  2090.                     'is_orphan'         => 0,
  2091.                     'poster_id'         => $poster_id,
  2092.                     'attach_comment'    => $attach_row['attach_comment'],
  2093.                 );
  2094.  
  2095.                 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
  2096.                     WHERE attach_id = ' . $attach_row['attach_id'] . '
  2097.                         AND is_orphan = 1
  2098.                         AND poster_id = ' . $user->data['user_id'];
  2099.                 $db->sql_query($sql);
  2100.             }
  2101.         }
  2102.  
  2103.         if ($space_taken && $files_added)
  2104.         {
  2105.             set_config_count('upload_dir_size', $space_taken, true);
  2106.             set_config_count('num_files', $files_added, true);
  2107.         }
  2108.     }
  2109.  
  2110.     $first_post_has_topic_info = ($post_mode == 'edit_first_post' &&
  2111.             (($post_visibility == ITEM_DELETED && $data['topic_posts_softdeleted'] == 1) ||
  2112.             ($post_visibility == ITEM_UNAPPROVED && $data['topic_posts_unapproved'] == 1) ||
  2113.             ($post_visibility == ITEM_REAPPROVE && $data['topic_posts_unapproved'] == 1) ||
  2114.             ($post_visibility == ITEM_APPROVED && $data['topic_posts_approved'] == 1)));
  2115.     // Fix the post's and topic's visibility and first/last post information, when the post is edited
  2116.     if (($post_mode != 'post' && $post_mode != 'reply') && $data['post_visibility'] != $post_visibility)
  2117.     {
  2118.         // If the post was not approved, it could also be the starter,
  2119.         // so we sync the starter after approving/restoring, to ensure that the stats are correct
  2120.         // Same applies for the last post
  2121.         $is_starter = ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED);
  2122.         $is_latest = ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED);
  2123.  
  2124.         $phpbb_content_visibility = $phpbb_container->get('content.visibility');
  2125.         $phpbb_content_visibility->set_post_visibility($post_visibility, $data['post_id'], $data['topic_id'], $data['forum_id'], $user->data['user_id'], time(), '', $is_starter, $is_latest);
  2126.     }
  2127.     else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $first_post_has_topic_info)
  2128.     {
  2129.         if ($post_visibility == ITEM_APPROVED || $data['topic_visibility'] == $post_visibility)
  2130.         {
  2131.             // only the subject can be changed from edit
  2132.             $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
  2133.  
  2134.             // Maybe not only the subject, but also changing anonymous usernames. ;)
  2135.             if ($data['poster_id'] == ANONYMOUS)
  2136.             {
  2137.                 $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape($username) . "'";
  2138.             }
  2139.  
  2140.             if ($post_visibility == ITEM_APPROVED)
  2141.             {
  2142.                 // this does not _necessarily_ mean that we must update the info again,
  2143.                 // it just means that we might have to
  2144.                 $sql = 'SELECT forum_last_post_id, forum_last_post_subject
  2145.                     FROM ' . FORUMS_TABLE . '
  2146.                     WHERE forum_id = ' . (int) $data['forum_id'];
  2147.                 $result = $db->sql_query($sql);
  2148.                 $row = $db->sql_fetchrow($result);
  2149.                 $db->sql_freeresult($result);
  2150.  
  2151.                 // this post is the latest post in the forum, better update
  2152.                 if ($row['forum_last_post_id'] == $data['post_id'] && ($row['forum_last_post_subject'] !== $subject || $data['poster_id'] == ANONYMOUS))
  2153.                 {
  2154.                     // the post's subject changed
  2155.                     if ($row['forum_last_post_subject'] !== $subject)
  2156.                     {
  2157.                         $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'";
  2158.                     }
  2159.  
  2160.                     // Update the user name if poster is anonymous... just in case a moderator changed it
  2161.                     if ($data['poster_id'] == ANONYMOUS)
  2162.                     {
  2163.                         $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape($username) . "'";
  2164.                     }
  2165.                 }
  2166.             }
  2167.         }
  2168.     }
  2169.  
  2170.     // Update forum stats
  2171.     $where_sql = array(
  2172.         POSTS_TABLE     => 'post_id = ' . $data['post_id'],
  2173.         TOPICS_TABLE    => 'topic_id = ' . $data['topic_id'],
  2174.         FORUMS_TABLE    => 'forum_id = ' . $data['forum_id'],
  2175.         USERS_TABLE     => 'user_id = ' . $poster_id
  2176.     );
  2177.  
  2178.     foreach ($sql_data as $table => $update_ary)
  2179.     {
  2180.         if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
  2181.         {
  2182.             $sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
  2183.             $db->sql_query($sql);
  2184.         }
  2185.     }
  2186.  
  2187.     // Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
  2188.     if ($topic_type == POST_GLOBAL)
  2189.     {
  2190.         $sql = 'DELETE FROM ' . TOPICS_TABLE . '
  2191.             WHERE topic_moved_id = ' . $data['topic_id'];
  2192.         $db->sql_query($sql);
  2193.     }
  2194.  
  2195.     // Committing the transaction before updating search index
  2196.     $db->sql_transaction('commit');
  2197.  
  2198.     // Delete draft if post was loaded...
  2199.     $draft_id = request_var('draft_loaded', 0);
  2200.     if ($draft_id)
  2201.     {
  2202.         $sql = 'DELETE FROM ' . DRAFTS_TABLE . "
  2203.             WHERE draft_id = $draft_id
  2204.                 AND user_id = {$user->data['user_id']}";
  2205.         $db->sql_query($sql);
  2206.     }
  2207.  
  2208.     // Index message contents
  2209.     if ($update_search_index && $data['enable_indexing'])
  2210.     {
  2211.         // Select the search method and do some additional checks to ensure it can actually be utilised
  2212.         $search_type = $config['search_type'];
  2213.  
  2214.         if (!class_exists($search_type))
  2215.         {
  2216.             trigger_error('NO_SUCH_SEARCH_MODULE');
  2217.         }
  2218.  
  2219.         $error = false;
  2220.         $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
  2221.  
  2222.         if ($error)
  2223.         {
  2224.             trigger_error($error);
  2225.         }
  2226.  
  2227.         $search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, $data['forum_id']);
  2228.     }
  2229.  
  2230.     // Topic Notification, do not change if moderator is changing other users posts...
  2231.     if ($user->data['user_id'] == $poster_id)
  2232.     {
  2233.         if (!$data['notify_set'] && $data['notify'])
  2234.         {
  2235.             $sql = 'INSERT INTO ' . TOPICS_WATCH_TABLE . ' (user_id, topic_id)
  2236.                 VALUES (' . $user->data['user_id'] . ', ' . $data['topic_id'] . ')';
  2237.             $db->sql_query($sql);
  2238.         }
  2239.         else if (($config['email_enable'] || $config['jab_enable']) && $data['notify_set'] && !$data['notify'])
  2240.         {
  2241.             $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . '
  2242.                 WHERE user_id = ' . $user->data['user_id'] . '
  2243.                     AND topic_id = ' . $data['topic_id'];
  2244.             $db->sql_query($sql);
  2245.         }
  2246.     }
  2247.  
  2248.     if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
  2249.     {
  2250.         // Mark this topic as posted to
  2251.         markread('post', $data['forum_id'], $data['topic_id']);
  2252.     }
  2253.  
  2254.     // Mark this topic as read
  2255.     // We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
  2256.     markread('topic', $data['forum_id'], $data['topic_id'], time());
  2257.  
  2258.     //
  2259.     if ($config['load_db_lastread'] && $user->data['is_registered'])
  2260.     {
  2261.         $sql = 'SELECT mark_time
  2262.             FROM ' . FORUMS_TRACK_TABLE . '
  2263.             WHERE user_id = ' . $user->data['user_id'] . '
  2264.                 AND forum_id = ' . $data['forum_id'];
  2265.         $result = $db->sql_query($sql);
  2266.         $f_mark_time = (int) $db->sql_fetchfield('mark_time');
  2267.         $db->sql_freeresult($result);
  2268.     }
  2269.     else if ($config['load_anon_lastread'] || $user->data['is_registered'])
  2270.     {
  2271.         $f_mark_time = false;
  2272.     }
  2273.  
  2274.     if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
  2275.     {
  2276.         // Update forum info
  2277.         $sql = 'SELECT forum_last_post_time
  2278.             FROM ' . FORUMS_TABLE . '
  2279.             WHERE forum_id = ' . $data['forum_id'];
  2280.         $result = $db->sql_query($sql);
  2281.         $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
  2282.         $db->sql_freeresult($result);
  2283.  
  2284.         update_forum_tracking_info($data['forum_id'], $forum_last_post_time, $f_mark_time, false);
  2285.     }
  2286.  
  2287.     // If a username was supplied or the poster is a guest, we will use the supplied username.
  2288.     // Doing it this way we can use "...post by guest-username..." in notifications when
  2289.     // "guest-username" is supplied or ommit the username if it is not.
  2290.     $username = ($username !== '' || !$user->data['is_registered']) ? $username : $user->data['username'];
  2291.  
  2292.     // Send Notifications
  2293.     $notification_data = array_merge($data, array(
  2294.         'topic_title'       => (isset($data['topic_title'])) ? $data['topic_title'] : $subject,
  2295.         'post_username'     => $username,
  2296.         'poster_id'         => $poster_id,
  2297.         'post_text'         => $data['message'],
  2298.         'post_time'         => $current_time,
  2299.         'post_subject'      => $subject,
  2300.     ));
  2301.  
  2302.     $phpbb_notifications = $phpbb_container->get('notification_manager');
  2303.  
  2304.     if ($post_visibility == ITEM_APPROVED)
  2305.     {
  2306.         switch ($mode)
  2307.         {
  2308.             case 'post':
  2309.                 $phpbb_notifications->add_notifications(array(
  2310.                     'notification.type.quote',
  2311.                     'notification.type.topic',
  2312.                 ), $notification_data);
  2313.             break;
  2314.  
  2315.             case 'reply':
  2316.             case 'quote':
  2317.                 $phpbb_notifications->add_notifications(array(
  2318.                     'notification.type.quote',
  2319.                     'notification.type.bookmark',
  2320.                     'notification.type.post',
  2321.                 ), $notification_data);
  2322.             break;
  2323.  
  2324.             case 'edit_topic':
  2325.             case 'edit_first_post':
  2326.             case 'edit':
  2327.             case 'edit_last_post':
  2328.                 $phpbb_notifications->update_notifications(array(
  2329.                     'notification.type.quote',
  2330.                     'notification.type.bookmark',
  2331.                     'notification.type.topic',
  2332.                     'notification.type.post',
  2333.                 ), $notification_data);
  2334.             break;
  2335.         }
  2336.     }
  2337.     else if ($post_visibility == ITEM_UNAPPROVED)
  2338.     {
  2339.         switch ($mode)
  2340.         {
  2341.             case 'post':
  2342.                 $phpbb_notifications->add_notifications('notification.type.topic_in_queue', $notification_data);
  2343.             break;
  2344.  
  2345.             case 'reply':
  2346.             case 'quote':
  2347.                 $phpbb_notifications->add_notifications('notification.type.post_in_queue', $notification_data);
  2348.             break;
  2349.  
  2350.             case 'edit_topic':
  2351.             case 'edit_first_post':
  2352.             case 'edit':
  2353.             case 'edit_last_post':
  2354.                 // Nothing to do here
  2355.             break;
  2356.         }
  2357.     }
  2358.     else if ($post_visibility == ITEM_REAPPROVE)
  2359.     {
  2360.         switch ($mode)
  2361.         {
  2362.             case 'edit_topic':
  2363.             case 'edit_first_post':
  2364.                 $phpbb_notifications->add_notifications('notification.type.topic_in_queue', $notification_data);
  2365.  
  2366.                 // Delete the approve_post notification so we can notify the user again,
  2367.                 // when his post got reapproved
  2368.                 $phpbb_notifications->delete_notifications('notification.type.approve_post', $notification_data['post_id']);
  2369.             break;
  2370.  
  2371.             case 'edit':
  2372.             case 'edit_last_post':
  2373.                 $phpbb_notifications->add_notifications('notification.type.post_in_queue', $notification_data);
  2374.  
  2375.                 // Delete the approve_post notification so we can notify the user again,
  2376.                 // when his post got reapproved
  2377.                 $phpbb_notifications->delete_notifications('notification.type.approve_post', $notification_data['post_id']);
  2378.             break;
  2379.  
  2380.             case 'post':
  2381.             case 'reply':
  2382.             case 'quote':
  2383.                 // Nothing to do here
  2384.             break;
  2385.         }
  2386.     }
  2387.     else if ($post_visibility == ITEM_DELETED)
  2388.     {
  2389.         switch ($mode)
  2390.         {
  2391.             case 'post':
  2392.             case 'reply':
  2393.             case 'quote':
  2394.             case 'edit_topic':
  2395.             case 'edit_first_post':
  2396.             case 'edit':
  2397.             case 'edit_last_post':
  2398.                 // Nothing to do here
  2399.             break;
  2400.         }
  2401.     }
  2402.  
  2403.     $params = $add_anchor = '';
  2404.  
  2405.     if ($post_visibility == ITEM_APPROVED)
  2406.     {
  2407.         $params .= '&amp;t=' . $data['topic_id'];
  2408.  
  2409.         if ($mode != 'post')
  2410.         {
  2411.             $params .= '&amp;p=' . $data['post_id'];
  2412.             $add_anchor = '#p' . $data['post_id'];
  2413.         }
  2414.     }
  2415.     else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic')
  2416.     {
  2417.         $params .= '&amp;t=' . $data['topic_id'];
  2418.     }
  2419.  
  2420.     $url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
  2421.     $url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;
  2422.  
  2423.     /**
  2424.     * This event is used for performing actions directly after a post or topic
  2425.     * has been submitted. When a new topic is posted, the topic ID is
  2426.     * available in the $data array.
  2427.     *
  2428.     * The only action that can be done by altering data made available to this
  2429.     * event is to modify the return URL ($url).
  2430.     *
  2431.     * @event core.submit_post_end
  2432.     * @var  string  mode                Variable containing posting mode value
  2433.     * @var  string  subject             Variable containing post subject value
  2434.     * @var  string  username            Variable containing post author name
  2435.     * @var  int     topic_type          Variable containing topic type value
  2436.     * @var  array   poll                Array with the poll data for the post
  2437.     * @var  array   data                Array with the data for the post
  2438.     * @var  int     post_visibility     Variable containing up to date post visibility
  2439.     * @var  bool    update_message      Flag indicating if the post will be updated
  2440.     * @var  bool    update_search_index Flag indicating if the search index will be updated
  2441.     * @var  string  url                 The "Return to topic" URL
  2442.     *
  2443.     * @since 3.1.0-a3
  2444.     * @change 3.1.0-RC3 Added vars mode, subject, username, topic_type,
  2445.     *       poll, update_message, update_search_index
  2446.     */
  2447.     $vars = array(
  2448.         'mode',
  2449.         'subject',
  2450.         'username',
  2451.         'topic_type',
  2452.         'poll',
  2453.         'data',
  2454.         'post_visibility',
  2455.         'update_message',
  2456.         'update_search_index',
  2457.         'url',
  2458.     );
  2459.     extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars)));
  2460.  
  2461.     return $url;
  2462. }
  2463.  
  2464. /**
  2465. * Handle topic bumping
  2466. * @param int $forum_id The ID of the forum the topic is being bumped belongs to
  2467. * @param int $topic_id The ID of the topic is being bumping
  2468. * @param array $post_data Passes some topic parameters:
  2469. *               - 'topic_title'
  2470. *               - 'topic_last_post_id'
  2471. *               - 'topic_last_poster_id'
  2472. *               - 'topic_last_post_subject'
  2473. *               - 'topic_last_poster_name'
  2474. *               - 'topic_last_poster_colour'
  2475. * @param int $bump_time The time at which topic was bumped, usually it is a current time as obtained via time().
  2476. * @return string An URL to the bumped topic, example: ./viewtopic.php?forum_id=1&amptopic_id=2&ampp=3#p3
  2477. */
  2478. function phpbb_bump_topic($forum_id, $topic_id, $post_data, $bump_time = false)
  2479. {
  2480.     global $config, $db, $user, $phpEx, $phpbb_root_path;
  2481.  
  2482.     if ($bump_time === false)
  2483.     {
  2484.         $bump_time = time();
  2485.     }
  2486.  
  2487.     // Begin bumping
  2488.     $db->sql_transaction('begin');
  2489.  
  2490.     // Update the topic's last post post_time
  2491.     $sql = 'UPDATE ' . POSTS_TABLE . "
  2492.         SET post_time = $bump_time
  2493.         WHERE post_id = {$post_data['topic_last_post_id']}
  2494.             AND topic_id = $topic_id";
  2495.     $db->sql_query($sql);
  2496.  
  2497.     // Sync the topic's last post time, the rest of the topic's last post data isn't changed
  2498.     $sql = 'UPDATE ' . TOPICS_TABLE . "
  2499.         SET topic_last_post_time = $bump_time,
  2500.             topic_bumped = 1,
  2501.             topic_bumper = " . $user->data['user_id'] . "
  2502.         WHERE topic_id = $topic_id";
  2503.     $db->sql_query($sql);
  2504.  
  2505.     // Update the forum's last post info
  2506.     $sql = 'UPDATE ' . FORUMS_TABLE . "
  2507.         SET forum_last_post_id = " . $post_data['topic_last_post_id'] . ",
  2508.             forum_last_poster_id = " . $post_data['topic_last_poster_id'] . ",
  2509.             forum_last_post_subject = '" . $db->sql_escape($post_data['topic_last_post_subject']) . "',
  2510.             forum_last_post_time = $bump_time,
  2511.             forum_last_poster_name = '" . $db->sql_escape($post_data['topic_last_poster_name']) . "',
  2512.             forum_last_poster_colour = '" . $db->sql_escape($post_data['topic_last_poster_colour']) . "'
  2513.         WHERE forum_id = $forum_id";
  2514.     $db->sql_query($sql);
  2515.  
  2516.     // Update bumper's time of the last posting to prevent flood
  2517.     $sql = 'UPDATE ' . USERS_TABLE . "
  2518.         SET user_lastpost_time = $bump_time
  2519.         WHERE user_id = " . $user->data['user_id'];
  2520.     $db->sql_query($sql);
  2521.  
  2522.     $db->sql_transaction('commit');
  2523.  
  2524.     // Mark this topic as posted to
  2525.     markread('post', $forum_id, $topic_id, $bump_time);
  2526.  
  2527.     // Mark this topic as read
  2528.     markread('topic', $forum_id, $topic_id, $bump_time);
  2529.  
  2530.     // Update forum tracking info
  2531.     if ($config['load_db_lastread'] && $user->data['is_registered'])
  2532.     {
  2533.         $sql = 'SELECT mark_time
  2534.             FROM ' . FORUMS_TRACK_TABLE . '
  2535.             WHERE user_id = ' . $user->data['user_id'] . '
  2536.                 AND forum_id = ' . $forum_id;
  2537.         $result = $db->sql_query($sql);
  2538.         $f_mark_time = (int) $db->sql_fetchfield('mark_time');
  2539.         $db->sql_freeresult($result);
  2540.     }
  2541.     else if ($config['load_anon_lastread'] || $user->data['is_registered'])
  2542.     {
  2543.         $f_mark_time = false;
  2544.     }
  2545.  
  2546.     if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
  2547.     {
  2548.         // Update forum info
  2549.         $sql = 'SELECT forum_last_post_time
  2550.             FROM ' . FORUMS_TABLE . '
  2551.             WHERE forum_id = ' . $forum_id;
  2552.         $result = $db->sql_query($sql);
  2553.         $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
  2554.         $db->sql_freeresult($result);
  2555.  
  2556.         update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time, false);
  2557.     }
  2558.  
  2559.     add_log('mod', $forum_id, $topic_id, 'LOG_BUMP_TOPIC', $post_data['topic_title']);
  2560.  
  2561.     $url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p={$post_data['topic_last_post_id']}") . "#p{$post_data['topic_last_post_id']}";
  2562.  
  2563.     return $url;
  2564. }
  2565.  
  2566. /**
  2567. * Show upload popup (progress bar)
  2568. */
  2569. function phpbb_upload_popup($forum_style = 0)
  2570. {
  2571.     global $template, $user;
  2572.  
  2573.     ($forum_style) ? $user->setup('posting', $forum_style) : $user->setup('posting');
  2574.  
  2575.     page_header($user->lang['PROGRESS_BAR']);
  2576.  
  2577.     $template->set_filenames(array(
  2578.             'popup' => 'posting_progress_bar.html')
  2579.     );
  2580.  
  2581.     $template->assign_vars(array(
  2582.             'PROGRESS_BAR'  => $user->img('upload_bar', $user->lang['UPLOAD_IN_PROGRESS']))
  2583.     );
  2584.  
  2585.     $template->display('popup');
  2586.  
  2587.     garbage_collection();
  2588.     exit_handler();
  2589. }
  2590.  
  2591. /**
  2592. * Do the various checks required for removing posts as well as removing it
  2593. */
  2594. function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $delete_reason = '')
  2595. {
  2596.     global $user, $auth, $config, $request;
  2597.     global $phpbb_root_path, $phpEx;
  2598.  
  2599.     $perm_check = ($is_soft) ? 'softdelete' : 'delete';
  2600.  
  2601.     // If moderator removing post or user itself removing post, present a confirmation screen
  2602.     if ($auth->acl_get("m_$perm_check", $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get("f_$perm_check", $forum_id) && $post_id == $post_data['topic_last_post_id'] && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time'])))
  2603.     {
  2604.         $s_hidden_fields = array(
  2605.             'p'     => $post_id,
  2606.             'f'     => $forum_id,
  2607.             'mode'  => ($is_soft) ? 'soft_delete' : 'delete',
  2608.         );
  2609.  
  2610.         if (confirm_box(true))
  2611.         {
  2612.             $data = array(
  2613.                 'topic_first_post_id'   => $post_data['topic_first_post_id'],
  2614.                 'topic_last_post_id'    => $post_data['topic_last_post_id'],
  2615.                 'topic_posts_approved'      => $post_data['topic_posts_approved'],
  2616.                 'topic_posts_unapproved'    => $post_data['topic_posts_unapproved'],
  2617.                 'topic_posts_softdeleted'   => $post_data['topic_posts_softdeleted'],
  2618.                 'topic_visibility'      => $post_data['topic_visibility'],
  2619.                 'topic_type'            => $post_data['topic_type'],
  2620.                 'post_visibility'       => $post_data['post_visibility'],
  2621.                 'post_reported'         => $post_data['post_reported'],
  2622.                 'post_time'             => $post_data['post_time'],
  2623.                 'poster_id'             => $post_data['poster_id'],
  2624.                 'post_postcount'        => $post_data['post_postcount'],
  2625.             );
  2626.  
  2627.             $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $delete_reason);
  2628.             $post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username'];
  2629.  
  2630.             if ($next_post_id === false)
  2631.             {
  2632.                 add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username, $delete_reason);
  2633.  
  2634.                 $meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id");
  2635.                 $message = $user->lang['POST_DELETED'];
  2636.             }
  2637.             else
  2638.             {
  2639.                 add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username, $delete_reason);
  2640.  
  2641.                 $meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p=$next_post_id") . "#p$next_post_id";
  2642.                 $message = $user->lang['POST_DELETED'];
  2643.  
  2644.                 if (!$request->is_ajax())
  2645.                 {
  2646.                     $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $meta_info . '">', '</a>');
  2647.                 }
  2648.             }
  2649.  
  2650.             meta_refresh(3, $meta_info);
  2651.             if (!$request->is_ajax())
  2652.             {
  2653.                 $message .= '<br /><br />' . $user->lang('RETURN_FORUM', '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
  2654.             }
  2655.             trigger_error($message);
  2656.         }
  2657.         else
  2658.         {
  2659.             global $user, $template, $request;
  2660.  
  2661.             $can_delete = $auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_delete', $forum_id));
  2662.             $can_softdelete = $auth->acl_get('m_softdelete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_softdelete', $forum_id));
  2663.  
  2664.             $template->assign_vars(array(
  2665.                 'S_SOFTDELETED'         => $post_data['post_visibility'] == ITEM_DELETED,
  2666.                 'S_CHECKED_PERMANENT'   => $request->is_set_post('delete_permanent') ? ' checked="checked"' : '',
  2667.                 'S_ALLOWED_DELETE'      => $can_delete,
  2668.                 'S_ALLOWED_SOFTDELETE'  => $can_softdelete,
  2669.             ));
  2670.  
  2671.             $l_confirm = 'DELETE_POST';
  2672.             if ($post_data['post_visibility'] == ITEM_DELETED)
  2673.             {
  2674.                 $l_confirm .= '_PERMANENTLY';
  2675.                 $s_hidden_fields['delete_permanent'] = '1';
  2676.             }
  2677.             else if (!$can_softdelete)
  2678.             {
  2679.                 $s_hidden_fields['delete_permanent'] = '1';
  2680.             }
  2681.  
  2682.             confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html');
  2683.         }
  2684.     }
  2685.  
  2686.     // If we are here the user is not able to delete - present the correct error message
  2687.     if ($post_data['poster_id'] != $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id))
  2688.     {
  2689.         trigger_error('DELETE_OWN_POSTS');
  2690.     }
  2691.  
  2692.     if ($post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id) && $post_id != $post_data['topic_last_post_id'])
  2693.     {
  2694.         trigger_error('CANNOT_DELETE_REPLIED');
  2695.     }
  2696.  
  2697.     trigger_error('USER_CANNOT_DELETE');
  2698. }
Advertisement
Add Comment
Please, Sign In to add comment