Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


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

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

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

functions_posting.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 77.94 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * @package phpBB3
 0005  * @version $Id$
 0006  * @copyright (c) 2005 phpBB Group
 0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 0008  *
 0009  */
 0010   
 0011  /**
 0012  * @ignore
 0013  */
 0014  if (!defined('IN_PHPBB'))
 0015  {
 0016      exit;
 0017  }
 0018   
 0019  /**
 0020  * Fill smiley templates (or just the variables) with smilies, either in a window or inline
 0021  */
 0022  function generate_smilies($mode, $forum_id)
 0023  {
 0024      global $auth, $db, $user, $config, $template;
 0025      global $phpEx, $phpbb_root_path;
 0026   
 0027      if ($mode == 'window')
 0028      {
 0029          if ($forum_id)
 0030          {
 0031              $sql = 'SELECT forum_style
 0032                  FROM ' . FORUMS_TABLE . "
 0033                  WHERE forum_id = $forum_id";
 0034              $result = $db->sql_query_limit($sql, 1);
 0035              $row = $db->sql_fetchrow($result);
 0036              $db->sql_freeresult($result);
 0037   
 0038              $user->setup('posting', (int) $row['forum_style']);
 0039          }
 0040          else
 0041          {
 0042              $user->setup('posting');
 0043          }
 0044   
 0045          page_header($user->lang['SMILIES']);
 0046   
 0047          $template->set_filenames(array(
 0048              'body' => 'posting_smilies.html')
 0049          );
 0050      }
 0051   
 0052      $display_link = false;
 0053      if ($mode == 'inline')
 0054      {
 0055          $sql = 'SELECT smiley_id
 0056              FROM ' . SMILIES_TABLE . '
 0057              WHERE display_on_posting = 0';
 0058          $result = $db->sql_query_limit($sql, 1, 0, 3600);
 0059   
 0060          if ($row = $db->sql_fetchrow($result))
 0061          {
 0062              $display_link = true;
 0063          }
 0064          $db->sql_freeresult($result);
 0065      }
 0066   
 0067      $last_url = '';
 0068   
 0069      $sql = 'SELECT *
 0070          FROM ' . SMILIES_TABLE .
 0071          (($mode == 'inline') ? ' WHERE display_on_posting = 1 ' : '') . '
 0072          ORDER BY smiley_order';
 0073      $result = $db->sql_query($sql, 3600);
 0074   
 0075      $smilies = array();
 0076      while ($row = $db->sql_fetchrow($result))
 0077      {
 0078          if (empty($smilies[$row['smiley_url']]))
 0079          {
 0080              $smilies[$row['smiley_url']] = $row;
 0081          }
 0082      }
 0083      $db->sql_freeresult($result);
 0084   
 0085      if (sizeof($smilies))
 0086      {
 0087          foreach ($smilies as $row)
 0088          {
 0089              $template->assign_block_vars('smiley', array(
 0090                  'SMILEY_CODE'    => $row['code'],
 0091                  'A_SMILEY_CODE'    => addslashes($row['code']),
 0092                  'SMILEY_IMG'    => $phpbb_root_path . $config['smilies_path'] . '/' . $row['smiley_url'],
 0093                  'SMILEY_WIDTH'    => $row['smiley_width'],
 0094                  'SMILEY_HEIGHT'    => $row['smiley_height'],
 0095                  'SMILEY_DESC'    => $row['emotion'])
 0096              );
 0097          }
 0098      }
 0099   
 0100      if ($mode == 'inline' && $display_link)
 0101      {
 0102          $template->assign_vars(array(
 0103              'S_SHOW_SMILEY_LINK'     => true,
 0104              'U_MORE_SMILIES'         => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&amp;f=' . $forum_id))
 0105          );
 0106      }
 0107   
 0108      if ($mode == 'window')
 0109      {
 0110          page_footer();
 0111      }
 0112  }
 0113   
 0114  /**
 0115  * Update last post information
 0116  * Should be used instead of sync() if only the last post information are out of sync... faster
 0117  *
 0118  * @param    string    $type                Can be forum|topic
 0119  * @param    mixed    $ids                topic/forum ids
 0120  * @param    bool    $return_update_sql    true: SQL query shall be returned, false: execute SQL
 0121  */
 0122  function update_post_information($type, $ids, $return_update_sql = false)
 0123  {
 0124      global $db;
 0125   
 0126      if (empty($ids))
 0127      {
 0128          return;
 0129      }
 0130      if (!is_array($ids))
 0131      {
 0132          $ids = array($ids);
 0133      }
 0134   
 0135   
 0136      $update_sql = $empty_forums = $not_empty_forums = array();
 0137   
 0138      if ($type != 'topic')
 0139      {
 0140          $topic_join = ', ' . TOPICS_TABLE . ' t';
 0141          $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_approved = 1';
 0142      }
 0143      else
 0144      {
 0145          $topic_join = '';
 0146          $topic_condition = '';
 0147      }
 0148   
 0149      if (sizeof($ids) == 1)
 0150      {
 0151          $sql = 'SELECT MAX(p.post_id) as last_post_id
 0152              FROM ' . POSTS_TABLE . " p $topic_join
 0153              WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
 0154                  $topic_condition
 0155                  AND p.post_approved = 1";
 0156      }
 0157      else
 0158      {
 0159          $sql = 'SELECT p.' . $type . '_id, MAX(p.post_id) as last_post_id
 0160              FROM ' . POSTS_TABLE . " p $topic_join
 0161              WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
 0162                  $topic_condition
 0163                  AND p.post_approved = 1
 0164              GROUP BY p.{$type}_id";
 0165      }
 0166      $result = $db->sql_query($sql);
 0167   
 0168      $last_post_ids = array();
 0169      while ($row = $db->sql_fetchrow($result))
 0170      {
 0171          if (sizeof($ids) == 1)
 0172          {
 0173              $row[$type . '_id'] = $ids[0];
 0174          }
 0175   
 0176          if ($type == 'forum')
 0177          {
 0178              $not_empty_forums[] = $row['forum_id'];
 0179   
 0180              if (empty($row['last_post_id']))
 0181              {
 0182                  $empty_forums[] = $row['forum_id'];
 0183              }
 0184          }
 0185   
 0186          $last_post_ids[] = $row['last_post_id'];
 0187      }
 0188      $db->sql_freeresult($result);
 0189   
 0190      if ($type == 'forum')
 0191      {
 0192          $empty_forums = array_merge($empty_forums, array_diff($ids, $not_empty_forums));
 0193   
 0194          foreach ($empty_forums as $void => $forum_id)
 0195          {
 0196              $update_sql[$forum_id][] = 'forum_last_post_id = 0';
 0197              $update_sql[$forum_id][] = "forum_last_post_subject = ''";
 0198              $update_sql[$forum_id][] = 'forum_last_post_time = 0';
 0199              $update_sql[$forum_id][] = 'forum_last_poster_id = 0';
 0200              $update_sql[$forum_id][] = "forum_last_poster_name = ''";
 0201              $update_sql[$forum_id][] = "forum_last_poster_colour = ''";
 0202          }
 0203      }
 0204   
 0205      if (sizeof($last_post_ids))
 0206      {
 0207          $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
 0208              FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 0209              WHERE p.poster_id = u.user_id
 0210                  AND ' . $db->sql_in_set('p.post_id', $last_post_ids);
 0211          $result = $db->sql_query($sql);
 0212   
 0213          while ($row = $db->sql_fetchrow($result))
 0214          {
 0215              $update_sql[$row["{$type}_id"]][] = $type . '_last_post_id = ' . (int) $row['post_id'];
 0216              $update_sql[$row["{$type}_id"]][] = "{$type}_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
 0217              $update_sql[$row["{$type}_id"]][] = $type . '_last_post_time = ' . (int) $row['post_time'];
 0218              $update_sql[$row["{$type}_id"]][] = $type . '_last_poster_id = ' . (int) $row['poster_id'];
 0219              $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
 0220              $update_sql[$row["{$type}_id"]][] = "{$type}_last_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "'";
 0221          }
 0222          $db->sql_freeresult($result);
 0223      }
 0224      unset($empty_forums, $ids, $last_post_ids);
 0225   
 0226      if ($return_update_sql || !sizeof($update_sql))
 0227      {
 0228          return $update_sql;
 0229      }
 0230   
 0231      $table = ($type == 'forum') ? FORUMS_TABLE : TOPICS_TABLE;
 0232   
 0233      foreach ($update_sql as $update_id => $update_sql_ary)
 0234      {
 0235          $sql = "UPDATE $table
 0236              SET " . implode(', ', $update_sql_ary) . "
 0237              WHERE {$type}_id = $update_id";
 0238          $db->sql_query($sql);
 0239      }
 0240   
 0241      return;
 0242  }
 0243   
 0244  /**
 0245  * Generate Topic Icons for display
 0246  */
 0247  function posting_gen_topic_icons($mode, $icon_id)
 0248  {
 0249      global $phpbb_root_path, $config, $template, $cache;
 0250   
 0251      // Grab icons
 0252      $icons = $cache->obtain_icons();
 0253   
 0254      if (!$icon_id)
 0255      {
 0256          $template->assign_var('S_NO_ICON_CHECKED', ' checked="checked"');
 0257      }
 0258   
 0259      if (sizeof($icons))
 0260      {
 0261          foreach ($icons as $id => $data)
 0262          {
 0263              if ($data['display'])
 0264              {
 0265                  $template->assign_block_vars('topic_icon', array(
 0266                      'ICON_ID'        => $id,
 0267                      'ICON_IMG'        => $phpbb_root_path . $config['icons_path'] . '/' . $data['img'],
 0268                      'ICON_WIDTH'    => $data['width'],
 0269                      'ICON_HEIGHT'    => $data['height'],
 0270      
 0271                      'S_CHECKED'            => ($id == $icon_id) ? true : false,
 0272                      'S_ICON_CHECKED'    => ($id == $icon_id) ? ' checked="checked"' : '')
 0273                  );
 0274              }
 0275          }
 0276   
 0277          return true;
 0278      }
 0279   
 0280      return false;
 0281  }
 0282   
 0283  /**
 0284  * Build topic types able to be selected
 0285  */
 0286  function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
 0287  {
 0288      global $auth, $user, $template, $topic_type;
 0289   
 0290      $toggle = false;
 0291   
 0292      $topic_types = array(
 0293          'sticky'    => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
 0294          'announce'    => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
 0295          'global'    => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
 0296      );
 0297   
 0298      $topic_type_array = array();
 0299   
 0300      foreach ($topic_types as $auth_key => $topic_value)
 0301      {
 0302          // We do not have a special post global announcement permission
 0303          $auth_key = ($auth_key == 'global') ? 'announce' : $auth_key;
 0304   
 0305          if ($auth->acl_get('f_' . $auth_key, $forum_id))
 0306          {
 0307              $toggle = true;
 0308   
 0309              $topic_type_array[] = array(
 0310                  'VALUE'            => $topic_value['const'],
 0311                  'S_CHECKED'        => ($cur_topic_type == $topic_value['const'] || ($forum_id == 0 && $topic_value['const'] == POST_GLOBAL)) ? ' checked="checked"' : '',
 0312                  'L_TOPIC_TYPE'    => $user->lang[$topic_value['lang']]
 0313              );
 0314          }
 0315      }
 0316   
 0317      if ($toggle)
 0318      {
 0319          $topic_type_array = array_merge(array(0 => array(
 0320              'VALUE'            => POST_NORMAL,
 0321              'S_CHECKED'        => ($topic_type == POST_NORMAL) ? ' checked="checked"' : '',
 0322              'L_TOPIC_TYPE'    => $user->lang['POST_NORMAL'])),
 0323   
 0324              $topic_type_array
 0325          );
 0326          
 0327          foreach ($topic_type_array as $array)
 0328          {
 0329              $template->assign_block_vars('topic_type', $array);
 0330          }
 0331   
 0332          $template->assign_vars(array(
 0333              'S_TOPIC_TYPE_STICKY'    => ($auth->acl_get('f_sticky', $forum_id)),
 0334              'S_TOPIC_TYPE_ANNOUNCE'    => ($auth->acl_get('f_announce', $forum_id)))
 0335          );
 0336      }
 0337   
 0338      return $toggle;
 0339  }
 0340   
 0341  //
 0342  // Attachment related functions
 0343  //
 0344   
 0345  /**
 0346  * Upload Attachment - filedata is generated here
 0347  * Uses upload class
 0348  */
 0349  function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
 0350  {
 0351      global $auth, $user, $config, $db, $cache;
 0352      global $phpbb_root_path, $phpEx;
 0353   
 0354      $filedata = array(
 0355          'error'    => array()
 0356      );
 0357   
 0358      include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
 0359      $upload = new fileupload();
 0360   
 0361      if (!$local)
 0362      {
 0363          $filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
 0364      }
 0365      else
 0366      {
 0367          $filedata['post_attach'] = true;
 0368      }
 0369   
 0370      if (!$filedata['post_attach'])
 0371      {
 0372          $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
 0373          return $filedata;
 0374      }
 0375   
 0376      $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
 0377      $upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
 0378   
 0379      $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name);
 0380   
 0381      if ($file->init_error)
 0382      {
 0383          $filedata['post_attach'] = false;
 0384          return $filedata;
 0385      }
 0386   
 0387      $cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE;
 0388   
 0389      // Make sure the image category only holds valid images...
 0390      if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
 0391      {
 0392          $file->remove();
 0393   
 0394          // If this error occurs a user tried to exploit an IE Bug by renaming extensions
 0395          // Since the image category is displaying content inline we need to catch this.
 0396          trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
 0397      }
 0398   
 0399      // Do we have to create a thumbnail?
 0400      $filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
 0401   
 0402      // Check Image Size, if it is an image
 0403      if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE)
 0404      {
 0405          $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
 0406      }
 0407   
 0408      // Admins and mods are allowed to exceed the allowed filesize
 0409      if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
 0410      {
 0411          if (!empty($extensions[$file->get('extension')]['max_filesize']))
 0412          {
 0413              $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
 0414          }
 0415          else
 0416          {
 0417              $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
 0418          }
 0419   
 0420          $file->upload->set_max_filesize($allowed_filesize);
 0421      }
 0422   
 0423      $file->clean_filename('unique', $user->data['user_id'] . '_');
 0424   
 0425      // Are we uploading an image *and* this image being within the image category? Only then perform additional image checks.
 0426      $no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true;
 0427   
 0428      $file->move_file($config['upload_path'], false, $no_image);
 0429   
 0430      if (sizeof($file->error))
 0431      {
 0432          $file->remove();
 0433          $filedata['error'] = array_merge($filedata['error'], $file->error);
 0434          $filedata['post_attach'] = false;
 0435   
 0436          return $filedata;
 0437      }
 0438   
 0439      $filedata['filesize'] = $file->get('filesize');
 0440      $filedata['mimetype'] = $file->get('mimetype');
 0441      $filedata['extension'] = $file->get('extension');
 0442      $filedata['physical_filename'] = $file->get('realname');
 0443      $filedata['real_filename'] = $file->get('uploadname');
 0444      $filedata['filetime'] = time();
 0445   
 0446      // Check our complete quota
 0447      if ($config['attachment_quota'])
 0448      {
 0449          if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
 0450          {
 0451              $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
 0452              $filedata['post_attach'] = false;
 0453   
 0454              $file->remove();
 0455   
 0456              return $filedata;
 0457          }
 0458      }
 0459   
 0460      // Check free disk space
 0461      if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
 0462      {
 0463          if ($free_space <= $file->get('filesize'))
 0464          {
 0465              $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
 0466              $filedata['post_attach'] = false;
 0467   
 0468              $file->remove();
 0469   
 0470              return $filedata;
 0471          }
 0472      }
 0473   
 0474      // Create Thumbnail
 0475      if ($filedata['thumbnail'])
 0476      {
 0477          $source = $file->get('destination_file');
 0478          $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
 0479   
 0480          if (!create_thumbnail($source, $destination, $file->get('mimetype')))
 0481          {
 0482              $filedata['thumbnail'] = 0;
 0483          }
 0484      }
 0485   
 0486      return $filedata;
 0487  }
 0488   
 0489  /**
 0490  * Calculate the needed size for Thumbnail
 0491  */
 0492  function get_img_size_format($width, $height)
 0493  {
 0494      global $config;
 0495   
 0496      // Maximum Width the Image can take
 0497      $max_width = ($config['img_max_thumb_width']) ? $config['img_max_thumb_width'] : 400;
 0498   
 0499      if ($width > $height)
 0500      {
 0501          return array(
 0502              round($width * ($max_width / $width)),
 0503              round($height * ($max_width / $width))
 0504          );
 0505      }
 0506      else
 0507      {
 0508          return array(
 0509              round($width * ($max_width / $height)),
 0510              round($height * ($max_width / $height))
 0511          );
 0512      }
 0513  }
 0514   
 0515  /**
 0516  * Return supported image types
 0517  */
 0518  function get_supported_image_types($type = false)
 0519  {
 0520      if (@extension_loaded('gd'))
 0521      {
 0522          $format = imagetypes();
 0523          $new_type = 0;
 0524   
 0525          if ($type !== false)
 0526          {
 0527              switch ($type)
 0528              {
 0529                  // GIF
 0530                  case 1:
 0531                      $new_type = ($format & IMG_GIF) ? IMG_GIF : false;
 0532                  break;
 0533   
 0534                  // JPG, JPC, JP2
 0535                  case 2:
 0536                  case 9:
 0537                  case 10:
 0538                  case 11:
 0539                  case 12:
 0540                      $new_type = ($format & IMG_JPG) ? IMG_JPG : false;
 0541                  break;
 0542   
 0543                  // PNG
 0544                  case 3:
 0545                      $new_type = ($format & IMG_PNG) ? IMG_PNG : false;
 0546                  break;
 0547   
 0548                  // BMP, WBMP
 0549                  case 6:
 0550                  case 15:
 0551                      $new_type = ($format & IMG_WBMP) ? IMG_WBMP : false;
 0552                  break;
 0553              }
 0554          }
 0555          else
 0556          {
 0557              $new_type = array();
 0558              $go_through_types = array(IMG_GIF, IMG_JPG, IMG_PNG, IMG_WBMP);
 0559   
 0560              foreach ($go_through_types as $check_type)
 0561              {
 0562                  if ($format & $check_type)
 0563                  {
 0564                      $new_type[] = $check_type;
 0565                  }
 0566              }
 0567          }
 0568   
 0569          return array(
 0570              'gd'        => ($new_type) ? true : false,
 0571              'format'    => $new_type,
 0572              'version'    => (function_exists('imagecreatetruecolor')) ? 2 : 1
 0573          );
 0574      }
 0575   
 0576      return array('gd' => false);
 0577  }
 0578   
 0579  /**
 0580  * Create Thumbnail
 0581  */
 0582  function create_thumbnail($source, $destination, $mimetype)
 0583  {
 0584      global $config;
 0585   
 0586      $min_filesize = (int) $config['img_min_thumb_filesize'];
 0587      $img_filesize = (file_exists($source)) ? @filesize($source) : false;
 0588   
 0589      if (!$img_filesize || $img_filesize <= $min_filesize)
 0590      {
 0591          return false;
 0592      }
 0593   
 0594      $dimension = @getimagesize($source);
 0595   
 0596      if ($dimension === false)
 0597      {
 0598          return false;
 0599      }
 0600   
 0601      list($width, $height, $type, ) = $dimension;
 0602   
 0603      if (empty($width) || empty($height))
 0604      {
 0605          return false;
 0606      }
 0607   
 0608      list($new_width, $new_height) = get_img_size_format($width, $height);
 0609   
 0610      // Do not create a thumbnail if the resulting width/height is bigger than the original one
 0611      if ($new_width > $width && $new_height > $height)
 0612      {
 0613          return false;
 0614      }
 0615   
 0616      $used_imagick = false;
 0617   
 0618      // Only use imagemagick if defined and the passthru function not disabled
 0619      if ($config['img_imagick'] && function_exists('passthru'))
 0620      {
 0621          @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -antialias -sample ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" +profile "*" "' . str_replace('\\', '/', $destination) . '"');
 0622   
 0623          if (file_exists($destination))
 0624          {
 0625              $used_imagick = true;
 0626          }
 0627      }
 0628   
 0629      if (!$used_imagick)
 0630      {
 0631          $type = get_supported_image_types($type);
 0632   
 0633          if ($type['gd'])
 0634          {
 0635              // If the type is not supported, we are not able to create a thumbnail
 0636              if ($type['format'] === false)
 0637              {
 0638                  return false;
 0639              }
 0640   
 0641              switch ($type['format'])
 0642              {
 0643                  case IMG_GIF:
 0644                      $image = @imagecreatefromgif($source);
 0645                  break;
 0646   
 0647                  case IMG_JPG:
 0648                      $image = @imagecreatefromjpeg($source);
 0649                  break;
 0650   
 0651                  case IMG_PNG:
 0652                      $image = @imagecreatefrompng($source);
 0653                  break;
 0654   
 0655                  case IMG_WBMP:
 0656                      $image = @imagecreatefromwbmp($source);
 0657                  break;
 0658              }
 0659   
 0660              if ($type['version'] == 1)
 0661              {
 0662                  $new_image = imagecreate($new_width, $new_height);
 0663   
 0664                  if ($new_image === false)
 0665                  {
 0666                      return false;
 0667                  }
 0668   
 0669                  imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
 0670              }
 0671              else
 0672              {
 0673                  $new_image = imagecreatetruecolor($new_width, $new_height);
 0674   
 0675                  if ($new_image === false)
 0676                  {
 0677                      return false;
 0678                  }
 0679   
 0680                  imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
 0681              }
 0682   
 0683              // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug
 0684              if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on')
 0685              {
 0686                  @touch($destination);
 0687              }
 0688   
 0689              switch ($type['format'])
 0690              {
 0691                  case IMG_GIF:
 0692                      imagegif($new_image, $destination);
 0693                  break;
 0694   
 0695                  case IMG_JPG:
 0696                      imagejpeg($new_image, $destination, 90);
 0697                  break;
 0698   
 0699                  case IMG_PNG:
 0700                      imagepng($new_image, $destination);
 0701                  break;
 0702   
 0703                  case IMG_WBMP:
 0704                      imagewbmp($new_image, $destination);
 0705                  break;
 0706              }
 0707   
 0708              imagedestroy($new_image);
 0709          }
 0710          else
 0711          {
 0712              return false;
 0713          }
 0714      }
 0715   
 0716      if (!file_exists($destination))
 0717      {
 0718          return false;
 0719      }
 0720   
 0721      @chmod($destination, 0666);
 0722   
 0723      return true;
 0724  }
 0725   
 0726  /**
 0727  * Assign Inline attachments (build option fields)
 0728  */
 0729  function posting_gen_inline_attachments(&$attachment_data)
 0730  {
 0731      global $template;
 0732   
 0733      if (sizeof($attachment_data))
 0734      {
 0735          $s_inline_attachment_options = '';
 0736   
 0737          foreach ($attachment_data as $i => $attachment)
 0738          {
 0739              $s_inline_attachment_options .= '<option value="' . $i . '">' . basename($attachment['real_filename']) . '</option>';
 0740          }
 0741   
 0742          $template->assign_var('S_INLINE_ATTACHMENT_OPTIONS', $s_inline_attachment_options);
 0743   
 0744          return true;
 0745      }
 0746   
 0747      return false;
 0748  }
 0749   
 0750  /**
 0751  * Generate inline attachment entry
 0752  */
 0753  function posting_gen_attachment_entry($attachment_data, &$filename_data)
 0754  {
 0755      global $template, $config, $phpbb_root_path, $phpEx, $user;
 0756   
 0757      $template->assign_vars(array(
 0758          'S_SHOW_ATTACH_BOX'    => true)
 0759      );
 0760   
 0761      if (sizeof($attachment_data))
 0762      {
 0763          $template->assign_vars(array(
 0764              'S_HAS_ATTACHMENTS'    => true)
 0765          );
 0766   
 0767          // We display the posted attachments within the desired order.
 0768          ($config['display_order']) ? krsort($attachment_data) : ksort($attachment_data);
 0769   
 0770          foreach ($attachment_data as $count => $attach_row)
 0771          {
 0772              $hidden = '';
 0773              $attach_row['real_filename'] = basename($attach_row['real_filename']);
 0774   
 0775              foreach ($attach_row as $key => $value)
 0776              {
 0777                  $hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />';
 0778              }
 0779   
 0780              $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);
 0781   
 0782              $template->assign_block_vars('attach_row', array(
 0783                  'FILENAME'            => basename($attach_row['real_filename']),
 0784                  'A_FILENAME'        => addslashes(basename($attach_row['real_filename'])),
 0785                  'FILE_COMMENT'        => $attach_row['attach_comment'],
 0786                  'ATTACH_ID'            => $attach_row['attach_id'],
 0787                  'S_IS_ORPHAN'        => $attach_row['is_orphan'],
 0788                  'ASSOC_INDEX'        => $count,
 0789   
 0790                  'U_VIEW_ATTACHMENT'    => $download_link,
 0791                  'S_HIDDEN'            => $hidden)
 0792              );
 0793          }
 0794      }
 0795   
 0796      $template->assign_vars(array(
 0797          'FILE_COMMENT'    => $filename_data['filecomment'],
 0798          'FILESIZE'        => $config['max_filesize'])
 0799      );
 0800   
 0801      return sizeof($attachment_data);
 0802  }
 0803   
 0804  //
 0805  // General Post functions
 0806  //
 0807   
 0808  /**
 0809  * Load Drafts
 0810  */
 0811  function load_drafts($topic_id = 0, $forum_id = 0, $id = 0)
 0812  {
 0813      global $user, $db, $template, $auth;
 0814      global $phpbb_root_path, $phpEx;
 0815   
 0816      $topic_ids = $forum_ids = $draft_rows = array();
 0817   
 0818      // Load those drafts not connected to forums/topics
 0819      // If forum_id == 0 AND topic_id == 0 then this is a PM draft
 0820      if (!$topic_id && !$forum_id)
 0821      {
 0822          $sql_and = ' AND d.forum_id = 0 AND d.topic_id = 0';
 0823      }
 0824      else
 0825      {
 0826          $sql_and = '';
 0827          $sql_and .= ($forum_id) ? ' AND d.forum_id = ' . (int) $forum_id : '';
 0828          $sql_and .= ($topic_id) ? ' AND d.topic_id = ' . (int) $topic_id : '';
 0829      }
 0830   
 0831      $sql = 'SELECT d.*, f.forum_id, f.forum_name
 0832          FROM ' . DRAFTS_TABLE . ' d
 0833          LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = d.forum_id)
 0834              WHERE d.user_id = ' . $user->data['user_id'] . "
 0835              $sql_and
 0836          ORDER BY d.save_time DESC";
 0837      $result = $db->sql_query($sql);
 0838   
 0839      while ($row = $db->sql_fetchrow($result))
 0840      {
 0841          if ($row['topic_id'])
 0842          {
 0843              $topic_ids[] = (int) $row['topic_id'];
 0844          }
 0845          $draft_rows[] = $row;
 0846      }
 0847      $db->sql_freeresult($result);
 0848   
 0849      if (!sizeof($draft_rows))
 0850      {
 0851          return;
 0852      }
 0853   
 0854      $topic_rows = array();
 0855      if (sizeof($topic_ids))
 0856      {
 0857          $sql = 'SELECT topic_id, forum_id, topic_title
 0858              FROM ' . TOPICS_TABLE . '
 0859              WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids));
 0860          $result = $db->sql_query($sql);
 0861   
 0862          while ($row = $db->sql_fetchrow($result))
 0863          {
 0864              $topic_rows[$row['topic_id']] = $row;
 0865          }
 0866          $db->sql_freeresult($result);
 0867      }
 0868      unset($topic_ids);
 0869   
 0870      $template->assign_var('S_SHOW_DRAFTS', true);
 0871   
 0872      foreach ($draft_rows as $draft)
 0873      {
 0874          $link_topic = $link_forum = $link_pm = false;
 0875          $insert_url = $view_url = $title = '';
 0876   
 0877          if (isset($topic_rows[$draft['topic_id']])
 0878              && (
 0879                  ($topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_get('f_read', $topic_rows[$draft['topic_id']]['forum_id']))
 0880                  ||
 0881                  (!$topic_rows[$draft['topic_id']]['forum_id'] && $auth->acl_getf_global('f_read'))
 0882              ))
 0883          {
 0884              $topic_forum_id = ($topic_rows[$draft['topic_id']]['forum_id']) ? $topic_rows[$draft['topic_id']]['forum_id'] : $forum_id;
 0885   
 0886              $link_topic = true;
 0887              $view_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_forum_id . '&amp;t=' . $draft['topic_id']);
 0888              $title = $topic_rows[$draft['topic_id']]['topic_title'];
 0889   
 0890              $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']);
 0891          }
 0892          else if ($draft['forum_id'] && $auth->acl_get('f_read', $draft['forum_id']))
 0893          {
 0894              $link_forum = true;
 0895              $view_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $draft['forum_id']);
 0896              $title = $draft['forum_name'];
 0897   
 0898              $insert_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'f=' . $draft['forum_id'] . '&amp;mode=post&amp;d=' . $draft['draft_id']);
 0899          }
 0900          else
 0901          {
 0902              // Either display as PM draft if forum_id and topic_id are empty or if access to the forums has been denied afterwards...
 0903              $link_pm = true;
 0904              $insert_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&amp;mode=compose&amp;d={$draft['draft_id']}");
 0905          }
 0906   
 0907          $template->assign_block_vars('draftrow', array(
 0908              'DRAFT_ID'        => $draft['draft_id'],
 0909              'DATE'            => $user->format_date($draft['save_time']),
 0910              'DRAFT_SUBJECT'    => $draft['draft_subject'],
 0911   
 0912              'TITLE'            => $title,
 0913              'U_VIEW'        => $view_url,
 0914              'U_INSERT'        => $insert_url,
 0915   
 0916              'S_LINK_PM'        => $link_pm,
 0917              'S_LINK_TOPIC'    => $link_topic,
 0918              'S_LINK_FORUM'    => $link_forum)
 0919          );
 0920      }
 0921  }
 0922   
 0923  /**
 0924  * Topic Review
 0925  */
 0926  function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true)
 0927  {
 0928      global $user, $auth, $db, $template, $bbcode, $cache;
 0929      global $config, $phpbb_root_path, $phpEx;
 0930   
 0931      // Go ahead and pull all data for this topic
 0932      $sql = 'SELECT p.post_id
 0933          FROM ' . POSTS_TABLE . ' p' . "
 0934          WHERE p.topic_id = $topic_id
 0935              " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . '
 0936              ' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
 0937          ORDER BY p.post_time DESC';
 0938      $result = $db->sql_query_limit($sql, $config['posts_per_page']);
 0939   
 0940      $post_list = array();
 0941   
 0942      while ($row = $db->sql_fetchrow($result))
 0943      {
 0944          $post_list[] = $row['post_id'];
 0945      }
 0946   
 0947      $db->sql_freeresult($result);
 0948   
 0949      if (!sizeof($post_list))
 0950      {
 0951          return false;
 0952      }
 0953   
 0954      $sql = $db->sql_build_query('SELECT', array(
 0955          'SELECT'    => 'u.username, u.user_id, u.user_colour, p.*',
 0956   
 0957          'FROM'        => array(
 0958              USERS_TABLE        => 'u',
 0959              POSTS_TABLE        => 'p',
 0960          ),
 0961   
 0962          'WHERE'        => $db->sql_in_set('p.post_id', $post_list) . '
 0963              AND u.user_id = p.poster_id'
 0964      ));
 0965   
 0966      $result = $db->sql_query($sql);
 0967   
 0968      $bbcode_bitfield = '';
 0969      $rowset = array();
 0970      $has_attachments = false;
 0971      while ($row = $db->sql_fetchrow($result))
 0972      {
 0973          $rowset[$row['post_id']] = $row;
 0974          $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
 0975   
 0976          if ($row['post_attachment'])
 0977          {
 0978              $has_attachments = true;
 0979          }
 0980      }
 0981      $db->sql_freeresult($result);
 0982   
 0983      // Instantiate BBCode class
 0984      if (!isset($bbcode) && $bbcode_bitfield !== '')
 0985      {
 0986          include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx);
 0987          $bbcode = new bbcode(base64_encode($bbcode_bitfield));
 0988      }
 0989   
 0990      // Grab extensions
 0991      $extensions = $attachments = array();
 0992      if ($has_attachments && $auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
 0993      {
 0994          $extensions = $cache->obtain_attach_extensions($forum_id);
 0995   
 0996          // Get attachments...
 0997          $sql = 'SELECT *
 0998              FROM ' . ATTACHMENTS_TABLE . '
 0999              WHERE ' . $db->sql_in_set('post_msg_id', $post_list) . '
 1000                  AND in_message = 0
 1001              ORDER BY filetime DESC, post_msg_id ASC';
 1002          $result = $db->sql_query($sql);
 1003   
 1004          while ($row = $db->sql_fetchrow($result))
 1005          {
 1006              $attachments[$row['post_msg_id']][] = $row;
 1007          }
 1008          $db->sql_freeresult($result);
 1009      }
 1010   
 1011      for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
 1012      {
 1013          // A non-existing rowset only happens if there was no user present for the entered poster_id
 1014          // This could be a broken posts table.
 1015          if (!isset($rowset[$post_list[$i]]))
 1016          {
 1017              continue;
 1018          }
 1019   
 1020          $row =& $rowset[$post_list[$i]];
 1021   
 1022          $poster_id        = $row['user_id'];
 1023          $post_subject    = $row['post_subject'];
 1024          $message        = censor_text($row['post_text']);
 1025   
 1026          $decoded_message = false;
 1027   
 1028          if ($show_quote_button && $auth->acl_get('f_reply', $forum_id))
 1029          {
 1030              $decoded_message = $message;
 1031              decode_message($decoded_message, $row['bbcode_uid']);
 1032   
 1033              $decoded_message = bbcode_nl2br($decoded_message);
 1034          }
 1035   
 1036          if ($row['bbcode_bitfield'])
 1037          {
 1038              $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
 1039          }
 1040   
 1041          $message = bbcode_nl2br($message);
 1042          $message = smiley_text($message, !$row['enable_smilies']);
 1043   
 1044          if (!empty($attachments[$row['post_id']]))
 1045          {
 1046              $update_count = array();
 1047              parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count);
 1048          }
 1049   
 1050          $post_subject = censor_text($post_subject);
 1051   
 1052          $template->assign_block_vars($mode . '_row', array(
 1053              'POST_AUTHOR_FULL'        => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
 1054              'POST_AUTHOR_COLOUR'    => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
 1055              'POST_AUTHOR'            => get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
 1056              'U_POST_AUTHOR'            => get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
 1057   
 1058              'S_HAS_ATTACHMENTS'    => (!empty($attachments[$row['post_id']])) ? true : false,
 1059   
 1060              'POST_SUBJECT'        => $post_subject,
 1061              'MINI_POST_IMG'        => $user->img('icon_post_target', $user->lang['POST']),
 1062              'POST_DATE'            => $user->format_date($row['post_time']),
 1063              'MESSAGE'            => $message,
 1064              'DECODED_MESSAGE'    => $decoded_message,
 1065              'POST_ID'            => $row['post_id'],
 1066              'U_MINI_POST'        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
 1067              '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) : '',
 1068              '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'])) : '')
 1069          );
 1070   
 1071          // Display not already displayed Attachments for this post, we already parsed them. ;)
 1072          if (!empty($attachments[$row['post_id']]))
 1073          {
 1074              foreach ($attachments[$row['post_id']] as $attachment)
 1075              {
 1076                  $template->assign_block_vars($mode . '_row.attachment', array(
 1077                      'DISPLAY_ATTACHMENT'    => $attachment)
 1078                  );
 1079              }
 1080          }
 1081   
 1082          unset($rowset[$i]);
 1083      }
 1084   
 1085      if ($mode == 'topic_review')
 1086      {
 1087          $template->assign_var('QUOTE_IMG', $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']));
 1088      }
 1089   
 1090      return true;
 1091  }
 1092   
 1093  /**
 1094  * User Notification
 1095  */
 1096  function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id)
 1097  {
 1098      global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
 1099   
 1100      $topic_notification = ($mode == 'reply' || $mode == 'quote') ? true : false;
 1101      $forum_notification = ($mode == 'post') ? true : false;
 1102   
 1103      if (!$topic_notification && !$forum_notification)
 1104      {
 1105          trigger_error('WRONG_NOTIFICATION_MODE');
 1106      }
 1107   
 1108      if (!$config['allow_topic_notify'])
 1109      {
 1110          return;
 1111      }
 1112   
 1113      $topic_title = ($topic_notification) ? $topic_title : $subject;
 1114      $topic_title = censor_text($topic_title);
 1115   
 1116      // Get banned User ID's
 1117      $sql = 'SELECT ban_userid
 1118          FROM ' . BANLIST_TABLE;
 1119      $result = $db->sql_query($sql);
 1120   
 1121      $sql_ignore_users = ANONYMOUS . ', ' . $user->data['user_id'];
 1122      while ($row = $db->sql_fetchrow($result))
 1123      {
 1124          if (isset($row['ban_userid']))
 1125          {
 1126              $sql_ignore_users .= ', ' . $row['ban_userid'];
 1127          }
 1128      }
 1129      $db->sql_freeresult($result);
 1130   
 1131      $notify_rows = array();
 1132   
 1133      // -- get forum_userids    || topic_userids
 1134      $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
 1135          FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u
 1136          WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . "
 1137              AND w.user_id NOT IN ($sql_ignore_users)
 1138              AND w.notify_status = 0
 1139              AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')
 1140              AND u.user_id = w.user_id';
 1141      $result = $db->sql_query($sql);
 1142   
 1143      while ($row = $db->sql_fetchrow($result))
 1144      {
 1145          $notify_rows[$row['user_id']] = array(
 1146              'user_id'        => $row['user_id'],
 1147              'username'        => $row['username'],
 1148              'user_email'    => $row['user_email'],
 1149              'user_jabber'    => $row['user_jabber'],
 1150              'user_lang'        => $row['user_lang'],
 1151              'notify_type'    => ($topic_notification) ? 'topic' : 'forum',
 1152              'template'        => ($topic_notification) ? 'topic_notify' : 'newtopic_notify',
 1153              'method'        => $row['user_notify_type'],
 1154              'allowed'        => false
 1155          );
 1156      }
 1157      $db->sql_freeresult($result);
 1158   
 1159      // forum notification is sent to those not already receiving topic notifications
 1160      if ($topic_notification)
 1161      {
 1162          if (sizeof($notify_rows))
 1163          {
 1164              $sql_ignore_users .= ', ' . implode(', ', array_keys($notify_rows));
 1165          }
 1166   
 1167          $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
 1168              FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u
 1169              WHERE fw.forum_id = $forum_id
 1170                  AND fw.user_id NOT IN ($sql_ignore_users)
 1171                  AND fw.notify_status = 0
 1172                  AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')
 1173                  AND u.user_id = fw.user_id';
 1174          $result = $db->sql_query($sql);
 1175   
 1176          while ($row = $db->sql_fetchrow($result))
 1177          {
 1178              $notify_rows[$row['user_id']] = array(
 1179                  'user_id'        => $row['user_id'],
 1180                  'username'        => $row['username'],
 1181                  'user_email'    => $row['user_email'],
 1182                  'user_jabber'    => $row['user_jabber'],
 1183                  'user_lang'        => $row['user_lang'],
 1184                  'notify_type'    => 'forum',
 1185                  'template'        => 'forum_notify',
 1186                  'method'        => $row['user_notify_type'],
 1187                  'allowed'        => false
 1188              );
 1189          }
 1190          $db->sql_freeresult($result);
 1191      }
 1192   
 1193      if (!sizeof($notify_rows))
 1194      {
 1195          return;
 1196      }
 1197   
 1198      // Make sure users are allowed to read the forum
 1199      foreach ($auth->acl_get_list(array_keys($notify_rows), 'f_read', $forum_id) as $forum_id => $forum_ary)
 1200      {
 1201          foreach ($forum_ary as $auth_option => $user_ary)
 1202          {
 1203              foreach ($user_ary as $user_id)
 1204              {
 1205                  $notify_rows[$user_id]['allowed'] = true;
 1206              }
 1207          }
 1208      }
 1209   
 1210   
 1211      // Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;)
 1212      $msg_users = $delete_ids = $update_notification = array();
 1213      foreach ($notify_rows as $user_id => $row)
 1214      {
 1215          if (!$row['allowed'] || !trim($row['user_email']))
 1216          {
 1217              $delete_ids[$row['notify_type']][] = $row['user_id'];
 1218          }
 1219          else
 1220          {
 1221              $msg_users[] = $row;
 1222              $update_notification[$row['notify_type']][] = $row['user_id'];
 1223          }
 1224      }
 1225      unset($notify_rows);
 1226   
 1227      // Now, we are able to really send out notifications
 1228      if (sizeof($msg_users))
 1229      {
 1230          include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
 1231          $messenger = new messenger();
 1232   
 1233          $msg_list_ary = array();
 1234          foreach ($msg_users as $row)
 1235          {
 1236              $pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]);
 1237   
 1238              $msg_list_ary[$row['template']][$pos]['method']    = $row['method'];
 1239              $msg_list_ary[$row['template']][$pos]['email']    = $row['user_email'];
 1240              $msg_list_ary[$row['template']][$pos]['jabber']    = $row['user_jabber'];
 1241              $msg_list_ary[$row['template']][$pos]['name']    = $row['username'];
 1242              $msg_list_ary[$row['template']][$pos]['lang']    = $row['user_lang'];
 1243          }
 1244          unset($msg_users);
 1245   
 1246          foreach ($msg_list_ary as $email_template => $email_list)
 1247          {
 1248              foreach ($email_list as $addr)
 1249              {
 1250                  $messenger->template($email_template, $addr['lang']);
 1251   
 1252                  $messenger->to($addr['email'], $addr['name']);
 1253                  $messenger->im($addr['jabber'], $addr['name']);
 1254   
 1255                  $messenger->assign_vars(array(
 1256                      'USERNAME'        => htmlspecialchars_decode($addr['name']),
 1257                      'TOPIC_TITLE'    => htmlspecialchars_decode($topic_title),
 1258                      'FORUM_NAME'    => htmlspecialchars_decode($forum_name),
 1259   
 1260                      'U_FORUM'                => generate_board_url() . "/viewforum.$phpEx?f=$forum_id",
 1261                      'U_TOPIC'                => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id",
 1262                      'U_NEWEST_POST'            => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&p=$post_id&e=$post_id",
 1263                      'U_STOP_WATCHING_TOPIC'    => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&unwatch=topic",
 1264                      'U_STOP_WATCHING_FORUM'    => generate_board_url() . "/viewforum.$phpEx?f=$forum_id&unwatch=forum",
 1265                  ));
 1266   
 1267                  $messenger->send($addr['method']);
 1268              }
 1269          }
 1270          unset($msg_list_ary);
 1271   
 1272          $messenger->save_queue();
 1273      }
 1274   
 1275      // Handle the DB updates
 1276      $db->sql_transaction('begin');
 1277   
 1278      if (!empty($update_notification['topic']))
 1279      {
 1280          $sql = 'UPDATE ' . TOPICS_WATCH_TABLE . "
 1281              SET notify_status = 1
 1282              WHERE topic_id = $topic_id
 1283                  AND " . $db->sql_in_set('user_id', $update_notification['topic']);
 1284          $db->sql_query($sql);
 1285      }
 1286   
 1287      if (!empty($update_notification['forum']))
 1288      {
 1289          $sql = 'UPDATE ' . FORUMS_WATCH_TABLE . "
 1290              SET notify_status = 1
 1291              WHERE forum_id = $forum_id
 1292                  AND " . $db->sql_in_set('user_id', $update_notification['forum']);
 1293          $db->sql_query($sql);
 1294      }
 1295   
 1296      // Now delete the user_ids not authorised to receive notifications on this topic/forum
 1297      if (!empty($delete_ids['topic']))
 1298      {
 1299          $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . "
 1300              WHERE topic_id = $topic_id
 1301                  AND " . $db->sql_in_set('user_id', $delete_ids['topic']);
 1302          $db->sql_query($sql);
 1303      }
 1304   
 1305      if (!empty($delete_ids['forum']))
 1306      {
 1307          $sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . "
 1308              WHERE forum_id = $forum_id
 1309                  AND " . $db->sql_in_set('user_id', $delete_ids['forum']);
 1310          $db->sql_query($sql);
 1311      }
 1312   
 1313      $db->sql_transaction('commit');
 1314  }
 1315   
 1316  //
 1317  // Post handling functions
 1318  //
 1319   
 1320  /**
 1321  * Delete Post
 1322  */
 1323  function delete_post($forum_id, $topic_id, $post_id, &$data)
 1324  {
 1325      global $db, $user, $auth;
 1326      global $config, $phpEx, $phpbb_root_path;
 1327   
 1328      // Specify our post mode
 1329      $post_mode = ($data['topic_first_post_id'] == $data['topic_last_post_id']) ? 'delete_topic' : (($data['topic_first_post_id'] == $post_id) ? 'delete_first_post' : (($data['topic_last_post_id'] == $post_id) ? 'delete_last_post' : 'delete'));
 1330      $sql_data = array();
 1331      $next_post_id = 0;
 1332   
 1333      include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
 1334   
 1335      $db->sql_transaction('begin');
 1336   
 1337      // we must make sure to update forums that contain the shadow'd topic
 1338      if ($post_mode == 'delete_topic')
 1339      {
 1340          $shadow_forum_ids = array();
 1341   
 1342          $sql = 'SELECT forum_id
 1343              FROM ' . TOPICS_TABLE . '
 1344              WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id);
 1345          $result = $db->sql_query($sql);
 1346          while ($row = $db->sql_fetchrow($result))
 1347          {
 1348              if (!isset($shadow_forum_ids[(int) $row['forum_id']]))
 1349              {
 1350                  $shadow_forum_ids[(int) $row['forum_id']] = 1;
 1351              }
 1352              else
 1353              {
 1354                  $shadow_forum_ids[(int) $row['forum_id']]++;
 1355              }
 1356          }
 1357          $db->sql_freeresult($result);
 1358      }
 1359   
 1360      if (!delete_posts('post_id', array($post_id), false, false))
 1361      {
 1362          // Try to delete topic, we may had an previous error causing inconsistency
 1363          if ($post_mode == 'delete_topic')
 1364          {
 1365              delete_topics('topic_id', array($topic_id), false);
 1366          }
 1367          trigger_error('ALREADY_DELETED');
 1368      }
 1369   
 1370      $db->sql_transaction('commit');
 1371   
 1372      // Collect the necessary information for updating the tables
 1373      $sql_data[FORUMS_TABLE] = '';
 1374      switch ($post_mode)
 1375      {
 1376          case 'delete_topic':
 1377   
 1378              foreach ($shadow_forum_ids as $updated_forum => $topic_count)
 1379              {
 1380                  // counting is fun! we only have to do sizeof($forum_ids) number of queries,
 1381                  // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum)
 1382                  $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);
 1383                  update_post_information('forum', $updated_forum);
 1384              }
 1385   
 1386              delete_topics('topic_id', array($topic_id), false);
 1387   
 1388              if ($data['topic_type'] != POST_GLOBAL)
 1389              {
 1390                  $sql_data[FORUMS_TABLE] .= 'forum_topics_real = forum_topics_real - 1';
 1391                  $sql_data[FORUMS_TABLE] .= ($data['topic_approved']) ? ', forum_posts = forum_posts - 1, forum_topics = forum_topics - 1' : '';
 1392              }
 1393   
 1394              $update_sql = update_post_information('forum', $forum_id, true);
 1395              if (sizeof($update_sql))
 1396              {
 1397                  $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : '';
 1398                  $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
 1399              }
 1400          break;
 1401   
 1402          case 'delete_first_post':
 1403              $sql = 'SELECT p.post_id, p.poster_id, p.post_username, u.username, u.user_colour
 1404                  FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
 1405                  WHERE p.topic_id = $topic_id
 1406                      AND p.poster_id = u.user_id
 1407                  ORDER BY p.post_time ASC";
 1408              $result = $db->sql_query_limit($sql, 1);
 1409              $row = $db->sql_fetchrow($result);
 1410              $db->sql_freeresult($result);
 1411   
 1412              if ($data['topic_type'] != POST_GLOBAL)
 1413              {
 1414                  $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
 1415              }
 1416   
 1417              $sql_data[TOPICS_TABLE] = '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'])) . "'";
 1418   
 1419              // 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"
 1420              $sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : '');
 1421   
 1422              $next_post_id = (int) $row['post_id'];
 1423          break;
 1424   
 1425          case 'delete_last_post':
 1426              if ($data['topic_type'] != POST_GLOBAL)
 1427              {
 1428                  $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 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   
 1438              $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' : '');
 1439   
 1440              $update_sql = update_post_information('topic', $topic_id, true);
 1441              if (sizeof($update_sql))
 1442              {
 1443                  $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]);
 1444                  $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]);
 1445              }
 1446              else
 1447              {
 1448                  $sql = 'SELECT MAX(post_id) as last_post_id
 1449                      FROM ' . POSTS_TABLE . "
 1450                      WHERE topic_id = $topic_id " .
 1451                          ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '');
 1452                  $result = $db->sql_query($sql);
 1453                  $row = $db->sql_fetchrow($result);
 1454                  $db->sql_freeresult($result);
 1455   
 1456                  $next_post_id = (int) $row['last_post_id'];
 1457              }
 1458          break;
 1459   
 1460          case 'delete':
 1461              $sql = 'SELECT post_id
 1462                  FROM ' . POSTS_TABLE . "
 1463                  WHERE topic_id = $topic_id " .
 1464                      ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '') . '
 1465                      AND post_time > ' . $data['post_time'] . '
 1466                  ORDER BY post_time ASC';
 1467              $result = $db->sql_query_limit($sql, 1);
 1468              $row = $db->sql_fetchrow($result);
 1469              $db->sql_freeresult($result);
 1470   
 1471              if ($data['topic_type'] != POST_GLOBAL)
 1472              {
 1473                  $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : '';
 1474              }
 1475   
 1476              $sql_data[TOPICS_TABLE] = 'topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : '');
 1477              $next_post_id = (int) $row['post_id'];
 1478          break;
 1479      }
 1480   
 1481  //    $sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : '';
 1482   
 1483      $db->sql_transaction('begin');
 1484   
 1485      $where_sql = array(
 1486          FORUMS_TABLE    => "forum_id = $forum_id",
 1487          TOPICS_TABLE    => "topic_id = $topic_id",
 1488          USERS_TABLE        => 'user_id = ' . $data['poster_id']
 1489      );
 1490   
 1491      foreach ($sql_data as $table => $update_sql)
 1492      {
 1493          if ($update_sql)
 1494          {
 1495              $db->sql_query("UPDATE $table SET $update_sql WHERE " . $where_sql[$table]);
 1496          }
 1497      }
 1498   
 1499      // Adjust posted info for this user by looking for a post by him/her within this topic...
 1500      if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS)
 1501      {
 1502          $sql = 'SELECT poster_id
 1503              FROM ' . POSTS_TABLE . '
 1504              WHERE topic_id = ' . $topic_id . '
 1505                  AND poster_id = ' . $data['poster_id'];
 1506          $result = $db->sql_query_limit($sql, 1);
 1507          $poster_id = (int) $db->sql_fetchfield('poster_id');
 1508          $db->sql_freeresult($result);
 1509   
 1510          // The user is not having any more posts within this topic
 1511          if (!$poster_id)
 1512          {
 1513              $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
 1514                  WHERE topic_id = ' . $topic_id . '
 1515                      AND user_id = ' . $data['poster_id'];
 1516              $db->sql_query($sql);
 1517          }
 1518      }
 1519   
 1520      $db->sql_transaction('commit');
 1521   
 1522      if ($data['post_reported'] && ($post_mode != 'delete_topic'))
 1523      {
 1524          sync('topic_reported', 'topic_id', array($topic_id));
 1525      }
 1526   
 1527      return $next_post_id;
 1528  }
 1529   
 1530  /**
 1531  * Submit Post
 1532  */
 1533  function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true)
 1534  {
 1535      global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
 1536   
 1537      // We do not handle erasing posts here
 1538      if ($mode == 'delete')
 1539      {
 1540          return false;
 1541      }
 1542   
 1543      $current_time = time();
 1544   
 1545      if ($mode == 'post')
 1546      {
 1547          $post_mode = 'post';
 1548          $update_message = true;
 1549      }
 1550      else if ($mode != 'edit')
 1551      {
 1552          $post_mode = 'reply';
 1553          $update_message = true;
 1554      }
 1555      else if ($mode == 'edit')
 1556      {
 1557          $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'));
 1558      }
 1559   
 1560      // First of all make sure the subject and topic title are having the correct length.
 1561      // To achieve this without cutting off between special chars we convert to an array and then count the elements.
 1562      $subject = truncate_string($subject);
 1563      $data['topic_title'] = truncate_string($data['topic_title']);
 1564   
 1565      // Collect some basic information about which tables and which rows to update/insert
 1566      $sql_data = $topic_row = array();
 1567      $poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id'];
 1568   
 1569      // Retrieve some additional information if not present
 1570      if ($mode == 'edit' && (!isset($data['post_approved']) || !isset($data['topic_approved']) || $data['post_approved'] === false || $data['topic_approved'] === false))
 1571      {
 1572          $sql = 'SELECT p.post_approved, t.topic_type, t.topic_replies, t.topic_replies_real, t.topic_approved
 1573              FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
 1574              WHERE t.topic_id = p.topic_id
 1575                  AND p.post_id = ' . $data['post_id'];
 1576          $result = $db->sql_query($sql);
 1577          $topic_row = $db->sql_fetchrow($result);
 1578          $db->sql_freeresult($result);
 1579   
 1580          $data['topic_approved'] = $topic_row['topic_approved'];
 1581          $data['post_approved'] = $topic_row['post_approved'];
 1582      }
 1583   
 1584      // Start the transaction here
 1585      $db->sql_transaction('begin');
 1586   
 1587   
 1588      // Collect Information
 1589      switch ($post_mode)
 1590      {
 1591          case 'post':
 1592          case 'reply':
 1593              $sql_data[POSTS_TABLE]['sql'] = array(
 1594                  'forum_id'            => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
 1595                  'poster_id'            => (int) $user->data['user_id'],
 1596                  'icon_id'            => $data['icon_id'],
 1597                  'poster_ip'            => $user->ip,
 1598                  'post_time'            => $current_time,
 1599                  'post_approved'        => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : 1,
 1600                  'enable_bbcode'        => $data['enable_bbcode'],
 1601                  'enable_smilies'    => $data['enable_smilies'],
 1602                  'enable_magic_url'    => $data['enable_urls'],
 1603                  'enable_sig'        => $data['enable_sig'],
 1604                  'post_username'        => (!$user->data['is_registered']) ? $username : '',
 1605                  'post_subject'        => $subject,
 1606                  'post_text'            => $data['message'],
 1607                  'post_checksum'        => $data['message_md5'],
 1608                  'post_attachment'    => (!empty($data['attachment_data'])) ? 1 : 0,
 1609                  'bbcode_bitfield'    => $data['bbcode_bitfield'],
 1610                  'bbcode_uid'        => $data['bbcode_uid'],
 1611                  'post_postcount'    => ($auth->acl_get('f_postcount', $data['forum_id'])) ? 1 : 0,
 1612                  'post_edit_locked'    => $data['post_edit_locked']
 1613              );
 1614          break;
 1615   
 1616          case 'edit_first_post':
 1617          case 'edit':
 1618   
 1619          case 'edit_last_post':
 1620          case 'edit_topic':
 1621   
 1622              // If edit reason is given always display edit info
 1623   
 1624              // If editing last post then display no edit info
 1625              // If m_edit permission then display no edit info
 1626              // If normal edit display edit info
 1627   
 1628              // Display edit info if edit reason given or user is editing his post, which is not the last within the topic.
 1629              if ($data['post_edit_reason'] || (!$auth->acl_get('m_edit', $data['forum_id']) && ($post_mode == 'edit' || $post_mode == 'edit_first_post')))
 1630              {
 1631                  $data['post_edit_reason']        = truncate_string($data['post_edit_reason'], 255, false);
 1632   
 1633                  $sql_data[POSTS_TABLE]['sql']    = array(
 1634                      'post_edit_time'    => $current_time,
 1635                      'post_edit_reason'    => $data['post_edit_reason'],
 1636                      'post_edit_user'    => (int) $data['post_edit_user'],
 1637                  );
 1638   
 1639                  $sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
 1640              }
 1641              else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id']))
 1642              {
 1643                  $sql_data[POSTS_TABLE]['sql'] = array(
 1644                      'post_edit_reason'    => '',
 1645                  );
 1646              }
 1647   
 1648              // If the person editing this post is different to the one having posted then we will add a log entry stating the edit
 1649              // Could be simplified by only adding to the log if the edit is not tracked - but this may confuse admins/mods
 1650              if ($user->data['user_id'] != $poster_id)
 1651              {
 1652                  $log_subject = ($subject) ? $subject : $data['topic_title'];
 1653                  add_log('mod', $data['forum_id'], $data['topic_id'], 'LOG_POST_EDITED', $log_subject, (!empty($username)) ? $username : $user->lang['GUEST']);
 1654              }
 1655   
 1656              if (!isset($sql_data[POSTS_TABLE]['sql']))
 1657              {
 1658                  $sql_data[POSTS_TABLE]['sql'] = array();
 1659              }
 1660   
 1661              $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
 1662                  'forum_id'            => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
 1663                  'poster_id'            => $data['poster_id'],
 1664                  'icon_id'            => $data['icon_id'],
 1665                  'post_approved'        => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : $data['post_approved'],
 1666                  'enable_bbcode'        => $data['enable_bbcode'],
 1667                  'enable_smilies'    => $data['enable_smilies'],
 1668                  'enable_magic_url'    => $data['enable_urls'],
 1669                  'enable_sig'        => $data['enable_sig'],
 1670                  'post_username'        => ($username && $data['poster_id'] == ANONYMOUS) ? $username : '',
 1671                  'post_subject'        => $subject,
 1672                  'post_checksum'        => $data['message_md5'],
 1673                  'post_attachment'    => (!empty($data['attachment_data'])) ? 1 : 0,
 1674                  'bbcode_bitfield'    => $data['bbcode_bitfield'],
 1675                  'bbcode_uid'        => $data['bbcode_uid'],
 1676                  'post_edit_locked'    => $data['post_edit_locked'])
 1677              );
 1678   
 1679              if ($update_message)
 1680              {
 1681                  $sql_data[POSTS_TABLE]['sql']['post_text'] = $data['message'];
 1682              }
 1683   
 1684          break;
 1685      }
 1686   
 1687      $post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved'];
 1688      $topic_row = array();
 1689   
 1690      // And the topic ladies and gentlemen
 1691      switch ($post_mode)
 1692      {
 1693          case 'post':
 1694              $sql_data[TOPICS_TABLE]['sql'] = array(
 1695                  'topic_poster'                => (int) $user->data['user_id'],
 1696                  'topic_time'                => $current_time,
 1697                  'forum_id'                    => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
 1698                  'icon_id'                    => $data['icon_id'],
 1699                  'topic_approved'            => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : 1,
 1700                  'topic_title'                => $subject,
 1701                  'topic_first_poster_name'    => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
 1702                  'topic_first_poster_colour'    => $user->data['user_colour'],
 1703                  'topic_type'                => $topic_type,
 1704                  'topic_time_limit'            => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
 1705                  'topic_attachment'            => (!empty($data['attachment_data'])) ? 1 : 0,
 1706              );
 1707   
 1708              if (isset($poll['poll_options']) && !empty($poll['poll_options']))
 1709              {
 1710                  $sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array(
 1711                      'poll_title'        => $poll['poll_title'],
 1712                      'poll_start'        => ($poll['poll_start']) ? $poll['poll_start'] : $current_time,
 1713                      'poll_max_options'    => $poll['poll_max_options'],
 1714                      'poll_length'        => ($poll['poll_length'] * 86400),
 1715                      'poll_vote_change'    => $poll['poll_vote_change'])
 1716                  );
 1717              }
 1718   
 1719              $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
 1720      
 1721              if ($topic_type != POST_GLOBAL)
 1722              {
 1723                  if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
 1724                  {
 1725                      $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
 1726                  }
 1727                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) ? ', forum_topics = forum_topics + 1' : '');
 1728              }
 1729          break;
 1730   
 1731          case 'reply':
 1732              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0' . (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) ? ', topic_replies = topic_replies + 1' : '') . ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : '');
 1733   
 1734              $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id'])) ? ', user_posts = user_posts + 1' : '');
 1735   
 1736              if (($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])) && $topic_type != POST_GLOBAL)
 1737              {
 1738                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
 1739              }
 1740          break;
 1741   
 1742          case 'edit_topic':
 1743          case 'edit_first_post':
 1744   
 1745              $sql_data[TOPICS_TABLE]['sql'] = array(
 1746                  'forum_id'                    => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
 1747                  'icon_id'                    => $data['icon_id'],
 1748                  'topic_approved'            => (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) ? 0 : $data['topic_approved'],
 1749                  'topic_title'                => $subject,
 1750                  'topic_first_poster_name'    => $username,
 1751                  'topic_type'                => $topic_type,
 1752                  'topic_time_limit'            => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
 1753                  'poll_title'                => (isset($poll['poll_options'])) ? $poll['poll_title'] : '',
 1754                  'poll_start'                => (isset($poll['poll_options'])) ? (($poll['poll_start']) ? $poll['poll_start'] : $current_time) : 0,
 1755                  'poll_max_options'            => (isset($poll['poll_options'])) ? $poll['poll_max_options'] : 1,
 1756                  'poll_length'                => (isset($poll['poll_options'])) ? ($poll['poll_length'] * 86400) : 0,
 1757                  'poll_vote_change'            => (isset($poll['poll_vote_change'])) ? $poll['poll_vote_change'] : 0,
 1758   
 1759                  'topic_attachment'            => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0),
 1760              );
 1761   
 1762              // Correctly set back the topic replies and forum posts... only if the topic was approved before and now gets disapproved
 1763              if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id']) && $data['topic_approved'])
 1764              {
 1765                  // Do we need to grab some topic informations?
 1766                  if (!sizeof($topic_row))
 1767                  {
 1768                      $sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved
 1769                          FROM ' . TOPICS_TABLE . '
 1770                          WHERE topic_id = ' . $data['topic_id'];
 1771                      $result = $db->sql_query($sql);
 1772                      $topic_row = $db->sql_fetchrow($result);
 1773                      $db->sql_freeresult($result);
 1774                  }
 1775   
 1776                  // If this is the only post remaining we do not need to decrement topic_replies.
 1777                  // Also do not decrement if first post - then the topic_replies will not be adjusted if approving the topic again.
 1778   
 1779                  // If this is an edited topic or the first post the topic gets completely disapproved later on...
 1780                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1';
 1781                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1);
 1782   
 1783                  set_config('num_topics', $config['num_topics'] - 1, true);
 1784                  set_config('num_posts', $config['num_posts'] - ($topic_row['topic_replies'] + 1), true);
 1785              }
 1786   
 1787          break;
 1788   
 1789          case 'edit':
 1790          case 'edit_last_post':
 1791   
 1792              // Correctly set back the topic replies and forum posts... but only if the post was approved before.
 1793              if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id']) && $data['post_approved'])
 1794              {
 1795                  $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1';
 1796                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1';
 1797   
 1798                  set_config('num_posts', $config['num_posts'] - 1, true);
 1799              }
 1800   
 1801          break;
 1802      }
 1803   
 1804      // Submit new topic
 1805      if ($post_mode == 'post')
 1806      {
 1807          $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
 1808              $db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
 1809          $db->sql_query($sql);
 1810   
 1811          $data['topic_id'] = $db->sql_nextid();
 1812   
 1813          $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
 1814              'topic_id' => $data['topic_id'])
 1815          );
 1816          unset($sql_data[TOPICS_TABLE]['sql']);
 1817      }
 1818   
 1819      // Submit new post
 1820      if ($post_mode == 'post' || $post_mode == 'reply')
 1821      {
 1822          if ($post_mode == 'reply')
 1823          {
 1824              $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
 1825                  'topic_id' => $data['topic_id'])
 1826              );
 1827          }
 1828   
 1829          $sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']);
 1830          $db->sql_query($sql);
 1831          $data['post_id'] = $db->sql_nextid();
 1832   
 1833          if ($post_mode == 'post')
 1834          {
 1835              $sql_data[TOPICS_TABLE]['sql'] = array(
 1836                  'topic_first_post_id'        => $data['post_id'],
 1837                  'topic_last_post_id'        => $data['post_id'],
 1838                  'topic_last_post_time'        => $current_time,
 1839                  'topic_last_poster_id'        => (int) $user->data['user_id'],
 1840                  'topic_last_poster_name'    => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
 1841                  'topic_last_poster_colour'    => $user->data['user_colour'],
 1842              );
 1843          }
 1844   
 1845          unset($sql_data[POSTS_TABLE]['sql']);
 1846      }
 1847   
 1848      $make_global = false;
 1849   
 1850      // Are we globalising or unglobalising?
 1851      if ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic')
 1852      {
 1853          if (!sizeof($topic_row))
 1854          {
 1855              $sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved, topic_last_post_id
 1856                  FROM ' . TOPICS_TABLE . '
 1857                  WHERE topic_id = ' . $data['topic_id'];
 1858              $result = $db->sql_query($sql);
 1859              $topic_row = $db->sql_fetchrow($result);
 1860              $db->sql_freeresult($result);
 1861          }
 1862   
 1863          // globalise/unglobalise?
 1864          if (($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL) || ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL))
 1865          {
 1866              if (!empty($sql_data[FORUMS_TABLE]['stat']) && implode('', $sql_data[FORUMS_TABLE]['stat']))
 1867              {
 1868                  $db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET ' . implode(', ', $sql_data[FORUMS_TABLE]['stat']) . ' WHERE forum_id = ' . $data['forum_id']);
 1869              }
 1870   
 1871              $make_global = true;
 1872              $sql_data[FORUMS_TABLE]['stat'] = array();
 1873          }
 1874   
 1875          // globalise
 1876          if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL)
 1877          {
 1878              // Decrement topic/post count
 1879              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies_real'] + 1);
 1880              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real - 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics - 1' : '');
 1881   
 1882              // Update forum_ids for all posts
 1883              $sql = 'UPDATE ' . POSTS_TABLE . '
 1884                  SET forum_id = 0
 1885                  WHERE topic_id = ' . $data['topic_id'];
 1886              $db->sql_query($sql);
 1887          }
 1888          // unglobalise
 1889          else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL)
 1890          {
 1891              // Increment topic/post count
 1892              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + ' . ($topic_row['topic_replies_real'] + 1);
 1893              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($topic_row['topic_approved']) ? ', forum_topics = forum_topics + 1' : '');
 1894   
 1895              // Update forum_ids for all posts
 1896              $sql = 'UPDATE ' . POSTS_TABLE . '
 1897                  SET forum_id = ' . $data['forum_id'] . '
 1898                  WHERE topic_id = ' . $data['topic_id'];
 1899              $db->sql_query($sql);
 1900          }
 1901      }
 1902   
 1903      // Update the topics table
 1904      if (isset($sql_data[TOPICS_TABLE]['sql']))
 1905      {
 1906          $sql = 'UPDATE ' . TOPICS_TABLE . '
 1907              SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . '
 1908              WHERE topic_id = ' . $data['topic_id'];
 1909          $db->sql_query($sql);
 1910      }
 1911   
 1912      // Update the posts table
 1913      if (isset($sql_data[POSTS_TABLE]['sql']))
 1914      {
 1915          $sql = 'UPDATE ' . POSTS_TABLE . '
 1916              SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . '
 1917              WHERE post_id = ' . $data['post_id'];
 1918          $db->sql_query($sql);
 1919      }
 1920   
 1921      // Update Poll Tables
 1922      if (isset($poll['poll_options']) && !empty($poll['poll_options']))
 1923      {
 1924          $cur_poll_options = array();
 1925   
 1926          if ($poll['poll_start'] && $mode == 'edit')
 1927          {
 1928              $sql = 'SELECT *
 1929                  FROM ' . POLL_OPTIONS_TABLE . '
 1930                  WHERE topic_id = ' . $data['topic_id'] . '
 1931                  ORDER BY poll_option_id';
 1932              $result = $db->sql_query($sql);
 1933   
 1934              $cur_poll_options = array();
 1935              while ($row = $db->sql_fetchrow($result))
 1936              {
 1937                  $cur_poll_options[] = $row;
 1938              }
 1939              $db->sql_freeresult($result);
 1940          }
 1941   
 1942          $sql_insert_ary = array();
 1943          
 1944          for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++)
 1945          {
 1946              if (strlen(trim($poll['poll_options'][$i])))
 1947              {
 1948                  if (empty($cur_poll_options[$i]))
 1949                  {
 1950                      // If we add options we need to put them to the end to be able to preserve votes...
 1951                      $sql_insert_ary[] = array(
 1952                          'poll_option_id'    => (int) sizeof($cur_poll_options) + 1 + sizeof($sql_insert_ary),
 1953                          'topic_id'            => (int) $data['topic_id'],
 1954                          'poll_option_text'    => (string) $poll['poll_options'][$i]
 1955                      );
 1956                  }
 1957                  else if ($poll['poll_options'][$i] != $cur_poll_options[$i])
 1958                  {
 1959                      $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
 1960                          SET poll_option_text = '" . $db->sql_escape($poll['poll_options'][$i]) . "'
 1961                          WHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . '
 1962                              AND topic_id = ' . $data['topic_id'];
 1963                      $db->sql_query($sql);
 1964                  }
 1965              }
 1966          }
 1967   
 1968          $db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);
 1969   
 1970          if (sizeof($poll['poll_options']) < sizeof($cur_poll_options))
 1971          {
 1972              $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
 1973                  WHERE poll_option_id > ' . sizeof($poll['poll_options']) . '
 1974                      AND topic_id = ' . $data['topic_id'];
 1975              $db->sql_query($sql);
 1976          }
 1977   
 1978          // 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
 1979          if ($mode == 'edit' && sizeof($poll['poll_options']) != sizeof($cur_poll_options))
 1980          {
 1981              $db->sql_query('DELETE FROM ' . POLL_VOTES_TABLE . ' WHERE topic_id = ' . $data['topic_id']);
 1982              $db->sql_query('UPDATE ' . POLL_OPTIONS_TABLE . ' SET poll_option_total = 0 WHERE topic_id = ' . $data['topic_id']);
 1983          }
 1984      }
 1985   
 1986      // Submit Attachments
 1987      if (!empty($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit')))
 1988      {
 1989          $space_taken = $files_added = 0;
 1990          $orphan_rows = array();
 1991   
 1992          foreach ($data['attachment_data'] as $pos => $attach_row)
 1993          {
 1994              $orphan_rows[(int) $attach_row['attach_id']] = array();
 1995          }
 1996   
 1997          if (sizeof($orphan_rows))
 1998          {
 1999              $sql = 'SELECT attach_id, filesize, physical_filename
 2000                  FROM ' . ATTACHMENTS_TABLE . '
 2001                  WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
 2002                      AND is_orphan = 1
 2003                      AND poster_id = ' . $user->data['user_id'];
 2004              $result = $db->sql_query($sql);
 2005   
 2006              $orphan_rows = array();
 2007              while ($row = $db->sql_fetchrow($result))
 2008              {
 2009                  $orphan_rows[$row['attach_id']] = $row;
 2010              }
 2011              $db->sql_freeresult($result);
 2012          }
 2013   
 2014          foreach ($data['attachment_data'] as $pos => $attach_row)
 2015          {
 2016              if ($attach_row['is_orphan'] && !in_array($attach_row['attach_id'], array_keys($orphan_rows)))
 2017              {
 2018                  continue;
 2019              }
 2020   
 2021              if (!$attach_row['is_orphan'])
 2022              {
 2023                  // update entry in db if attachment already stored in db and filespace
 2024                  $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
 2025                      SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
 2026                      WHERE attach_id = " . (int) $attach_row['attach_id'] . '
 2027                          AND is_orphan = 0';
 2028                  $db->sql_query($sql);
 2029              }
 2030              else
 2031              {
 2032                  // insert attachment into db
 2033                  if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
 2034                  {
 2035                      continue;
 2036                  }
 2037   
 2038                  $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
 2039                  $files_added++;
 2040   
 2041                  $attach_sql = array(
 2042                      'post_msg_id'        => $data['post_id'],
 2043                      'topic_id'            => $data['topic_id'],
 2044                      'is_orphan'            => 0,
 2045                      'poster_id'            => $poster_id,
 2046                      'attach_comment'    => $attach_row['attach_comment'],
 2047                  );
 2048   
 2049                  $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
 2050                      WHERE attach_id = ' . $attach_row['attach_id'] . '
 2051                          AND is_orphan = 1
 2052                          AND poster_id = ' . $user->data['user_id'];
 2053                  $db->sql_query($sql);
 2054              }
 2055          }
 2056   
 2057          if ($space_taken && $files_added)
 2058          {
 2059              set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
 2060              set_config('num_files', $config['num_files'] + $files_added, true);
 2061          }
 2062      }
 2063   
 2064      // we need to update the last forum information
 2065      // only applicable if the topic is not global and it is approved
 2066      // we also check to make sure we are not dealing with globaling the latest topic (pretty rare but still needs to be checked)
 2067      if ($topic_type != POST_GLOBAL && !$make_global && ($post_approved || !$data['post_approved']))
 2068      {
 2069          // the last post makes us update the forum table. This can happen if...
 2070          // We make a new topic
 2071          // We reply to a topic
 2072          // We edit the last post in a topic and this post is the latest in the forum (maybe)
 2073          // We edit the only post in the topic
 2074          // We edit the first post in the topic and all the other posts are not approved
 2075          if (($post_mode == 'post' || $post_mode == 'reply') && $post_approved)
 2076          {
 2077              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id'];
 2078              $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'";
 2079              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time;
 2080              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id'];
 2081              $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'] : '')) . "'";
 2082              $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'";
 2083          }
 2084          else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
 2085          {
 2086              // this does not _necessarily_ mean that we must update the info again,
 2087              // it just means that we might have to
 2088              $sql = 'SELECT forum_last_post_id, forum_last_post_subject
 2089                  FROM ' . FORUMS_TABLE . '
 2090                  WHERE forum_id = ' . (int) $data['forum_id'];
 2091              $result = $db->sql_query($sql);
 2092              $row = $db->sql_fetchrow($result);
 2093              $db->sql_freeresult($result);
 2094   
 2095              // this post is the latest post in the forum, better update
 2096              if ($row['forum_last_post_id'] == $data['post_id'])
 2097              {
 2098                  if ($post_approved && $row['forum_last_post_subject'] !== $subject)
 2099                  {
 2100                      // the only data that can really be changed is the post's subject
 2101                      $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_subject = \'' . $db->sql_escape($subject) . '\'';
 2102                  }
 2103                  else if ($data['post_approved'] !== $post_approved)
 2104                  {
 2105                      // we need a fresh change of socks, everything has become invalidated
 2106                      $sql = 'SELECT MAX(topic_last_post_id) as last_post_id
 2107                          FROM ' . TOPICS_TABLE . '
 2108                          WHERE forum_id = ' . (int) $data['forum_id'] . '
 2109                              AND topic_approved = 1';
 2110                      $result = $db->sql_query($sql);
 2111                      $row = $db->sql_fetchrow($result);
 2112                      $db->sql_freeresult($result);
 2113   
 2114                      // any posts left in this forum?
 2115                      if (!empty($row['last_post_id']))
 2116                      {
 2117                          $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
 2118                              FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 2119                              WHERE p.poster_id = u.user_id
 2120                                  AND p.post_id = ' . (int) $row['last_post_id'];
 2121                          $result = $db->sql_query($sql);
 2122                          $row = $db->sql_fetchrow($result);
 2123                          $db->sql_freeresult($result);
 2124   
 2125                          // salvation, a post is found! jam it into the forums table
 2126                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
 2127                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
 2128                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
 2129                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
 2130                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
 2131                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
 2132                      }
 2133                      else
 2134                      {
 2135                          // just our luck, the last topic in the forum has just been turned unapproved...
 2136                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
 2137                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
 2138                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
 2139                          $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
 2140                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
 2141                          $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
 2142                      }
 2143                  }
 2144              }
 2145          }
 2146      }
 2147      else if ($make_global)
 2148      {
 2149          // somebody decided to be a party pooper, we must recalculate the whole shebang (maybe)
 2150          $sql = 'SELECT forum_last_post_id
 2151              FROM ' . FORUMS_TABLE . '
 2152              WHERE forum_id = ' . (int) $data['forum_id'];
 2153          $result = $db->sql_query($sql);
 2154          $forum_row = $db->sql_fetchrow($result);
 2155          $db->sql_freeresult($result);
 2156   
 2157          // we made a topic global, go get new data
 2158          if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL && $forum_row['forum_last_post_id'] == $topic_row['topic_last_post_id'])
 2159          {
 2160              // we need a fresh change of socks, everything has become invalidated
 2161              $sql = 'SELECT MAX(topic_last_post_id) as last_post_id
 2162                  FROM ' . TOPICS_TABLE . '
 2163                  WHERE forum_id = ' . (int) $data['forum_id'] . '
 2164                      AND topic_approved = 1';
 2165              $result = $db->sql_query($sql);
 2166              $row = $db->sql_fetchrow($result);
 2167              $db->sql_freeresult($result);
 2168   
 2169              // any posts left in this forum?
 2170              if (!empty($row['last_post_id']))
 2171              {
 2172                  $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
 2173                      FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 2174                      WHERE p.poster_id = u.user_id
 2175                          AND p.post_id = ' . (int) $row['last_post_id'];
 2176                  $result = $db->sql_query($sql);
 2177                  $row = $db->sql_fetchrow($result);
 2178                  $db->sql_freeresult($result);
 2179   
 2180                  // salvation, a post is found! jam it into the forums table
 2181                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
 2182                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
 2183                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
 2184                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
 2185                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
 2186                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
 2187              }
 2188              else
 2189              {
 2190                  // just our luck, the last topic in the forum has just been globalized...
 2191                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
 2192                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
 2193                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
 2194                  $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
 2195                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
 2196                  $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
 2197              }
 2198          }
 2199          else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL && $forum_row['forum_last_post_id'] < $topic_row['topic_last_post_id'])
 2200          {
 2201              // this post has a higher id, it is newer
 2202              $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
 2203                  FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 2204                  WHERE p.poster_id = u.user_id
 2205                      AND p.post_id = ' . (int) $topic_row['topic_last_post_id'];
 2206              $result = $db->sql_query($sql);
 2207              $row = $db->sql_fetchrow($result);
 2208              $db->sql_freeresult($result);
 2209   
 2210              // salvation, a post is found! jam it into the forums table
 2211              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
 2212              $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
 2213              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
 2214              $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
 2215              $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
 2216              $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
 2217          }
 2218      }
 2219   
 2220      // topic sync time!
 2221      // simply, we update if it is a reply or the last post is edited
 2222      if ($post_approved)
 2223      {
 2224          // reply requires the whole thing
 2225          if ($post_mode == 'reply')
 2226          {
 2227              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $data['post_id'];
 2228              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $user->data['user_id'];
 2229              $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'] : '')) . "'";
 2230              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . (($user->data['user_id'] != ANONYMOUS) ? $db->sql_escape($user->data['user_colour']) : '') . "'";
 2231              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
 2232              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $current_time;
 2233          }
 2234          else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
 2235          {
 2236              // only the subject can be changed from edit
 2237              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'";
 2238          }
 2239      }
 2240      else if (!$data['post_approved'] && ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])))
 2241      {
 2242          // like having the rug pulled from under us
 2243          $sql = 'SELECT MAX(post_id) as last_post_id
 2244              FROM ' . POSTS_TABLE . '
 2245              WHERE topic_id = ' . (int) $data['topic_id'] . '
 2246                  AND post_approved = 1';
 2247          $result = $db->sql_query($sql);
 2248          $row = $db->sql_fetchrow($result);
 2249          $db->sql_freeresult($result);
 2250   
 2251          // any posts left in this forum?
 2252          if (!empty($row['last_post_id']))
 2253          {
 2254              $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
 2255                  FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
 2256                  WHERE p.poster_id = u.user_id
 2257                      AND p.post_id = ' . (int) $row['last_post_id'];
 2258              $result = $db->sql_query($sql);
 2259              $row = $db->sql_fetchrow($result);
 2260              $db->sql_freeresult($result);
 2261   
 2262              // salvation, a post is found! jam it into the topics table
 2263              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $row['post_id'];
 2264              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
 2265              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $row['post_time'];
 2266              $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $row['poster_id'];
 2267              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
 2268              $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
 2269          }
 2270      }
 2271   
 2272      // Update total post count, do not consider moderated posts/topics
 2273      if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
 2274      {
 2275          if ($post_mode == 'post')
 2276          {
 2277              set_config('num_topics', $config['num_topics'] + 1, true);
 2278              set_config('num_posts', $config['num_posts'] + 1, true);
 2279          }
 2280   
 2281          if ($post_mode == 'reply')
 2282          {
 2283              set_config('num_posts', $config['num_posts'] + 1, true);
 2284          }
 2285      }
 2286   
 2287      // Update forum stats
 2288      $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 = ' . $user->data['user_id']);
 2289   
 2290      foreach ($sql_data as $table => $update_ary)
 2291      {
 2292          if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
 2293          {
 2294              $sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
 2295              $db->sql_query($sql);
 2296          }
 2297      }
 2298   
 2299      // Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
 2300      if ($make_global)
 2301      {
 2302          $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 2303              WHERE topic_moved_id = ' . $data['topic_id'];
 2304          $db->sql_query($sql);
 2305      }
 2306   
 2307      // Committing the transaction before updating search index
 2308      $db->sql_transaction('commit');
 2309   
 2310      // Delete draft if post was loaded...
 2311      $draft_id = request_var('draft_loaded', 0);
 2312      if ($draft_id)
 2313      {
 2314          $sql = 'DELETE FROM ' . DRAFTS_TABLE . "
 2315              WHERE draft_id = $draft_id
 2316                  AND user_id = {$user->data['user_id']}";
 2317          $db->sql_query($sql);
 2318      }
 2319   
 2320      // Index message contents
 2321      if ($update_message && $data['enable_indexing'])
 2322      {
 2323          // Select the search method and do some additional checks to ensure it can actually be utilised
 2324          $search_type = basename($config['search_type']);
 2325   
 2326          if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
 2327          {
 2328              trigger_error('NO_SUCH_SEARCH_MODULE');
 2329          }
 2330   
 2331          if (!class_exists($search_type))
 2332          {
 2333              include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
 2334          }
 2335   
 2336          $error = false;
 2337          $search = new $search_type($error);
 2338   
 2339          if ($error)
 2340          {
 2341              trigger_error($error);
 2342          }
 2343   
 2344          $search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']);
 2345      }
 2346   
 2347      // Topic Notification, do not change if moderator is changing other users posts...
 2348      if ($user->data['user_id'] == $poster_id)
 2349      {
 2350          if (!$data['notify_set'] && $data['notify'])
 2351          {
 2352              $sql = 'INSERT INTO ' . TOPICS_WATCH_TABLE . ' (user_id, topic_id)
 2353                  VALUES (' . $user->data['user_id'] . ', ' . $data['topic_id'] . ')';
 2354              $db->sql_query($sql);
 2355          }
 2356          else if ($data['notify_set'] && !$data['notify'])
 2357          {
 2358              $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . '
 2359                  WHERE user_id = ' . $user->data['user_id'] . '
 2360                      AND topic_id = ' . $data['topic_id'];
 2361              $db->sql_query($sql);
 2362          }
 2363      }
 2364   
 2365      if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
 2366      {
 2367          // Mark this topic as posted to
 2368          markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
 2369      }
 2370   
 2371      // Mark this topic as read
 2372      // We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
 2373      markread('topic', $data['forum_id'], $data['topic_id'], time());
 2374   
 2375      //
 2376      if ($config['load_db_lastread'] && $user->data['is_registered'])
 2377      {
 2378          $sql = 'SELECT mark_time
 2379              FROM ' . FORUMS_TRACK_TABLE . '
 2380              WHERE user_id = ' . $user->data['user_id'] . '
 2381                  AND forum_id = ' . $data['forum_id'];
 2382          $result = $db->sql_query($sql);
 2383          $f_mark_time = (int) $db->sql_fetchfield('mark_time');
 2384          $db->sql_freeresult($result);
 2385      }
 2386      else if ($config['load_anon_lastread'] || $user->data['is_registered'])
 2387      {
 2388          $f_mark_time = false;
 2389      }
 2390   
 2391      if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
 2392      {
 2393          // Update forum info
 2394          $sql = 'SELECT forum_last_post_time
 2395              FROM ' . FORUMS_TABLE . '
 2396              WHERE forum_id = ' . $data['forum_id'];
 2397          $result = $db->sql_query($sql);
 2398          $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
 2399          $db->sql_freeresult($result);
 2400   
 2401          update_forum_tracking_info($data['forum_id'], $forum_last_post_time, $f_mark_time, false);
 2402      }
 2403   
 2404      // Send Notifications
 2405      if ($mode != 'edit' && $mode != 'delete' && ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id'])))
 2406      {
 2407          user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
 2408      }
 2409   
 2410      $params = $add_anchor = '';
 2411   
 2412      if ($auth->acl_get('f_noapprove', $data['forum_id']) || $auth->acl_get('m_approve', $data['forum_id']))
 2413      {
 2414          $params .= '&amp;t=' . $data['topic_id'];
 2415   
 2416          if ($mode != 'post')
 2417          {
 2418              $params .= '&amp;p=' . $data['post_id'];
 2419              $add_anchor = '#p' . $data['post_id'];
 2420          }
 2421      }
 2422      else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic')
 2423      {
 2424          $params .= '&amp;t=' . $data['topic_id'];
 2425      }
 2426   
 2427      $url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
 2428      $url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;
 2429   
 2430      return $url;
 2431  }
 2432   
 2433  ?>