Guest User

Ivn

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