[ Index ]

PHP Cross Reference of phpBB-3.1.10-deutsch

title

Body

[close]

/includes/ -> functions_convert.php (source)

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


Generated: Sun Feb 19 19:52:41 2017 Cross-referenced by PHPXref 0.7.1