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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
functions_convert.php
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 ?>