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  ?>