Jorup16

Functions_Posting -ASEI

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