Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


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

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

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

functions_convert.php

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


0001  <?php
0002  /**
0003  *
0004  * @package install
0005  * @version $Id$
0006  * @copyright (c) 2006 phpBB Group
0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
0008  *
0009  */
0010   
0011  /**
0012  * @ignore
0013  */
0014  if (!defined('IN_PHPBB'))
0015  {
0016      exit;
0017  }
0018   
0019  /**
0020  * Default avatar width/height
0021  * @ignore
0022  */
0023  define('DEFAULT_AVATAR_X', 80);
0024  define('DEFAULT_AVATAR_Y', 80);
0025   
0026  // Global functions - all functions can be used by convertors
0027   
0028  // SIMPLE FUNCTIONS
0029   
0030  /**
0031  * Return the preceding value
0032  */
0033  function dec($var)
0034  {
0035      return --$var;
0036  }
0037   
0038  /**
0039  * Return the next value
0040  */
0041  function inc($var)
0042  {
0043      return ++$var;
0044  }
0045   
0046  /**
0047  * Return whether the value is positive
0048  */
0049  function is_positive($n)
0050  {
0051      return ($n > 0) ? 1 : 0;
0052  }
0053   
0054  /**
0055  * Boolean inverse of the value
0056  */
0057  function not($var)
0058  {
0059      return ($var) ? 0 : 1;
0060  }
0061   
0062  /**
0063  * Convert a textual value to it's equivalent boolean value
0064  *
0065  * @param string $str String to convert (converts yes, on, y, 1 and true to boolean true)
0066  * @return boolean The equivalent value
0067  */
0068  function str_to_bool($str)
0069  {
0070      $str = strtolower($str);
0071      return ($str == 'yes' || $str == 'on' || $str == 'y' || $str == 'true' || $str == '1') ? true : false;
0072  }
0073   
0074  /**
0075  * Function to mimic php's empty() function (it is the same)
0076  */
0077  function is_empty($mixed)
0078  {
0079      return empty($mixed);
0080  }
0081   
0082  /**
0083  * Convert the name of a user's primary group to the appropriate equivalent phpBB group id
0084  *
0085  * @param string $status The name of the group
0086  * @return int The group_id corresponding to the equivalent group
0087  */
0088  function str_to_primary_group($status)
0089  {
0090      switch (ucfirst(strtolower($status)))
0091      {
0092          case 'Administrator':
0093              return get_group_id('administrators');
0094          break;
0095   
0096          case 'Super moderator':
0097          case 'Global moderator':
0098          case 'Moderator':
0099              return get_group_id('global_moderators');
0100          break;
0101   
0102          case 'Guest':
0103          case 'Anonymous':
0104              return get_group_id('guests');
0105          break;
0106   
0107          default:
0108              return get_group_id('registered');
0109          break;
0110      }
0111  }
0112   
0113  /**
0114  * Convert a boolean into the appropriate phpBB constant indicating whether the item is locked
0115  */
0116  function is_item_locked($bool)
0117  {
0118      return ($bool) ? ITEM_LOCKED : ITEM_UNLOCKED;
0119  }
0120   
0121  /**
0122  * Convert a value from days to seconds
0123  */
0124  function days_to_seconds($days)
0125  {
0126      return ($days * 86400);
0127  }
0128   
0129  /**
0130  * Determine whether a user is anonymous and return the appropriate new user_id
0131  */
0132  function is_user_anonymous($user_id)
0133  {
0134      return ($user_id > ANONYMOUS) ? $user_id : ANONYMOUS;
0135  }
0136   
0137  /**
0138  * Generate a key value based on existing values
0139  *
0140  * @param int $pad Amount to add to the maximum value
0141  * @return int Key value
0142  */
0143  function auto_id($pad = 0)
0144  {
0145      global $auto_id, $convert_row;
0146   
0147      if (!empty($convert_row['max_id']))
0148      {
0149          return $convert_row['max_id'] + $pad;
0150      }
0151      
0152      return $auto_id + $pad;
0153  }
0154   
0155  /**
0156  * Convert a boolean into the appropriate phpBB constant indicating whether the user is active
0157  */
0158  function set_user_type($user_active)
0159  {
0160      return ($user_active) ? USER_NORMAL : USER_INACTIVE;
0161  }
0162   
0163  /**
0164  * Convert a value from minutes to hours
0165  */
0166  function minutes_to_hours($minutes)
0167  {
0168      return ($minutes / 3600);
0169  }
0170   
0171  /**
0172  * Return the group_id for a given group name
0173  */
0174  function get_group_id($group_name)
0175  {
0176      global $db, $group_mapping;
0177   
0178      if (empty($group_mapping))
0179      {
0180          $sql = 'SELECT group_name, group_id
0181              FROM ' . GROUPS_TABLE;
0182          $result = $db->sql_query($sql);
0183   
0184          $group_mapping = array();
0185          while ($row = $db->sql_fetchrow($result))
0186          {
0187              $group_mapping[strtoupper($row['group_name'])] = (int) $row['group_id'];
0188          }
0189          $db->sql_freeresult($result);
0190      }
0191   
0192      if (!sizeof($group_mapping))
0193      {
0194          add_default_groups();
0195          return get_group_id($group_name);
0196      }
0197   
0198      if (isset($group_mapping[strtoupper($group_name)]))
0199      {
0200          return $group_mapping[strtoupper($group_name)];
0201      }
0202   
0203      return $group_mapping['REGISTERED'];
0204  }
0205   
0206  /**
0207  * Generate the email hash stored in the users table
0208  */
0209  function gen_email_hash($email)
0210  {
0211      return (crc32(strtolower($email)) . strlen($email));
0212  }
0213   
0214  /**
0215  * Convert a boolean into the appropriate phpBB constant indicating whether the topic is locked
0216  */
0217  function is_topic_locked($bool)
0218  {
0219      return (!empty($bool)) ? ITEM_LOCKED : ITEM_UNLOCKED;
0220  }
0221   
0222  /**
0223  * Generate a bbcode_uid value
0224  */
0225  function make_uid($timestamp)
0226  {
0227      static $last_timestamp, $last_uid;
0228   
0229      if (empty($last_timestamp) || $timestamp != $last_timestamp)
0230      {
0231          $last_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);
0232      }
0233      $last_timestamp = $timestamp;
0234      return $last_uid;
0235  }
0236   
0237   
0238  /**
0239  * Validate a website address
0240  */
0241  function validate_website($url)
0242  {
0243      if ($url === 'http://')
0244      {
0245          return '';
0246      }
0247      else if (!preg_match('#^[a-z0-9]+://#i', $url) && strlen($url) > 0)
0248      {
0249          return 'http://' . $url;
0250      }
0251      return $url;
0252  }
0253   
0254  /**
0255  * Convert nulls to zeros for fields which allowed a NULL value in the source but not the destination
0256  */
0257  function null_to_zero($value)
0258  {
0259      return ($value === NULL) ? 0 : $value;
0260  }
0261   
0262  /**
0263  * Convert nulls to empty strings for fields which allowed a NULL value in the source but not the destination
0264  */
0265  function null_to_str($value)
0266  {
0267      return ($value === NULL) ? '' : $value;
0268  }
0269   
0270  // EXTENDED FUNCTIONS
0271   
0272  /**
0273  * Get old config value
0274  */
0275  function get_config_value($config_name)
0276  {
0277      static $convert_config;
0278   
0279      if (!isset($convert_config))
0280      {
0281          $convert_config = get_config();
0282      }
0283      
0284      if (!isset($convert_config[$config_name]))
0285      {
0286          return false;
0287      }
0288   
0289      return (empty($convert_config[$config_name])) ? '' : $convert_config[$config_name];
0290  }
0291   
0292  /**
0293  * Convert an IP address from the hexadecimal notation to normal dotted-quad notation
0294  */
0295  function decode_ip($int_ip)
0296  {
0297      if (!$int_ip)
0298      {
0299          return $int_ip;
0300      }
0301   
0302      $hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
0303   
0304      // 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...
0305      if (sizeof($hexipbang) < 4)
0306      {
0307          return $int_ip;
0308      }
0309   
0310      return hexdec($hexipbang[0]) . '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
0311  }
0312   
0313  /**
0314  * Reverse the encoding of wild-carded bans
0315  */
0316  function decode_ban_ip($int_ip)
0317  {
0318      return str_replace('255', '*', decode_ip($int_ip));
0319  }
0320   
0321  /**
0322  * Determine the MIME-type of a specified filename
0323  * This does not actually inspect the file, but simply uses the file extension
0324  */
0325  function mimetype($filename)
0326  {
0327      if (!preg_match('/\.([a-z0-9]+)$/i', $filename, $m))
0328      {
0329          return 'application/octet-stream';
0330      }
0331   
0332      switch (strtolower($m[1]))
0333      {
0334          case 'zip':        return 'application/zip';
0335          case 'jpeg':    return 'image/jpeg';
0336          case 'jpg':        return 'image/jpeg';
0337          case 'jpe':        return 'image/jpeg';
0338          case 'png':        return 'image/png';
0339          case 'gif':        return 'image/gif';
0340          case 'htm':
0341          case 'html':    return 'text/html';
0342          case 'tif':        return 'image/tiff';
0343          case 'tiff':    return 'image/tiff';
0344          case 'ras':        return 'image/x-cmu-raster';
0345          case 'pnm':        return 'image/x-portable-anymap';
0346          case 'pbm':        return 'image/x-portable-bitmap';
0347          case 'pgm':        return 'image/x-portable-graymap';
0348          case 'ppm':        return 'image/x-portable-pixmap';
0349          case 'rgb':        return 'image/x-rgb';
0350          case 'xbm':        return 'image/x-xbitmap';
0351          case 'xpm':        return 'image/x-xpixmap';
0352          case 'xwd':        return 'image/x-xwindowdump';
0353          case 'z':        return 'application/x-compress';
0354          case 'gtar':    return 'application/x-gtar';
0355          case 'tgz':        return 'application/x-gtar';
0356          case 'gz':        return 'application/x-gzip';
0357          case 'tar':        return 'application/x-tar';
0358          case 'xls':        return 'application/excel';
0359          case 'pdf':        return 'application/pdf';
0360          case 'ppt':        return 'application/powerpoint';
0361          case 'rm':        return 'application/vnd.rn-realmedia';
0362          case 'wma':        return 'audio/x-ms-wma';
0363          case 'swf':        return 'application/x-shockwave-flash';
0364          case 'ief':        return 'image/ief';
0365          case 'doc':
0366          case 'dot':
0367          case 'wrd':        return 'application/msword';
0368          case 'ai':
0369          case 'eps':
0370          case 'ps':        return 'application/postscript';
0371          case 'asc':
0372          case 'txt':
0373          case 'c':
0374          case 'cc':
0375          case 'h':
0376          case 'hh':
0377          case 'cpp':
0378          case 'hpp':
0379          case 'php':
0380          case 'php3':    return 'text/plain';
0381          default:         return 'application/octet-stream';
0382      }
0383  }
0384   
0385  /**
0386  * Obtain the dimensions of all remotely hosted avatars
0387  * This should only be called from execute_last
0388  * There can be significant network overhead if there are a large number of remote avatars
0389  * @todo Look at the option of allowing the user to decide whether this is called or to force the dimensions
0390  */
0391  function remote_avatar_dims()
0392  {
0393      global $db;
0394   
0395      $sql = 'SELECT user_id, user_avatar
0396          FROM ' . USERS_TABLE . '
0397          WHERE user_avatar_type = ' . AVATAR_REMOTE;
0398      $result = $db->sql_query($sql);
0399   
0400      $remote_avatars = array();
0401      while ($row = $db->sql_fetchrow($result))
0402      {
0403          $remote_avatars[(int) $row['user_id']] = $row['user_avatar'];
0404      }
0405      $db->sql_freeresult($result);
0406   
0407      foreach ($remote_avatars as $user_id => $avatar)
0408      {
0409          $width = (int) get_remote_avatar_dim($avatar, 0);
0410          $height = (int) get_remote_avatar_dim($avatar, 1);
0411   
0412          $sql = 'UPDATE ' . USERS_TABLE . '
0413              SET user_avatar_width = ' . (int) $width . ', user_avatar_height = ' . (int) $height . '
0414              WHERE user_id = ' . $user_id;
0415          $db->sql_query($sql);
0416      }
0417  }
0418   
0419  function import_avatar_gallery($gallery_name = '', $subdirs_as_galleries = false)
0420  {
0421      global $config, $convert, $phpbb_root_path, $user;
0422   
0423      $relative_path = empty($convert->convertor['source_path_absolute']);
0424   
0425      if (empty($convert->convertor['avatar_gallery_path']))
0426      {
0427          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'import_avatar_gallery()'), __LINE__, __FILE__);
0428      }
0429   
0430      $src_path = relative_base(path($convert->convertor['avatar_gallery_path'], $relative_path), $relative_path);
0431   
0432      if (is_dir($src_path))
0433      {
0434          // Do not die on failure... safe mode restrictions may be in effect.
0435          copy_dir($convert->convertor['avatar_gallery_path'], path($config['avatar_gallery_path']) . $gallery_name, !$subdirs_as_galleries, false, false, $relative_path);
0436   
0437          // only doing 1 level deep. (ibf 1.x)
0438          // notes: ibf has 2 tiers: directly in the avatar directory for base gallery (handled in the above statement), plus subdirs(handled below).
0439          // 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.
0440          if ($subdirs_as_galleries)
0441          {
0442              $dirlist = array();
0443              if ($handle = @opendir($src_path))
0444              {
0445                  while ($entry = readdir($handle))
0446                  {
0447                      if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
0448                      {
0449                          continue;
0450                      }
0451   
0452                      if (is_dir($src_path . $entry))
0453                      {
0454                          $dirlist[] = $entry;
0455                      }
0456                  }
0457                  closedir($handle);
0458              }
0459              else if ($dir = @dir($src_path))
0460              {
0461                  while ($entry = $dir->read())
0462                  {
0463                      if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
0464                      {
0465                          continue;
0466                      }
0467   
0468                      if (is_dir($src_path . $entry))
0469                      {
0470                          $dirlist[] = $entry;
0471                      }
0472                  }
0473                  $dir->close();
0474              }
0475   
0476              for ($i = 0; $i < sizeof($dirlist); ++$i)
0477              {
0478                  $dir = $dirlist[$i];
0479   
0480                  // Do not die on failure... safe mode restrictions may be in effect.
0481                  copy_dir(path($convert->convertor['avatar_gallery_path'], $relative_path) . $dir, path($config['avatar_gallery_path']) . $dir, true, false, false, $relative_path);
0482              }
0483          }
0484      }
0485  }
0486   
0487  function import_attachment_files($category_name = '')
0488  {
0489      global $config, $convert, $phpbb_root_path, $db, $user;
0490   
0491      $sql = 'SELECT config_value AS upload_path
0492          FROM ' . CONFIG_TABLE . "
0493          WHERE config_name = 'upload_path'";
0494      $result = $db->sql_query($sql);
0495      $config['upload_path'] = $db->sql_fetchfield('upload_path');
0496      $db->sql_freeresult($result);
0497   
0498      $relative_path = empty($convert->convertor['source_path_absolute']);
0499   
0500      if (empty($convert->convertor['upload_path']))
0501      {
0502          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment_files()'), __LINE__, __FILE__);
0503      }
0504   
0505      if (is_dir(relative_base(path($convert->convertor['upload_path'], $relative_path), $relative_path)))
0506      {
0507          copy_dir($convert->convertor['upload_path'], path($config['upload_path']) . $category_name, true, false, true, $relative_path);
0508      }
0509  }
0510   
0511  function attachment_forum_perms($forum_id)
0512  {
0513      if (!is_array($forum_id))
0514      {
0515          $forum_id = array($forum_id);
0516      }
0517   
0518      return serialize($forum_id);
0519  }
0520   
0521  // base64todec function
0522  // -> from php manual?
0523  function base64_unpack($string)
0524  {
0525      $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-';
0526      $base = strlen($chars);
0527   
0528      $length = strlen($string);
0529      $number = 0;
0530   
0531      for ($i = 1; $i <= $length; $i++)
0532      {
0533          $pos = $length - $i;
0534          $operand = strpos($chars, substr($string, $pos, 1));
0535          $exponent = pow($base, $i-1);
0536          $dec_value = $operand * $exponent;
0537          $number += $dec_value;
0538      }
0539   
0540      return $number;
0541  }
0542   
0543  function _import_check($config_var, $source, $use_target)
0544  {
0545      global $convert, $config;
0546   
0547      $result = array(
0548          'orig_source'    => $source,
0549          'copied'        => false,
0550          'relative_path'    => (empty($convert->convertor['source_path_absolute'])) ? true : false,
0551      );
0552   
0553      // copy file will prepend $phpBB_root_path
0554      $target = $config[$config_var] . '/' . basename(($use_target === false) ? $source : $use_target);
0555   
0556      if (!empty($convert->convertor[$config_var]) && strpos($source, $convert->convertor[$config_var]) !== 0)
0557      {
0558          $source = $convert->convertor[$config_var] . $source;
0559      }
0560   
0561      $result['source'] = $source;
0562   
0563      if (file_exists(relative_base($source, $result['relative_path'], __LINE__, __FILE__)))
0564      {
0565          $result['copied'] = copy_file($source, $target, false, false, $result['relative_path']);
0566      }
0567   
0568      if ($result['copied'])
0569      {
0570          $result['target'] = basename($target);
0571      }
0572      else
0573      {
0574          $result['target'] = ($use_target !== false) ? $result['orig_source'] : basename($target);
0575      }
0576   
0577      return $result;
0578  }
0579   
0580  function import_attachment($source, $use_target = false)
0581  {
0582      if (empty($source))
0583      {
0584          return '';
0585      }
0586   
0587      global $convert, $phpbb_root_path, $config, $user;
0588   
0589      if (empty($convert->convertor['upload_path']))
0590      {
0591          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment()'), __LINE__, __FILE__);
0592      }
0593   
0594      $result = _import_check('upload_path', $source, $use_target);
0595   
0596      if ($result['copied'])
0597      {
0598          // Thumbnails?
0599          if (is_array($convert->convertor['thumbnails']))
0600          {
0601              $thumb_dir = $convert->convertor['thumbnails'][0];
0602              $thumb_prefix = $convert->convertor['thumbnails'][1];
0603              $thumb_source = $thumb_dir . $thumb_prefix . basename($result['source']);
0604   
0605              if (strpos($thumb_source, $convert->convertor['upload_path']) !== 0)
0606              {
0607                  $thumb_source = $convert->convertor['upload_path'] . $thumb_source;
0608              }
0609              $thumb_target = $config['upload_path'] . '/thumb_' . $result['target'];
0610   
0611              if (file_exists(relative_base($thumb_source, $result['relative_path'], __LINE__, __FILE__)))
0612              {
0613                  copy_file($thumb_source, $thumb_target, false, false, $result['relative_path']);
0614              }
0615          }
0616      }
0617   
0618      return $result['target'];
0619  }
0620   
0621  function import_rank($source, $use_target = false)
0622  {
0623      if (empty($source))
0624      {
0625          return '';
0626      }
0627   
0628      global $convert, $phpbb_root_path, $config, $user;
0629   
0630      if (!isset($convert->convertor['ranks_path']))
0631      {
0632          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_RANKS_PATH'], 'import_rank()'), __LINE__, __FILE__);
0633      }
0634   
0635      $result = _import_check('ranks_path', $source, $use_target);
0636      return $result['target'];
0637  }
0638   
0639  function import_smiley($source, $use_target = false)
0640  {
0641      if (empty($source))
0642      {
0643          return '';
0644      }
0645   
0646      global $convert, $phpbb_root_path, $config, $user;
0647   
0648      if (!isset($convert->convertor['smilies_path']))
0649      {
0650          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'import_smiley()'), __LINE__, __FILE__);
0651      }
0652   
0653      $result = _import_check('smilies_path', $source, $use_target);
0654      return $result['target'];
0655  }
0656   
0657  /*
0658  */
0659  function import_avatar($source, $use_target = false, $user_id = false)
0660  {
0661      if (empty($source) || preg_match('#^https?:#i', $source) || preg_match('#blank\.(gif|png)$#i', $source))
0662      {
0663          return;
0664      }
0665   
0666      global $convert, $phpbb_root_path, $config, $user;
0667   
0668      if (!isset($convert->convertor['avatar_path']))
0669      {
0670          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'import_avatar()'), __LINE__, __FILE__);
0671      }
0672      
0673      if ($use_target === false && $user_id !== false)
0674      {
0675          $use_target = $config['avatar_salt'] . '_' . $user_id . '.' . substr(strrchr($source, '.'), 1);
0676      }
0677      
0678      $result = _import_check('avatar_path', $source, $use_target);
0679   
0680      return ((!empty($user_id)) ? $user_id : $use_target) . '.' . substr(strrchr($source, '.'), 1);
0681  }
0682   
0683  /**
0684  * @todo all image dimension functions below (there are a *lot*) should get revisited and converted to one or two functions (no more needed, really).
0685  */
0686   
0687  /**
0688  * Calculate the size of the specified image
0689  * Called from the following functions for calculating the size of specific image types
0690  */
0691  function get_image_dim($source)
0692  {
0693      if (empty($source))
0694      {
0695          return array(0, 0);
0696      }
0697   
0698      global $convert;
0699   
0700      $relative_path = empty($convert->convertor['source_path_absolute']);
0701   
0702      if (file_exists(relative_base($source, $relative_path)))
0703      {
0704          $image = relative_base($source, $relative_path);
0705          return @getimagesize($image);
0706      }
0707   
0708      return false;
0709  }
0710   
0711  /**
0712  * Obtain the width of the specified smilie
0713  */
0714  function get_smiley_width($src)
0715  {
0716      return get_smiley_dim($src, 0);
0717  }
0718   
0719  /**
0720  * Obtain the height of the specified smilie
0721  */
0722  function get_smiley_height($src)
0723  {
0724      return get_smiley_dim($src, 1);
0725  }
0726   
0727  /**
0728  * Obtain the size of the specified smilie (using the cache if possible) and cache the value
0729  */
0730  function get_smiley_dim($source, $axis)
0731  {
0732      if (empty($source))
0733      {
0734          return 15;
0735      }
0736   
0737      static $smiley_cache = array();
0738   
0739      if (isset($smiley_cache[$source]))
0740      {
0741          return $smiley_cache[$source][$axis];
0742      }
0743   
0744      global $convert, $phpbb_root_path, $config, $user;
0745   
0746      $orig_source = $source;
0747   
0748      if (!isset($convert->convertor['smilies_path']))
0749      {
0750          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'get_smiley_dim()'), __LINE__, __FILE__);
0751      }
0752   
0753      if (!empty($convert->convertor['smilies_path']) && strpos($source, $convert->convertor['smilies_path']) !== 0)
0754      {
0755          $source = $convert->convertor['smilies_path'] . $source;
0756      }
0757   
0758      $smiley_cache[$orig_source] = get_image_dim($source);
0759   
0760      if (empty($smiley_cache[$orig_source]) || empty($smiley_cache[$orig_source][0]) || empty($smiley_cache[$orig_source][1]))
0761      {
0762          $smiley_cache[$orig_source] = array(15, 15);
0763          return 15;
0764      }
0765   
0766      return $smiley_cache[$orig_source][$axis];
0767  }
0768   
0769  /**
0770  * Obtain the width of the specified avatar
0771  */
0772  function get_avatar_width($src, $func = false, $arg1 = false, $arg2 = false)
0773  {
0774      return get_avatar_dim($src, 0, $func, $arg1, $arg2);
0775  }
0776   
0777  /**
0778  * Obtain the height of the specified avatar
0779  */
0780  function get_avatar_height($src, $func = false, $arg1 = false, $arg2 = false)
0781  {
0782      return get_avatar_dim($src, 1, $func, $arg1, $arg2);
0783  }
0784   
0785  /**
0786  */
0787  function get_avatar_dim($src, $axis, $func = false, $arg1 = false, $arg2 = false)
0788  {
0789      $avatar_type = AVATAR_UPLOAD;
0790   
0791      if ($func)
0792      {
0793          if ($arg1 || $arg2)
0794          {
0795              $ary = array($arg1);
0796   
0797              if ($arg2)
0798              {
0799                  $ary[] = $arg2;
0800              }
0801   
0802              $avatar_type = call_user_func_array($func, $ary);
0803          }
0804          else
0805          {
0806              $avatar_type = call_user_func($func);
0807          }
0808      }
0809   
0810      switch ($avatar_type)
0811      {
0812          case AVATAR_UPLOAD:
0813              return get_upload_avatar_dim($src, $axis);
0814          break;
0815   
0816          case AVATAR_GALLERY:
0817              return get_gallery_avatar_dim($src, $axis);
0818          break;
0819   
0820          case AVATAR_REMOTE:
0821               // see notes on this functions usage and (hopefully) model $func to avoid this accordingly
0822              return get_remote_avatar_dim($src, $axis);
0823          break;
0824   
0825          default:
0826              $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
0827              $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
0828   
0829              return $axis ? $default_y : $default_x;
0830          break;
0831      }
0832  }
0833   
0834  /**
0835  * Obtain the size of the specified uploaded avatar (using the cache if possible) and cache the value
0836  */
0837  function get_upload_avatar_dim($source, $axis)
0838  {
0839      static $cachedims = false;
0840      static $cachekey = false;
0841   
0842      if (empty($source))
0843      {
0844          return 0;
0845      }
0846   
0847      if ($cachekey == $source)
0848      {
0849          return $cachedims[$axis];
0850      }
0851   
0852      $orig_source = $source;
0853   
0854      if (substr($source, 0, 7) == 'upload:')
0855      {
0856          $source = substr($source, 7);
0857      }
0858   
0859      global $convert, $phpbb_root_path, $config, $user;
0860   
0861      if (!isset($convert->convertor['avatar_path']))
0862      {
0863          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'get_upload_avatar_dim()'), __LINE__, __FILE__);
0864      }
0865   
0866      if (!empty($convert->convertor['avatar_path']) && strpos($source, $convert->convertor['avatar_path']) !== 0)
0867      {
0868          $source = path($convert->convertor['avatar_path'], empty($convert->convertor['source_path_absolute'])) . $source;
0869      }
0870   
0871      $cachedims = get_image_dim($source);
0872   
0873      if (empty($cachedims) || empty($cachedims[0]) || empty($cachedims[1]))
0874      {
0875          $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
0876          $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
0877   
0878          $cachedims = array($default_x, $default_y);
0879      }
0880   
0881      return $cachedims[$axis];
0882  }
0883   
0884  /**
0885  * Obtain the size of the specified gallery avatar (using the cache if possible) and cache the value
0886  */
0887  function get_gallery_avatar_dim($source, $axis)
0888  {
0889      if (empty($source))
0890      {
0891          return 0;
0892      }
0893   
0894      static $avatar_cache = array();
0895   
0896      if (isset($avatar_cache[$source]))
0897      {
0898          return $avatar_cache[$source][$axis];
0899      }
0900   
0901      global $convert, $phpbb_root_path, $config, $user;
0902   
0903      $orig_source = $source;
0904   
0905      if (!isset($convert->convertor['avatar_gallery_path']))
0906      {
0907          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'get_gallery_avatar_dim()'), __LINE__, __FILE__);
0908      }
0909   
0910      if (!empty($convert->convertor['avatar_gallery_path']) && strpos($source, $convert->convertor['avatar_gallery_path']) !== 0)
0911      {
0912          $source = path($convert->convertor['avatar_gallery_path'], empty($convert->convertor['source_path_absolute'])) . $source;
0913      }
0914   
0915      $avatar_cache[$orig_source] = get_image_dim($source);
0916   
0917      if (empty($avatar_cache[$orig_source]) || empty($avatar_cache[$orig_source][0]) || empty($avatar_cache[$orig_source][1]))
0918      {
0919          $default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
0920          $default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
0921   
0922          $avatar_cache[$orig_source] = array($default_x, $default_y);
0923      }
0924   
0925      return $avatar_cache[$orig_source][$axis];
0926  }
0927   
0928  /**
0929  * Obtain the size of the specified remote avatar (using the cache if possible) and cache the value
0930  * Whilst it's unlikely that remote avatars will be duplicated, it is possible so caching seems the best option
0931  * This should only be called from a post processing step due to the possibility of network timeouts
0932  */
0933  function get_remote_avatar_dim($src, $axis)
0934  {
0935      if (empty($src))
0936      {
0937          return 0;
0938      }
0939   
0940      static $remote_avatar_cache = array();
0941   
0942      // an ugly hack: we assume that the dimensions of each remote avatar are accessed exactly twice (x and y)
0943      if (isset($remote_avatar_cache[$src]))
0944      {
0945          $retval = $remote_avatar_cache[$src][$axis];
0946          unset($remote_avatar_cache);
0947          return $retval;
0948      }
0949      
0950      $url_info = @parse_url($src);
0951      if (empty($url_info['host']))
0952      {
0953          return 0;
0954      }
0955      $host = $url_info['host'];
0956      $port = (isset($url_info['port'])) ? $url_info['port'] : 0;
0957      $protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
0958      if (empty($port))
0959      {
0960          switch(strtolower($protocol))
0961          {
0962              case 'ftp':
0963                  $port = 21;
0964                  break;
0965                  
0966              case 'https':
0967                  $port = 443;
0968                  break;
0969              
0970              default:
0971                  $port = 80;
0972          }
0973      }
0974      
0975      $timeout = @ini_get('default_socket_timeout');
0976      @ini_set('default_socket_timeout', 2);
0977      
0978      // We're just trying to reach the server to avoid timeouts
0979      $fp = @fsockopen($host, $port, $errno, $errstr, 1);
0980      if ($fp)
0981      {
0982          $remote_avatar_cache[$src] = @getimagesize($src);
0983          fclose($fp);
0984      }
0985      
0986      $default_x     = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
0987      $default_y     = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
0988      $default     = array($default_x, $default_y);
0989      
0990      if (empty($remote_avatar_cache[$src]) || empty($remote_avatar_cache[$src][0]) || empty($remote_avatar_cache[$src][1]))
0991      {
0992          $remote_avatar_cache[$src] = $default;
0993      }
0994      else
0995      {
0996          // We trust gallery and uploaded avatars to conform to the size settings; we might have to adjust here
0997          if ($remote_avatar_cache[$src][0] > $default_x || $remote_avatar_cache[$src][1] > $default_y)
0998          {
0999              $bigger = ($remote_avatar_cache[$src][0] > $remote_avatar_cache[$src][1]) ? 0 : 1;
1000              $ratio = $default[$bigger] / $remote_avatar_cache[$src][$bigger];
1001              $remote_avatar_cache[$src][0] = (int)($remote_avatar_cache[$src][0] * $ratio);
1002              $remote_avatar_cache[$src][1] = (int)($remote_avatar_cache[$src][1] * $ratio);
1003          }
1004      }
1005      
1006      @ini_set('default_socket_timeout', $timeout);
1007      return $remote_avatar_cache[$src][$axis];
1008  }
1009   
1010  function set_user_options()
1011  {
1012      global $convert_row;
1013   
1014      // Key need to be set in row, else default value is chosen
1015      $keyoptions = array(
1016          'viewimg'        => array('bit' => 0, 'default' => 1),
1017          'viewflash'        => array('bit' => 1, 'default' => 1),
1018          'viewsmilies'    => array('bit' => 2, 'default' => 1),
1019          'viewsigs'        => array('bit' => 3, 'default' => 1),
1020          'viewavatars'    => array('bit' => 4, 'default' => 1),
1021          'viewcensors'    => array('bit' => 5, 'default' => 1),
1022          'attachsig'        => array('bit' => 6, 'default' => 0),
1023          'bbcode'        => array('bit' => 8, 'default' => 1),
1024          'smilies'        => array('bit' => 9, 'default' => 1),
1025          'popuppm'        => array('bit' => 10, 'default' => 0),
1026      );
1027   
1028      $option_field = 0;
1029   
1030      foreach ($keyoptions as $key => $key_ary)
1031      {
1032          $value = (isset($convert_row[$key])) ? (int) $convert_row[$key] : $key_ary['default'];
1033   
1034          if ($value && !($option_field & 1 << $key_ary['bit']))
1035          {
1036              $option_field += 1 << $key_ary['bit'];
1037          }
1038      }
1039   
1040      return $option_field;
1041  }
1042   
1043  /**
1044  * Index messages on the fly as we convert them
1045  * @todo naderman, can you check that this works with the new search plugins as it's use is currently disabled (and thus untested)
1046  function search_indexing($message = '')
1047  {
1048      global $fulltext_search, $convert_row;
1049   
1050      if (!isset($convert_row['post_id']))
1051      {
1052          return;
1053      }
1054   
1055      if (!$message)
1056      {
1057          if (!isset($convert_row['message']))
1058          {
1059              return;
1060          }
1061   
1062          $message = $convert_row['message'];
1063      }
1064   
1065      $title = (isset($convert_row['title'])) ? $convert_row['title'] : '';
1066   
1067      $fulltext_search->index('post', $convert_row['post_id'], $message, $title, $convert_row['poster_id'], $convert_row['forum_id']);
1068  }
1069  */
1070   
1071  function make_unique_filename($filename)
1072  {
1073      if (!strlen($filename))
1074      {
1075          $filename = md5(unique_id()) . '.dat';
1076      }
1077      else if ($filename[0] == '.')
1078      {
1079          $filename = md5(unique_id()) . $filename;
1080      }
1081      else if (preg_match('/\.([a-z]+)$/i', $filename, $m))
1082      {
1083          $filename = preg_replace('/\.([a-z]+)$/i', '_' . md5(unique_id()) . '.\1', $filename);
1084      }
1085      else
1086      {
1087          $filename .= '_' . md5(unique_id()) . '.dat';
1088      }
1089   
1090      return $filename;
1091  }
1092   
1093  function words_unique(&$words)
1094  {
1095      reset($words);
1096      $return_array = array();
1097   
1098      $word = current($words);
1099      do
1100      {
1101          $return_array[$word] = $word;
1102      }
1103      while ($word = next($words));
1104   
1105      return $return_array;
1106  }
1107   
1108  /**
1109  * Adds a user to the specified group and optionally makes them a group leader
1110  * This function does not create the group if it does not exist and so should only be called after the groups have been created
1111  */
1112  function add_user_group($group_id, $user_id, $group_leader=false)
1113  {
1114      global $convert, $phpbb_root_path, $config, $user, $db;
1115      
1116      $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1117          'group_id'        => $group_id,
1118          'user_id'        => $user_id,
1119          'group_leader'    => ($group_leader) ? 1 : 0,
1120          'user_pending'    => 0));
1121      $db->sql_query($sql);
1122  }
1123   
1124  // STANDALONE FUNCTIONS
1125   
1126  /**
1127  * Add users to the pre-defined "special" groups
1128  *
1129  * @param string $group The name of the special group to add to
1130  * @param string $select_query An SQL query to retrieve the user(s) to add to the group
1131  */
1132  function user_group_auth($group, $select_query, $use_src_db)
1133  {
1134      global $convert, $phpbb_root_path, $config, $user, $db, $src_db, $same_db;
1135   
1136      if (!in_array($group, array('guests', 'registered', 'registered_coppa', 'global_moderators', 'administrators', 'bots')))
1137      {
1138          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_WRONG_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1139          return;
1140      }
1141   
1142      $sql = 'SELECT group_id
1143          FROM ' . GROUPS_TABLE . "
1144          WHERE group_name = '" . $db->sql_escape(strtoupper($group)) . "'";
1145      $result = $db->sql_query($sql);
1146      $group_id = (int) $db->sql_fetchfield('group_id');
1147      $db->sql_freeresult($result);
1148   
1149      if (!$group_id)
1150      {
1151          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1152          return;
1153      }
1154   
1155      if ($same_db || !$use_src_db)
1156      {
1157          $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' (user_id, group_id, user_pending)
1158              ' . str_replace('{' . strtoupper($group) . '}', $group_id . ', 0', $select_query);
1159          $db->sql_query($sql);
1160      }
1161      else
1162      {
1163          $result = $src_db->sql_query(str_replace('{' . strtoupper($group) . '}', $group_id . ' ', $select_query));
1164          while ($row = $src_db->sql_fetchrow($result))
1165          {
1166              // this might become quite a lot of INSERTS unfortunately
1167              $sql = 'INSERT INTO ' . USER_GROUP_TABLE . " (user_id, group_id, user_pending)
1168                  VALUES ({$row['user_id']}$group_id, 0)";
1169              $db->sql_query($sql);
1170          }
1171          $src_db->sql_freeresult($result);
1172      }
1173  }
1174   
1175  /**
1176  * Retrieves configuration information from the source forum and caches it as an array
1177  * Both database and file driven configuration formats can be handled
1178  * (the type used is specified in $config_schema, see convert_phpbb20.php for more details)
1179  */
1180  function get_config()
1181  {
1182      static $convert_config;
1183      global $user;
1184   
1185      if (isset($convert_config))
1186      {
1187          return $convert_config;
1188      }
1189   
1190      global $src_db, $same_db, $phpbb_root_path, $config;
1191      global $convert;
1192   
1193      if ($convert->config_schema['table_format'] != 'file')
1194      {
1195          if ($convert->mysql_convert && $same_db)
1196          {
1197              $src_db->sql_query("SET NAMES 'binary'");
1198          }
1199   
1200          $sql = 'SELECT * FROM ' . $convert->src_table_prefix . $convert->config_schema['table_name'];
1201          $result = $src_db->sql_query($sql);
1202          $row = $src_db->sql_fetchrow($result);
1203   
1204          if (!$row)
1205          {
1206              $convert->p_master->error($user->lang['CONV_ERROR_GET_CONFIG'], __LINE__, __FILE__);
1207          }
1208      }
1209   
1210      if (is_array($convert->config_schema['table_format']))
1211      {
1212          $convert_config = array();
1213          list($key, $val) = each($convert->config_schema['table_format']);
1214   
1215          do
1216          {
1217              $convert_config[$row[$key]] = $row[$val];
1218          }
1219          while ($row = $src_db->sql_fetchrow($result));
1220          $src_db->sql_freeresult($result);
1221   
1222          if ($convert->mysql_convert && $same_db)
1223          {
1224              $src_db->sql_query("SET NAMES 'utf8'");
1225          }
1226      }
1227      else if ($convert->config_schema['table_format'] == 'file')
1228      {
1229          $filename = $convert->options['forum_path'] . '/' . $convert->config_schema['filename'];
1230          if (!file_exists($filename))
1231          {
1232              $convert->p_master->error($user->lang['FILE_NOT_FOUND'] . ': ' . $filename, __LINE__, __FILE__);
1233          }
1234   
1235          $convert_config = extract_variables_from_file($filename);
1236          if (!empty($convert->config_schema['array_name']))
1237          {
1238              $convert_config = $convert_config[$convert->config_schema['array_name']];
1239          }
1240      }
1241      else
1242      {
1243          $convert_config = $row;
1244          if ($convert->mysql_convert && $same_db)
1245          {
1246              $src_db->sql_query("SET NAMES 'utf8'");
1247          }
1248      }
1249   
1250      if (!sizeof($convert_config))
1251      {
1252          $convert->p_master->error($user->lang['CONV_ERROR_CONFIG_EMPTY'], __LINE__, __FILE__);
1253      }
1254   
1255      return $convert_config;
1256  }
1257   
1258  /**
1259  * Transfers the relevant configuration information from the source forum
1260  * The mapping of fields is specified in $config_schema, see convert_phpbb20.php for more details
1261  */
1262  function restore_config($schema)
1263  {
1264      global $db, $config;
1265   
1266      $convert_config = get_config();
1267      foreach ($schema['settings'] as $config_name => $src)
1268      {
1269          if (preg_match('/(.*)\((.*)\)/', $src, $m))
1270          {
1271              $var = (empty($m[2]) || empty($convert_config[$m[2]])) ? "''" : "'" . addslashes($convert_config[$m[2]]) . "'";
1272              $exec = '$config_value = ' . $m[1] . '(' . $var . ');';
1273              eval($exec);
1274          }
1275          else
1276          {
1277              $config_value = (isset($convert_config[$src])) ? $convert_config[$src] : '';
1278          }
1279   
1280          if ($config_value !== '')
1281          {
1282              // Most are...
1283              if (is_string($config_value))
1284              {
1285                  $config_value = utf8_htmlspecialchars($config_value);
1286              }
1287   
1288              set_config($config_name, $config_value);
1289          }
1290      }
1291  }
1292   
1293  /**
1294  * Update the count of PM's in custom folders for all users
1295  */
1296  function update_folder_pm_count()
1297  {
1298      global $db, $convert, $user;
1299   
1300      $sql = 'SELECT user_id, folder_id, COUNT(msg_id) as num_messages
1301          FROM ' . PRIVMSGS_TO_TABLE . '
1302          WHERE folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ', ' . PRIVMSGS_INBOX . ', ' . PRIVMSGS_OUTBOX . ', ' . PRIVMSGS_SENTBOX . ')
1303          GROUP BY folder_id, user_id';
1304      $result = $db->sql_query($sql);
1305   
1306      while ($row = $db->sql_fetchrow($result))
1307      {
1308          $db->sql_query('UPDATE ' . PRIVMSGS_FOLDER_TABLE . ' SET pm_count = ' . $row['num_messages'] . '
1309              WHERE user_id = ' . $row['user_id'] . ' AND folder_id = ' . $row['folder_id']);
1310      }
1311      $db->sql_freeresult($result);
1312  }
1313   
1314  // Functions mainly used by the main convertor script
1315   
1316  function path($path, $path_relative = true)
1317  {
1318      if ($path === false)
1319      {
1320          return '';
1321      }
1322   
1323      if (substr($path, -1) != '/')
1324      {
1325          $path .= '/';
1326      }
1327   
1328      if (!$path_relative)
1329      {
1330          return $path;
1331      }
1332   
1333      if (substr($path, 0, 1) == '/')
1334      {
1335          $path = substr($path, 1);
1336      }
1337   
1338      return $path;
1339  }
1340   
1341  /**
1342  * Extract the variables defined in a configuration file
1343  * @todo As noted by Xore we need to look at this from a security perspective
1344  */
1345  function extract_variables_from_file($_filename)
1346  {
1347      include($_filename);
1348   
1349      $vars = get_defined_vars();
1350      unset($vars['_filename']);
1351   
1352      return $vars;
1353  }
1354   
1355  function get_path($src_path, $src_url, $test_file)
1356  {
1357      global $config, $phpbb_root_path, $phpEx;
1358   
1359      $board_config = get_config();
1360   
1361      $test_file = preg_replace('/\.php$/i', ".$phpEx", $test_file);
1362      $src_path = path($src_path);
1363   
1364      if (@file_exists($phpbb_root_path . $src_path . $test_file))
1365      {
1366          return $src_path;
1367      }
1368   
1369      if (!empty($src_url) && !empty($board_config['server_name']))
1370      {
1371          if (!preg_match('#https?://([^/]+)(.*)#i', $src_url, $m))
1372          {
1373              return false;
1374          }
1375   
1376          if ($m[1] != $board_config['server_name'])
1377          {
1378              return false;
1379          }
1380   
1381          $url_parts = explode('/', $m[2]);
1382          if (substr($src_url, -1) != '/')
1383          {
1384              if (preg_match('/.*\.([a-z0-9]{3,4})$/i', $url_parts[sizeof($url_parts) - 1]))
1385              {
1386                  $url_parts[sizeof($url_parts) - 1] = '';
1387              }
1388              else
1389              {
1390                  $url_parts[] = '';
1391              }
1392          }
1393   
1394          $script_path = $board_config['script_path'];
1395          if (substr($script_path, -1) == '/')
1396          {
1397              $script_path = substr($script_path, 0, -1);
1398          }
1399   
1400          $path_array = array();
1401   
1402          $phpbb_parts = explode('/', $script_path);
1403          for ($i = 0; $i < sizeof($url_parts); ++$i)
1404          {
1405              if ($i < sizeof($phpbb_parts[$i]) && $url_parts[$i] == $phpbb_parts[$i])
1406              {
1407                  $path_array[] = $url_parts[$i];
1408                  unset($url_parts[$i]);
1409              }
1410              else
1411              {
1412                  $path = '';
1413                  for ($j = $i; $j < sizeof($phpbb_parts); ++$j)
1414                  {
1415                      $path .= '../';
1416                  }
1417                  $path .= implode('/', $url_parts);
1418                  break;
1419              }
1420          }
1421   
1422          if (!empty($path))
1423          {
1424              if (@file_exists($phpbb_root_path . $path . $test_file))
1425              {
1426                  return $path;
1427              }
1428          }
1429      }
1430   
1431      return false;
1432  }
1433   
1434  function compare_table($tables, $tablename, &$prefixes)
1435  {
1436      for ($i = 0, $table_size = sizeof($tables); $i < $table_size; ++$i)
1437      {
1438          if (preg_match('/(.*)' . $tables[$i] . '$/', $tablename, $m))
1439          {
1440              if (empty($m[1]))
1441              {
1442                  $m[1] = '*';
1443              }
1444   
1445              if (isset($prefixes[$m[1]]))
1446              {
1447                  $prefixes[$m[1]]++;
1448              }
1449              else
1450              {
1451                  $prefixes[$m[1]] = 1;
1452              }
1453          }
1454      }
1455  }
1456   
1457  /**
1458  * Grant permissions to a specified user or group
1459  *
1460  * @param string $ug_type user|group|user_role|group_role
1461  * @param mixed $forum_id forum ids (array|int|0) -> 0 == all forums
1462  * @param mixed $ug_id [int] user_id|group_id : [string] usergroup name
1463  * @param mixed $acl_list [string] acl entry : [array] acl entries : [string] role entry
1464  * @param int $setting ACL_YES|ACL_NO|ACL_NEVER
1465  */
1466  function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
1467  {
1468      global $db, $convert, $user, $config;
1469      static $acl_option_ids, $group_ids;
1470   
1471      if (($ug_type == 'group' || $ug_type == 'group_role') && is_string($ug_id))
1472      {
1473          if (!isset($group_ids[$ug_id]))
1474          {
1475              $sql = 'SELECT group_id
1476                  FROM ' . GROUPS_TABLE . "
1477                  WHERE group_name = '" . $db->sql_escape(strtoupper($ug_id)) . "'";
1478              $result = $db->sql_query_limit($sql, 1);
1479              $id = (int) $db->sql_fetchfield('group_id');
1480              $db->sql_freeresult($result);
1481   
1482              if (!$id)
1483              {
1484                  return;
1485              }
1486   
1487              $group_ids[$ug_id] = $id;
1488          }
1489   
1490          $ug_id = (int) $group_ids[$ug_id];
1491      }
1492   
1493      $table = ($ug_type == 'user' || $ug_type == 'user_role') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
1494      $id_field = ($ug_type == 'user' || $ug_type == 'user_role') ? 'user_id' : 'group_id';
1495   
1496      // Role based permissions are the simplest to handle so check for them first
1497      if ($ug_type == 'user_role' || $ug_type == 'group_role')
1498      {
1499          if (is_numeric($forum_id))
1500          {
1501              $sql = 'SELECT role_id
1502                  FROM ' . ACL_ROLES_TABLE . "
1503                  WHERE role_name = 'ROLE_" . $db->sql_escape($acl_list) . "'";
1504              $result = $db->sql_query_limit($sql, 1);
1505              $row = $db->sql_fetchrow($result);
1506              $db->sql_freeresult($result);
1507   
1508              // If we have no role id there is something wrong here
1509              if ($row)
1510              {
1511                  $sql = "INSERT INTO $table ($id_field, forum_id, auth_role_id) VALUES ($ug_id$forum_id" . $row['role_id'] . ')';
1512                  $db->sql_query($sql);
1513              }
1514          }
1515   
1516          return;
1517      }
1518   
1519      // Build correct parameters
1520      $auth = array();
1521   
1522      if (!is_array($acl_list))
1523      {
1524          $auth = array($acl_list => $setting);
1525      }
1526      else
1527      {
1528          foreach ($acl_list as $auth_option)
1529          {
1530              $auth[$auth_option] = $setting;
1531          }
1532      }
1533      unset($acl_list);
1534   
1535      if (!is_array($forum_id))
1536      {
1537          $forum_id = array($forum_id);
1538      }
1539   
1540      // Set any flags as required
1541      foreach ($auth as $auth_option => $acl_setting)
1542      {
1543          $flag = substr($auth_option, 0, strpos($auth_option, '_') + 1);
1544          if (empty($auth[$flag]))
1545          {
1546              $auth[$flag] = $acl_setting;
1547          }
1548      }
1549   
1550      if (!is_array($acl_option_ids) || empty($acl_option_ids))
1551      {
1552          $sql = 'SELECT auth_option_id, auth_option
1553              FROM ' . ACL_OPTIONS_TABLE;
1554          $result = $db->sql_query($sql);
1555   
1556          while ($row = $db->sql_fetchrow($result))
1557          {
1558              $acl_option_ids[$row['auth_option']] = $row['auth_option_id'];
1559          }
1560          $db->sql_freeresult($result);
1561      }
1562   
1563      $sql_forum = 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id), false, true);
1564   
1565      $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";
1566      $result = $db->sql_query($sql);
1567   
1568      $cur_auth = array();
1569      while ($row = $db->sql_fetchrow($result))
1570      {
1571          $cur_auth[$row['forum_id']][$row['auth_option_id']] = $row['auth_setting'];
1572      }
1573      $db->sql_freeresult($result);
1574   
1575      $sql_ary = array();
1576      foreach ($forum_id as $forum)
1577      {
1578          foreach ($auth as $auth_option => $setting)
1579          {
1580              $auth_option_id = $acl_option_ids[$auth_option];
1581   
1582              if (!$auth_option_id)
1583              {
1584                  continue;
1585              }
1586   
1587              switch ($setting)
1588              {
1589                  case ACL_NO:
1590                      if (isset($cur_auth[$forum][$auth_option_id]))
1591                      {
1592                          $sql_ary['delete'][] = "DELETE FROM $table
1593                              WHERE forum_id = $forum
1594                                  AND auth_option_id = $auth_option_id
1595                                  AND $id_field = $ug_id";
1596                      }
1597                  break;
1598   
1599                  default:
1600                      if (!isset($cur_auth[$forum][$auth_option_id]))
1601                      {
1602                          $sql_ary['insert'][] = "$ug_id$forum$auth_option_id$setting";
1603                      }
1604                      else if ($cur_auth[$forum][$auth_option_id] != $setting)
1605                      {
1606                          $sql_ary['update'][] = "UPDATE " . $table . "
1607                              SET auth_setting = $setting
1608                              WHERE $id_field = $ug_id
1609                                  AND forum_id = $forum
1610                                  AND auth_option_id = $auth_option_id";
1611                      }
1612              }
1613          }
1614      }
1615      unset($cur_auth);
1616   
1617      $sql = '';
1618      foreach ($sql_ary as $sql_type => $sql_subary)
1619      {
1620          switch ($sql_type)
1621          {
1622              case 'insert':
1623                  switch ($db->sql_layer)
1624                  {
1625                      case 'mysql':
1626                      case 'mysql4':
1627                          $sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary));
1628                      break;
1629   
1630                      case 'mssql':
1631                      case 'sqlite':
1632                          $sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
1633                      break;
1634   
1635                      default:
1636                          foreach ($sql_subary as $sql)
1637                          {
1638                              $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) VALUES ($sql)";
1639                              $db->sql_query($sql);
1640                              $sql = '';
1641                          }
1642                  }
1643   
1644                  if ($sql != '')
1645                  {
1646                      $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) $sql";
1647                      $db->sql_query($sql);
1648                  }
1649              break;
1650   
1651              case 'update':
1652              case 'delete':
1653                  foreach ($sql_subary as $sql)
1654                  {
1655                      $db->sql_query($sql);
1656                      $sql = '';
1657                  }
1658              break;
1659          }
1660          unset($sql_ary[$sql_type]);
1661      }
1662      unset($sql_ary);
1663   
1664  }
1665   
1666  /**
1667  * Update the count of unread private messages for all users
1668  */
1669  function update_unread_count()
1670  {
1671      global $db;
1672   
1673      $sql = 'SELECT user_id, COUNT(msg_id) as num_messages
1674          FROM ' . PRIVMSGS_TO_TABLE . '
1675          WHERE pm_unread = 1
1676              AND folder_id <> ' . PRIVMSGS_OUTBOX . '
1677          GROUP BY user_id';
1678      $result = $db->sql_query($sql);
1679   
1680      while ($row = $db->sql_fetchrow($result))
1681      {
1682          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_unread_privmsg = ' . $row['num_messages'] . '
1683              WHERE user_id = ' . $row['user_id']);
1684      }
1685      $db->sql_freeresult($result);
1686  }
1687   
1688  /**
1689  * Add any of the pre-defined "special" groups which are missing from the database
1690  */
1691  function add_default_groups()
1692  {
1693      global $db;
1694   
1695      $default_groups = array(
1696          'GUESTS'            => array('', 0, 0),
1697          'REGISTERED'        => array('', 0, 0),
1698          'REGISTERED_COPPA'    => array('', 0, 0),
1699          'GLOBAL_MODERATORS'    => array('00AA00', 1, 0),
1700          'ADMINISTRATORS'    => array('AA0000', 1, 1),
1701          'BOTS'                => array('9E8DA7', 0, 0)
1702      );
1703   
1704      $sql = 'SELECT *
1705          FROM ' . GROUPS_TABLE . '
1706          WHERE ' . $db->sql_in_set('group_name', array_keys($default_groups));
1707      $result = $db->sql_query($sql);
1708   
1709      while ($row = $db->sql_fetchrow($result))
1710      {
1711          unset($default_groups[strtoupper($row['group_name'])]);
1712      }
1713      $db->sql_freeresult($result);
1714   
1715      $sql_ary = array();
1716   
1717      foreach ($default_groups as $name => $data)
1718      {
1719          $sql_ary[] = array(
1720              'group_name'            => (string) $name,
1721              'group_desc'            => '',
1722              'group_desc_uid'        => '',
1723              'group_desc_bitfield'    => '',
1724              'group_type'            => GROUP_SPECIAL,
1725              'group_colour'            => (string) $data[0],
1726              'group_legend'            => (int) $data[1],
1727              'group_founder_manage'    => (int) $data[2]
1728          );
1729      }
1730   
1731      if (sizeof($sql_ary))
1732      {
1733          $db->sql_multi_insert(GROUPS_TABLE, $sql_ary);
1734      }
1735  }
1736   
1737   
1738  /**
1739  * Sync post count. We might need to do this in batches.
1740  */
1741  function sync_post_count($offset, $limit)
1742  {
1743      global $db;
1744      $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1745              FROM ' . POSTS_TABLE . '
1746              WHERE post_postcount = 1
1747              GROUP BY poster_id
1748              ORDER BY poster_id';
1749      $result = $db->sql_query_limit($sql, $limit, $offset);
1750   
1751      while ($row = $db->sql_fetchrow($result))
1752      {
1753          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1754      }
1755      $db->sql_freeresult($result);
1756  }
1757   
1758  /**
1759  * Add the search bots into the database
1760  * This code should be used in execute_last if the source database did not have bots
1761  * If you are converting bots this function should not be called
1762  * @todo We might want to look at sharing the bot list between the install code and this code for consistancy
1763  */
1764  function add_bots()
1765  {
1766      global $db, $convert, $user, $config, $phpbb_root_path, $phpEx;
1767   
1768      $db->sql_query($convert->truncate_statement . BOTS_TABLE);
1769   
1770      $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1771      $result = $db->sql_query($sql);
1772      $group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1773      $db->sql_freeresult($result);
1774   
1775      if (!$group_id)
1776      {
1777          add_default_groups();
1778   
1779          $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1780          $result = $db->sql_query($sql);
1781          $group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1782          $db->sql_freeresult($result);
1783   
1784          if (!$group_id)
1785          {
1786              global $install;
1787              $install->error($user->lang['CONV_ERROR_INCONSISTENT_GROUPS'], __LINE__, __FILE__);
1788          }
1789      }
1790   
1791      $bots = array(
1792          'AdsBot [Google]'            => array('AdsBot-Google', ''),
1793          'Alexa [Bot]'                => array('ia_archiver', ''),
1794          'Alta Vista [Bot]'            => array('Scooter/', ''),
1795          'Ask Jeeves [Bot]'            => array('Ask Jeeves', ''),
1796          'Baidu [Spider]'            => array('Baiduspider+(', ''),
1797          'Exabot [Bot]'                => array('Exabot/', ''),
1798          'FAST Enterprise [Crawler]'    => array('FAST Enterprise Crawler', ''),
1799          'FAST WebCrawler [Crawler]'    => array('FAST-WebCrawler/', ''),
1800          'Francis [Bot]'                => array('http://www.neomo.de/', ''),
1801          'Gigabot [Bot]'                => array('Gigabot/', ''),
1802          'Google Adsense [Bot]'        => array('Mediapartners-Google', ''),
1803          'Google Desktop'            => array('Google Desktop', ''),
1804          'Google Feedfetcher'        => array('Feedfetcher-Google', ''),
1805          'Google [Bot]'                => array('Googlebot', ''),
1806          'Heise IT-Markt [Crawler]'    => array('heise-IT-Markt-Crawler', ''),
1807          'Heritrix [Crawler]'        => array('heritrix/1.', ''),
1808          'IBM Research [Bot]'        => array('ibm.com/cs/crawler', ''),
1809          'ICCrawler - ICjobs'        => array('ICCrawler - ICjobs', ''),
1810          'ichiro [Crawler]'            => array('ichiro/2', ''),
1811          'Majestic-12 [Bot]'            => array('MJ12bot/', ''),
1812          'Metager [Bot]'                => array('MetagerBot/', ''),
1813          'MSN NewsBlogs'                => array('msnbot-NewsBlogs/', ''),
1814          'MSN [Bot]'                    => array('msnbot/', ''),
1815          'MSNbot Media'                => array('msnbot-media/', ''),
1816          'NG-Search [Bot]'            => array('NG-Search/', ''),
1817          'Nutch [Bot]'                => array('http://lucene.apache.org/nutch/', ''),
1818          'Nutch/CVS [Bot]'            => array('NutchCVS/', ''),
1819          'OmniExplorer [Bot]'        => array('OmniExplorer_Bot/', ''),
1820          'Online link [Validator]'    => array('online link validator', ''),
1821          'psbot [Picsearch]'            => array('psbot/0', ''),
1822          'Seekport [Bot]'            => array('Seekbot/', ''),
1823          'Sensis [Crawler]'            => array('Sensis Web Crawler', ''),
1824          'SEO Crawler'                => array('SEO search Crawler/', ''),
1825          'Seoma [Crawler]'            => array('Seoma [SEO Crawler]', ''),
1826          'SEOSearch [Crawler]'        => array('SEOsearch/', ''),
1827          'Snappy [Bot]'                => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
1828          'Steeler [Crawler]'            => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
1829          'Synoo [Bot]'                => array('SynooBot/', ''),
1830          'Telekom [Bot]'                => array('crawleradmin.t-info@telekom.de', ''),
1831          'TurnitinBot [Bot]'            => array('TurnitinBot/', ''),
1832          'Voyager [Bot]'                => array('voyager/1.0', ''),
1833          'W3 [Sitesearch]'            => array('W3 SiteSearch Crawler', ''),
1834          'W3C [Linkcheck]'            => array('W3C-checklink/', ''),
1835          'W3C [Validator]'            => array('W3C_*Validator', ''),
1836          'WiseNut [Bot]'                => array('http://www.WISEnutbot.com', ''),
1837          'YaCy [Bot]'                => array('yacybot', ''),
1838          'Yahoo MMCrawler [Bot]'        => array('Yahoo-MMCrawler/', ''),
1839          'Yahoo Slurp [Bot]'            => array('Yahoo! DE Slurp', ''),
1840          'Yahoo [Bot]'                => array('Yahoo! Slurp', ''),
1841          'YahooSeeker [Bot]'            => array('YahooSeeker/', ''),
1842      );
1843   
1844      if (!function_exists('user_add'))
1845      {
1846          include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1847      }
1848   
1849      foreach ($bots as $bot_name => $bot_ary)
1850      {
1851          $user_row = array(
1852              'user_type'                => USER_IGNORE,
1853              'group_id'                => $group_id,
1854              'username'                => $bot_name,
1855              'user_regdate'            => time(),
1856              'user_password'            => '',
1857              'user_colour'            => '9E8DA7',
1858              'user_email'            => '',
1859              'user_lang'                => $config['default_lang'],
1860              'user_style'            => 1,
1861              'user_timezone'            => 0,
1862              'user_allow_massemail'    => 0,
1863          );
1864   
1865          $user_id = user_add($user_row);
1866   
1867          if ($user_id)
1868          {
1869              $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1870                  'bot_active'    => 1,
1871                  'bot_name'        => $bot_name,
1872                  'user_id'        => $user_id,
1873                  'bot_agent'        => $bot_ary[0],
1874                  'bot_ip'        => $bot_ary[1])
1875              );
1876              $db->sql_query($sql);
1877          }
1878      }
1879  }
1880   
1881  /**
1882  * Update any dynamic configuration variables after the conversion is finished
1883  * @todo Confirm that this updates all relevant values since it has not necessarily been kept in sync with all changes
1884  */
1885  function update_dynamic_config()
1886  {
1887      global $db, $config;
1888   
1889      // Get latest username
1890      $sql = 'SELECT user_id, username, user_colour
1891          FROM ' . USERS_TABLE . '
1892          WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
1893   
1894      if (!empty($config['increment_user_id']))
1895      {
1896          $sql .= ' AND user_id <> ' . $config['increment_user_id'];
1897      }
1898   
1899      $sql .= ' ORDER BY user_id DESC';
1900   
1901      $result = $db->sql_query_limit($sql, 1);
1902      $row = $db->sql_fetchrow($result);
1903      $db->sql_freeresult($result);
1904   
1905      if ($row)
1906      {
1907          set_config('newest_user_id', $row['user_id'], true);
1908          set_config('newest_username', $row['username'], true);
1909          set_config('newest_user_colour', $row['user_colour'], true);
1910      }
1911   
1912  //    Also do not reset record online user/date. There will be old data or the fresh data from the schema.
1913  //    set_config('record_online_users', 1, true);
1914  //    set_config('record_online_date', time(), true);
1915   
1916      $sql = 'SELECT COUNT(post_id) AS stat
1917          FROM ' . POSTS_TABLE . '
1918          WHERE post_approved = 1';
1919      $result = $db->sql_query($sql);
1920      $row = $db->sql_fetchrow($result);
1921      $db->sql_freeresult($result);
1922   
1923      set_config('num_posts', (int) $row['stat'], true);
1924   
1925      $sql = 'SELECT COUNT(topic_id) AS stat
1926          FROM ' . TOPICS_TABLE . '
1927          WHERE topic_approved = 1';
1928      $result = $db->sql_query($sql);
1929      $row = $db->sql_fetchrow($result);
1930      $db->sql_freeresult($result);
1931   
1932      set_config('num_topics', (int) $row['stat'], true);
1933   
1934      $sql = 'SELECT COUNT(user_id) AS stat
1935          FROM ' . USERS_TABLE . '
1936          WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
1937      $result = $db->sql_query($sql);
1938      $row = $db->sql_fetchrow($result);
1939      $db->sql_freeresult($result);
1940   
1941      set_config('num_users', (int) $row['stat'], true);
1942   
1943      $sql = 'SELECT COUNT(attach_id) as stat
1944          FROM ' . ATTACHMENTS_TABLE . '
1945          WHERE is_orphan = 0';
1946      $result = $db->sql_query($sql);
1947      set_config('num_files', (int) $db->sql_fetchfield('stat'), true);
1948      $db->sql_freeresult($result);
1949   
1950      $sql = 'SELECT SUM(filesize) as stat
1951          FROM ' . ATTACHMENTS_TABLE . '
1952          WHERE is_orphan = 0';
1953      $result = $db->sql_query($sql);
1954      set_config('upload_dir_size', (int) $db->sql_fetchfield('stat'), true);
1955      $db->sql_freeresult($result);
1956   
1957      /**
1958      * We do not resync users post counts - this can be done by the admin after conversion if wanted.
1959      $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1960          FROM ' . POSTS_TABLE . '
1961          WHERE post_postcount = 1
1962          GROUP BY poster_id';
1963      $result = $db->sql_query($sql);
1964   
1965      while ($row = $db->sql_fetchrow($result))
1966      {
1967          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1968      }
1969      $db->sql_freeresult($result);
1970      */
1971  }
1972   
1973  /**
1974  * Updates topics_posted entries
1975  */
1976  function update_topics_posted()
1977  {
1978      global $db, $config;
1979   
1980      switch ($db->sql_layer)
1981      {
1982          case 'sqlite':
1983          case 'firebird':
1984              $db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
1985          break;
1986   
1987          default:
1988              $db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
1989          break;
1990      }
1991   
1992      // This can get really nasty... therefore we only do the last six months
1993      $get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
1994   
1995      // Select forum ids, do not include categories
1996      $sql = 'SELECT forum_id
1997          FROM ' . FORUMS_TABLE . '
1998          WHERE forum_type <> ' . FORUM_CAT;
1999      $result = $db->sql_query($sql);
2000   
2001      $forum_ids = array();
2002      while ($row = $db->sql_fetchrow($result))
2003      {
2004          $forum_ids[] = $row['forum_id'];
2005      }
2006      $db->sql_freeresult($result);
2007   
2008      // Any global announcements? ;)
2009      $forum_ids[] = 0;
2010   
2011      // Now go through the forums and get us some topics...
2012      foreach ($forum_ids as $forum_id)
2013      {
2014          $sql = 'SELECT p.poster_id, p.topic_id
2015              FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
2016              WHERE t.forum_id = ' . $forum_id . '
2017                  AND t.topic_moved_id = 0
2018                  AND t.topic_last_post_time > ' . $get_from_time . '
2019                  AND t.topic_id = p.topic_id
2020                  AND p.poster_id <> ' . ANONYMOUS . '
2021              GROUP BY p.poster_id, p.topic_id';
2022          $result = $db->sql_query($sql);
2023   
2024          $posted = array();
2025          while ($row = $db->sql_fetchrow($result))
2026          {
2027              $posted[$row['poster_id']][] = $row['topic_id'];
2028          }
2029          $db->sql_freeresult($result);
2030   
2031          $sql_ary = array();
2032          foreach ($posted as $user_id => $topic_row)
2033          {
2034              foreach ($topic_row as $topic_id)
2035              {
2036                  $sql_ary[] = array(
2037                      'user_id'        => (int) $user_id,
2038                      'topic_id'        => (int) $topic_id,
2039                      'topic_posted'    => 1,
2040                  );
2041              }
2042          }
2043          unset($posted);
2044   
2045          if (sizeof($sql_ary))
2046          {
2047              $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
2048          }
2049      }
2050  }
2051   
2052  /**
2053  * Ensure that all users have a default group specified and update related information such as their colour
2054  */
2055  function fix_empty_primary_groups()
2056  {
2057      global $db;
2058   
2059      // Set group ids for users not already having it
2060      $sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2061          WHERE group_id = 0 AND user_type = ' . USER_INACTIVE;
2062      $db->sql_query($sql);
2063   
2064      $sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2065          WHERE group_id = 0 AND user_type = ' . USER_NORMAL;
2066      $db->sql_query($sql);
2067   
2068      $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('guests') . ' WHERE user_id = ' . ANONYMOUS);
2069   
2070      $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('administrators');
2071      $result = $db->sql_query($sql);
2072   
2073      $user_ids = array();
2074      while ($row = $db->sql_fetchrow($result))
2075      {
2076          $user_ids[] = $row['user_id'];
2077      }
2078      $db->sql_freeresult($result);
2079   
2080      if (sizeof($user_ids))
2081      {
2082          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('administrators') . '
2083              WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2084      }
2085   
2086      $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('global_moderators');
2087   
2088      $user_ids = array();
2089      while ($row = $db->sql_fetchrow($result))
2090      {
2091          $user_ids[] = $row['user_id'];
2092      }
2093      $db->sql_freeresult($result);
2094   
2095      if (sizeof($user_ids))
2096      {
2097          $db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('global_moderators') . '
2098              WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2099      }
2100   
2101      // Set user colour
2102      $sql = 'SELECT group_id, group_colour FROM ' . GROUPS_TABLE . "
2103          WHERE group_colour <> ''";
2104      $result = $db->sql_query($sql);
2105   
2106      while ($row = $db->sql_fetchrow($result))
2107      {
2108          $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_colour = '{$row['group_colour']}' WHERE group_id = {$row['group_id']}");
2109      }
2110      $db->sql_freeresult($result);
2111  }
2112   
2113  /**
2114  * Cleanly remove invalid user entries after converting the users table...
2115  */
2116  function remove_invalid_users()
2117  {
2118      global $convert, $db, $phpEx, $phpbb_root_path;
2119   
2120      // username_clean is UNIQUE
2121      $sql = 'SELECT user_id
2122          FROM ' . USERS_TABLE . "
2123          WHERE username_clean = ''";
2124      $result = $db->sql_query($sql);
2125      $row = $db->sql_fetchrow($result);
2126      $db->sql_freeresult($result);
2127   
2128      if ($row)
2129      {
2130          if (!function_exists('user_delete'))
2131          {
2132              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2133          }
2134   
2135          user_delete('remove', $row['user_id']);
2136      }
2137  }
2138   
2139  function convert_bbcode($message, $convert_size = true, $extended_bbcodes = false)
2140  {
2141      static $orig, $repl, $origx, $replx, $str_from, $str_to;
2142   
2143      if (empty($orig))
2144      {
2145          $orig = $repl = array();
2146   
2147          $orig[] = '#\[(php|sql)\](.*?)\[/(php|sql)\]#is';
2148          $repl[] = '[code]\2[/code]';
2149   
2150          $orig[] = '#\[font=[^\]]+\](.*?)\[/font\]#is';
2151          $repl[] = '\1';
2152   
2153          $orig[] = '#\[align=[a-z]+\](.*?)\[/align\]#is';
2154          $repl[] = '\1';
2155   
2156          $orig[] = '#\[/list=.*?\]#is';
2157          $repl[] = '[/list]';
2158   
2159          $origx = array(
2160              '#\[glow[^\]]+\](.*?)\[/glow\]#is',
2161              '#\[shadow[^\]]+\](.*?)\[/shadow\]#is',
2162              '#\[flash[^\]]+\](.*?)\[/flash\]#is'
2163          );
2164   
2165          $replx = array(
2166              '\1',
2167              '\1',
2168              '[url=\1]Flash[/url]'
2169          );
2170   
2171          $str_from = array(
2172              '[ftp]',    '[/ftp]',
2173              '[ftp=',    '[/ftp]',
2174              '[pre]',    '[/pre]',
2175              '[table]',    '[/table]',
2176              '[td]',        '[/td]',
2177              '[tr]',        '[/tr]',
2178              '[s]',        '[/s]',
2179              '[left]',    '[/left]',
2180              '[right]',    '[/right]',
2181              '[center]',    '[/center]',
2182              '[sub]',    '[/sub]',
2183              '[sup]',    '[/sup]',
2184              '[tt]',        '[/tt]',
2185              '[move]',    '[/move]',
2186              '[hr]'
2187          );
2188   
2189          $str_to = array(
2190              '[url]',    '[/url]',
2191              '[url=',    '[/url]',
2192              '[code]',    '[/code]',
2193              "\n",        '',
2194              '',            '',
2195              "\n",        '',
2196              '',            '',
2197              '',            '',
2198              '',            '',
2199              '',            '',
2200              '',            '',
2201              '',            '',
2202              '',            '',
2203              '',            '',
2204              "\n\n"
2205          );
2206   
2207          for ($i = 0; $i < sizeof($str_from); ++$i)
2208          {
2209              $origx[] = '#\\' . str_replace(']', '\\]', $str_from[$i]) . '#is';
2210              $replx[] = $str_to[$i];
2211          }
2212      }
2213   
2214      if (preg_match_all('#\[email=([^\]]+)\](.*?)\[/email\]#i', $message, $m))
2215      {
2216          for ($i = 0; $i < sizeof($m[1]); ++$i)
2217          {
2218              if ($m[1][$i] == $m[2][$i])
2219              {
2220                  $message = str_replace($m[0][$i], '[email]' . $m[1][$i] . '[/email]', $message);
2221              }
2222              else
2223              {
2224                  $message = str_replace($m[0][$i], $m[2][$i] . ' ([email]' . $m[1][$i] . '[/email])', $message);
2225              }
2226          }
2227      }
2228   
2229      if ($convert_size && preg_match('#\[size=[0-9]+\].*?\[/size\]#i', $message))
2230      {
2231          $size = array(9, 9, 12, 15, 18, 24, 29, 29, 29, 29);
2232          $message = preg_replace('#\[size=([0-9]+)\](.*?)\[/size\]#i', '[size=\1]\2[/size]', $message);
2233          $message = preg_replace('#\[size=[0-9]{2,}\](.*?)\[/size\]#i', '[size=29]\1[/size]', $message);
2234   
2235          for ($i = sizeof($size); $i; )
2236          {
2237              $i--;
2238              $message = str_replace('[size=' . $i . ']', '[size=' . $size[$i] . ']', $message);
2239          }
2240      }
2241   
2242      if ($extended_bbcodes)
2243      {
2244          $message = preg_replace($origx, $replx, $message);
2245      }
2246   
2247      $message = preg_replace($orig, $repl, $message);
2248      return $message;
2249  }
2250   
2251   
2252  function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2253  {
2254      global $convert, $phpbb_root_path, $config, $user, $db;
2255   
2256      if (substr($trg, -1) == '/')
2257      {
2258          $trg .= basename($src);
2259      }
2260      $src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2261      $trg_path = $trg;
2262   
2263      if (!$overwrite && @file_exists($trg_path))
2264      {
2265          return true;
2266      }
2267   
2268      if (!@file_exists($src_path))
2269      {
2270          return;
2271      }
2272   
2273      $path = $phpbb_root_path;
2274      $parts = explode('/', $trg);
2275      unset($parts[sizeof($parts) - 1]);
2276   
2277      for ($i = 0; $i < sizeof($parts); ++$i)
2278      {
2279          $path .= $parts[$i] . '/';
2280   
2281          if (!is_dir($path))
2282          {
2283              @mkdir($path, 0777);
2284          }
2285      }
2286   
2287      if (!is_writable($path))
2288      {
2289          @chmod($path, 0777);
2290      }
2291   
2292      if (!@copy($src_path, $phpbb_root_path . $trg_path))
2293      {
2294          $convert->p_master->error(sprintf($user->lang['COULD_NOT_COPY'], $src_path, $phpbb_root_path . $trg_path), __LINE__, __FILE__, !$die_on_failure);
2295          return;
2296      }
2297   
2298      if ($perm = @fileperms($src_path))
2299      {
2300          @chmod($phpbb_root_path . $trg_path, $perm);
2301      }
2302   
2303      return true;
2304  }
2305   
2306  function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2307  {
2308      global $convert, $phpbb_root_path, $config, $user, $db;
2309   
2310      $dirlist = $filelist = $bad_dirs = array();
2311      $src = path($src, $source_relative_path);
2312      $trg = path($trg);
2313      $src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2314      $trg_path = $phpbb_root_path . $trg;
2315   
2316      if (!is_dir($trg_path))
2317      {
2318          @mkdir($trg_path, 0777);
2319          @chmod($trg_path, 0777);
2320      }
2321   
2322      if (!@is_writable($trg_path))
2323      {
2324          $bad_dirs[] = path($config['script_path']) . $trg;
2325      }
2326   
2327      if ($handle = @opendir($src_path))
2328      {
2329          while ($entry = readdir($handle))
2330          {
2331              if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2332              {
2333                  continue;
2334              }
2335   
2336              if (is_dir($src_path . $entry))
2337              {
2338                  $dirlist[] = $entry;
2339              }
2340              else
2341              {
2342                  $filelist[] = $entry;
2343              }
2344          }
2345          closedir($handle);
2346      }
2347      else if ($dir = @dir($src_path))
2348      {
2349          while ($entry = $dir->read())
2350          {
2351              if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2352              {
2353                  continue;
2354              }
2355   
2356              if (is_dir($src_path . $entry))
2357              {
2358                  $dirlist[] = $entry;
2359              }
2360              else
2361              {
2362                  $filelist[] = $entry;
2363              }
2364          }
2365          $dir->close();
2366      }
2367      else
2368      {
2369          $convert->p_master->error(sprintf($user->lang['CONV_ERROR_COULD_NOT_READ'], relative_base($src, $source_relative_path)), __LINE__, __FILE__);
2370      }
2371   
2372      if ($copy_subdirs)
2373      {
2374          for ($i = 0; $i < sizeof($dirlist); ++$i)
2375          {
2376              $dir = $dirlist[$i];
2377   
2378              if ($dir == 'CVS')
2379              {
2380                  continue;
2381              }
2382   
2383              if (!is_dir($trg_path . $dir))
2384              {
2385                  @mkdir($trg_path . $dir, 0777);
2386                  @chmod($trg_path . $dir, 0777);
2387              }
2388   
2389              if (!@is_writable($trg_path . $dir))
2390              {
2391                  $bad_dirs[] = $trg . $dir;
2392                  $bad_dirs[] = $trg_path . $dir;
2393              }
2394   
2395              if (!sizeof($bad_dirs))
2396              {
2397                  copy_dir($src . $dir, $trg . $dir, true, $overwrite, $die_on_failure, $source_relative_path);
2398              }
2399          }
2400      }
2401   
2402      if (sizeof($bad_dirs))
2403      {
2404          $str = (sizeof($bad_dirs) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
2405          sort($bad_dirs);
2406          $convert->p_master->error(sprintf($str, implode('<br />', $bad_dirs)), __LINE__, __FILE__);
2407      }
2408   
2409      for ($i = 0; $i < sizeof($filelist); ++$i)
2410      {
2411          copy_file($src . $filelist[$i], $trg . $filelist[$i], $overwrite, $die_on_failure, $source_relative_path);
2412      }
2413  }
2414   
2415  function relative_base($path, $is_relative = true, $line = false, $file = false)
2416  {
2417      global $convert, $phpbb_root_path, $config, $user, $db;
2418   
2419      if (!$is_relative)
2420      {
2421          return $path;
2422      }
2423   
2424      if (empty($convert->options['forum_path']) && $is_relative)
2425      {
2426          $line = $line ? $line : __LINE__;
2427          $file = $file ? $file : __FILE__;
2428   
2429          $convert->p_master->error($user->lang['CONV_ERROR_NO_FORUM_PATH'], $line, $file);
2430      }
2431   
2432      return $convert->options['forum_path'] . '/' . $path;
2433  }
2434   
2435  function get_smiley_display()
2436  {
2437      static $smiley_count = 0;
2438      $smiley_count++;
2439      return ($smiley_count < 50) ? 1 : 0;
2440  }
2441   
2442   
2443  function fill_dateformat($user_dateformat)
2444  {
2445      global $config;
2446      
2447      return ((empty($user_dateformat)) ? $config['default_dateformat'] : $user_dateformat);
2448  }
2449   
2450   
2451   
2452  ?>