[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/includes/ -> functions_convert.php (source)

   1  <?php
   2  /**
   3  *
   4  * @package install
   5  * @version $Id$
   6  * @copyright (c) 2006 phpBB Group
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
   8  *
   9  */
  10  
  11  /**
  12  * @ignore
  13  */
  14  if (!defined('IN_PHPBB'))
  15  {
  16      exit;
  17  }
  18  
  19  /**
  20  * Default avatar width/height
  21  * @ignore
  22  */
  23  define('DEFAULT_AVATAR_X', 80);
  24  define('DEFAULT_AVATAR_Y', 80);
  25  
  26  // Global functions - all functions can be used by convertors
  27  
  28  // SIMPLE FUNCTIONS
  29  
  30  /**
  31  * Return the preceding value
  32  */
  33  function dec($var)
  34  {
  35      return --$var;
  36  }
  37  
  38  /**
  39  * Return the next value
  40  */
  41  function inc($var)
  42  {
  43      return ++$var;
  44  }
  45  
  46  /**
  47  * Return whether the value is positive
  48  */
  49  function is_positive($n)
  50  {
  51      return ($n > 0) ? 1 : 0;
  52  }
  53  
  54  /**
  55  * Boolean inverse of the value
  56  */
  57  function not($var)
  58  {
  59      return ($var) ? 0 : 1;
  60  }
  61  
  62  /**
  63  * Convert a textual value to it's equivalent boolean value
  64  *
  65  * @param string $str String to convert (converts yes, on, y, 1 and true to boolean true)
  66  * @return boolean The equivalent value
  67  */
  68  function str_to_bool($str)
  69  {
  70      $str = strtolower($str);
  71      return ($str == 'yes' || $str == 'on' || $str == 'y' || $str == 'true' || $str == '1') ? true : false;
  72  }
  73  
  74  /**
  75  * Function to mimic php's empty() function (it is the same)
  76  */
  77  function is_empty($mixed)
  78  {
  79      return empty($mixed);
  80  }
  81  
  82  /**
  83  * Convert the name of a user's primary group to the appropriate equivalent phpBB group id
  84  *
  85  * @param string $status The name of the group
  86  * @return int The group_id corresponding to the equivalent group
  87  */
  88  function str_to_primary_group($status)
  89  {
  90      switch (ucfirst(strtolower($status)))
  91      {
  92          case 'Administrator':
  93              return get_group_id('administrators');
  94          break;
  95  
  96          case 'Super moderator':
  97          case 'Global moderator':
  98          case 'Moderator':
  99              return get_group_id('global_moderators');
 100          break;
 101  
 102          case 'Guest':
 103          case 'Anonymous':
 104              return get_group_id('guests');
 105          break;
 106  
 107          default:
 108              return get_group_id('registered');
 109          break;
 110      }
 111  }
 112  
 113  /**
 114  * Convert a boolean into the appropriate phpBB constant indicating whether the item is locked
 115  */
 116  function is_item_locked($bool)
 117  {
 118      return ($bool) ? ITEM_LOCKED : ITEM_UNLOCKED;
 119  }
 120  
 121  /**
 122  * Convert a value from days to seconds
 123  */
 124  function days_to_seconds($days)
 125  {
 126      return ($days * 86400);
 127  }
 128  
 129  /**
 130  * Determine whether a user is anonymous and return the appropriate new user_id
 131  */
 132  function is_user_anonymous($user_id)
 133  {
 134      return ($user_id > ANONYMOUS) ? $user_id : ANONYMOUS;
 135  }
 136  
 137  /**
 138  * Generate a key value based on existing values
 139  *
 140  * @param int $pad Amount to add to the maximum value
 141  * @return int Key value
 142  */
 143  function auto_id($pad = 0)
 144  {
 145      global $auto_id, $convert_row;
 146  
 147      if (!empty($convert_row['max_id']))
 148      {
 149          return $convert_row['max_id'] + $pad;
 150      }
 151  
 152      return $auto_id + $pad;
 153  }
 154  
 155  /**
 156  * Convert a boolean into the appropriate phpBB constant indicating whether the user is active
 157  */
 158  function set_user_type($user_active)
 159  {
 160      return ($user_active) ? USER_NORMAL : USER_INACTIVE;
 161  }
 162  
 163  /**
 164  * Convert a value from minutes to hours
 165  */
 166  function minutes_to_hours($minutes)
 167  {
 168      return ($minutes / 3600);
 169  }
 170  
 171  /**
 172  * Return the group_id for a given group name
 173  */
 174  function get_group_id($group_name)
 175  {
 176      global $db, $group_mapping;
 177  
 178      if (empty($group_mapping))
 179      {
 180          $sql = 'SELECT group_name, group_id
 181              FROM ' . GROUPS_TABLE;
 182          $result = $db->sql_query($sql);
 183  
 184          $group_mapping = array();
 185          while ($row = $db->sql_fetchrow($result))
 186          {
 187              $group_mapping[strtoupper($row['group_name'])] = (int) $row['group_id'];
 188          }
 189          $db->sql_freeresult($result);
 190      }
 191  
 192      if (!sizeof($group_mapping))
 193      {
 194          add_default_groups();
 195          return get_group_id($group_name);
 196      }
 197  
 198      if (isset($group_mapping[strtoupper($group_name)]))
 199      {
 200          return $group_mapping[strtoupper($group_name)];
 201      }
 202  
 203      return $group_mapping['REGISTERED'];
 204  }
 205  
 206  /**
 207  * Generate the email hash stored in the users table
 208  *
 209  * Note: Deprecated, calls should directly go to phpbb_email_hash()
 210  */
 211  function gen_email_hash($email)
 212  {
 213      return phpbb_email_hash($email);
 214  }
 215  
 216  /**
 217  * Convert a boolean into the appropriate phpBB constant indicating whether the topic is locked
 218  */
 219  function is_topic_locked($bool)
 220  {
 221      return (!empty($bool)) ? ITEM_LOCKED : ITEM_UNLOCKED;
 222  }
 223  
 224  /**
 225  * Generate a bbcode_uid value
 226  */
 227  function make_uid($timestamp)
 228  {
 229      static $last_timestamp, $last_uid;
 230  
 231      if (empty($last_timestamp) || $timestamp != $last_timestamp)
 232      {
 233          $last_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);
 234      }
 235      $last_timestamp = $timestamp;
 236      return $last_uid;
 237  }
 238  
 239  
 240  /**
 241  * Validate a website address
 242  */
 243  function validate_website($url)
 244  {
 245      if ($url === 'http://')
 246      {
 247          return '';
 248      }
 249      else if (!preg_match('#^[a-z0-9]+://#i', $url) && strlen($url) > 0)
 250      {
 251          return 'http://' . $url;
 252      }
 253      return $url;
 254  }
 255  
 256  /**
 257  * Convert nulls to zeros for fields which allowed a NULL value in the source but not the destination
 258  */
 259  function null_to_zero($value)
 260  {
 261      return ($value === NULL) ? 0 : $value;
 262  }
 263  
 264  /**
 265  * Convert nulls to empty strings for fields which allowed a NULL value in the source but not the destination
 266  */
 267  function null_to_str($value)
 268  {
 269      return ($value === NULL) ? '' : $value;
 270  }
 271  
 272  // EXTENDED FUNCTIONS
 273  
 274  /**
 275  * Get old config value
 276  */
 277  function get_config_value($config_name)
 278  {
 279      static $convert_config;
 280  
 281      if (!isset($convert_config))
 282      {
 283          $convert_config = get_config();
 284      }
 285  
 286      if (!isset($convert_config[$config_name]))
 287      {
 288          return false;
 289      }
 290  
 291      return (empty($convert_config[$config_name])) ? '' : $convert_config[$config_name];
 292  }
 293  
 294  /**
 295  * Convert an IP address from the hexadecimal notation to normal dotted-quad notation
 296  */
 297  function decode_ip($int_ip)
 298  {
 299      if (!$int_ip)
 300      {
 301          return $int_ip;
 302      }
 303  
 304      $hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
 305  
 306      // Any mod changing the way ips are stored? Then we are not able to convert and enter the ip "as is" to not "destroy" anything...
 307      if (sizeof($hexipbang) < 4)
 308      {
 309          return $int_ip;
 310      }
 311  
 312      return hexdec($hexipbang[0]) . '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
 313  }
 314  
 315  /**
 316  * Reverse the encoding of wild-carded bans
 317  */
 318  function decode_ban_ip($int_ip)
 319  {
 320      return str_replace('255', '*', decode_ip($int_ip));
 321  }
 322  
 323  /**
 324  * Determine the MIME-type of a specified filename
 325  * This does not actually inspect the file, but simply uses the file extension
 326  */
 327  function mimetype($filename)
 328  {
 329      if (!preg_match('/\.([a-z0-9]+)$/i', $filename, $m))
 330      {
 331          return 'application/octet-stream';
 332      }
 333  
 334      switch (strtolower($m[1]))
 335      {
 336          case 'zip':        return 'application/zip';
 337          case 'jpeg':    return 'image/jpeg';
 338          case 'jpg':        return 'image/jpeg';
 339          case 'jpe':        return 'image/jpeg';
 340          case 'png':        return 'image/png';
 341          case 'gif':        return 'image/gif';
 342          case 'htm':
 343          case 'html':    return 'text/html';
 344          case 'tif':        return 'image/tiff';
 345          case 'tiff':    return 'image/tiff';
 346          case 'ras':        return 'image/x-cmu-raster';
 347          case 'pnm':        return 'image/x-portable-anymap';
 348          case 'pbm':        return 'image/x-portable-bitmap';
 349          case 'pgm':        return 'image/x-portable-graymap';
 350          case 'ppm':        return 'image/x-portable-pixmap';
 351          case 'rgb':        return 'image/x-rgb';
 352          case 'xbm':        return 'image/x-xbitmap';
 353          case 'xpm':        return 'image/x-xpixmap';
 354          case 'xwd':        return 'image/x-xwindowdump';
 355          case 'z':        return 'application/x-compress';
 356          case 'gtar':    return 'application/x-gtar';
 357          case 'tgz':        return 'application/x-gtar';
 358          case 'gz':        return 'application/x-gzip';
 359          case 'tar':        return 'application/x-tar';
 360          case 'xls':        return 'application/excel';
 361          case 'pdf':        return 'application/pdf';
 362          case 'ppt':        return 'application/powerpoint';
 363          case 'rm':        return 'application/vnd.rn-realmedia';
 364          case 'wma':        return 'audio/x-ms-wma';
 365          case 'swf':        return 'application/x-shockwave-flash';
 366          case 'ief':        return 'image/ief';
 367          case 'doc':
 368          case 'dot':
 369          case 'wrd':        return 'application/msword';
 370          case 'ai':
 371          case 'eps':
 372          case 'ps':        return 'application/postscript';
 373          case 'asc':
 374          case 'txt':
 375          case 'c':
 376          case 'cc':
 377          case 'h':
 378          case 'hh':
 379          case 'cpp':
 380          case 'hpp':
 381          case 'php':
 382          case 'php3':    return 'text/plain';
 383          default:         return 'application/octet-stream';
 384      }
 385  }
 386  
 387  /**
 388  * Obtain the dimensions of all remotely hosted avatars
 389  * This should only be called from execute_last
 390  * There can be significant network overhead if there are a large number of remote avatars
 391  * @todo Look at the option of allowing the user to decide whether this is called or to force the dimensions
 392  */
 393  function remote_avatar_dims()
 394  {
 395      global $db;
 396  
 397      $sql = 'SELECT user_id, user_avatar
 398          FROM ' . USERS_TABLE . '
 399          WHERE user_avatar_type = ' . AVATAR_REMOTE;
 400      $result = $db->sql_query($sql);
 401  
 402      $remote_avatars = array();
 403      while ($row = $db->sql_fetchrow($result))
 404      {
 405          $remote_avatars[(int) $row['user_id']] = $row['user_avatar'];
 406      }
 407      $db->sql_freeresult($result);
 408  
 409      foreach ($remote_avatars as $user_id => $avatar)
 410      {
 411          $width = (int) get_remote_avatar_dim($avatar, 0);
 412          $height = (int) get_remote_avatar_dim($avatar, 1);
 413  
 414          $sql = 'UPDATE ' . USERS_TABLE . '
 415              SET user_avatar_width = ' . (int) $width . ', user_avatar_height = ' . (int) $height . '
 416              WHERE user_id = ' . $user_id;
 417          $db->sql_query($sql);
 418      }
 419  }
 420  
 421  function import_avatar_gallery($gallery_name = '', $subdirs_as_galleries = false)
 422  {
 423      global $config, $convert, $phpbb_root_path, $user;
 424  
 425      $relative_path = empty($convert->convertor['source_path_absolute']);
 426  
 427      // check for trailing slash
 428      if (rtrim($convert->convertor['avatar_gallery_path'], '/') === '')
 429      {
 430          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'import_avatar_gallery()'), __LINE__, __FILE__);
 431      }
 432  
 433      $src_path = relative_base(path($convert->convertor['avatar_gallery_path'], $relative_path), $relative_path);
 434  
 435      if (is_dir($src_path))
 436      {
 437          // Do not die on failure... safe mode restrictions may be in effect.
 438          copy_dir($convert->convertor['avatar_gallery_path'], path($config['avatar_gallery_path']) . $gallery_name, !$subdirs_as_galleries, false, false, $relative_path);
 439  
 440          // only doing 1 level deep. (ibf 1.x)
 441          // notes: ibf has 2 tiers: directly in the avatar directory for base gallery (handled in the above statement), plus subdirs(handled below).
 442          // recursive subdirs ignored. -- i don't know if other forums support recursive galleries. if they do, this following code could be upgraded to be recursive.
 443          if ($subdirs_as_galleries)
 444          {
 445              $dirlist = array();
 446              if ($handle = @opendir($src_path))
 447              {
 448                  while ($entry = readdir($handle))
 449                  {
 450                      if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
 451                      {
 452                          continue;
 453                      }
 454  
 455                      if (is_dir($src_path . $entry))
 456                      {
 457                          $dirlist[] = $entry;
 458                      }
 459                  }
 460                  closedir($handle);
 461              }
 462              else if ($dir = @dir($src_path))
 463              {
 464                  while ($entry = $dir->read())
 465                  {
 466                      if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
 467                      {
 468                          continue;
 469                      }
 470  
 471                      if (is_dir($src_path . $entry))
 472                      {
 473                          $dirlist[] = $entry;
 474                      }
 475                  }
 476                  $dir->close();
 477              }
 478  
 479              for ($i = 0; $i < sizeof($dirlist); ++$i)
 480              {
 481                  $dir = $dirlist[$i];
 482  
 483                  // Do not die on failure... safe mode restrictions may be in effect.
 484                  copy_dir(path($convert->convertor['avatar_gallery_path'], $relative_path) . $dir, path($config['avatar_gallery_path']) . $dir, true, false, false, $relative_path);
 485              }
 486          }
 487      }
 488  }
 489  
 490  function import_attachment_files($category_name = '')
 491  {
 492      global $config, $convert, $phpbb_root_path, $db, $user;
 493  
 494      $sql = 'SELECT config_value AS upload_path
 495          FROM ' . CONFIG_TABLE . "
 496          WHERE config_name = 'upload_path'";
 497      $result = $db->sql_query($sql);
 498      $config['upload_path'] = $db->sql_fetchfield('upload_path');
 499      $db->sql_freeresult($result);
 500  
 501      $relative_path = empty($convert->convertor['source_path_absolute']);
 502  
 503      if (empty($convert->convertor['upload_path']))
 504      {
 505          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment_files()'), __LINE__, __FILE__);
 506      }
 507  
 508      if (is_dir(relative_base(path($convert->convertor['upload_path'], $relative_path), $relative_path)))
 509      {
 510          copy_dir($convert->convertor['upload_path'], path($config['upload_path']) . $category_name, true, false, true, $relative_path);
 511      }
 512  }
 513  
 514  function attachment_forum_perms($forum_id)
 515  {
 516      if (!is_array($forum_id))
 517      {
 518          $forum_id = array($forum_id);
 519      }
 520  
 521      return serialize($forum_id);
 522  }
 523  
 524  // base64todec function
 525  // -> from php manual?
 526  function base64_unpack($string)
 527  {
 528      $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-';
 529      $base = strlen($chars);
 530  
 531      $length = strlen($string);
 532      $number = 0;
 533  
 534      for ($i = 1; $i <= $length; $i++)
 535      {
 536          $pos = $length - $i;
 537          $operand = strpos($chars, substr($string, $pos, 1));
 538          $exponent = pow($base, $i-1);
 539          $dec_value = $operand * $exponent;
 540          $number += $dec_value;
 541      }
 542  
 543      return $number;
 544  }
 545  
 546  function _import_check($config_var, $source, $use_target)
 547  {
 548      global $convert, $config;
 549  
 550      $result = array(
 551          'orig_source'    => $source,
 552          'copied'        => false,
 553          'relative_path'    => (empty($convert->convertor['source_path_absolute'])) ? true : false,
 554      );
 555  
 556      // copy file will prepend $phpBB_root_path
 557      $target = $config[$config_var] . '/' . utf8_basename(($use_target === false) ? $source : $use_target);
 558  
 559      if (!empty($convert->convertor[$config_var]) && strpos($source, $convert->convertor[$config_var]) !== 0)
 560      {
 561          $source = $convert->convertor[$config_var] . $source;
 562      }
 563  
 564      $result['source'] = $source;
 565  
 566      if (file_exists(relative_base($source, $result['relative_path'], __LINE__, __FILE__)))
 567      {
 568          $result['copied'] = copy_file($source, $target, false, false, $result['relative_path']);
 569      }
 570  
 571      if ($result['copied'])
 572      {
 573          $result['target'] = utf8_basename($target);
 574      }
 575      else
 576      {
 577          $result['target'] = ($use_target !== false) ? $result['orig_source'] : utf8_basename($target);
 578      }
 579  
 580      return $result;
 581  }
 582  
 583  function import_attachment($source, $use_target = false)
 584  {
 585      if (empty($source))
 586      {
 587          return '';
 588      }
 589  
 590      global $convert, $phpbb_root_path, $config, $user;
 591  
 592      // check for trailing slash
 593      if (rtrim($convert->convertor['upload_path'], '/') === '')
 594      {
 595          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment()'), __LINE__, __FILE__);
 596      }
 597  
 598      $result = _import_check('upload_path', $source, $use_target);
 599  
 600      if ($result['copied'])
 601      {
 602          // Thumbnails?
 603          if (is_array($convert->convertor['thumbnails']))
 604          {
 605              $thumb_dir = $convert->convertor['thumbnails'][0];
 606              $thumb_prefix = $convert->convertor['thumbnails'][1];
 607              $thumb_source = $thumb_dir . $thumb_prefix . utf8_basename($result['source']);
 608  
 609              if (strpos($thumb_source, $convert->convertor['upload_path']) !== 0)
 610              {
 611                  $thumb_source = $convert->convertor['upload_path'] . $thumb_source;
 612              }
 613              $thumb_target = $config['upload_path'] . '/thumb_' . $result['target'];
 614  
 615              if (file_exists(relative_base($thumb_source, $result['relative_path'], __LINE__, __FILE__)))
 616              {
 617                  copy_file($thumb_source, $thumb_target, false, false, $result['relative_path']);
 618              }
 619          }
 620      }
 621  
 622      return $result['target'];
 623  }
 624  
 625  function import_rank($source, $use_target = false)
 626  {
 627      if (empty($source))
 628      {
 629          return '';
 630      }
 631  
 632      global $convert, $phpbb_root_path, $config, $user;
 633  
 634      if (!isset($convert->convertor['ranks_path']))
 635      {
 636          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_RANKS_PATH'], 'import_rank()'), __LINE__, __FILE__);
 637      }
 638  
 639      $result = _import_check('ranks_path', $source, $use_target);
 640      return $result['target'];
 641  }
 642  
 643  function import_smiley($source, $use_target = false)
 644  {
 645      if (empty($source))
 646      {
 647          return '';
 648      }
 649  
 650      global $convert, $phpbb_root_path, $config, $user;
 651  
 652      // check for trailing slash
 653      if (rtrim($convert->convertor['smilies_path'], '/') === '')
 654      {
 655          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'import_smiley()'), __LINE__, __FILE__);
 656      }
 657  
 658      $result = _import_check('smilies_path', $source, $use_target);
 659      return $result['target'];
 660  }
 661  
 662  /*
 663  */
 664  function import_avatar($source, $use_target = false, $user_id = false)
 665  {
 666      if (empty($source) || preg_match('#^https?:#i', $source) || preg_match('#blank\.(gif|png)$#i', $source))
 667      {
 668          return;
 669      }
 670  
 671      global $convert, $phpbb_root_path, $config, $user;
 672  
 673      // check for trailing slash
 674      if (rtrim($convert->convertor['avatar_path'], '/') === '')
 675      {
 676          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'import_avatar()'), __LINE__, __FILE__);
 677      }
 678  
 679      if ($use_target === false && $user_id !== false)
 680      {
 681          $use_target = $config['avatar_salt'] . '_' . $user_id . '.' . substr(strrchr($source, '.'), 1);
 682      }
 683  
 684      $result = _import_check('avatar_path', $source, $use_target);
 685  
 686      return ((!empty($user_id)) ? $user_id : $use_target) . '.' . substr(strrchr($source, '.'), 1);
 687  }
 688  
 689  /**
 690  * @todo all image dimension functions below (there are a *lot*) should get revisited and converted to one or two functions (no more needed, really).
 691  */
 692  
 693  /**
 694  * Calculate the size of the specified image
 695  * Called from the following functions for calculating the size of specific image types
 696  */
 697  function get_image_dim($source)
 698  {
 699      if (empty($source))
 700      {
 701          return array(0, 0);
 702      }
 703  
 704      global $convert;
 705  
 706      $relative_path = empty($convert->convertor['source_path_absolute']);
 707  
 708      if (file_exists(relative_base($source, $relative_path)))
 709      {
 710          $image = relative_base($source, $relative_path);
 711          return @getimagesize($image);
 712      }
 713  
 714      return false;
 715  }
 716  
 717  /**
 718  * Obtain the width of the specified smilie
 719  */
 720  function get_smiley_width($src)
 721  {
 722      return get_smiley_dim($src, 0);
 723  }
 724  
 725  /**
 726  * Obtain the height of the specified smilie
 727  */
 728  function get_smiley_height($src)
 729  {
 730      return get_smiley_dim($src, 1);
 731  }
 732  
 733  /**
 734  * Obtain the size of the specified smilie (using the cache if possible) and cache the value
 735  */
 736  function get_smiley_dim($source, $axis)
 737  {
 738      if (empty($source))
 739      {
 740          return 15;
 741      }
 742  
 743      static $smiley_cache = array();
 744  
 745      if (isset($smiley_cache[$source]))
 746      {
 747          return $smiley_cache[$source][$axis];
 748      }
 749  
 750      global $convert, $phpbb_root_path, $config, $user;
 751  
 752      $orig_source = $source;
 753  
 754      if (!isset($convert->convertor['smilies_path']))
 755      {
 756          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'get_smiley_dim()'), __LINE__, __FILE__);
 757      }
 758  
 759      if (!empty($convert->convertor['smilies_path']) && strpos($source, $convert->convertor['smilies_path']) !== 0)
 760      {
 761          $source = $convert->convertor['smilies_path'] . $source;
 762      }
 763  
 764      $smiley_cache[$orig_source] = get_image_dim($source);
 765  
 766      if (empty($smiley_cache[$orig_source]) || empty($smiley_cache[$orig_source][0]) || empty($smiley_cache[$orig_source][1]))
 767      {
 768          $smiley_cache[$orig_source] = array(15, 15);
 769          return 15;
 770      }
 771  
 772      return $smiley_cache[$orig_source][$axis];
 773  }
 774  
 775  /**
 776  * Obtain the width of the specified avatar
 777  */
 778  function get_avatar_width($src, $func = false, $arg1 = false, $arg2 = false)
 779  {
 780      return get_avatar_dim($src, 0, $func, $arg1, $arg2);
 781  }
 782  
 783  /**
 784  * Obtain the height of the specified avatar
 785  */
 786  function get_avatar_height($src, $func = false, $arg1 = false, $arg2 = false)
 787  {
 788      return get_avatar_dim($src, 1, $func, $arg1, $arg2);
 789  }
 790  
 791  /**
 792  */
 793  function get_avatar_dim($src, $axis, $func = false, $arg1 = false, $arg2 = false)
 794  {
 795      $avatar_type = AVATAR_UPLOAD;
 796  
 797      if ($func)
 798      {
 799          if ($arg1 || $arg2)
 800          {
 801              $ary = array($arg1);
 802  
 803              if ($arg2)
 804              {
 805                  $ary[] = $arg2;
 806              }
 807  
 808              $avatar_type = call_user_func_array($func, $ary);
 809          }
 810          else
 811          {
 812              $avatar_type = call_user_func($func);
 813          }
 814      }
 815  
 816      switch ($avatar_type)
 817      {
 818          case AVATAR_UPLOAD:
 819              return get_upload_avatar_dim($src, $axis);
 820          break;
 821  
 822          case AVATAR_GALLERY:
 823              return get_gallery_avatar_dim($src, $axis);
 824          break;
 825  
 826          case AVATAR_REMOTE:
 827               // see notes on this functions usage and (hopefully) model $func to avoid this accordingly
 828              return get_remote_avatar_dim($src, $axis);
 829          break;
 830  
 831          default:
 832              $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
 833              $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
 834  
 835              return $axis ? $default_y : $default_x;
 836          break;
 837      }
 838  }
 839  
 840  /**
 841  * Obtain the size of the specified uploaded avatar (using the cache if possible) and cache the value
 842  */
 843  function get_upload_avatar_dim($source, $axis)
 844  {
 845      static $cachedims = false;
 846      static $cachekey = false;
 847  
 848      if (empty($source))
 849      {
 850          return 0;
 851      }
 852  
 853      if ($cachekey == $source)
 854      {
 855          return $cachedims[$axis];
 856      }
 857  
 858      $orig_source = $source;
 859  
 860      if (substr($source, 0, 7) == 'upload:')
 861      {
 862          $source = substr($source, 7);
 863      }
 864  
 865      global $convert, $phpbb_root_path, $config, $user;
 866  
 867      if (!isset($convert->convertor['avatar_path']))
 868      {
 869          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'get_upload_avatar_dim()'), __LINE__, __FILE__);
 870      }
 871  
 872      if (!empty($convert->convertor['avatar_path']) && strpos($source, $convert->convertor['avatar_path']) !== 0)
 873      {
 874          $source = path($convert->convertor['avatar_path'], empty($convert->convertor['source_path_absolute'])) . $source;
 875      }
 876  
 877      $cachedims = get_image_dim($source);
 878  
 879      if (empty($cachedims) || empty($cachedims[0]) || empty($cachedims[1]))
 880      {
 881          $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
 882          $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
 883  
 884          $cachedims = array($default_x, $default_y);
 885      }
 886  
 887      return $cachedims[$axis];
 888  }
 889  
 890  /**
 891  * Obtain the size of the specified gallery avatar (using the cache if possible) and cache the value
 892  */
 893  function get_gallery_avatar_dim($source, $axis)
 894  {
 895      if (empty($source))
 896      {
 897          return 0;
 898      }
 899  
 900      static $avatar_cache = array();
 901  
 902      if (isset($avatar_cache[$source]))
 903      {
 904          return $avatar_cache[$source][$axis];
 905      }
 906  
 907      global $convert, $phpbb_root_path, $config, $user;
 908  
 909      $orig_source = $source;
 910  
 911      if (!isset($convert->convertor['avatar_gallery_path']))
 912      {
 913          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'get_gallery_avatar_dim()'), __LINE__, __FILE__);
 914      }
 915  
 916      if (!empty($convert->convertor['avatar_gallery_path']) && strpos($source, $convert->convertor['avatar_gallery_path']) !== 0)
 917      {
 918          $source = path($convert->convertor['avatar_gallery_path'], empty($convert->convertor['source_path_absolute'])) . $source;
 919      }
 920  
 921      $avatar_cache[$orig_source] = get_image_dim($source);
 922  
 923      if (empty($avatar_cache[$orig_source]) || empty($avatar_cache[$orig_source][0]) || empty($avatar_cache[$orig_source][1]))
 924      {
 925          $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
 926          $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
 927  
 928          $avatar_cache[$orig_source] = array($default_x, $default_y);
 929      }
 930  
 931      return $avatar_cache[$orig_source][$axis];
 932  }
 933  
 934  /**
 935  * Obtain the size of the specified remote avatar (using the cache if possible) and cache the value
 936  * Whilst it's unlikely that remote avatars will be duplicated, it is possible so caching seems the best option
 937  * This should only be called from a post processing step due to the possibility of network timeouts
 938  */
 939  function get_remote_avatar_dim($src, $axis)
 940  {
 941      if (empty($src))
 942      {
 943          return 0;
 944      }
 945  
 946      static $remote_avatar_cache = array();
 947  
 948      // an ugly hack: we assume that the dimensions of each remote avatar are accessed exactly twice (x and y)
 949      if (isset($remote_avatar_cache[$src]))
 950      {
 951          $retval = $remote_avatar_cache[$src][$axis];
 952          unset($remote_avatar_cache);
 953          return $retval;
 954      }
 955  
 956      $url_info = @parse_url($src);
 957      if (empty($url_info['host']))
 958      {
 959          return 0;
 960      }
 961      $host = $url_info['host'];
 962      $port = (isset($url_info['port'])) ? $url_info['port'] : 0;
 963      $protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
 964      if (empty($port))
 965      {
 966          switch(strtolower($protocol))
 967          {
 968              case 'ftp':
 969                  $port = 21;
 970                  break;
 971  
 972              case 'https':
 973                  $port = 443;
 974                  break;
 975  
 976              default:
 977                  $port = 80;
 978          }
 979      }
 980  
 981      $timeout = @ini_get('default_socket_timeout');
 982      @ini_set('default_socket_timeout', 2);
 983  
 984      // We're just trying to reach the server to avoid timeouts
 985      $fp = @fsockopen($host, $port, $errno, $errstr, 1);
 986      if ($fp)
 987      {
 988          $remote_avatar_cache[$src] = @getimagesize($src);
 989          fclose($fp);
 990      }
 991  
 992      $default_x     = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
 993      $default_y     = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
 994      $default     = array($default_x, $default_y);
 995  
 996      if (empty($remote_avatar_cache[$src]) || empty($remote_avatar_cache[$src][0]) || empty($remote_avatar_cache[$src][1]))
 997      {
 998          $remote_avatar_cache[$src] = $default;
 999      }
1000      else
1001      {
1002          // We trust gallery and uploaded avatars to conform to the size settings; we might have to adjust here
1003          if ($remote_avatar_cache[$src][0] > $default_x || $remote_avatar_cache[$src][1] > $default_y)
1004          {
1005              $bigger = ($remote_avatar_cache[$src][0] > $remote_avatar_cache[$src][1]) ? 0 : 1;
1006              $ratio = $default[$bigger] / $remote_avatar_cache[$src][$bigger];
1007              $remote_avatar_cache[$src][0] = (int)($remote_avatar_cache[$src][0] * $ratio);
1008              $remote_avatar_cache[$src][1] = (int)($remote_avatar_cache[$src][1] * $ratio);
1009          }
1010      }
1011  
1012      @ini_set('default_socket_timeout', $timeout);
1013      return $remote_avatar_cache[$src][$axis];
1014  }
1015  
1016  function set_user_options()
1017  {
1018      global $convert_row;
1019  
1020      // Key need to be set in row, else default value is chosen
1021      $keyoptions = array(
1022          'viewimg'        => array('bit' => 0, 'default' => 1),
1023          'viewflash'        => array('bit' => 1, 'default' => 1),
1024          'viewsmilies'    => array('bit' => 2, 'default' => 1),
1025          'viewsigs'        => array('bit' => 3, 'default' => 1),
1026          'viewavatars'    => array('bit' => 4, 'default' => 1),
1027          'viewcensors'    => array('bit' => 5, 'default' => 1),
1028          'attachsig'        => array('bit' => 6, 'default' => 0),
1029          'bbcode'        => array('bit' => 8, 'default' => 1),
1030          'smilies'        => array('bit' => 9, 'default' => 1),
1031          'popuppm'        => array('bit' => 10, 'default' => 0),
1032          'sig_bbcode'    => array('bit' => 15, 'default' => 1),
1033          'sig_smilies'    => array('bit' => 16, 'default' => 1),
1034          'sig_links'        => array('bit' => 17, 'default' => 1),
1035      );
1036  
1037      $option_field = 0;
1038  
1039      foreach ($keyoptions as $key => $key_ary)
1040      {
1041          $value = (isset($convert_row[$key])) ? (int) $convert_row[$key] : $key_ary['default'];
1042  
1043          if ($value && !($option_field & 1 << $key_ary['bit']))
1044          {
1045              $option_field += 1 << $key_ary['bit'];
1046          }
1047      }
1048  
1049      return $option_field;
1050  }
1051  
1052  /**
1053  * Index messages on the fly as we convert them
1054  * @todo naderman, can you check that this works with the new search plugins as it's use is currently disabled (and thus untested)
1055  function search_indexing($message = '')
1056  {
1057      global $fulltext_search, $convert_row;
1058  
1059      if (!isset($convert_row['post_id']))
1060      {
1061          return;
1062      }
1063  
1064      if (!$message)
1065      {
1066          if (!isset($convert_row['message']))
1067          {
1068              return;
1069          }
1070  
1071          $message = $convert_row['message'];
1072      }
1073  
1074      $title = (isset($convert_row['title'])) ? $convert_row['title'] : '';
1075  
1076      $fulltext_search->index('post', $convert_row['post_id'], $message, $title, $convert_row['poster_id'], $convert_row['forum_id']);
1077  }
1078  */
1079  
1080  function make_unique_filename($filename)
1081  {
1082      if (!strlen($filename))
1083      {
1084          $filename = md5(unique_id()) . '.dat';
1085      }
1086      else if ($filename[0] == '.')
1087      {
1088          $filename = md5(unique_id()) . $filename;
1089      }
1090      else if (preg_match('/\.([a-z]+)$/i', $filename, $m))
1091      {
1092          $filename = preg_replace('/\.([a-z]+)$/i', '_' . md5(unique_id()) . '.\1', $filename);
1093      }
1094      else
1095      {
1096          $filename .= '_' . md5(unique_id()) . '.dat';
1097      }
1098  
1099      return $filename;
1100  }
1101  
1102  function words_unique(&$words)
1103  {
1104      reset($words);
1105      $return_array = array();
1106  
1107      $word = current($words);
1108      do
1109      {
1110          $return_array[$word] = $word;
1111      }
1112      while ($word = next($words));
1113  
1114      return $return_array;
1115  }
1116  
1117  /**
1118  * Adds a user to the specified group and optionally makes them a group leader
1119  * This function does not create the group if it does not exist and so should only be called after the groups have been created
1120  */
1121  function add_user_group($group_id, $user_id, $group_leader=false)
1122  {
1123      global $convert, $phpbb_root_path, $config, $user, $db;
1124  
1125      $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1126          'group_id'        => $group_id,
1127          'user_id'        => $user_id,
1128          'group_leader'    => ($group_leader) ? 1 : 0,
1129          'user_pending'    => 0));
1130      $db->sql_query($sql);
1131  }
1132  
1133  // STANDALONE FUNCTIONS
1134  
1135  /**
1136  * Add users to the pre-defined "special" groups
1137  *
1138  * @param string $group The name of the special group to add to
1139  * @param string $select_query An SQL query to retrieve the user(s) to add to the group
1140  */
1141  function user_group_auth($group, $select_query, $use_src_db)
1142  {
1143      global $convert, $phpbb_root_path, $config, $user, $db, $src_db, $same_db;
1144  
1145      if (!in_array($group, array('guests', 'registered', 'registered_coppa', 'global_moderators', 'administrators', 'bots')))
1146      {
1147          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_WRONG_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1148          return;
1149      }
1150  
1151      $sql = 'SELECT group_id
1152          FROM ' . GROUPS_TABLE . "
1153          WHERE group_name = '" . $db->sql_escape(strtoupper($group)) . "'";
1154      $result = $db->sql_query($sql);
1155      $group_id = (int) $db->sql_fetchfield('group_id');
1156      $db->sql_freeresult($result);
1157  
1158      if (!$group_id)
1159      {
1160          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1161          return;
1162      }
1163  
1164      if ($same_db || !$use_src_db)
1165      {
1166          $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' (user_id, group_id, user_pending)
1167              ' . str_replace('{' . strtoupper($group) . '}', $group_id . ', 0', $select_query);
1168          $db->sql_query($sql);
1169      }
1170      else
1171      {
1172          $result = $src_db->sql_query(str_replace('{' . strtoupper($group) . '}', $group_id . ' ', $select_query));
1173          while ($row = $src_db->sql_fetchrow($result))
1174          {
1175              // this might become quite a lot of INSERTS unfortunately
1176              $sql = 'INSERT INTO ' . USER_GROUP_TABLE . " (user_id, group_id, user_pending)
1177                  VALUES ({$row['user_id']}, $group_id, 0)";
1178              $db->sql_query($sql);
1179          }
1180          $src_db->sql_freeresult($result);
1181      }
1182  }
1183  
1184  /**
1185  * Retrieves configuration information from the source forum and caches it as an array
1186  * Both database and file driven configuration formats can be handled
1187  * (the type used is specified in $config_schema, see convert_phpbb20.php for more details)
1188  */
1189  function get_config()
1190  {
1191      static $convert_config;
1192      global $user;
1193  
1194      if (isset($convert_config))
1195      {
1196          return $convert_config;
1197      }
1198  
1199      global $src_db, $same_db, $phpbb_root_path, $config;
1200      global $convert;
1201  
1202      if ($convert->config_schema['table_format'] != 'file')
1203      {
1204          if ($convert->mysql_convert && $same_db)
1205          {
1206              $src_db->sql_query("SET NAMES 'binary'");
1207          }
1208  
1209          $sql = 'SELECT * FROM ' . $convert->src_table_prefix . $convert->config_schema['table_name'];
1210          $result = $src_db->sql_query($sql);
1211          $row = $src_db->sql_fetchrow($result);
1212  
1213          if (!$row)
1214          {
1215              $convert->p_master->error($user->lang['CONV_ERROR_GET_CONFIG'], __LINE__, __FILE__);
1216          }
1217      }
1218  
1219      if (is_array($convert->config_schema['table_format']))
1220      {
1221          $convert_config = array();
1222          list($key, $val) = each($convert->config_schema['table_format']);
1223  
1224          do
1225          {
1226              $convert_config[$row[$key]] = $row[$val];
1227          }
1228          while ($row = $src_db->sql_fetchrow($result));
1229          $src_db->sql_freeresult($result);
1230  
1231          if ($convert->mysql_convert && $same_db)
1232          {
1233              $src_db->sql_query("SET NAMES 'utf8'");
1234          }
1235      }
1236      else if ($convert->config_schema['table_format'] == 'file')
1237      {
1238          $filename = $convert->options['forum_path'] . '/' . $convert->config_schema['filename'];
1239          if (!file_exists($filename))
1240          {
1241              $convert->p_master->error($user->lang['FILE_NOT_FOUND'] . ': ' . $filename, __LINE__, __FILE__);
1242          }
1243  
1244          if (isset($convert->config_schema['array_name']))
1245          {
1246              unset($convert->config_schema['array_name']);
1247          }
1248  
1249          $convert_config = extract_variables_from_file($filename);
1250          if (!empty($convert->config_schema['array_name']))
1251          {
1252              $convert_config = $convert_config[$convert->config_schema['array_name']];
1253          }
1254      }
1255      else
1256      {
1257          $convert_config = $row;
1258          if ($convert->mysql_convert && $same_db)
1259          {
1260              $src_db->sql_query("SET NAMES 'utf8'");
1261          }
1262      }
1263  
1264      if (!sizeof($convert_config))
1265      {
1266          $convert->p_master->error($user->lang['CONV_ERROR_CONFIG_EMPTY'], __LINE__, __FILE__);
1267      }
1268  
1269      return $convert_config;
1270  }
1271  
1272  /**
1273  * Transfers the relevant configuration information from the source forum
1274  * The mapping of fields is specified in $config_schema, see convert_phpbb20.php for more details
1275  */
1276  function restore_config($schema)
1277  {
1278      global $db, $config;
1279  
1280      $convert_config = get_config();
1281  
1282      foreach ($schema['settings'] as $config_name => $src)
1283      {
1284          if (preg_match('/(.*)\((.*)\)/', $src, $m))
1285          {
1286              $var = (empty($m[2]) || empty($convert_config[$m[2]])) ? "''" : "'" . addslashes($convert_config[$m[2]]) . "'";
1287              $exec = '$config_value = ' . $m[1] . '(' . $var . ');';
1288              eval($exec);
1289          }
1290          else
1291          {
1292              if ($schema['table_format'] != 'file' || empty($schema['array_name']))
1293              {
1294                  $config_value = (isset($convert_config[$src])) ? $convert_config[$src] : '';
1295              }
1296              else if (!empty($schema['array_name']))
1297              {
1298                  $src_ary = $schema['array_name'];
1299                  $config_value = (isset($convert_config[$src_ary][$src])) ? $convert_config[$src_ary][$src] : '';
1300              }
1301             }
1302  
1303          if ($config_value !== '')
1304          {
1305              // Most are...
1306              if (is_string($config_value))
1307              {
1308                  $config_value = truncate_string(utf8_htmlspecialchars($config_value), 255, 255, false);
1309              }
1310  
1311              set_config($config_name, $config_value);
1312          }
1313      }
1314  }
1315  
1316  /**
1317  * Update the count of PM's in custom folders for all users
1318  */
1319  function update_folder_pm_count()
1320  {
1321      global $db, $convert, $user;
1322  
1323      $sql = 'SELECT user_id, folder_id, COUNT(msg_id) as num_messages
1324          FROM ' . PRIVMSGS_TO_TABLE . '
1325          WHERE folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ', ' . PRIVMSGS_INBOX . ', ' . PRIVMSGS_OUTBOX . ', ' . PRIVMSGS_SENTBOX . ')
1326          GROUP BY folder_id, user_id';
1327      $result = $db->sql_query($sql);
1328  
1329      while ($row = $db->sql_fetchrow($result))
1330      {
1331          $db->sql_query('UPDATE ' . PRIVMSGS_FOLDER_TABLE . ' SET pm_count = ' . $row['num_messages'] . '
1332              WHERE user_id = ' . $row['user_id'] . ' AND folder_id = ' . $row['folder_id']);
1333      }
1334      $db->sql_freeresult($result);
1335  }
1336  
1337  // Functions mainly used by the main convertor script
1338  
1339  function path($path, $path_relative = true)
1340  {
1341      if ($path === false)
1342      {
1343          return '';
1344      }
1345  
1346      if (substr($path, -1) != '/')
1347      {
1348          $path .= '/';
1349      }
1350  
1351      if (!$path_relative)
1352      {
1353          return $path;
1354      }
1355  
1356      if (substr($path, 0, 1) == '/')
1357      {
1358          $path = substr($path, 1);
1359      }
1360  
1361      return $path;
1362  }
1363  
1364  /**
1365  * Extract the variables defined in a configuration file
1366  * @todo As noted by Xore we need to look at this from a security perspective
1367  */
1368  function extract_variables_from_file($_filename)
1369  {
1370      include($_filename);
1371  
1372      $vars = get_defined_vars();
1373      unset($vars['_filename']);
1374  
1375      return $vars;
1376  }
1377  
1378  function get_path($src_path, $src_url, $test_file)
1379  {
1380      global $config, $phpbb_root_path, $phpEx;
1381  
1382      $board_config = get_config();
1383  
1384      $test_file = preg_replace('/\.php$/i', ".$phpEx", $test_file);
1385      $src_path = path($src_path);
1386  
1387      if (@file_exists($phpbb_root_path . $src_path . $test_file))
1388      {
1389          return $src_path;
1390      }
1391  
1392      if (!empty($src_url) && !empty($board_config['server_name']))
1393      {
1394          if (!preg_match('#https?://([^/]+)(.*)#i', $src_url, $m))
1395          {
1396              return false;
1397          }
1398  
1399          if ($m[1] != $board_config['server_name'])
1400          {
1401              return false;
1402          }
1403  
1404          $url_parts = explode('/', $m[2]);
1405          if (substr($src_url, -1) != '/')
1406          {
1407              if (preg_match('/.*\.([a-z0-9]{3,4})$/i', $url_parts[sizeof($url_parts) - 1]))
1408              {
1409                  $url_parts[sizeof($url_parts) - 1] = '';
1410              }
1411              else
1412              {
1413                  $url_parts[] = '';
1414              }
1415          }
1416  
1417          $script_path = $board_config['script_path'];
1418          if (substr($script_path, -1) == '/')
1419          {
1420              $script_path = substr($script_path, 0, -1);
1421          }
1422  
1423          $path_array = array();
1424  
1425          $phpbb_parts = explode('/', $script_path);
1426          for ($i = 0; $i < sizeof($url_parts); ++$i)
1427          {
1428              if ($i < sizeof($phpbb_parts[$i]) && $url_parts[$i] == $phpbb_parts[$i])
1429              {
1430                  $path_array[] = $url_parts[$i];
1431                  unset($url_parts[$i]);
1432              }
1433              else
1434              {
1435                  $path = '';
1436                  for ($j = $i; $j < sizeof($phpbb_parts); ++$j)
1437                  {
1438                      $path .= '../';
1439                  }
1440                  $path .= implode('/', $url_parts);
1441                  break;
1442              }
1443          }
1444  
1445          if (!empty($path))
1446          {
1447              if (@file_exists($phpbb_root_path . $path . $test_file))
1448              {
1449                  return $path;
1450              }
1451          }
1452      }
1453  
1454      return false;
1455  }
1456  
1457  function compare_table($tables, $tablename, &$prefixes)
1458  {
1459      for ($i = 0, $table_size = sizeof($tables); $i < $table_size; ++$i)
1460      {
1461          if (preg_match('/(.*)' . $tables[$i] . '$/', $tablename, $m))
1462          {
1463              if (empty($m[1]))
1464              {
1465                  $m[1] = '*';
1466              }
1467  
1468              if (isset($prefixes[$m[1]]))
1469              {
1470                  $prefixes[$m[1]]++;
1471              }
1472              else
1473              {
1474                  $prefixes[$m[1]] = 1;
1475              }
1476          }
1477      }
1478  }
1479  
1480  /**
1481  * Grant permissions to a specified user or group
1482  *
1483  * @param string $ug_type user|group|user_role|group_role
1484  * @param mixed $forum_id forum ids (array|int|0) -> 0 == all forums
1485  * @param mixed $ug_id [int] user_id|group_id : [string] usergroup name
1486  * @param mixed $acl_list [string] acl entry : [array] acl entries : [string] role entry
1487  * @param int $setting ACL_YES|ACL_NO|ACL_NEVER
1488  */
1489  function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
1490  {
1491      global $db, $convert, $user, $config;
1492      static $acl_option_ids, $group_ids;
1493  
1494      if (($ug_type == 'group' || $ug_type == 'group_role') && is_string($ug_id))
1495      {
1496          if (!isset($group_ids[$ug_id]))
1497          {
1498              $sql = 'SELECT group_id
1499                  FROM ' . GROUPS_TABLE . "
1500                  WHERE group_name = '" . $db->sql_escape(strtoupper($ug_id)) . "'";
1501              $result = $db->sql_query_limit($sql, 1);
1502              $id = (int) $db->sql_fetchfield('group_id');
1503              $db->sql_freeresult($result);
1504  
1505              if (!$id)
1506              {
1507                  return;
1508              }
1509  
1510              $group_ids[$ug_id] = $id;
1511          }
1512  
1513          $ug_id = (int) $group_ids[$ug_id];
1514      }
1515  
1516      $table = ($ug_type == 'user' || $ug_type == 'user_role') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
1517      $id_field = ($ug_type == 'user' || $ug_type == 'user_role') ? 'user_id' : 'group_id';
1518  
1519      // Role based permissions are the simplest to handle so check for them first
1520      if ($ug_type == 'user_role' || $ug_type == 'group_role')
1521      {
1522          if (is_numeric($forum_id))
1523          {
1524              $sql = 'SELECT role_id
1525                  FROM ' . ACL_ROLES_TABLE . "
1526                  WHERE role_name = 'ROLE_" . $db->sql_escape($acl_list) . "'";
1527              $result = $db->sql_query_limit($sql, 1);
1528              $row = $db->sql_fetchrow($result);
1529              $db->sql_freeresult($result);
1530  
1531              // If we have no role id there is something wrong here
1532              if ($row)
1533              {
1534                  $sql = "INSERT INTO $table ($id_field, forum_id, auth_role_id) VALUES ($ug_id, $forum_id, " . $row['role_id'] . ')';
1535                  $db->sql_query($sql);
1536              }
1537          }
1538  
1539          return;
1540      }
1541  
1542      // Build correct parameters
1543      $auth = array();
1544  
1545      if (!is_array($acl_list))
1546      {
1547          $auth = array($acl_list => $setting);
1548      }
1549      else
1550      {
1551          foreach ($acl_list as $auth_option)
1552          {
1553              $auth[$auth_option] = $setting;
1554          }
1555      }
1556      unset($acl_list);
1557  
1558      if (!is_array($forum_id))
1559      {
1560          $forum_id = array($forum_id);
1561      }
1562  
1563      // Set any flags as required
1564      foreach ($auth as $auth_option => $acl_setting)
1565      {
1566          $flag = substr($auth_option, 0, strpos($auth_option, '_') + 1);
1567          if (empty($auth[$flag]))
1568          {
1569              $auth[$flag] = $acl_setting;
1570          }
1571      }
1572  
1573      if (!is_array($acl_option_ids) || empty($acl_option_ids))
1574      {
1575          $sql = 'SELECT auth_option_id, auth_option
1576              FROM ' . ACL_OPTIONS_TABLE;
1577          $result = $db->sql_query($sql);
1578  
1579          while ($row = $db->sql_fetchrow($result))
1580          {
1581              $acl_option_ids[$row['auth_option']] = $row['auth_option_id'];
1582          }
1583          $db->sql_freeresult($result);
1584      }
1585  
1586      $sql_forum = 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id), false, true);
1587  
1588      $sql = ($ug_type == 'user') ? 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.user_id = $ug_id" : 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_GROUPS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.group_id = $ug_id";
1589      $result = $db->sql_query($sql);
1590  
1591      $cur_auth = array();
1592      while ($row = $db->sql_fetchrow($result))
1593      {
1594          $cur_auth[$row['forum_id']][$row['auth_option_id']] = $row['auth_setting'];
1595      }
1596      $db->sql_freeresult($result);
1597  
1598      $sql_ary = array();
1599      foreach ($forum_id as $forum)
1600      {
1601          foreach ($auth as $auth_option => $setting)
1602          {
1603              $auth_option_id = $acl_option_ids[$auth_option];
1604  
1605              if (!$auth_option_id)
1606              {
1607                  continue;
1608              }
1609  
1610              switch ($setting)
1611              {
1612                  case ACL_NO:
1613                      if (isset($cur_auth[$forum][$auth_option_id]))
1614                      {
1615                          $sql_ary['delete'][] = "DELETE FROM $table
1616                              WHERE forum_id = $forum
1617                                  AND auth_option_id = $auth_option_id
1618                                  AND $id_field = $ug_id";
1619                      }
1620                  break;
1621  
1622                  default:
1623                      if (!isset($cur_auth[$forum][$auth_option_id]))
1624                      {
1625                          $sql_ary['insert'][] = "$ug_id, $forum, $auth_option_id, $setting";
1626                      }
1627                      else if ($cur_auth[$forum][$auth_option_id] != $setting)
1628                      {
1629                          $sql_ary['update'][] = "UPDATE " . $table . "
1630                              SET auth_setting = $setting
1631                              WHERE $id_field = $ug_id
1632                                  AND forum_id = $forum
1633                                  AND auth_option_id = $auth_option_id";
1634                      }
1635              }
1636          }
1637      }
1638      unset($cur_auth);
1639  
1640      $sql = '';
1641      foreach ($sql_ary as $sql_type => $sql_subary)
1642      {
1643          switch ($sql_type)
1644          {
1645              case 'insert':
1646                  switch ($db->sql_layer)
1647                  {
1648                      case 'mysql':
1649                      case 'mysql4':
1650                          $sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary));
1651                      break;
1652  
1653                      case 'mssql':
1654                      case 'sqlite':
1655                      case 'mssqlnative':
1656                          $sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
1657                      break;
1658  
1659                      default:
1660                          foreach ($sql_subary as $sql)
1661                          {
1662                              $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) VALUES ($sql)";
1663                              $db->sql_query($sql);
1664                              $sql = '';
1665                          }
1666                  }
1667  
1668                  if ($sql != '')
1669                  {
1670                      $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) $sql";
1671                      $db->sql_query($sql);
1672                  }
1673              break;
1674  
1675              case 'update':
1676              case 'delete':
1677                  foreach ($sql_subary as $sql)
1678                  {
1679                      $db->sql_query($sql);
1680                      $sql = '';
1681                  }
1682              break;
1683          }
1684          unset($sql_ary[$sql_type]);
1685      }
1686      unset($sql_ary);
1687  
1688  }
1689  
1690  /**
1691  * Update the count of unread private messages for all users
1692  */
1693  function update_unread_count()
1694  {
1695      global $db;
1696  
1697      $sql = 'SELECT user_id, COUNT(msg_id) as num_messages
1698          FROM ' . PRIVMSGS_TO_TABLE . '
1699          WHERE pm_unread = 1
1700              AND folder_id <> ' . PRIVMSGS_OUTBOX . '
1701          GROUP BY user_id';
1702      $result = $db->sql_query($sql);
1703  
1704      while ($row = $db->sql_fetchrow($result))
1705      {
1706          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_unread_privmsg = ' . $row['num_messages'] . '
1707              WHERE user_id = ' . $row['user_id']);
1708      }
1709      $db->sql_freeresult($result);
1710  }
1711  
1712  /**
1713  * Add any of the pre-defined "special" groups which are missing from the database
1714  */
1715  function add_default_groups()
1716  {
1717      global $db;
1718  
1719      $default_groups = array(
1720          'GUESTS'            => array('', 0, 0),
1721          'REGISTERED'        => array('', 0, 0),
1722          'REGISTERED_COPPA'    => array('', 0, 0),
1723          'GLOBAL_MODERATORS'    => array('00AA00', 1, 0),
1724          'ADMINISTRATORS'    => array('AA0000', 1, 1),
1725          'BOTS'                => array('9E8DA7', 0, 0),
1726          'NEWLY_REGISTERED'        => array('', 0, 0),
1727      );
1728  
1729      $sql = 'SELECT *
1730          FROM ' . GROUPS_TABLE . '
1731          WHERE ' . $db->sql_in_set('group_name', array_keys($default_groups));
1732      $result = $db->sql_query($sql);
1733  
1734      while ($row = $db->sql_fetchrow($result))
1735      {
1736          unset($default_groups[strtoupper($row['group_name'])]);
1737      }
1738      $db->sql_freeresult($result);
1739  
1740      $sql_ary = array();
1741  
1742      foreach ($default_groups as $name => $data)
1743      {
1744          $sql_ary[] = array(
1745              'group_name'            => (string) $name,
1746              'group_desc'            => '',
1747              'group_desc_uid'        => '',
1748              'group_desc_bitfield'    => '',
1749              'group_type'            => GROUP_SPECIAL,
1750              'group_colour'            => (string) $data[0],
1751              'group_legend'            => (int) $data[1],
1752              'group_founder_manage'    => (int) $data[2]
1753          );
1754      }
1755  
1756      if (sizeof($sql_ary))
1757      {
1758          $db->sql_multi_insert(GROUPS_TABLE, $sql_ary);
1759      }
1760  }
1761  
1762  
1763  /**
1764  * Sync post count. We might need to do this in batches.
1765  */
1766  function sync_post_count($offset, $limit)
1767  {
1768      global $db;
1769      $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1770              FROM ' . POSTS_TABLE . '
1771              WHERE post_postcount = 1
1772                  AND post_approved = 1
1773              GROUP BY poster_id
1774              ORDER BY poster_id';
1775      $result = $db->sql_query_limit($sql, $limit, $offset);
1776  
1777      while ($row = $db->sql_fetchrow($result))
1778      {
1779          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1780      }
1781      $db->sql_freeresult($result);
1782  }
1783  
1784  /**
1785  * Add the search bots into the database
1786  * This code should be used in execute_last if the source database did not have bots
1787  * If you are converting bots this function should not be called
1788  * @todo We might want to look at sharing the bot list between the install code and this code for consistancy
1789  */
1790  function add_bots()
1791  {
1792      global $db, $convert, $user, $config, $phpbb_root_path, $phpEx;
1793  
1794      $db->sql_query($convert->truncate_statement . BOTS_TABLE);
1795  
1796      $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1797      $result = $db->sql_query($sql);
1798      $group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1799      $db->sql_freeresult($result);
1800  
1801      if (!$group_id)
1802      {
1803          add_default_groups();
1804  
1805          $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1806          $result = $db->sql_query($sql);
1807          $group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1808          $db->sql_freeresult($result);
1809  
1810          if (!$group_id)
1811          {
1812              global $install;
1813              $install->error($user->lang['CONV_ERROR_INCONSISTENT_GROUPS'], __LINE__, __FILE__);
1814          }
1815      }
1816  
1817      $bots = array(
1818          'AdsBot [Google]'            => array('AdsBot-Google', ''),
1819          'Alexa [Bot]'                => array('ia_archiver', ''),
1820          'Alta Vista [Bot]'            => array('Scooter/', ''),
1821          'Ask Jeeves [Bot]'            => array('Ask Jeeves', ''),
1822          'Baidu [Spider]'            => array('Baiduspider+(', ''),
1823          'Bing [Bot]'                => array('bingbot/', ''),
1824          'Exabot [Bot]'                => array('Exabot/', ''),
1825          'FAST Enterprise [Crawler]'    => array('FAST Enterprise Crawler', ''),
1826          'FAST WebCrawler [Crawler]'    => array('FAST-WebCrawler/', ''),
1827          'Francis [Bot]'                => array('http://www.neomo.de/', ''),
1828          'Gigabot [Bot]'                => array('Gigabot/', ''),
1829          'Google Adsense [Bot]'        => array('Mediapartners-Google', ''),
1830          'Google Desktop'            => array('Google Desktop', ''),
1831          'Google Feedfetcher'        => array('Feedfetcher-Google', ''),
1832          'Google [Bot]'                => array('Googlebot', ''),
1833          'Heise IT-Markt [Crawler]'    => array('heise-IT-Markt-Crawler', ''),
1834          'Heritrix [Crawler]'        => array('heritrix/1.', ''),
1835          'IBM Research [Bot]'        => array('ibm.com/cs/crawler', ''),
1836          'ICCrawler - ICjobs'        => array('ICCrawler - ICjobs', ''),
1837          'ichiro [Crawler]'            => array('ichiro/2', ''),
1838          'Majestic-12 [Bot]'            => array('MJ12bot/', ''),
1839          'Metager [Bot]'                => array('MetagerBot/', ''),
1840          'MSN NewsBlogs'                => array('msnbot-NewsBlogs/', ''),
1841          'MSN [Bot]'                    => array('msnbot/', ''),
1842          'MSNbot Media'                => array('msnbot-media/', ''),
1843          'NG-Search [Bot]'            => array('NG-Search/', ''),
1844          'Nutch [Bot]'                => array('http://lucene.apache.org/nutch/', ''),
1845          'Nutch/CVS [Bot]'            => array('NutchCVS/', ''),
1846          'OmniExplorer [Bot]'        => array('OmniExplorer_Bot/', ''),
1847          'Online link [Validator]'    => array('online link validator', ''),
1848          'psbot [Picsearch]'            => array('psbot/0', ''),
1849          'Seekport [Bot]'            => array('Seekbot/', ''),
1850          'Sensis [Crawler]'            => array('Sensis Web Crawler', ''),
1851          'SEO Crawler'                => array('SEO search Crawler/', ''),
1852          'Seoma [Crawler]'            => array('Seoma [SEO Crawler]', ''),
1853          'SEOSearch [Crawler]'        => array('SEOsearch/', ''),
1854          'Snappy [Bot]'                => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
1855          'Steeler [Crawler]'            => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
1856          'Synoo [Bot]'                => array('SynooBot/', ''),
1857          'Telekom [Bot]'                => array('crawleradmin.t-info@telekom.de', ''),
1858          'TurnitinBot [Bot]'            => array('TurnitinBot/', ''),
1859          'Voyager [Bot]'                => array('voyager/1.0', ''),
1860          'W3 [Sitesearch]'            => array('W3 SiteSearch Crawler', ''),
1861          'W3C [Linkcheck]'            => array('W3C-checklink/', ''),
1862          'W3C [Validator]'            => array('W3C_*Validator', ''),
1863          'WiseNut [Bot]'                => array('http://www.WISEnutbot.com', ''),
1864          'YaCy [Bot]'                => array('yacybot', ''),
1865          'Yahoo MMCrawler [Bot]'        => array('Yahoo-MMCrawler/', ''),
1866          'Yahoo Slurp [Bot]'            => array('Yahoo! DE Slurp', ''),
1867          'Yahoo [Bot]'                => array('Yahoo! Slurp', ''),
1868          'YahooSeeker [Bot]'            => array('YahooSeeker/', ''),
1869      );
1870  
1871      if (!function_exists('user_add'))
1872      {
1873          include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1874      }
1875  
1876      foreach ($bots as $bot_name => $bot_ary)
1877      {
1878          $user_row = array(
1879              'user_type'                => USER_IGNORE,
1880              'group_id'                => $group_id,
1881              'username'                => $bot_name,
1882              'user_regdate'            => time(),
1883              'user_password'            => '',
1884              'user_colour'            => '9E8DA7',
1885              'user_email'            => '',
1886              'user_lang'                => $config['default_lang'],
1887              'user_style'            => 1,
1888              'user_timezone'            => 0,
1889              'user_allow_massemail'    => 0,
1890          );
1891  
1892          $user_id = user_add($user_row);
1893  
1894          if ($user_id)
1895          {
1896              $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1897                  'bot_active'    => 1,
1898                  'bot_name'        => $bot_name,
1899                  'user_id'        => $user_id,
1900                  'bot_agent'        => $bot_ary[0],
1901                  'bot_ip'        => $bot_ary[1])
1902              );
1903              $db->sql_query($sql);
1904          }
1905      }
1906  }
1907  
1908  /**
1909  * Update any dynamic configuration variables after the conversion is finished
1910  * @todo Confirm that this updates all relevant values since it has not necessarily been kept in sync with all changes
1911  */
1912  function update_dynamic_config()
1913  {
1914      global $db, $config;
1915  
1916      // Get latest username
1917      $sql = 'SELECT user_id, username, user_colour
1918          FROM ' . USERS_TABLE . '
1919          WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
1920  
1921      if (!empty($config['increment_user_id']))
1922      {
1923          $sql .= ' AND user_id <> ' . $config['increment_user_id'];
1924      }
1925  
1926      $sql .= ' ORDER BY user_id DESC';
1927  
1928      $result = $db->sql_query_limit($sql, 1);
1929      $row = $db->sql_fetchrow($result);
1930      $db->sql_freeresult($result);
1931  
1932      if ($row)
1933      {
1934          set_config('newest_user_id', $row['user_id'], true);
1935          set_config('newest_username', $row['username'], true);
1936          set_config('newest_user_colour', $row['user_colour'], true);
1937      }
1938  
1939  //    Also do not reset record online user/date. There will be old data or the fresh data from the schema.
1940  //    set_config('record_online_users', 1, true);
1941  //    set_config('record_online_date', time(), true);
1942  
1943      $sql = 'SELECT COUNT(post_id) AS stat
1944          FROM ' . POSTS_TABLE . '
1945          WHERE post_approved = 1';
1946      $result = $db->sql_query($sql);
1947      $row = $db->sql_fetchrow($result);
1948      $db->sql_freeresult($result);
1949  
1950      set_config('num_posts', (int) $row['stat'], true);
1951  
1952      $sql = 'SELECT COUNT(topic_id) AS stat
1953          FROM ' . TOPICS_TABLE . '
1954          WHERE topic_approved = 1';
1955      $result = $db->sql_query($sql);
1956      $row = $db->sql_fetchrow($result);
1957      $db->sql_freeresult($result);
1958  
1959      set_config('num_topics', (int) $row['stat'], true);
1960  
1961      $sql = 'SELECT COUNT(user_id) AS stat
1962          FROM ' . USERS_TABLE . '
1963          WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
1964      $result = $db->sql_query($sql);
1965      $row = $db->sql_fetchrow($result);
1966      $db->sql_freeresult($result);
1967  
1968      set_config('num_users', (int) $row['stat'], true);
1969  
1970      $sql = 'SELECT COUNT(attach_id) as stat
1971          FROM ' . ATTACHMENTS_TABLE . '
1972          WHERE is_orphan = 0';
1973      $result = $db->sql_query($sql);
1974      set_config('num_files', (int) $db->sql_fetchfield('stat'), true);
1975      $db->sql_freeresult($result);
1976  
1977      $sql = 'SELECT SUM(filesize) as stat
1978          FROM ' . ATTACHMENTS_TABLE . '
1979          WHERE is_orphan = 0';
1980      $result = $db->sql_query($sql);
1981      set_config('upload_dir_size', (float) $db->sql_fetchfield('stat'), true);
1982      $db->sql_freeresult($result);
1983  
1984      /**
1985      * We do not resync users post counts - this can be done by the admin after conversion if wanted.
1986      $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1987          FROM ' . POSTS_TABLE . '
1988          WHERE post_postcount = 1
1989          GROUP BY poster_id';
1990      $result = $db->sql_query($sql);
1991  
1992      while ($row = $db->sql_fetchrow($result))
1993      {
1994          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1995      }
1996      $db->sql_freeresult($result);
1997      */
1998  }
1999  
2000  /**
2001  * Updates topics_posted entries
2002  */
2003  function update_topics_posted()
2004  {
2005      global $db, $config;
2006  
2007      switch ($db->sql_layer)
2008      {
2009          case 'sqlite':
2010          case 'firebird':
2011              $db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
2012          break;
2013  
2014          default:
2015              $db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
2016          break;
2017      }
2018  
2019      // This can get really nasty... therefore we only do the last six months
2020      $get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
2021  
2022      // Select forum ids, do not include categories
2023      $sql = 'SELECT forum_id
2024          FROM ' . FORUMS_TABLE . '
2025          WHERE forum_type <> ' . FORUM_CAT;
2026      $result = $db->sql_query($sql);
2027  
2028      $forum_ids = array();
2029      while ($row = $db->sql_fetchrow($result))
2030      {
2031          $forum_ids[] = $row['forum_id'];
2032      }
2033      $db->sql_freeresult($result);
2034  
2035      // Any global announcements? ;)
2036      $forum_ids[] = 0;
2037  
2038      // Now go through the forums and get us some topics...
2039      foreach ($forum_ids as $forum_id)
2040      {
2041          $sql = 'SELECT p.poster_id, p.topic_id
2042              FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
2043              WHERE t.forum_id = ' . $forum_id . '
2044                  AND t.topic_moved_id = 0
2045                  AND t.topic_last_post_time > ' . $get_from_time . '
2046                  AND t.topic_id = p.topic_id
2047                  AND p.poster_id <> ' . ANONYMOUS . '
2048              GROUP BY p.poster_id, p.topic_id';
2049          $result = $db->sql_query($sql);
2050  
2051          $posted = array();
2052          while ($row = $db->sql_fetchrow($result))
2053          {
2054              $posted[$row['poster_id']][] = $row['topic_id'];
2055          }
2056          $db->sql_freeresult($result);
2057  
2058          $sql_ary = array();
2059          foreach ($posted as $user_id => $topic_row)
2060          {
2061              foreach ($topic_row as $topic_id)
2062              {
2063                  $sql_ary[] = array(
2064                      'user_id'        => (int) $user_id,
2065                      'topic_id'        => (int) $topic_id,
2066                      'topic_posted'    => 1,
2067                  );
2068              }
2069          }
2070          unset($posted);
2071  
2072          if (sizeof($sql_ary))
2073          {
2074              $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
2075          }
2076      }
2077  }
2078  
2079  /**
2080  * Ensure that all users have a default group specified and update related information such as their colour
2081  */
2082  function fix_empty_primary_groups()
2083  {
2084      global $db;
2085  
2086      // Set group ids for users not already having it
2087      $sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2088          WHERE group_id = 0 AND user_type = ' . USER_INACTIVE;
2089      $db->sql_query($sql);
2090  
2091      $sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2092          WHERE group_id = 0 AND user_type = ' . USER_NORMAL;
2093      $db->sql_query($sql);
2094  
2095      $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('guests') . ' WHERE user_id = ' . ANONYMOUS);
2096  
2097      $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('administrators');
2098      $result = $db->sql_query($sql);
2099  
2100      $user_ids = array();
2101      while ($row = $db->sql_fetchrow($result))
2102      {
2103          $user_ids[] = $row['user_id'];
2104      }
2105      $db->sql_freeresult($result);
2106  
2107      if (sizeof($user_ids))
2108      {
2109          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('administrators') . '
2110              WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2111      }
2112  
2113      $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('global_moderators');
2114  
2115      $user_ids = array();
2116      while ($row = $db->sql_fetchrow($result))
2117      {
2118          $user_ids[] = $row['user_id'];
2119      }
2120      $db->sql_freeresult($result);
2121  
2122      if (sizeof($user_ids))
2123      {
2124          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('global_moderators') . '
2125              WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2126      }
2127  
2128      // Set user colour
2129      $sql = 'SELECT group_id, group_colour FROM ' . GROUPS_TABLE . "
2130          WHERE group_colour <> ''";
2131      $result = $db->sql_query($sql);
2132  
2133      while ($row = $db->sql_fetchrow($result))
2134      {
2135          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_colour = '{$row['group_colour']}' WHERE group_id = {$row['group_id']}");
2136      }
2137      $db->sql_freeresult($result);
2138  }
2139  
2140  /**
2141  * Cleanly remove invalid user entries after converting the users table...
2142  */
2143  function remove_invalid_users()
2144  {
2145      global $convert, $db, $phpEx, $phpbb_root_path;
2146  
2147      // username_clean is UNIQUE
2148      $sql = 'SELECT user_id
2149          FROM ' . USERS_TABLE . "
2150          WHERE username_clean = ''";
2151      $result = $db->sql_query($sql);
2152      $row = $db->sql_fetchrow($result);
2153      $db->sql_freeresult($result);
2154  
2155      if ($row)
2156      {
2157          if (!function_exists('user_delete'))
2158          {
2159              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2160          }
2161  
2162          user_delete('remove', $row['user_id']);
2163      }
2164  }
2165  
2166  function convert_bbcode($message, $convert_size = true, $extended_bbcodes = false)
2167  {
2168      static $orig, $repl, $origx, $replx, $str_from, $str_to;
2169  
2170      if (empty($orig))
2171      {
2172          $orig = $repl = array();
2173  
2174          $orig[] = '#\[(php|sql)\](.*?)\[/(php|sql)\]#is';
2175          $repl[] = '[code]\2[/code]';
2176  
2177          $orig[] = '#\[font=[^\]]+\](.*?)\[/font\]#is';
2178          $repl[] = '\1';
2179  
2180          $orig[] = '#\[align=[a-z]+\](.*?)\[/align\]#is';
2181          $repl[] = '\1';
2182  
2183          $orig[] = '#\[/list=.*?\]#is';
2184          $repl[] = '[/list]';
2185  
2186          $origx = array(
2187              '#\[glow[^\]]+\](.*?)\[/glow\]#is',
2188              '#\[shadow[^\]]+\](.*?)\[/shadow\]#is',
2189              '#\[flash[^\]]+\](.*?)\[/flash\]#is'
2190          );
2191  
2192          $replx = array(
2193              '\1',
2194              '\1',
2195              '[url=\1]Flash[/url]'
2196          );
2197  
2198          $str_from = array(
2199              '[ftp]',    '[/ftp]',
2200              '[ftp=',    '[/ftp]',
2201              '[pre]',    '[/pre]',
2202              '[table]',    '[/table]',
2203              '[td]',        '[/td]',
2204              '[tr]',        '[/tr]',
2205              '[s]',        '[/s]',
2206              '[left]',    '[/left]',
2207              '[right]',    '[/right]',
2208              '[center]',    '[/center]',
2209              '[sub]',    '[/sub]',
2210              '[sup]',    '[/sup]',
2211              '[tt]',        '[/tt]',
2212              '[move]',    '[/move]',
2213              '[hr]'
2214          );
2215  
2216          $str_to = array(
2217              '[url]',    '[/url]',
2218              '[url=',    '[/url]',
2219              '[code]',    '[/code]',
2220              "\n",        '',
2221              '',            '',
2222              "\n",        '',
2223              '',            '',
2224              '',            '',
2225              '',            '',
2226              '',            '',
2227              '',            '',
2228              '',            '',
2229              '',            '',
2230              '',            '',
2231              "\n\n"
2232          );
2233  
2234          for ($i = 0; $i < sizeof($str_from); ++$i)
2235          {
2236              $origx[] = '#\\' . str_replace(']', '\\]', $str_from[$i]) . '#is';
2237              $replx[] = $str_to[$i];
2238          }
2239      }
2240  
2241      if (preg_match_all('#\[email=([^\]]+)\](.*?)\[/email\]#i', $message, $m))
2242      {
2243          for ($i = 0; $i < sizeof($m[1]); ++$i)
2244          {
2245              if ($m[1][$i] == $m[2][$i])
2246              {
2247                  $message = str_replace($m[0][$i], '[email]' . $m[1][$i] . '[/email]', $message);
2248              }
2249              else
2250              {
2251                  $message = str_replace($m[0][$i], $m[2][$i] . ' ([email]' . $m[1][$i] . '[/email])', $message);
2252              }
2253          }
2254      }
2255  
2256      if ($convert_size && preg_match('#\[size=[0-9]+\].*?\[/size\]#i', $message))
2257      {
2258          $size = array(9, 9, 12, 15, 18, 24, 29, 29, 29, 29);
2259          $message = preg_replace('#\[size=([0-9]+)\](.*?)\[/size\]#i', '[size=\1]\2[/size]', $message);
2260          $message = preg_replace('#\[size=[0-9]{2,}\](.*?)\[/size\]#i', '[size=29]\1[/size]', $message);
2261  
2262          for ($i = sizeof($size); $i; )
2263          {
2264              $i--;
2265              $message = str_replace('[size=' . $i . ']', '[size=' . $size[$i] . ']', $message);
2266          }
2267      }
2268  
2269      if ($extended_bbcodes)
2270      {
2271          $message = preg_replace($origx, $replx, $message);
2272      }
2273  
2274      $message = preg_replace($orig, $repl, $message);
2275      return $message;
2276  }
2277  
2278  
2279  function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2280  {
2281      global $convert, $phpbb_root_path, $config, $user, $db;
2282  
2283      if (substr($trg, -1) == '/')
2284      {
2285          $trg .= utf8_basename($src);
2286      }
2287      $src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2288      $trg_path = $trg;
2289  
2290      if (!$overwrite && @file_exists($trg_path))
2291      {
2292          return true;
2293      }
2294  
2295      if (!@file_exists($src_path))
2296      {
2297          return;
2298      }
2299  
2300      $path = $phpbb_root_path;
2301      $parts = explode('/', $trg);
2302      unset($parts[sizeof($parts) - 1]);
2303  
2304      for ($i = 0; $i < sizeof($parts); ++$i)
2305      {
2306          $path .= $parts[$i] . '/';
2307  
2308          if (!is_dir($path))
2309          {
2310              @mkdir($path, 0777);
2311          }
2312      }
2313  
2314      if (!phpbb_is_writable($path))
2315      {
2316          @chmod($path, 0777);
2317      }
2318  
2319      if (!@copy($src_path, $phpbb_root_path . $trg_path))
2320      {
2321          $convert->p_master->error(sprintf($user->lang['COULD_NOT_COPY'], $src_path, $phpbb_root_path . $trg_path), __LINE__, __FILE__, !$die_on_failure);
2322          return;
2323      }
2324  
2325      if ($perm = @fileperms($src_path))
2326      {
2327          @chmod($phpbb_root_path . $trg_path, $perm);
2328      }
2329  
2330      return true;
2331  }
2332  
2333  function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2334  {
2335      global $convert, $phpbb_root_path, $config, $user, $db;
2336  
2337      $dirlist = $filelist = $bad_dirs = array();
2338      $src = path($src, $source_relative_path);
2339      $trg = path($trg);
2340      $src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2341      $trg_path = $phpbb_root_path . $trg;
2342  
2343      if (!is_dir($trg_path))
2344      {
2345          @mkdir($trg_path, 0777);
2346          @chmod($trg_path, 0777);
2347      }
2348  
2349      if (!phpbb_is_writable($trg_path))
2350      {
2351          $bad_dirs[] = path($config['script_path']) . $trg;
2352      }
2353  
2354      if ($handle = @opendir($src_path))
2355      {
2356          while ($entry = readdir($handle))
2357          {
2358              if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2359              {
2360                  continue;
2361              }
2362  
2363              if (is_dir($src_path . $entry))
2364              {
2365                  $dirlist[] = $entry;
2366              }
2367              else
2368              {
2369                  $filelist[] = $entry;
2370              }
2371          }
2372          closedir($handle);
2373      }
2374      else if ($dir = @dir($src_path))
2375      {
2376          while ($entry = $dir->read())
2377          {
2378              if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2379              {
2380                  continue;
2381              }
2382  
2383              if (is_dir($src_path . $entry))
2384              {
2385                  $dirlist[] = $entry;
2386              }
2387              else
2388              {
2389                  $filelist[] = $entry;
2390              }
2391          }
2392          $dir->close();
2393      }
2394      else
2395      {
2396          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_COULD_NOT_READ'], relative_base($src, $source_relative_path)), __LINE__, __FILE__);
2397      }
2398  
2399      if ($copy_subdirs)
2400      {
2401          for ($i = 0; $i < sizeof($dirlist); ++$i)
2402          {
2403              $dir = $dirlist[$i];
2404  
2405              if ($dir == 'CVS')
2406              {
2407                  continue;
2408              }
2409  
2410              if (!is_dir($trg_path . $dir))
2411              {
2412                  @mkdir($trg_path . $dir, 0777);
2413                  @chmod($trg_path . $dir, 0777);
2414              }
2415  
2416              if (!phpbb_is_writable($trg_path . $dir))
2417              {
2418                  $bad_dirs[] = $trg . $dir;
2419                  $bad_dirs[] = $trg_path . $dir;
2420              }
2421  
2422              if (!sizeof($bad_dirs))
2423              {
2424                  copy_dir($src . $dir, $trg . $dir, true, $overwrite, $die_on_failure, $source_relative_path);
2425              }
2426          }
2427      }
2428  
2429      if (sizeof($bad_dirs))
2430      {
2431          $str = (sizeof($bad_dirs) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
2432          sort($bad_dirs);
2433          $convert->p_master->error(sprintf($str, implode('<br />', $bad_dirs)), __LINE__, __FILE__);
2434      }
2435  
2436      for ($i = 0; $i < sizeof($filelist); ++$i)
2437      {
2438          copy_file($src . $filelist[$i], $trg . $filelist[$i], $overwrite, $die_on_failure, $source_relative_path);
2439      }
2440  }
2441  
2442  function relative_base($path, $is_relative = true, $line = false, $file = false)
2443  {
2444      global $convert, $phpbb_root_path, $config, $user, $db;
2445  
2446      if (!$is_relative)
2447      {
2448          return $path;
2449      }
2450  
2451      if (empty($convert->options['forum_path']) && $is_relative)
2452      {
2453          $line = $line ? $line : __LINE__;
2454          $file = $file ? $file : __FILE__;
2455  
2456          $convert->p_master->error($user->lang['CONV_ERROR_NO_FORUM_PATH'], $line, $file);
2457      }
2458  
2459      return $convert->options['forum_path'] . '/' . $path;
2460  }
2461  
2462  function get_smiley_display()
2463  {
2464      static $smiley_count = 0;
2465      $smiley_count++;
2466      return ($smiley_count < 50) ? 1 : 0;
2467  }
2468  
2469  
2470  function fill_dateformat($user_dateformat)
2471  {
2472      global $config;
2473  
2474      return ((empty($user_dateformat)) ? $config['default_dateformat'] : $user_dateformat);
2475  }
2476  
2477  
2478  
2479  ?>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1