[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/ -> functions_admin.php (source)

   1  <?php
   2  /** 
   3  *
   4  * @package acp
   5  * @version $Id: functions_admin.php,v 1.186 2006/11/03 23:09:15 davidmj Exp $
   6  * @copyright (c) 2005 phpBB Group 
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License 
   8  *
   9  */
  10  
  11  /**
  12  * Recalculate Binary Tree
  13  function recalc_btree($sql_id, $sql_table, $module_class = '')
  14  {
  15      global $db;
  16  
  17      if (!$sql_id || !$sql_table)
  18      {
  19          return;
  20      }
  21  
  22      $sql_where = ($module_class) ? " WHERE module_class = '" . $db->sql_escape($module_class) . "'" : '';
  23  
  24      // Reset to minimum possible left and right id
  25      $sql = "SELECT MIN(left_id) as min_left_id, MIN(right_id) as min_right_id
  26          FROM $sql_table
  27          $sql_where";
  28      $result = $db->sql_query($sql);
  29      $row = $db->sql_fetchrow($result);
  30      $db->sql_freeresult($result);
  31  
  32      $substract = (int) (min($row['min_left_id'], $row['min_right_id']) - 1);
  33  
  34      if ($substract > 0)
  35      {
  36          $sql = "UPDATE $sql_table 
  37              SET left_id = left_id - $substract, right_id = right_id - $substract
  38              $sql_where";
  39          $db->sql_query($sql);
  40      }
  41  
  42      $sql = "SELECT $sql_id, parent_id, left_id, right_id 
  43          FROM $sql_table
  44          $sql_where
  45          ORDER BY left_id ASC, parent_id ASC, $sql_id ASC";
  46      $f_result = $db->sql_query($sql);
  47  
  48      while ($item_data = $db->sql_fetchrow($f_result))
  49      {
  50          if ($item_data['parent_id'])
  51          {
  52              $sql = "SELECT left_id, right_id
  53                  FROM $sql_table
  54                  $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
  55                      $sql_id = {$item_data['parent_id']}";
  56              $result = $db->sql_query($sql);
  57  
  58              if (!$row = $db->sql_fetchrow($result))
  59              {
  60                  $sql = "UPDATE $sql_table SET parent_id = 0 WHERE $sql_id = " . $item_data[$sql_id];
  61                  $db->sql_query($sql);
  62              }
  63              $db->sql_freeresult($result);
  64  
  65              $sql = "UPDATE $sql_table
  66                  SET left_id = left_id + 2, right_id = right_id + 2
  67                  $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
  68                      left_id > {$row['right_id']}";
  69              $db->sql_query($sql);
  70  
  71              $sql = "UPDATE $sql_table
  72                  SET right_id = right_id + 2
  73                  $sql_where " . (($sql_where) ? 'AND' : 'WHERE') . "
  74                      {$row['left_id']} BETWEEN left_id AND right_id";
  75              $db->sql_query($sql);
  76  
  77              $item_data['left_id'] = $row['right_id'];
  78              $item_data['right_id'] = $row['right_id'] + 1;
  79          }
  80          else
  81          {
  82              $sql = "SELECT MAX(right_id) AS right_id
  83                  FROM $sql_table
  84                  $sql_where";
  85              $result = $db->sql_query($sql);
  86              $row = $db->sql_fetchrow($result);
  87              $db->sql_freeresult($result);
  88  
  89              $item_data['left_id'] = $row['right_id'] + 1;
  90              $item_data['right_id'] = $row['right_id'] + 2;
  91          }
  92      
  93          $sql = "UPDATE $sql_table
  94              SET left_id = {$item_data['left_id']}, right_id = {$item_data['right_id']}
  95              WHERE $sql_id = " . $item_data[$sql_id];
  96          $db->sql_query($sql);
  97      }
  98      $db->sql_freeresult($f_result);
  99  }
 100  */
 101  
 102  /**
 103  * Simple version of jumpbox, just lists authed forums
 104  */
 105  function make_forum_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $only_acl_post = false, $return_array = false)
 106  {
 107      global $db, $user, $auth;
 108  
 109      $acl = ($ignore_acl) ? '' : (($only_acl_post) ? 'f_post' : array('f_list', 'a_forum', 'a_forumadd', 'a_forumdel'));
 110  
 111      // This query is identical to the jumpbox one
 112      $sql = 'SELECT forum_id, parent_id, forum_name, forum_type, forum_status, left_id, right_id
 113          FROM ' . FORUMS_TABLE . '
 114          ORDER BY left_id ASC';
 115      $result = $db->sql_query($sql);
 116  
 117      $right = $iteration = 0;
 118      $padding_store = array('0' => '');
 119      $padding = '';
 120      $forum_list = ($return_array) ? array() : '';
 121  
 122      // Sometimes it could happen that forums will be displayed here not be displayed within the index page
 123      // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions.
 124      // If this happens, the padding could be "broken"
 125  
 126      while ($row = $db->sql_fetchrow($result))
 127      {
 128          if ($row['left_id'] < $right)
 129          {
 130              $padding .= '&nbsp; &nbsp;';
 131              $padding_store[$row['parent_id']] = $padding;
 132          }
 133          else if ($row['left_id'] > $right + 1)
 134          {
 135              $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
 136          }
 137  
 138          $right = $row['right_id'];
 139  
 140          if ($acl && !$auth->acl_gets($acl, $row['forum_id']))
 141          {
 142              continue;
 143          }
 144  
 145          if ((is_array($ignore_id) && in_array($row['forum_id'], $ignore_id)) || $row['forum_id'] == $ignore_id)
 146          {
 147              continue;
 148          }
 149  
 150          if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
 151          {
 152              // Non-postable forum with no subforums, don't display
 153              continue;
 154          }
 155  
 156          if ($row['forum_type'] != FORUM_POST && $ignore_nonpost)
 157          {
 158              continue;
 159          }
 160  
 161          if ($return_array)
 162          {
 163              // Include some more informations...
 164              $selected = (is_array($select_id)) ? ((in_array($row['forum_id'], $select_id)) ? true : false) : (($row['forum_id'] == $select_id) ? true : false);
 165              $forum_list[$row['forum_id']] = array_merge(array('padding' => $padding, 'selected' => $selected), $row);
 166          }
 167          else
 168          {
 169              $selected = (is_array($select_id)) ? ((in_array($row['forum_id'], $select_id)) ? ' selected="selected"' : '') : (($row['forum_id'] == $select_id) ? ' selected="selected"' : '');
 170              $forum_list .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
 171          }
 172  
 173          $iteration++;
 174      }
 175      $db->sql_freeresult($result);
 176      unset($padding_store);
 177  
 178      return $forum_list;
 179  }
 180  
 181  /**
 182  * Generate size select options
 183  */
 184  function size_select_options($size_compare)
 185  {
 186      global $user;
 187  
 188      $size_types_text = array($user->lang['BYTES'], $user->lang['KB'], $user->lang['MB']);
 189      $size_types = array('b', 'kb', 'mb');
 190  
 191      $s_size_options = '';
 192  
 193      for ($i = 0, $size = sizeof($size_types_text); $i < $size; $i++)
 194      {
 195          $selected = ($size_compare == $size_types[$i]) ? ' selected="selected"' : '';
 196          $s_size_options .= '<option value="' . $size_types[$i] . '"' . $selected . '>' . $size_types_text[$i] . '</option>';
 197      }
 198  
 199      return $s_size_options;
 200  }
 201  
 202  /**
 203  * Generate list of groups
 204  */
 205  function group_select_options($group_id, $exclude_ids = false)
 206  {
 207      global $db, $user, $config;
 208  
 209      $exclude_sql = ($exclude_ids !== false && sizeof($exclude_ids)) ? 'WHERE ' . $db->sql_in_set('group_id', array_map('intval', $exclude_ids), true) : '';
 210      $sql_and = (!$config['coppa_enable']) ? (($exclude_sql) ? ' AND ' : ' WHERE ') . "group_name <> 'REGISTERED_COPPA'" : '';
 211  
 212      $sql = 'SELECT group_id, group_name, group_type 
 213          FROM ' . GROUPS_TABLE . "
 214          $exclude_sql
 215          $sql_and
 216          ORDER BY group_type DESC, group_name ASC";
 217      $result = $db->sql_query($sql);
 218  
 219      $s_group_options = '';
 220      while ($row = $db->sql_fetchrow($result))
 221      {
 222          $selected = ($row['group_id'] == $group_id) ? ' selected="selected"' : '';
 223          $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . $selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
 224      }
 225      $db->sql_freeresult($result);
 226  
 227      return $s_group_options;
 228  }
 229  
 230  /**
 231  * Obtain authed forums list
 232  */
 233  function get_forum_list($acl_list = 'f_list', $id_only = true, $postable_only = false, $no_cache = false)
 234  {
 235      global $db, $auth;
 236      static $forum_rows;
 237  
 238      if (!isset($forum_rows))
 239      {
 240          // This query is identical to the jumpbox one
 241          $expire_time = ($no_cache) ? 0 : 120;
 242  
 243          $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
 244              FROM ' . FORUMS_TABLE . '
 245              ORDER BY left_id ASC';
 246          $result = $db->sql_query($sql, $expire_time);
 247  
 248          $forum_rows = array();
 249          while ($row = $db->sql_fetchrow($result))
 250          {
 251              $forum_rows[] = $row;
 252          }
 253          $db->sql_freeresult($result);
 254      }
 255  
 256      $rowset = array();
 257      foreach ($forum_rows as $row)
 258      {
 259          if ($postable_only && $row['forum_type'] != FORUM_POST)
 260          {
 261              continue;
 262          }
 263  
 264          if ($acl_list == '' || ($acl_list != '' && $auth->acl_gets($acl_list, $row['forum_id'])))
 265          {
 266              $rowset[] = ($id_only) ? $row['forum_id'] : $row;
 267          }
 268      }
 269  
 270      return $rowset;
 271  }
 272  
 273  /**
 274  * Get forum branch
 275  */
 276  function get_forum_branch($forum_id, $type = 'all', $order = 'descending', $include_forum = true)
 277  {
 278      global $db;
 279  
 280      switch ($type)
 281      {
 282          case 'parents':
 283              $condition = 'f1.left_id BETWEEN f2.left_id AND f2.right_id';
 284          break;
 285  
 286          case 'children':
 287              $condition = 'f2.left_id BETWEEN f1.left_id AND f1.right_id';
 288          break;
 289  
 290          default:
 291              $condition = 'f2.left_id BETWEEN f1.left_id AND f1.right_id OR f1.left_id BETWEEN f2.left_id AND f2.right_id';
 292          break;
 293      }
 294  
 295      $rows = array();
 296  
 297      $sql = 'SELECT f2.*
 298          FROM ' . FORUMS_TABLE . ' f1
 299          LEFT JOIN ' . FORUMS_TABLE . " f2 ON ($condition)
 300          WHERE f1.forum_id = $forum_id
 301          ORDER BY f2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
 302      $result = $db->sql_query($sql);
 303  
 304      while ($row = $db->sql_fetchrow($result))
 305      {
 306          if (!$include_forum && $row['forum_id'] == $forum_id)
 307          {
 308              continue;
 309          }
 310  
 311          $rows[] = $row;
 312      }
 313      $db->sql_freeresult($result);
 314  
 315      return $rows;
 316  }
 317  
 318  /**
 319  * Get physical file listing
 320  */
 321  function filelist($rootdir, $dir = '', $type = 'gif|jpg|jpeg|png')
 322  {
 323      $matches = array();
 324  
 325      // Remove initial / if present
 326      $rootdir = (substr($rootdir, 0, 1) == '/') ? substr($rootdir, 1) : $rootdir;
 327      // Add closing / if not present
 328      $rootdir = ($rootdir && substr($rootdir, -1) != '/') ? $rootdir . '/' : $rootdir;
 329  
 330      // Remove initial / if present
 331      $dir = (substr($dir, 0, 1) == '/') ? substr($dir, 1) : $dir;
 332      // Add closing / if not present
 333      $dir = ($dir && substr($dir, -1) != '/') ? $dir . '/' : $dir;
 334  
 335      if (!is_dir($rootdir . $dir))
 336      {
 337          return false;
 338      }
 339  
 340      $dh = opendir($rootdir . $dir);
 341      while (($fname = readdir($dh)) !== false)
 342      {
 343          if (is_file("$rootdir$dir$fname"))
 344          {
 345              if (filesize("$rootdir$dir$fname") && preg_match('#\.' . $type . '$#i', $fname))
 346              {
 347                  $matches[$dir][] = $fname;
 348              }
 349          }
 350          else if ($fname[0] != '.' && is_dir("$rootdir$dir$fname"))
 351          {
 352              $matches += filelist($rootdir, "$dir$fname", $type);
 353          }
 354      }
 355      closedir($dh);
 356  
 357      return $matches;
 358  }
 359  
 360  /**
 361  * Move topic(s)
 362  */
 363  function move_topics($topic_ids, $forum_id, $auto_sync = true)
 364  {
 365      global $db;
 366  
 367      if (empty($topic_ids))
 368      {
 369          return;
 370      }
 371  
 372      $forum_ids = array($forum_id);
 373  
 374      if (!is_array($topic_ids))
 375      {
 376          $topic_ids = array($topic_ids);
 377      }
 378  
 379      $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 380          WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids) . '
 381              AND forum_id = ' . $forum_id;
 382      $db->sql_query($sql);
 383  
 384      if ($auto_sync)
 385      {
 386          $sql = 'SELECT DISTINCT forum_id
 387              FROM ' . TOPICS_TABLE . '
 388              WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 389          $result = $db->sql_query($sql);
 390  
 391          while ($row = $db->sql_fetchrow($result))
 392          {
 393              $forum_ids[] = $row['forum_id'];
 394          }
 395          $db->sql_freeresult($result);
 396      }
 397  
 398      $table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE);
 399      foreach ($table_ary as $table)
 400      {
 401          $sql = "UPDATE $table
 402              SET forum_id = $forum_id
 403              WHERE " . $db->sql_in_set('topic_id', $topic_ids);
 404          $db->sql_query($sql);
 405      }
 406      unset($table_ary);
 407  
 408      if ($auto_sync)
 409      {
 410          sync('forum', 'forum_id', $forum_ids, true);
 411          unset($forum_ids);
 412      }
 413  }
 414  
 415  /**
 416  * Move post(s)
 417  */
 418  function move_posts($post_ids, $topic_id, $auto_sync = true)
 419  {
 420      global $db;
 421  
 422      if (!is_array($post_ids))
 423      {
 424          $post_ids = array($post_ids);
 425      }
 426  
 427      $forum_ids = array();
 428      $topic_ids = array($topic_id);
 429  
 430      $sql = 'SELECT DISTINCT topic_id, forum_id
 431          FROM ' . POSTS_TABLE . '
 432          WHERE ' . $db->sql_in_set('post_id', $post_ids);
 433      $result = $db->sql_query($sql);
 434  
 435      while ($row = $db->sql_fetchrow($result))
 436      {
 437          $forum_ids[] = $row['forum_id'];
 438          $topic_ids[] = $row['topic_id'];
 439      }
 440      $db->sql_freeresult($result);
 441  
 442      $sql = 'SELECT forum_id 
 443          FROM ' . TOPICS_TABLE . ' 
 444          WHERE topic_id = ' . $topic_id;
 445      $result = $db->sql_query($sql);
 446      $forum_row = $db->sql_fetchrow($result);
 447      $db->sql_freeresult($result);
 448  
 449      if (!$forum_row)
 450      {
 451          trigger_error('NO_TOPIC');
 452      }
 453  
 454      $sql = 'UPDATE ' . POSTS_TABLE . '
 455          SET forum_id = ' . $forum_row['forum_id'] . ", topic_id = $topic_id
 456          WHERE " . $db->sql_in_set('post_id', $post_ids);
 457      $db->sql_query($sql);
 458  
 459      $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
 460          SET topic_id = $topic_id, in_message = 0
 461          WHERE " . $db->sql_in_set('post_msg_id', $post_ids);
 462      $db->sql_query($sql);
 463  
 464      if ($auto_sync)
 465      {
 466          $forum_ids[] = $forum_row['forum_id'];
 467  
 468          sync('topic_reported', 'topic_id', $topic_ids);
 469          sync('topic_attachment', 'topic_id', $topic_ids);
 470          sync('topic', 'topic_id', $topic_ids, true);
 471          sync('forum', 'forum_id', $forum_ids, true);
 472      }
 473  
 474      // Update posted informations
 475      update_posted_info($topic_ids);
 476  }
 477  
 478  /**
 479  * Remove topic(s)
 480  */
 481  function delete_topics($where_type, $where_ids, $auto_sync = true)
 482  {
 483      global $db, $config;
 484  
 485      $forum_ids = $topic_ids = array();
 486  
 487      if (is_array($where_ids))
 488      {
 489          $where_ids = array_unique($where_ids);
 490      }
 491      else
 492      {
 493          $where_ids = array($where_ids);
 494      }
 495  
 496      if (!sizeof($where_ids))
 497      {
 498          return array('topics' => 0, 'posts' => 0);
 499      }
 500  
 501      $return = array(
 502          'posts'    =>    delete_posts($where_type, $where_ids, false, true)
 503      );
 504  
 505      $sql = 'SELECT topic_id, forum_id
 506          FROM ' . TOPICS_TABLE . '
 507          WHERE ' . $db->sql_in_set($where_type, $where_ids);
 508      $result = $db->sql_query($sql);
 509  
 510      while ($row = $db->sql_fetchrow($result))
 511      {
 512          $forum_ids[] = $row['forum_id'];
 513          $topic_ids[] = $row['topic_id'];
 514      }
 515      $db->sql_freeresult($result);
 516  
 517      $return['topics'] = sizeof($topic_ids);
 518  
 519      if (!sizeof($topic_ids))
 520      {
 521          return $return;
 522      }
 523  
 524      $db->sql_transaction('begin');
 525  
 526      $table_ary = array(TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, POLL_VOTES_TABLE, POLL_OPTIONS_TABLE, TOPICS_WATCH_TABLE, TOPICS_TABLE);
 527  
 528      foreach ($table_ary as $table)
 529      {
 530          $sql = "DELETE FROM $table 
 531              WHERE " . $db->sql_in_set('topic_id', $topic_ids);
 532          $db->sql_query($sql);
 533      }
 534      unset($table_ary);
 535  
 536      $sql = 'DELETE FROM ' . TOPICS_TABLE . ' 
 537          WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids);
 538      $db->sql_query($sql);
 539  
 540      $db->sql_transaction('commit');
 541  
 542      if ($auto_sync)
 543      {
 544          sync('forum', 'forum_id', $forum_ids, true);
 545          sync('topic_reported', $where_type, $where_ids);
 546      }
 547  
 548      set_config('num_topics', $config['num_topics'] - sizeof($return['topics']), true);
 549  
 550      return $return;
 551  }
 552  
 553  /**
 554  * Remove post(s)
 555  */
 556  function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true)
 557  {
 558      global $db, $config, $phpbb_root_path, $phpEx;
 559  
 560      if (is_array($where_ids))
 561      {
 562          $where_ids = array_unique($where_ids);
 563      }
 564      else
 565      {
 566          $where_ids = array($where_ids);
 567      }
 568  
 569      if (!sizeof($where_ids))
 570      {
 571          return false;
 572      }
 573  
 574      $post_ids = $topic_ids = $forum_ids = $post_counts = array();
 575  
 576      $sql = 'SELECT post_id, poster_id, post_postcount, topic_id, forum_id
 577          FROM ' . POSTS_TABLE . '
 578          WHERE ' . $db->sql_in_set($where_type, array_map('intval', $where_ids));
 579      $result = $db->sql_query($sql);
 580  
 581      while ($row = $db->sql_fetchrow($result))
 582      {
 583          $post_ids[] = $row['post_id'];
 584          $poster_ids[] = $row['poster_id'];
 585          $topic_ids[] = $row['topic_id'];
 586          $forum_ids[] = $row['forum_id'];
 587  
 588          if ($row['post_postcount'])
 589          {
 590              $post_counts[$row['poster_id']] = (!empty($post_counts[$row['poster_id']])) ? $post_counts[$row['poster_id']] + 1 : 1;
 591          }
 592      }
 593      $db->sql_freeresult($result);
 594  
 595      if (!sizeof($post_ids))
 596      {
 597          return false;
 598      }
 599  
 600      $db->sql_transaction('begin');
 601  
 602      $table_ary = array(POSTS_TABLE, REPORTS_TABLE);
 603  
 604      foreach ($table_ary as $table)
 605      {
 606          $sql = "DELETE FROM $table 
 607              WHERE " . $db->sql_in_set('post_id', $post_ids);
 608          $db->sql_query($sql);
 609      }
 610      unset($table_ary);
 611  
 612      // Adjust users post counts
 613      if (sizeof($post_counts))
 614      {
 615          foreach ($post_counts as $poster_id => $substract)
 616          {
 617              $sql = 'UPDATE ' . USERS_TABLE . '
 618                  SET user_posts = user_posts - ' . $substract . '
 619                  WHERE user_id = ' . $poster_id;
 620              $db->sql_query($sql);
 621          }
 622      }
 623  
 624      // Remove the message from the search index
 625      $search_type = basename($config['search_type']);
 626  
 627      if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
 628      {
 629          trigger_error('NO_SUCH_SEARCH_MODULE');
 630      }
 631  
 632      include_once("{$phpbb_root_path}includes/search/$search_type.$phpEx");
 633  
 634      $error = false;
 635      $search = new $search_type($error);
 636  
 637      if ($error)
 638      {
 639          trigger_error($error);
 640      }
 641  
 642      $search->index_remove($post_ids, $poster_ids, $forum_ids);
 643  
 644      delete_attachments('post', $post_ids, false);
 645  
 646      $db->sql_transaction('commit');
 647  
 648      // Resync topics_posted table
 649      if ($posted_sync)
 650      {
 651          update_posted_info($topic_ids);
 652      }
 653  
 654      if ($auto_sync)
 655      {
 656          sync('topic_reported', 'topic_id', $topic_ids);
 657          sync('topic', 'topic_id', $topic_ids, true);
 658          sync('forum', 'forum_id', $forum_ids, true);
 659      }
 660  
 661      set_config('num_posts', $config['num_posts'] - sizeof($post_ids), true);
 662  
 663      return sizeof($post_ids);
 664  }
 665  
 666  /**
 667  * Delete Attachments
 668  *
 669  * @param string $mode can be: post|topic|attach|user
 670  * @param mixed $ids can be: post_ids, topic_ids, attach_ids, user_ids
 671  * @param bool $resync set this to false if you are deleting posts or topics
 672  */
 673  function delete_attachments($mode, $ids, $resync = true)
 674  {
 675      global $db, $config;
 676  
 677      if (is_array($ids))
 678      {
 679          $ids = array_unique($ids);
 680          $ids = array_map('intval', $ids);
 681      }
 682      else
 683      {
 684          $ids = array((int) $ids);
 685      }
 686  
 687      if (!sizeof($ids))
 688      {
 689          return false;
 690      }
 691  
 692      $sql_id = ($mode == 'user') ? 'poster_id' : (($mode == 'post') ? 'post_msg_id' : (($mode == 'topic') ? 'topic_id' : 'attach_id'));
 693  
 694      $post_ids = $topic_ids = $physical = array();
 695  
 696      // Collect post and topics ids for later use
 697      if ($mode == 'attach' || $mode == 'user' || ($mode == 'topic' && $resync))
 698      {
 699          $sql = 'SELECT post_msg_id as post_id, topic_id, physical_filename, thumbnail, filesize
 700              FROM ' . ATTACHMENTS_TABLE . '
 701              WHERE ' . $db->sql_in_set($sql_id, $ids);
 702          $result = $db->sql_query($sql);
 703  
 704          while ($row = $db->sql_fetchrow($result))
 705          {
 706              $post_ids[] = $row['post_id'];
 707              $topic_ids[] = $row['topic_id'];
 708              $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']);
 709          }
 710          $db->sql_freeresult($result);
 711      }
 712  
 713      if ($mode == 'post')
 714      {
 715          $sql = 'SELECT topic_id, physical_filename, thumbnail, filesize
 716              FROM ' . ATTACHMENTS_TABLE . '
 717              WHERE ' . $db->sql_in_set('post_msg_id', $ids) . '
 718                  AND in_message = 0';
 719          $result = $db->sql_query($sql);
 720  
 721          while ($row = $db->sql_fetchrow($result))
 722          {
 723              $topic_ids[] = $row['topic_id'];
 724              $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']);
 725          }
 726          $db->sql_freeresult($result);
 727      }
 728  
 729      // Delete attachments
 730      $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
 731          WHERE ' . $db->sql_in_set($sql_id, $ids);
 732      $db->sql_query($sql);
 733      $num_deleted = $db->sql_affectedrows();
 734  
 735      if (!$num_deleted)
 736      {
 737          return 0;
 738      }
 739  
 740      // Delete attachments from filesystem
 741      $space_removed = $files_removed = 0;
 742      foreach ($physical as $file_ary)
 743      {
 744          if (phpbb_unlink($file_ary['filename'], 'file'))
 745          {
 746              $space_removed += $file_ary['filesize'];
 747              $files_removed++;
 748          }
 749  
 750          if ($file_ary['thumbnail'])
 751          {
 752              phpbb_unlink($file_ary['filename'], 'thumbnail');
 753          }
 754      }
 755      set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true);
 756      set_config('num_files', $config['num_files'] - $files_removed, true);
 757  
 758      if ($mode == 'topic' && !$resync)
 759      {
 760          return $num_deleted;
 761      }
 762  
 763      if ($mode == 'post')
 764      {
 765          $post_ids = $ids;
 766      }
 767      unset($ids);
 768  
 769      $post_ids = array_unique($post_ids);
 770      $topic_ids = array_unique($topic_ids);
 771  
 772      // Update post indicators
 773      if (sizeof($post_ids))
 774      {
 775          if ($mode == 'post' || $mode == 'topic')
 776          {
 777              $sql = 'UPDATE ' . POSTS_TABLE . ' 
 778                  SET post_attachment = 0
 779                  WHERE ' . $db->sql_in_set('post_id', $post_ids);
 780              $db->sql_query($sql);
 781          }
 782  
 783          if ($mode == 'user' || $mode == 'attach')
 784          {
 785              $remaining = array();
 786  
 787              $sql = 'SELECT post_msg_id
 788                  FROM ' . ATTACHMENTS_TABLE . ' 
 789                  WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
 790                      AND in_message = 0';
 791              $result = $db->sql_query($sql);
 792  
 793              while ($row = $db->sql_fetchrow($result))
 794              {
 795                  $remaining[] = $row['post_msg_id'];        
 796              }
 797              $db->sql_freeresult($result);
 798  
 799              $unset_ids = array_diff($post_ids, $remaining);
 800  
 801              if (sizeof($unset_ids))
 802              {
 803                  $sql = 'UPDATE ' . POSTS_TABLE . ' 
 804                      SET post_attachment = 0
 805                      WHERE ' . $db->sql_in_set('post_id', $unset_ids);
 806                  $db->sql_query($sql);
 807              }
 808  
 809              $remaining = array();
 810  
 811              $sql = 'SELECT post_msg_id
 812                  FROM ' . ATTACHMENTS_TABLE . ' 
 813                  WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
 814                      AND in_message = 1';
 815              $result = $db->sql_query($sql);
 816  
 817              while ($row = $db->sql_fetchrow($result))
 818              {
 819                  $remaining[] = $row['post_msg_id'];        
 820              }
 821              $db->sql_freeresult($result);
 822  
 823              $unset_ids = array_diff($post_ids, $remaining);
 824  
 825              if (sizeof($unset_ids))
 826              {
 827                  $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' 
 828                      SET message_attachment = 0
 829                      WHERE ' . $db->sql_in_set('msg_id', $unset_ids);
 830                  $db->sql_query($sql);
 831              }
 832          }
 833      }
 834  
 835      if (sizeof($topic_ids))
 836      {
 837          // Update topic indicator
 838          if ($mode == 'topic')
 839          {
 840              $sql = 'UPDATE ' . TOPICS_TABLE . '
 841                  SET topic_attachment = 0
 842                  WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 843              $db->sql_query($sql);
 844          }
 845  
 846          if ($mode == 'post' || $mode == 'user' || $mode == 'attach')
 847          {
 848              $remaining = array();
 849  
 850              $sql = 'SELECT topic_id
 851                  FROM ' . ATTACHMENTS_TABLE . ' 
 852                  WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 853              $result = $db->sql_query($sql);
 854  
 855              while ($row = $db->sql_fetchrow($result))
 856              {
 857                  $remaining[] = $row['topic_id'];        
 858              }
 859              $db->sql_freeresult($result);
 860  
 861              $unset_ids = array_diff($topic_ids, $remaining);
 862  
 863              if (sizeof($unset_ids))
 864              {
 865                  $sql = 'UPDATE ' . TOPICS_TABLE . ' 
 866                      SET topic_attachment = 0
 867                      WHERE ' . $db->sql_in_set('topic_id', $unset_ids);
 868                  $db->sql_query($sql);
 869              }
 870          }
 871      }
 872  
 873      return $num_deleted;
 874  }
 875  
 876  /**
 877  * Remove topic shadows
 878  */
 879  function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true)
 880  {
 881      $where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : '');
 882  
 883      switch ($db->sql_layer)
 884      {
 885          case 'mysql4':
 886          case 'mysqli':
 887              $sql = 'DELETE t.*
 888                  FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
 889                  WHERE t.topic_moved_id = t2.topic_id
 890                      AND t.topic_time < ' . (time() - $max_age)
 891                  . $where;
 892              $db->sql_query($sql);
 893          break;
 894      
 895          default:
 896              $sql = 'SELECT t.topic_id
 897                  FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
 898                  WHERE t.topic_moved_id = t2.topic_id
 899                      AND t.topic_time < ' . (time() - $max_age)
 900                  . $where;
 901              $result = $db->sql_query($sql);
 902  
 903              $topic_ids = array();
 904              while ($row = $db->sql_fetchrow($result))
 905              {
 906                  $topic_ids[] = $row['topic_id'];
 907              }
 908              $db->sql_freeresult($result);
 909  
 910              if (sizeof($topic_ids))
 911              {
 912                  $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 913                      WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 914                  $db->sql_query($sql);
 915              }
 916          break;
 917      }
 918  
 919      if ($auto_sync)
 920      {
 921          $where_type = ($forum_id) ? 'forum_id' : '';
 922          sync('forum', $where_type, $forum_id, true);
 923      }
 924  }
 925  
 926  /**
 927  * Update/Sync posted informations for topics
 928  */
 929  function update_posted_info(&$topic_ids)
 930  {
 931      global $db, $config;
 932  
 933      if (empty($topic_ids) || !$config['load_db_track'])
 934      {
 935          return;
 936      }
 937  
 938      // First of all, let us remove any posted information for these topics
 939      $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
 940          WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
 941      $db->sql_query($sql);
 942  
 943      // Now, let us collect the user/topic combos for rebuilding the information
 944      $sql = 'SELECT poster_id, topic_id
 945          FROM ' . POSTS_TABLE . '
 946          WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
 947              AND poster_id <> ' . ANONYMOUS . '
 948          GROUP BY poster_id, topic_id';
 949      $result = $db->sql_query($sql);
 950  
 951      $posted = array();
 952      while ($row = $db->sql_fetchrow($result))
 953      {
 954          // Add as key to make them unique (grouping by) and circumvent empty keys on array_unique
 955          $posted[$row['poster_id']][] = $row['topic_id'];
 956      }
 957      $db->sql_freeresult($result);
 958  
 959      // Now add the information...
 960      $sql_ary = array();
 961      foreach ($posted as $user_id => $topic_row)
 962      {
 963          foreach ($topic_row as $topic_id)
 964          {
 965              $sql_ary[] = array(
 966                  'user_id'        => $user_id,
 967                  'topic_id'        => $topic_id,
 968                  'topic_posted'    => 1,
 969              );
 970          }
 971      }
 972      unset($posted);
 973  
 974      $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
 975  }
 976  
 977  /**
 978  * Delete File
 979  */
 980  function phpbb_unlink($filename, $mode = 'file')
 981  {
 982      global $config, $user, $phpbb_root_path;
 983  
 984      $filename = ($mode == 'thumbnail') ? $phpbb_root_path . $config['upload_path'] . '/thumb_' . basename($filename) : $phpbb_root_path . $config['upload_path'] . '/' . basename($filename);
 985      return @unlink($filename);
 986  }
 987  
 988  /**
 989  * All-encompasing sync function
 990  *
 991  * Exaples:
 992  * <code>
 993  * sync('topic', 'topic_id', 123);            // resync topic #123
 994  * sync('topic', 'forum_id', array(2, 3));    // resync topics from forum #2 and #3
 995  * sync('topic');                            // resync all topics
 996  * sync('topic', 'range', 'topic_id BETWEEN 1 AND 60');    // resync a range of topics/forums (only available for 'topic' and 'forum' modes)
 997  * </code>
 998  *
 999  * Modes:
1000  * - forum                Resync complete forum
1001  * - topic                Resync topics
1002  * - topic_moved            Removes topic shadows that would be in the same forum as the topic they link to
1003  * - topic_approved        Resyncs the topic_approved flag according to the status of the first post
1004  * - post_reported        Resyncs the post_reported flag, relying on actual reports
1005  * - topic_reported        Resyncs the topic_reported flag, relying on post_reported flags
1006  * - post_attachement    Same as post_reported, but with attachment flags
1007  * - topic_attachement    Same as topic_reported, but with attachment flags
1008  */
1009  function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $sync_extra = false)
1010  {
1011      global $db;
1012  
1013      if (is_array($where_ids))
1014      {
1015          $where_ids = array_unique($where_ids);
1016          $where_ids = array_map('intval', $where_ids);
1017      }
1018      else if ($where_type != 'range')
1019      {
1020          $where_ids = ($where_ids) ? array((int) $where_ids) : array();
1021      }
1022  
1023      if ($mode == 'forum' || $mode == 'topic' || $mode == 'topic_approved')
1024      {
1025          if (!$where_type)
1026          {
1027              $where_sql = '';
1028              $where_sql_and = 'WHERE';
1029          }
1030          else if ($where_type == 'range')
1031          {
1032              // Only check a range of topics/forums. For instance: 'topic_id BETWEEN 1 AND 60'
1033              $where_sql = 'WHERE (' . $mode[0] . ".$where_ids)";
1034              $where_sql_and = $where_sql . "\n\tAND";
1035          }
1036          else
1037          {
1038              // Do not sync the "global forum"
1039              $where_ids = array_diff($where_ids, array(0));
1040  
1041              if (!sizeof($where_ids))
1042              {
1043                  // Empty array with IDs. This means that we don't have any work to do. Just return.
1044                  return;
1045              }
1046  
1047              // Limit the topics/forums we are syncing, use specific topic/forum IDs.
1048              // $where_type contains the field for the where clause (forum_id, topic_id)
1049              $where_sql = 'WHERE ' . $db->sql_in_set($mode[0] . '.' . $where_type, $where_ids);
1050              $where_sql_and = $where_sql . "\n\tAND";
1051          }
1052      }
1053      else
1054      {
1055          if (!sizeof($where_ids))
1056          {
1057              return;
1058          }
1059  
1060          // $where_type contains the field for the where clause (forum_id, topic_id)
1061          $where_sql = 'WHERE ' . $db->sql_in_set($mode[0] . '.' . $where_type, $where_ids);
1062          $where_sql_and = $where_sql . "\n\tAND";
1063      }
1064  
1065      switch ($mode)
1066      {
1067          case 'topic_moved':
1068              switch ($db->sql_layer)
1069              {
1070                  case 'mysql4':
1071                  case 'mysqli':
1072                      $sql = 'DELETE FROM ' . TOPICS_TABLE . '
1073                          USING ' . TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
1074                          WHERE t1.topic_moved_id = t2.topic_id
1075                              AND t1.forum_id = t2.forum_id";
1076                      $db->sql_query($sql);
1077                  break;
1078              
1079                  default:
1080                      $sql = 'SELECT t1.topic_id
1081                          FROM ' .TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
1082                          WHERE t1.topic_moved_id = t2.topic_id
1083                              AND t1.forum_id = t2.forum_id";
1084                      $result = $db->sql_query($sql);
1085  
1086                      $topic_id_ary = array();
1087                      while ($row = $db->sql_fetchrow($result))
1088                      {
1089                          $topic_id_ary[] = $row['topic_id'];
1090                      }
1091                      $db->sql_freeresult($result);
1092  
1093                      if (!sizeof($topic_id_ary))
1094                      {
1095                          return;
1096                      }
1097  
1098                      $sql = 'DELETE FROM ' . TOPICS_TABLE . '
1099                          WHERE ' . $db->sql_in_set('topic_id', $topic_id_ary);
1100                      $db->sql_query($sql);
1101  
1102                  break;
1103              }
1104          break;
1105  
1106          case 'topic_approved':
1107              switch ($db->sql_layer)
1108              {
1109                  case 'mysql4':
1110                  case 'mysqli':
1111                      $sql = 'UPDATE ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
1112                          SET t.topic_approved = p.post_approved
1113                          $where_sql_and t.topic_first_post_id = p.post_id";
1114                      $db->sql_query($sql);
1115                  break;
1116  
1117                  default:
1118                      $sql = 'SELECT t.topic_id, p.post_approved
1119                          FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
1120                          $where_sql_and p.post_id = t.topic_first_post_id
1121                              AND p.post_approved <> t.topic_approved";
1122                      $result = $db->sql_query($sql);
1123  
1124                      $topic_ids = array();
1125                      while ($row = $db->sql_fetchrow($result))
1126                      {
1127                          $topic_ids[] = $row['topic_id'];
1128                      }
1129                      $db->sql_freeresult($result);
1130  
1131                      if (!sizeof($topic_ids))
1132                      {
1133                          return;
1134                      }
1135  
1136                      $sql = 'UPDATE ' . TOPICS_TABLE . '
1137                          SET topic_approved = 1 - topic_approved
1138                          WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
1139                      $db->sql_query($sql);
1140                  break;
1141              }
1142          break;
1143  
1144          case 'post_reported':
1145              $post_ids = $post_reported = array();
1146  
1147              $sql = 'SELECT p.post_id, p.post_reported
1148                  FROM ' . POSTS_TABLE . " p
1149                  $where_sql
1150                  GROUP BY p.post_id, p.post_reported";
1151              $result = $db->sql_query($sql);
1152  
1153              while ($row = $db->sql_fetchrow($result))
1154              {
1155                  $post_ids[$row['post_id']] = $row['post_id'];
1156                  if ($row['post_reported'])
1157                  {
1158                      $post_reported[$row['post_id']] = 1;
1159                  }
1160              }
1161              $db->sql_freeresult($result);
1162  
1163              $sql = 'SELECT DISTINCT(post_id)
1164                  FROM ' . REPORTS_TABLE . '
1165                  WHERE ' . $db->sql_in_set('post_id', $post_ids) . '
1166                      AND report_closed = 0';
1167              $result = $db->sql_query($sql);
1168  
1169              $post_ids = array();
1170              while ($row = $db->sql_fetchrow($result))
1171              {
1172                  if (!isset($post_reported[$row['post_id']]))
1173                  {
1174                      $post_ids[] = $row['post_id'];
1175                  }
1176                  else
1177                  {
1178                      unset($post_reported[$row['post_id']]);
1179                  }
1180              }
1181              $db->sql_freeresult($result);
1182  
1183              // $post_reported should be empty by now, if it's not it contains
1184              // posts that are falsely flagged as reported
1185              foreach ($post_reported as $post_id => $void)
1186              {
1187                  $post_ids[] = $post_id;
1188              }
1189  
1190              if (sizeof($post_ids))
1191              {
1192                  $sql = 'UPDATE ' . POSTS_TABLE . '
1193                      SET post_reported = 1 - post_reported
1194                      WHERE ' . $db->sql_in_set('post_id', $post_ids);
1195                  $db->sql_query($sql);
1196              }
1197          break;
1198  
1199          case 'topic_reported':
1200              if ($sync_extra)
1201              {
1202                  sync('post_reported', $where_type, $where_ids);
1203              }
1204  
1205              $topic_ids = $topic_reported = array();
1206  
1207              $sql = 'SELECT DISTINCT(t.topic_id)
1208                  FROM ' . POSTS_TABLE . " t
1209                  $where_sql_and t.post_reported = 1";
1210              $result = $db->sql_query($sql);
1211  
1212              while ($row = $db->sql_fetchrow($result))
1213              {
1214                  $topic_reported[$row['topic_id']] = 1;
1215              }
1216              $db->sql_freeresult($result);
1217  
1218              $sql = 'SELECT t.topic_id, t.topic_reported
1219                  FROM ' . TOPICS_TABLE . " t
1220                  $where_sql";
1221              $result = $db->sql_query($sql);
1222  
1223              while ($row = $db->sql_fetchrow($result))
1224              {
1225                  if ($row['topic_reported'] ^ isset($topic_reported[$row['topic_id']]))
1226                  {
1227                      $topic_ids[] = $row['topic_id'];
1228                  }
1229              }
1230              $db->sql_freeresult($result);
1231  
1232              if (sizeof($topic_ids))
1233              {
1234                  $sql = 'UPDATE ' . TOPICS_TABLE . '
1235                      SET topic_reported = 1 - topic_reported
1236                      WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
1237                  $db->sql_query($sql);
1238              }
1239          break;
1240  
1241          case 'post_attachment':
1242              $post_ids = $post_attachment = array();
1243  
1244              $sql = 'SELECT p.post_id, p.post_attachment
1245                  FROM ' . POSTS_TABLE . " p
1246                  $where_sql
1247                  GROUP BY p.post_id, p.post_attachment";
1248              $result = $db->sql_query($sql);
1249  
1250              while ($row = $db->sql_fetchrow($result))
1251              {
1252                  $post_ids[$row['post_id']] = $row['post_id'];
1253                  if ($row['post_attachment'])
1254                  {
1255                      $post_attachment[$row['post_id']] = 1;
1256                  }
1257              }
1258              $db->sql_freeresult($result);
1259  
1260              $sql = 'SELECT DISTINCT(post_msg_id)
1261                  FROM ' . ATTACHMENTS_TABLE . '
1262                  WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
1263                      AND in_message = 0';
1264              $result = $db->sql_query($sql);
1265  
1266              $post_ids = array();
1267              while ($row = $db->sql_fetchrow($result))
1268              {
1269                  if (!isset($post_attachment[$row['post_id']]))
1270                  {
1271                      $post_ids[] = $row['post_id'];
1272                  }
1273                  else
1274                  {
1275                      unset($post_attachment[$row['post_id']]);
1276                  }
1277              }
1278              $db->sql_freeresult($result);
1279  
1280              // $post_attachment should be empty by now, if it's not it contains
1281              // posts that are falsely flagged as having attachments
1282              foreach ($post_attachment as $post_id => $void)
1283              {
1284                  $post_ids[] = $post_id;
1285              }
1286  
1287              if (sizeof($post_ids))
1288              {
1289                  $sql = 'UPDATE ' . POSTS_TABLE . '
1290                      SET post_attachment = 1 - post_attachment
1291                      WHERE ' . $db->sql_in_set('post_id', $post_ids);
1292                  $db->sql_query($sql);
1293              }
1294          break;
1295  
1296          case 'topic_attachment':
1297              if ($sync_extra)
1298              {
1299                  sync('post_attachment', $where_type, $where_ids);
1300              }
1301  
1302              $topic_ids = $topic_attachment = array();
1303  
1304              $sql = 'SELECT DISTINCT(t.topic_id)
1305                  FROM ' . POSTS_TABLE . " t
1306                  $where_sql_and t.post_attachment = 1";
1307              $result = $db->sql_query($sql);
1308  
1309              while ($row = $db->sql_fetchrow($result))
1310              {
1311                  $topic_attachment[$row['topic_id']] = 1;
1312              }
1313              $db->sql_freeresult($result);
1314  
1315              $sql = 'SELECT t.topic_id, t.topic_attachment
1316                  FROM ' . TOPICS_TABLE . " t
1317                  $where_sql";
1318              $result = $db->sql_query($sql);
1319  
1320              while ($row = $db->sql_fetchrow($result))
1321              {
1322                  if ($row['topic_attachment'] ^ isset($topic_attachment[$row['topic_id']]))
1323                  {
1324                      $topic_ids[] = $row['topic_id'];
1325                  }
1326              }
1327              $db->sql_freeresult($result);
1328  
1329              if (sizeof($topic_ids))
1330              {
1331                  $sql = 'UPDATE ' . TOPICS_TABLE . '
1332                      SET topic_attachment = 1 - topic_attachment
1333                      WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
1334                  $db->sql_query($sql);
1335              }
1336          break;
1337  
1338          case 'forum':
1339  
1340              // 1: Get the list of all forums
1341              $sql = 'SELECT f.*
1342                  FROM ' . FORUMS_TABLE . " f
1343                  $where_sql";
1344              $result = $db->sql_query($sql);
1345  
1346              $forum_data = $forum_ids = $post_ids = $last_post_id = $post_info = array();
1347              while ($row = $db->sql_fetchrow($result))
1348              {
1349                  if ($row['forum_type'] == FORUM_LINK)
1350                  {
1351                      continue;
1352                  }
1353  
1354                  $forum_id = (int) $row['forum_id'];
1355                  $forum_ids[$forum_id] = $forum_id;
1356  
1357                  $forum_data[$forum_id] = $row;
1358                  $forum_data[$forum_id]['posts'] = 0;
1359                  $forum_data[$forum_id]['topics'] = 0;
1360                  $forum_data[$forum_id]['topics_real'] = 0;
1361                  $forum_data[$forum_id]['last_post_id'] = 0;
1362                  $forum_data[$forum_id]['last_post_subject'] = '';
1363                  $forum_data[$forum_id]['last_post_time'] = 0;
1364                  $forum_data[$forum_id]['last_poster_id'] = 0;
1365                  $forum_data[$forum_id]['last_poster_name'] = '';
1366                  $forum_data[$forum_id]['last_poster_colour'] = '';
1367              }
1368              $db->sql_freeresult($result);
1369  
1370              if (!sizeof($forum_ids))
1371              {
1372                  break;
1373              }
1374  
1375              $forum_ids = array_values($forum_ids);
1376  
1377              // 2: Get topic counts for each forum
1378              $sql = 'SELECT forum_id, topic_approved, COUNT(topic_id) AS forum_topics
1379                  FROM ' . TOPICS_TABLE . '
1380                  WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
1381                  GROUP BY forum_id, topic_approved';
1382              $result = $db->sql_query($sql);
1383  
1384              while ($row = $db->sql_fetchrow($result))
1385              {
1386                  $forum_id = (int) $row['forum_id'];
1387                  $forum_data[$forum_id]['topics_real'] += $row['forum_topics'];
1388  
1389                  if ($row['topic_approved'])
1390                  {
1391                      $forum_data[$forum_id]['topics'] = $row['forum_topics'];
1392                  }
1393              }
1394              $db->sql_freeresult($result);
1395  
1396              // 3: Get post count and last_post_id for each forum
1397              if (sizeof($forum_ids) == 1)
1398              {
1399                  $sql = 'SELECT COUNT(post_id) AS forum_posts, MAX(post_id) AS last_post_id
1400                      FROM ' . POSTS_TABLE . '
1401                      WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
1402                          AND post_approved = 1';
1403              }
1404              else
1405              {
1406                  $sql = 'SELECT forum_id, COUNT(post_id) AS forum_posts, MAX(post_id) AS last_post_id
1407                      FROM ' . POSTS_TABLE . '
1408                      WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
1409                          AND post_approved = 1
1410                      GROUP BY forum_id';
1411              }
1412  
1413              $result = $db->sql_query($sql);
1414  
1415              while ($row = $db->sql_fetchrow($result))
1416              {
1417                  $forum_id = (sizeof($forum_ids) == 1) ? (int) $forum_ids[0] : (int) $row['forum_id'];
1418  
1419                  $forum_data[$forum_id]['posts'] = (int) $row['forum_posts'];
1420                  $forum_data[$forum_id]['last_post_id'] = (int) $row['last_post_id'];
1421  
1422                  $post_ids[] = $row['last_post_id'];
1423              }
1424              $db->sql_freeresult($result);
1425  
1426              // 4: Retrieve last_post infos
1427              if (sizeof($post_ids))
1428              {
1429                  $sql = 'SELECT p.post_id, p.poster_id, p.post_subject, p.post_time, p.post_username, u.username, u.user_colour
1430                      FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
1431                      WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
1432                          AND p.poster_id = u.user_id';
1433                  $result = $db->sql_query($sql);
1434  
1435                  while ($row = $db->sql_fetchrow($result))
1436                  {
1437                      $post_info[$row['post_id']] = $row;
1438                  }
1439                  $db->sql_freeresult($result);
1440  
1441                  foreach ($forum_data as $forum_id => $data)
1442                  {
1443                      if ($data['last_post_id'])
1444                      {
1445                          if (isset($post_info[$data['last_post_id']]))
1446                          {
1447                              $forum_data[$forum_id]['last_post_subject'] = $post_info[$data['last_post_id']]['post_subject'];
1448                              $forum_data[$forum_id]['last_post_time'] = $post_info[$data['last_post_id']]['post_time'];
1449                              $forum_data[$forum_id]['last_poster_id'] = $post_info[$data['last_post_id']]['poster_id'];
1450                              $forum_data[$forum_id]['last_poster_name'] = ($post_info[$data['last_post_id']]['poster_id'] != ANONYMOUS) ? $post_info[$data['last_post_id']]['username'] : $post_info[$data['last_post_id']]['post_username'];
1451                              $forum_data[$forum_id]['last_poster_colour'] = $post_info[$data['last_post_id']]['user_colour'];
1452                          }
1453                          else
1454                          {
1455                              // For some reason we did not find the post in the db
1456                              $forum_data[$forum_id]['last_post_id'] = 0;
1457                              $forum_data[$forum_id]['last_post_subject'] = '';
1458                              $forum_data[$forum_id]['last_post_time'] = 0;
1459                              $forum_data[$forum_id]['last_poster_id'] = 0;
1460                              $forum_data[$forum_id]['last_poster_name'] = '';
1461                              $forum_data[$forum_id]['last_poster_colour'] = '';
1462                          }
1463                      }
1464                  }
1465                  unset($post_info);
1466              }
1467  
1468              // 5: Now do that thing
1469              $fieldnames = array('posts', 'topics', 'topics_real', 'last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour');
1470  
1471              foreach ($forum_data as $forum_id => $row)
1472              {
1473                  $sql_ary = array();
1474  
1475                  foreach ($fieldnames as $fieldname)
1476                  {
1477                      if ($row['forum_' . $fieldname] != $row[$fieldname])
1478                      {
1479                          if (preg_match('#(name|colour|subject)$#', $fieldname))
1480                          {
1481                              $sql_ary['forum_' . $fieldname] = (string) $row[$fieldname];
1482                          }
1483                          else
1484                          {
1485                              $sql_ary['forum_' . $fieldname] = (int) $row[$fieldname];
1486                          }
1487                      }
1488                  }
1489  
1490                  if (sizeof($sql_ary))
1491                  {
1492                      $sql = 'UPDATE ' . FORUMS_TABLE . '
1493                          SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1494                          WHERE forum_id = ' . $forum_id;
1495                      $db->sql_query($sql);
1496                  }
1497              }
1498          break;
1499  
1500          case 'topic':
1501              $topic_data = $post_ids = $approved_unapproved_ids = $resync_forums = $delete_topics = $delete_posts = $moved_topics = array();
1502  
1503              $sql = 'SELECT t.topic_id, t.forum_id, t.topic_moved_id, t.topic_approved, ' . (($sync_extra) ? 't.topic_attachment, t.topic_reported, ' : '') . 't.topic_poster, t.topic_time, t.topic_replies, t.topic_replies_real, t.topic_first_post_id, t.topic_first_poster_name, t.topic_first_poster_colour, t.topic_last_post_id, t.topic_last_post_subject, t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_poster_colour, t.topic_last_post_time
1504                  FROM ' . TOPICS_TABLE . " t
1505                  $where_sql";
1506              $result = $db->sql_query($sql);
1507  
1508              while ($row = $db->sql_fetchrow($result))
1509              {
1510                  if ($row['topic_moved_id'])
1511                  {
1512                      $moved_topics[] = $row['topic_id'];
1513                      continue;
1514                  }
1515  
1516                  $topic_id = (int) $row['topic_id'];
1517                  $topic_data[$topic_id] = $row;
1518                  $topic_data[$topic_id]['replies_real'] = -1;
1519                  $topic_data[$topic_id]['replies'] = 0;
1520                  $topic_data[$topic_id]['first_post_id'] = 0;
1521                  $topic_data[$topic_id]['last_post_id'] = 0;
1522                  unset($topic_data[$topic_id]['topic_id']);
1523  
1524                  // This array holds all topic_ids
1525                  $delete_topics[$topic_id] = '';
1526  
1527                  if ($sync_extra)
1528                  {
1529                      $topic_data[$topic_id]['reported'] = 0;
1530                      $topic_data[$topic_id]['attachment'] = 0;
1531                  }
1532              }
1533              $db->sql_freeresult($result);
1534  
1535              // Use "t" as table alias because of the $where_sql clause
1536              // NOTE: 't.post_approved' in the GROUP BY is causing a major slowdown.
1537              $sql = 'SELECT t.topic_id, t.post_approved, COUNT(t.post_id) AS total_posts, MIN(t.post_id) AS first_post_id, MAX(t.post_id) AS last_post_id
1538                  FROM ' . POSTS_TABLE . " t
1539                  $where_sql
1540                  GROUP BY t.topic_id, t.post_approved";
1541              $result = $db->sql_query($sql);
1542  
1543              while ($row = $db->sql_fetchrow($result))
1544              {
1545                  $topic_id = (int) $row['topic_id'];
1546  
1547                  $row['first_post_id'] = (int) $row['first_post_id'];
1548                  $row['last_post_id'] = (int) $row['last_post_id'];
1549  
1550                  if (!isset($topic_data[$topic_id]))
1551                  {
1552                      // Hey, these posts come from a topic that does not exist
1553                      $delete_posts[$topic_id] = '';
1554                  }
1555                  else
1556                  {
1557                      // Unset the corresponding entry in $delete_topics
1558                      // When we'll be done, only topics with no posts will remain
1559                      unset($delete_topics[$topic_id]);
1560  
1561                      $topic_data[$topic_id]['replies_real'] += $row['total_posts'];
1562                      $topic_data[$topic_id]['first_post_id'] = (!$topic_data[$topic_id]['first_post_id']) ? $row['first_post_id'] : min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']);
1563  
1564                      if ($row['post_approved'] || !$topic_data[$topic_id]['last_post_id'])
1565                      {
1566                          $topic_data[$topic_id]['replies'] = $row['total_posts'] - 1;
1567                          $topic_data[$topic_id]['last_post_id'] = $row['last_post_id'];
1568                      }
1569                  }
1570              }
1571              $db->sql_freeresult($result);
1572  
1573              foreach ($topic_data as $topic_id => $row)
1574              {
1575                  $post_ids[] = $row['first_post_id'];
1576                  if ($row['first_post_id'] != $row['last_post_id'])
1577                  {
1578                      $post_ids[] = $row['last_post_id'];
1579                  }
1580              }
1581  
1582              // Now we delete empty topics and orphan posts
1583              if (sizeof($delete_posts))
1584              {
1585                  delete_posts('topic_id', array_keys($delete_posts), false);
1586                  unset($delete_posts);
1587              }
1588  
1589              if (!sizeof($topic_data))
1590              {
1591                  // If we get there, topic ids were invalid or topics did not contain any posts
1592                  delete_topics($where_type, $where_ids, true);
1593                  return;
1594              }
1595  
1596              if (sizeof($delete_topics))
1597              {
1598                  $delete_topic_ids = array();
1599                  foreach ($delete_topics as $topic_id => $void)
1600                  {
1601                      unset($topic_data[$topic_id]);
1602                      $delete_topic_ids[] = $topic_id;
1603                  }
1604  
1605                  delete_topics('topic_id', $delete_topic_ids, false);
1606                  unset($delete_topics, $delete_topic_ids);
1607              }
1608  
1609              // Make sure shadow topics do link to existing topics
1610              if (sizeof($moved_topics))
1611              {
1612                  $delete_topics = array();
1613  
1614                  $sql = 'SELECT t1.topic_id, t1.topic_moved_id
1615                      FROM ' . TOPICS_TABLE . ' t1
1616                      LEFT JOIN ' . TOPICS_TABLE . ' t2 ON (t2.topic_id = t1.topic_moved_id)
1617                      WHERE ' . $db->sql_in_set('t1.topic_id', $moved_topics) . '
1618                          AND t2.topic_id IS NULL';
1619                  $result = $db->sql_query($sql);
1620  
1621                  while ($row = $db->sql_fetchrow($result))
1622                  {
1623                      $delete_topics[] = $row['topic_id'];
1624                  }
1625                  $db->sql_freeresult($result);
1626  
1627                  if (sizeof($delete_topics))
1628                  {
1629                      delete_topics('topic_id', $delete_topics, false);
1630                  }
1631                  unset($delete_topics);
1632              }
1633  
1634              $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour
1635                  FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
1636                  WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
1637                      AND u.user_id = p.poster_id';
1638              $result = $db->sql_query($sql);
1639  
1640              $post_ids = array();
1641              while ($row = $db->sql_fetchrow($result))
1642              {
1643                  $topic_id = intval($row['topic_id']);
1644  
1645                  if ($row['post_id'] == $topic_data[$topic_id]['first_post_id'])
1646                  {
1647                      if ($topic_data[$topic_id]['topic_approved'] != $row['post_approved'])
1648                      {
1649                          $approved_unapproved_ids[] = $topic_id;
1650                      }
1651                      $topic_data[$topic_id]['time'] = $row['post_time'];
1652                      $topic_data[$topic_id]['poster'] = $row['poster_id'];
1653                      $topic_data[$topic_id]['first_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
1654                      $topic_data[$topic_id]['first_poster_colour'] = $row['user_colour'];
1655                  }
1656  
1657                  if ($row['post_id'] == $topic_data[$topic_id]['last_post_id'])
1658                  {
1659                      $topic_data[$topic_id]['last_poster_id'] = $row['poster_id'];
1660                      $topic_data[$topic_id]['last_post_subject'] = $row['post_subject'];
1661                      $topic_data[$topic_id]['last_post_time'] = $row['post_time'];
1662                      $topic_data[$topic_id]['last_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'];
1663                      $topic_data[$topic_id]['last_poster_colour'] = $row['user_colour'];
1664                  }
1665              }
1666              $db->sql_freeresult($result);
1667  
1668              // approved becomes unapproved, and vice-versa
1669              if (sizeof($approved_unapproved_ids))
1670              {
1671                  $sql = 'UPDATE ' . TOPICS_TABLE . '
1672                      SET topic_approved = 1 - topic_approved
1673                      WHERE ' . $db->sql_in_set('topic_id', $approved_unapproved_ids);
1674                  $db->sql_query($sql);
1675              }
1676              unset($approved_unapproved_ids);
1677  
1678              // These are fields that will be synchronised
1679              $fieldnames = array('time', 'replies', 'replies_real', 'poster', 'first_post_id', 'first_poster_name', 'first_poster_colour', 'last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour');
1680  
1681              if ($sync_extra)
1682              {
1683                  // This routine assumes that post_reported values are correct
1684                  // if they are not, use sync('post_reported') first
1685                  $sql = 'SELECT t.topic_id, p.post_id
1686                      FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
1687                      $where_sql_and p.topic_id = t.topic_id
1688                          AND p.post_reported = 1
1689                      GROUP BY t.topic_id, p.post_id";
1690                  $result = $db->sql_query($sql);
1691  
1692                  $fieldnames[] = 'reported';
1693                  while ($row = $db->sql_fetchrow($result))
1694                  {
1695                      $topic_data[intval($row['topic_id'])]['reported'] = 1;
1696                  }
1697                  $db->sql_freeresult($result);
1698  
1699                  // This routine assumes that post_attachment values are correct
1700                  // if they are not, use sync('post_attachment') first
1701                  $sql = 'SELECT t.topic_id, p.post_id
1702                      FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
1703                      $where_sql_and p.topic_id = t.topic_id
1704                          AND p.post_attachment = 1
1705                      GROUP BY t.topic_id, p.post_id";
1706                  $result = $db->sql_query($sql);
1707  
1708                  $fieldnames[] = 'attachment';
1709                  while ($row = $db->sql_fetchrow($result))
1710                  {
1711                      $topic_data[intval($row['topic_id'])]['attachment'] = 1;
1712                  }
1713                  $db->sql_freeresult($result);
1714              }
1715  
1716              foreach ($topic_data as $topic_id => $row)
1717              {
1718                  $sql_ary = array();
1719  
1720                  foreach ($fieldnames as $fieldname)
1721                  {
1722                      if (isset($row[$fieldname]) && isset($row['topic_' . $fieldname]) && $row['topic_' . $fieldname] != $row[$fieldname])
1723                      {
1724                          $sql_ary['topic_' . $fieldname] = $row[$fieldname];
1725                      }
1726                  }
1727  
1728                  if (sizeof($sql_ary))
1729                  {
1730                      $sql = 'UPDATE ' . TOPICS_TABLE . '
1731                          SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1732                          WHERE topic_id = ' . $topic_id;
1733                      $db->sql_query($sql);
1734  
1735                      $resync_forums[$row['forum_id']] = $row['forum_id'];
1736                  }
1737              }
1738              unset($topic_data);
1739  
1740              // if some topics have been resync'ed then resync parent forums
1741              // except when we're only syncing a range, we don't want to sync forums during
1742              // batch processing.
1743              if ($resync_parents && sizeof($resync_forums) && $where_type != 'range')
1744              {
1745                  sync('forum', 'forum_id', array_values($resync_forums), true);
1746              }
1747          break;
1748      }
1749  
1750      return;
1751  }
1752  
1753  /**
1754  * Prune function
1755  */
1756  function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync = true)
1757  {
1758      global $db;
1759  
1760      if (!is_array($forum_id))
1761      {
1762          $forum_id = array($forum_id);
1763      }
1764  
1765      if (!sizeof($forum_id))
1766      {
1767          return;
1768      }
1769  
1770      $sql_and = '';
1771  
1772      if (!($prune_flags & FORUM_FLAG_PRUNE_ANNOUNCE))
1773      {
1774          $sql_and .= ' AND topic_type <> ' . POST_ANNOUNCE;
1775      }
1776  
1777      if (!($prune_flags & FORUM_FLAG_PRUNE_STICKY))
1778      {
1779          $sql_and .= ' AND topic_type <> ' . POST_STICKY;
1780      }
1781  
1782      if ($prune_mode == 'posted')
1783      {
1784          $sql_and .= " AND topic_last_post_time < $prune_date";
1785      }
1786  
1787      if ($prune_mode == 'viewed')
1788      {
1789          $sql_and .= " AND topic_last_view_time < $prune_date";
1790      }
1791  
1792      $sql = 'SELECT topic_id
1793          FROM ' . TOPICS_TABLE . '
1794          WHERE ' . $db->sql_in_set('forum_id', $forum_id) . "
1795              AND poll_start = 0 
1796              $sql_and";
1797      $result = $db->sql_query($sql);
1798  
1799      $topic_list = array();
1800      while ($row = $db->sql_fetchrow($result))
1801      {
1802          $topic_list[] = $row['topic_id'];
1803      }
1804      $db->sql_freeresult($result);
1805  
1806      if ($prune_flags & FORUM_FLAG_PRUNE_POLL)
1807      {
1808          $sql = 'SELECT topic_id
1809              FROM ' . TOPICS_TABLE . '
1810              WHERE ' . $db->sql_in_set('forum_id', $forum_id) . "
1811                  AND poll_start > 0 
1812                  AND poll_last_vote < $prune_date 
1813                  $sql_and";
1814          $result = $db->sql_query($sql);
1815  
1816          while ($row = $db->sql_fetchrow($result))
1817          {
1818              $topic_list[] = $row['topic_id'];
1819          }
1820          $db->sql_freeresult($result);
1821  
1822          $topic_list = array_unique($topic_list);
1823      }
1824  
1825      return delete_topics('topic_id', $topic_list, $auto_sync);
1826  }
1827  
1828  /**
1829  * Function auto_prune(), this function now relies on passed vars
1830  */
1831  function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq)
1832  {
1833      global $db;
1834  
1835      $sql = 'SELECT forum_name
1836          FROM ' . FORUMS_TABLE . "
1837          WHERE forum_id = $forum_id";
1838      $result = $db->sql_query($sql, 3600);
1839      $row = $db->sql_fetchrow($result);
1840      $db->sql_freeresult($result);
1841  
1842      if ($row)
1843      {
1844          $prune_date = time() - ($prune_days * 86400);
1845          $next_prune = time() + ($prune_freq * 86400);
1846  
1847          prune($forum_id, $prune_mode, $prune_date, $prune_flags, true);
1848  
1849          $sql = 'UPDATE ' . FORUMS_TABLE . "
1850              SET prune_next = $next_prune
1851              WHERE forum_id = $forum_id";
1852          $db->sql_query($sql);
1853  
1854          add_log('admin', 'LOG_AUTO_PRUNE', $row['forum_name']);
1855      }
1856  
1857      return;
1858  }
1859  
1860  /**
1861  * remove_comments will strip the sql comment lines out of an uploaded sql file
1862  * specifically for mssql and postgres type files in the install....
1863  */
1864  function remove_comments(&$output)
1865  {
1866      $lines = explode("\n", $output);
1867      $output = '';
1868  
1869      // try to keep mem. use down
1870      $linecount = sizeof($lines);
1871  
1872      $in_comment = false;
1873      for ($i = 0; $i < $linecount; $i++)
1874      {
1875          if (trim($lines[$i]) == '/*')
1876          {
1877              $in_comment = true;
1878          }
1879  
1880          if (!$in_comment)
1881          {
1882              $output .= $lines[$i] . "\n";
1883          }
1884  
1885          if (trim($lines[$i]) == '*/')
1886          {
1887              $in_comment = false;
1888          }
1889      }
1890  
1891      unset($lines);
1892      return $output;
1893  }
1894  
1895  /**
1896  * remove_remarks will strip the sql comment lines out of an uploaded sql file
1897  */
1898  function remove_remarks(&$sql)
1899  {
1900      $sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql));
1901  }
1902  
1903  /**
1904  * split_sql_file will split an uploaded sql file into single sql statements.
1905  * Note: expects trim() to have already been run on $sql.
1906  */
1907  function split_sql_file($sql, $delimiter)
1908  {
1909      $sql = str_replace("\r" , '', $sql);
1910      $data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql);
1911  
1912      foreach ($data as $key => $value)
1913      {
1914          $data[$key] = trim($value);
1915      }
1916  
1917      // The empty case
1918      $end_data = end($data);
1919  
1920      if (empty($end_data))
1921      {
1922          unset($data[key($data)]);
1923      }
1924  
1925      return $data;
1926  }
1927  
1928  /**
1929  * Cache moderators, called whenever permissions are changed via admin_permissions. Changes of username
1930  * and group names must be carried through for the moderators table
1931  *
1932  * @todo let the admin define if he wants to display moderators (forum-based) - display_on_index already present and checked for...
1933  */
1934  function cache_moderators()
1935  {
1936      global $db, $cache, $auth, $phpbb_root_path, $phpEx;
1937  
1938      // Remove cached sql results
1939      $cache->destroy('sql', MODERATOR_CACHE_TABLE);
1940  
1941      // Clear table
1942      $db->sql_query((($db->sql_layer != 'sqlite') ? 'TRUNCATE TABLE ' : 'DELETE FROM ') . MODERATOR_CACHE_TABLE);
1943  
1944      // We add moderators who have forum moderator permissions without an explicit ACL_NEVER setting
1945      $hold_ary = $ug_id_ary = $sql_ary = array();
1946  
1947      // Grab all users having moderative options...
1948      $hold_ary = $auth->acl_user_raw_data(false, 'm_%', false);
1949  
1950      // Add users?
1951      if (sizeof($hold_ary))
1952      {
1953          // At least one moderative option warrants a display
1954          $ug_id_ary = array_keys($hold_ary);
1955  
1956          // Remove users who have group memberships with DENY moderator permissions
1957          $sql = $db->sql_build_query('SELECT', array(
1958              'SELECT'    => 'a.forum_id, ug.user_id',
1959  
1960              'FROM'        => array(
1961                  ACL_OPTIONS_TABLE    => 'o',
1962                  USER_GROUP_TABLE    => 'ug',
1963                  ACL_GROUPS_TABLE    => 'a'
1964              ),
1965  
1966              'LEFT_JOIN'    => array(
1967                  array(
1968                      'FROM'    => array(ACL_ROLES_DATA_TABLE => 'r'),
1969                      'ON'    => 'a.auth_role_id = r.role_id'
1970                  )
1971              ),
1972  
1973              'WHERE'        => '(o.auth_option_id = a.auth_option_id OR o.auth_option_id = r.auth_option_id)
1974                  AND ((a.auth_setting = ' . ACL_NEVER . ' AND r.auth_setting IS NULL)
1975                      OR r.auth_setting = ' . ACL_NEVER . ')
1976                  AND a.group_id = ug.group_id
1977                  AND ' . $db->sql_in_set('ug.user_id', $ug_id_ary) . "
1978                  AND ug.user_pending = 0
1979                  AND o.auth_option LIKE 'm\_%'" . 
1980                  (($db->sql_layer == 'mssql' || $db->sql_layer == 'mssql_odbc') ? " ESCAPE '\\'" : ''),
1981          ));
1982          $result = $db->sql_query($sql);
1983  
1984          while ($row = $db->sql_fetchrow($result))
1985          {
1986              if (isset($hold_ary[$row['user_id']][$row['forum_id']]))
1987              {
1988                  unset($hold_ary[$row['user_id']][$row['forum_id']]);
1989              }
1990          }
1991          $db->sql_freeresult($result);
1992  
1993          if (sizeof($hold_ary))
1994          {
1995              // Get usernames...
1996              $sql = 'SELECT user_id, username
1997                  FROM ' . USERS_TABLE . '
1998                  WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary));
1999              $result = $db->sql_query($sql);
2000  
2001              $usernames_ary = array();
2002              while ($row = $db->sql_fetchrow($result))
2003              {
2004                  $usernames_ary[$row['user_id']] = $row['username'];
2005              }
2006  
2007              foreach ($hold_ary as $user_id => $forum_id_ary)
2008              {
2009                  // Do not continue if user does not exist
2010                  if (!isset($usernames_ary[$user_id]))
2011                  {
2012                      continue;
2013                  }
2014  
2015                  foreach ($forum_id_ary as $forum_id => $auth_ary)
2016                  {
2017                      $sql_ary[] = array(
2018                          'forum_id'        => $forum_id,
2019                          'user_id'        => $user_id,
2020                          'username'        => $usernames_ary[$user_id],
2021                          'group_id'        => 0,
2022                          'group_name'    => ''
2023                      );
2024                  }
2025              }
2026          }
2027      }
2028  
2029      // Now to the groups...
2030      $hold_ary = $auth->acl_group_raw_data(false, 'm_%', false);
2031  
2032      if (sizeof($hold_ary))
2033      {
2034          $ug_id_ary = array_keys($hold_ary);
2035  
2036          // Make sure not hidden or special groups are involved...
2037          $sql = 'SELECT group_name, group_id, group_type
2038              FROM  ' . GROUPS_TABLE . '
2039              WHERE ' . $db->sql_in_set('group_id', $ug_id_ary);
2040          $result = $db->sql_query($sql);
2041  
2042          $groupnames_ary = array();
2043          while ($row = $db->sql_fetchrow($result))
2044          {
2045              if ($row['group_type'] == GROUP_HIDDEN || $row['group_type'] == GROUP_SPECIAL)
2046              {
2047                  unset($hold_ary[$row['group_id']]);
2048              }
2049  
2050              $groupnames_ary[$row['group_id']] = $row['group_name'];
2051          }
2052          $db->sql_freeresult($result);
2053  
2054          foreach ($hold_ary as $group_id => $forum_id_ary)
2055          {
2056              // If there is no group, we do not assign it...
2057              if (!isset($groupnames_ary[$group_id]))
2058              {
2059                  continue;
2060              }
2061  
2062              foreach ($forum_id_ary as $forum_id => $auth_ary)
2063              {
2064                  $flag = false;
2065                  foreach ($auth_ary as $auth_option => $setting)
2066                  {
2067                      // Make sure at least one ACL_YES option is set...
2068                      if ($setting == ACL_YES)
2069                      {
2070                          $flag = true;
2071                          break;
2072                      }
2073                  }
2074  
2075                  if (!$flag)
2076                  {
2077                      continue;
2078                  }
2079  
2080                  $sql_ary[] = array(
2081                      'forum_id'        => $forum_id,
2082                      'user_id'        => 0,
2083                      'username'        => '',
2084                      'group_id'        => $group_id,
2085                      'group_name'    => $groupnames_ary[$group_id]
2086                  );
2087              }
2088          }
2089      }
2090  
2091      $db->sql_multi_insert(MODERATOR_CACHE_TABLE, $sql_ary);
2092  }
2093  
2094  /**
2095  * View log
2096  */
2097  function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $limit_days = 0, $sort_by = 'l.log_time DESC')
2098  {
2099      global $db, $user, $auth, $phpEx, $phpbb_root_path, $phpbb_admin_path;
2100  
2101      $topic_id_list = $reportee_id_list = $is_auth = $is_mod = array();
2102  
2103      $profile_url = (defined('IN_ADMIN')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview') : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile');
2104  
2105      switch ($mode)
2106      {
2107          case 'admin':
2108              $log_type = LOG_ADMIN;
2109              $sql_forum = '';
2110          break;
2111  
2112          case 'mod':
2113              $log_type = LOG_MOD;
2114  
2115              if ($topic_id)
2116              {
2117                  $sql_forum = 'AND l.topic_id = ' . intval($topic_id);
2118              }
2119              else if (is_array($forum_id))
2120              {
2121                  $sql_forum = 'AND ' . $db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
2122              }
2123              else
2124              {
2125                  $sql_forum = ($forum_id) ? 'AND l.forum_id = ' . intval($forum_id) : '';
2126              }
2127          break;
2128  
2129          case 'user':
2130              $log_type = LOG_USERS;
2131              $sql_forum = 'AND l.reportee_id = ' . intval($user_id);
2132          break;
2133          
2134          case 'users':
2135              $log_type = LOG_USERS;
2136              $sql_forum = '';
2137          break;
2138  
2139          case 'critical':
2140              $log_type = LOG_CRITICAL;
2141              $sql_forum = '';
2142          break;
2143          
2144          default:
2145              return;
2146      }
2147  
2148      $sql = "SELECT l.*, u.username
2149          FROM " . LOG_TABLE . " l, " . USERS_TABLE . " u
2150          WHERE l.log_type = $log_type
2151              AND u.user_id = l.user_id
2152              " . (($limit_days) ? "AND l.log_time >= $limit_days" : '') . "
2153              $sql_forum
2154          ORDER BY $sort_by";
2155      $result = $db->sql_query_limit($sql, $limit, $offset);
2156  
2157      $i = 0;
2158      $log = array();
2159      while ($row = $db->sql_fetchrow($result))
2160      {
2161          if ($row['topic_id'])
2162          {
2163              $topic_id_list[] = $row['topic_id'];
2164          }
2165  
2166          if ($row['reportee_id'])
2167          {
2168              $reportee_id_list[] = $row['reportee_id'];
2169          }
2170  
2171          $log[$i] = array(
2172              'id'                => $row['log_id'],
2173              'reportee_id'        => $row['reportee_id'],
2174              'reportee_username'    => '',
2175              'user_id'            => $row['user_id'],
2176              'username'            => '<a href="' . $profile_url . '&amp;u=' . $row['user_id'] . '">' . $row['username'] . '</a>',
2177              'ip'                => $row['log_ip'],
2178              'time'                => $row['log_time'],
2179              'forum_id'            => $row['forum_id'],
2180              'topic_id'            => $row['topic_id'],
2181  
2182              'viewforum'            => ($row['forum_id'] && $auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']) : false,
2183              'action'            => (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
2184          );
2185  
2186          if (!empty($row['log_data']))
2187          {
2188              $log_data_ary = unserialize($row['log_data']);
2189  
2190              if (isset($user->lang[$row['log_operation']]))
2191              {
2192                  $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary);
2193                  $log[$i]['action'] = str_replace("\n", '<br />', censor_text($log[$i]['action']));
2194              }
2195              else
2196              {
2197                  $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
2198              }
2199          }
2200  
2201          $i++;
2202      }
2203      $db->sql_freeresult($result);
2204  
2205      if (sizeof($topic_id_list))
2206      {
2207          $topic_id_list = array_unique($topic_id_list);
2208  
2209          // This query is not really needed if move_topics() updates the forum_id field, 
2210          // although it's also used to determine if the topic still exists in the database
2211          $sql = 'SELECT topic_id, forum_id
2212              FROM ' . TOPICS_TABLE . '
2213              WHERE ' . $db->sql_in_set('topic_id', array_map('intval', $topic_id_list));
2214          $result = $db->sql_query($sql);
2215  
2216          $default_forum_id = 0;
2217  
2218          while ($row = $db->sql_fetchrow($result))
2219          {
2220              if (!$row['forum_id'])
2221              {
2222                  if ($auth->acl_getf_global('f_read'))
2223                  {
2224                      if (!$default_forum_id)
2225                      {
2226                          $sql = 'SELECT forum_id
2227                              FROM ' . FORUMS_TABLE . '
2228                              WHERE forum_type = ' . FORUM_POST;
2229                          $f_result = $db->sql_query_limit($sql, 1);
2230                          $default_forum_id = (int) $db->sql_fetchfield('forum_id', false, $f_result);
2231                          $db->sql_freeresult($f_result);
2232                      }
2233  
2234                      $is_auth[$row['topic_id']] = $default_forum_id;
2235                  }
2236              }
2237              else
2238              {
2239                  if ($auth->acl_get('f_read', $row['forum_id']))
2240                  {
2241                      $is_auth[$row['topic_id']] = $row['forum_id'];
2242                  }
2243              }
2244  
2245              if ($auth->acl_gets('a_', 'm_', $row['forum_id']))
2246              {
2247                  $is_mod[$row['topic_id']] = $row['forum_id'];
2248              }
2249          }
2250          $db->sql_freeresult($result);
2251  
2252          foreach ($log as $key => $row)
2253          {
2254              $log[$key]['viewtopic'] = (isset($is_auth[$row['topic_id']])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $is_auth[$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
2255              $log[$key]['viewlogs'] = (isset($is_mod[$row['topic_id']])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $user->session_id) : false;
2256          }
2257      }
2258  
2259      if ($reportee_id_list)
2260      {
2261          $reportee_id_list = array_unique($reportee_id_list);
2262          $reportee_names_list = array();
2263  
2264          if (!function_exists('user_get_id_name'))
2265          {
2266              include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2267          }
2268  
2269          user_get_id_name($reportee_id_list, $reportee_names_list);
2270  
2271          foreach ($log as $key => $row)
2272          {
2273              $log[$key]['reportee_username'] = (isset($reportee_names_list[$row['reportee_id']])) ? '<a href="' . $profile_url . '&amp;u=' . $row['reportee_id'] . '">' . $reportee_names_list[$row['reportee_id']] . '</a>' : false;
2274          }
2275      }
2276  
2277      $sql = 'SELECT COUNT(l.log_id) AS total_entries
2278          FROM ' . LOG_TABLE . " l
2279          WHERE l.log_type = $log_type
2280              AND l.log_time >= $limit_days
2281              $sql_forum";
2282      $result = $db->sql_query($sql);
2283      $log_count = (int) $db->sql_fetchfield('total_entries');
2284      $db->sql_freeresult($result);
2285  
2286      return;
2287  }
2288  
2289  /**
2290  * Update foes - remove moderators and administrators from foe lists...
2291  */
2292  function update_foes()
2293  {
2294      global $db, $auth;
2295  
2296      $perms = array();
2297      foreach ($auth->acl_get_list(false, array('a_', 'm_'), false) as $forum_id => $forum_ary)
2298      {
2299          foreach ($forum_ary as $auth_option => $user_ary)
2300          {
2301              $perms = array_merge($perms, $user_ary);
2302          }
2303      }
2304  
2305      if (sizeof($perms))
2306      {
2307          $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' 
2308              WHERE ' . $db->sql_in_set('zebra_id', array_unique($perms)) . '
2309                  AND foe = 1';
2310          $db->sql_query($sql);
2311      }
2312      unset($perms);
2313  }
2314  
2315  /**
2316  * Lists inactive users
2317  */
2318  function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_inactive_time DESC')
2319  {
2320      global $db, $user;
2321  
2322      $sql = 'SELECT user_id, username, user_regdate, user_lastvisit, user_inactive_time, user_inactive_reason
2323          FROM ' . USERS_TABLE . ' 
2324          WHERE user_type = ' . USER_INACTIVE . 
2325          (($limit_days) ? " AND user_inactive_time >= $limit_days" : '') . " 
2326          ORDER BY $sort_by";
2327      $result = $db->sql_query_limit($sql, $limit, $offset);
2328  
2329      while ($row = $db->sql_fetchrow($result))
2330      {
2331          $row['inactive_reason'] = $user->lang['INACTIVE_REASON_UNKNOWN'];
2332          switch ($row['user_inactive_reason'])
2333          {
2334              case INACTIVE_REGISTER:
2335                  $row['inactive_reason'] = $user->lang['INACTIVE_REASON_REGISTER'];
2336              break;
2337  
2338              case INACTIVE_PROFILE:
2339                  $row['inactive_reason'] = $user->lang['INACTIVE_REASON_PROFILE'];
2340              break;
2341  
2342              case INACTIVE_MANUAL:
2343                  $row['inactive_reason'] = $user->lang['INACTIVE_REASON_MANUAL'];
2344              break;
2345  
2346              case INACTIVE_REMIND:
2347                  $row['inactive_reason'] = $user->lang['INACTIVE_REASON_REMIND'];
2348              break;
2349          }
2350      
2351          $users[] = $row;
2352      }
2353      
2354      $sql = 'SELECT COUNT(user_id) AS user_count
2355          FROM ' . USERS_TABLE . '
2356          WHERE user_type = ' . USER_INACTIVE . 
2357          (($limit_days) ? " AND user_inactive_time >= $limit_days" : '');
2358      $result = $db->sql_query($sql);
2359      $user_count = (int) $db->sql_fetchfield('user_count');
2360      $db->sql_freeresult($result);
2361  
2362      return;
2363  }
2364  
2365  /**
2366  * Lists warned users
2367  */
2368  function view_warned_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_warnings DESC')
2369  {
2370      global $db;
2371  
2372      $sql = 'SELECT user_id, username, user_warnings, user_last_warning
2373          FROM ' . USERS_TABLE . '
2374          WHERE user_warnings > 0
2375          ' . (($limit_days) ? "AND user_last_warning >= $limit_days" : '') . "
2376          ORDER BY $sort_by";
2377      $result = $db->sql_query_limit($sql, $limit, $offset);
2378      $users = $db->sql_fetchrowset($result);
2379      $db->sql_freeresult($result);
2380  
2381      $sql = 'SELECT count(user_id) AS user_count
2382          FROM ' . USERS_TABLE . '
2383          WHERE user_warnings > 0
2384          ' . (($limit_days) ? "AND user_last_warning >= $limit_days" : '');
2385      $result = $db->sql_query($sql);
2386      $user_count = (int) $db->sql_fetchfield('user_count');
2387      $db->sql_freeresult($result);
2388  
2389      return;
2390  }
2391  
2392  /**
2393  * Get database size
2394  * Currently only mysql and mssql are supported
2395  */
2396  function get_database_size()
2397  {
2398      global $db, $user, $table_prefix;
2399  
2400      $database_size = false;
2401  
2402      // This code is heavily influenced by a similar routine in phpMyAdmin 2.2.0
2403      switch ($db->sql_layer)
2404      {
2405          case 'mysql':
2406          case 'mysql4':
2407          case 'mysqli':
2408          
2409              $sql = 'SELECT VERSION() AS mysql_version';
2410              $result = $db->sql_query($sql);
2411              $row = $db->sql_fetchrow($result);
2412              $db->sql_freeresult($result);
2413  
2414              if ($row)
2415              {
2416                  $version = $row['mysql_version'];
2417  
2418                  if (preg_match('#(3\.23|[45]\.)#', $version))
2419                  {
2420                      $db_name = (preg_match('#^(?:3\.23\.(?:[6-9]|[1-9]{2}))|[45]\.#', $version)) ? "`{$db->dbname}`" : $db->dbname;
2421  
2422                      $sql = 'SHOW TABLE STATUS
2423                          FROM ' . $db_name;
2424                      $result = $db->sql_query($sql);
2425  
2426                      $database_size = 0;
2427                      while ($row = $db->sql_fetchrow($result))
2428                      {
2429                          if ((isset($row['Type']) && $row['Type'] != 'MRG_MyISAM') || (isset($row['Engine']) && ($row['Engine'] == 'MyISAM' || $row['Engine'] == 'InnoDB')))
2430                          {
2431                              if ($table_prefix != '')
2432                              {
2433                                  if (strpos($row['Name'], $table_prefix) !== false)
2434                                  {
2435                                      $database_size += $row['Data_length'] + $row['Index_length'];
2436                                  }
2437                              }
2438                              else
2439                              {
2440                                  $database_size += $row['Data_length'] + $row['Index_length'];
2441                              }
2442                          }
2443                      }
2444                      $db->sql_freeresult($result);
2445                  }
2446              }
2447  
2448          break;
2449  
2450          case 'mssql':
2451          case 'mssql_odbc':
2452          
2453              $sql = 'SELECT ((SUM(size) * 8.0) * 1024.0) as dbsize
2454                  FROM sysfiles';
2455              $result = $db->sql_query($sql);
2456              $database_size = ($row = $db->sql_fetchrow($result)) ? $row['dbsize'] : false;
2457              $db->sql_freeresult($result);
2458  
2459          break;
2460  
2461          case 'postgres':
2462  
2463              $sql = "SELECT proname
2464                  FROM pg_proc
2465                  WHERE proname = 'pg_database_size'";
2466              $result = $db->sql_query($sql);
2467              $row = $db->sql_fetchrow($result);
2468              $db->sql_freeresult($result);
2469  
2470              if ($row['proname'] == 'pg_database_size')
2471              {
2472                  $sql = "SELECT oid
2473                      FROM pg_database
2474                      WHERE datname = '" . $db->dbname . "'";
2475                  $result = $db->sql_query($sql);
2476                  $row = $db->sql_fetchrow($result);
2477                  $db->sql_freeresult($result);
2478  
2479                  $oid = $row['oid'];
2480  
2481                  $sql = 'SELECT pg_database_size(' . $oid . ') as size';
2482                  $result = $db->sql_query($sql);
2483                  $row = $db->sql_fetchrow($result);
2484                  $db->sql_freeresult($result);
2485  
2486                  $database_size = $row['size'];
2487              }
2488  
2489          break;
2490      }
2491  
2492      if ($database_size !== false)
2493      {
2494          $database_size = ($database_size >= 1048576) ? sprintf('%.2f ' . $user->lang['MB'], ($database_size / 1048576)) : (($database_size >= 1024) ? sprintf('%.2f ' . $user->lang['KB'], ($database_size / 1024)) : sprintf('%.2f ' . $user->lang['BYTES'], $database_size));
2495      }
2496      else
2497      {
2498          $database_size = $user->lang['NOT_AVAILABLE'];
2499      }
2500  
2501      return $database_size;
2502  }
2503  
2504  /**
2505  * Retrieve contents from remotely stored file
2506  */
2507  function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 10)
2508  {
2509      global $user;
2510  
2511      if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout))
2512      {
2513          @fputs($fsock, "GET $directory/$filename HTTP/1.1\r\n");
2514          @fputs($fsock, "HOST: $host\r\n");
2515          @fputs($fsock, "Connection: close\r\n\r\n");
2516      
2517          $file_info = '';
2518          $get_info = false;
2519  
2520          while (!@feof($fsock))
2521          {
2522              if ($get_info)
2523              {
2524                  $file_info .= @fread($fsock, 1024);
2525              }
2526              else
2527              {
2528                  $line = @fgets($fsock, 1024);
2529                  if ($line == "\r\n")
2530                  {
2531                      $get_info = true;
2532                  }
2533                  else if (strpos($line, '404 Not Found') !== false)
2534                  {
2535                      $errstr = $user->lang['FILE_NOT_FOUND'] . ': ' . $filename;
2536                      return false;
2537                  }
2538              }
2539          }
2540          @fclose($fsock);
2541      }
2542      else
2543      {
2544          if ($errstr)
2545          {
2546              return false;
2547          }
2548          else
2549          {
2550              $errstr = 'fsock disabled';
2551              return false;
2552          }
2553      }
2554      
2555      return $file_info;
2556  }
2557  
2558  /**
2559  * Tidy Warnings
2560  * Remove all warnings which have now expired from the database
2561  * The duration of a warning can be defined by the administrator
2562  * This only removes the warning and reduces the assosciated count,
2563  * it does not remove the user note recording the contents of the warning
2564  */
2565  function tidy_warnings()
2566  {
2567      global $db, $config;
2568  
2569      $expire_date = time() - ($config['warnings_expire_days'] * 86400);
2570      $warning_list = $user_list = array();
2571  
2572      $sql = 'SELECT * FROM ' . WARNINGS_TABLE . "
2573          WHERE warning_time < $expire_date";
2574      $result = $db->sql_query($sql);
2575  
2576      while ($row = $db->sql_fetchrow($result))
2577      {
2578          $warning_list[] = $row['warning_id'];
2579          $user_list[$row['user_id']] = isset($user_list[$row['user_id']]) ? $user_list[$row['user_id']]++ : 1;
2580      }
2581      $db->sql_freeresult($result);
2582  
2583      if (sizeof($warning_list))
2584      {
2585          $db->sql_transaction('begin');
2586  
2587          $sql = 'DELETE FROM ' . WARNINGS_TABLE . '
2588              WHERE ' . $db->sql_in_set('warning_id', $warning_list);
2589          $db->sql_query($sql);
2590      
2591          foreach ($user_list as $user_id => $value)
2592          {
2593              $sql = 'UPDATE ' . USERS_TABLE . " SET user_warnings = user_warnings - $value
2594                  WHERE user_id = $user_id";
2595              $db->sql_query($sql);
2596          }
2597  
2598          $db->sql_transaction('commit');
2599      }
2600  
2601      set_config('warnings_last_gc', time(), true);
2602  }
2603  
2604  /**
2605  * Tidy database, doing some maintanance tasks
2606  */
2607  function tidy_database()
2608  {
2609      global $db;
2610  
2611      set_config('database_last_gc', time(), true);
2612  }
2613  
2614  /**
2615  * Add permission language - this will make sure custom files will be included
2616  */
2617  function add_permission_language()
2618  {
2619      global $user, $phpEx;
2620  
2621      // First of all, our own file.
2622      $user->add_lang('acp/permissions_phpbb');
2623  
2624      $files_to_add = array();
2625  
2626      // Now search in acp and mods folder for permissions_ files.
2627      foreach (array('acp/', 'mods/') as $path)
2628      {
2629          $dh = opendir($user->lang_path . $path);
2630  
2631          if ($dh !== false)
2632          {
2633              while (($file = readdir($dh)) !== false)
2634              {
2635                  if (strpos($file, 'permissions_') === 0 && strpos($file, 'permissions_phpbb') === false && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx)
2636                  {
2637                      $files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1));
2638                  }
2639              }
2640              closedir($dh);
2641          }
2642      }
2643  
2644      if (!sizeof($files_to_add))
2645      {
2646          return false;
2647      }
2648  
2649      $user->add_lang($files_to_add);
2650      return true;
2651  }
2652  
2653  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6