/** * Constructor * * @param array $forum_config * Forum configuration * * @param type FluxBB $fluxbb * FluxBB instance */ function Forum($forum_config, $fluxbb) { $this->forum_config = $forum_config; if (!empty($forum_config['path'])) { // Check whether it is absolute path if (strpos($forum_config['path'], '/') === 0 || strpos($forum_config['path'], ':') === 1) { $this->path = $forum_config['path']; } else { $this->path = PUN_ROOT . $forum_config['path']; } $this->path = realpath(rtrim($this->path, '/')) . '/'; conv_log('Will convert avatars', true); conv_log('Forum path: ' . $this->path, true); } else { conv_log('Warning: avatars will not be converted due to missing path', true); } $this->fluxbb = $fluxbb; }
/** * Shows an error */ function conv_error($message, $file = null, $line = null, $dberror = false) { global $fluxbb, $forum, $lang_convert; if (isset($fluxbb)) { $fluxbb->close_database(); } if (isset($forum)) { $forum->close_database(); } conv_log('Error: ' . $message . ' in ' . $line . ', ' . $line . (is_array($dberror) ? "\n" . implode(', ', $dberror) : '')); if (isset($lang_convert[$message])) { $message = $lang_convert[$message]; } echo sprintf($lang_convert['Error'], $message) . (defined('PUN_DEBUG') && isset($file) ? ' ' . sprintf($lang_convert['Error file line'], $file, $line) : '') . "\n"; if (defined('PUN_DEBUG') && $dberror !== false) { echo sprintf($lang_convert['Database reported'], $dberror['error_msg']) . "\n"; conv_log('[' . $dberror['error_no'] . '] Query: ' . $dberror['error_sql']); } conv_log('', false, true); exit(1); }
} // We're done $alerts = array(sprintf($lang_convert['Rebuild search index note'], $lang_convert['rebuild search index'])); if (!$forum->converts_password) { $alerts[] = $lang_convert['Password converter mod']; } $fluxbb->close_database(); if (!empty($session['dupe_users'])) { conv_message("\n" . '---------------------------' . "\n"); conv_message($lang_convert['Username dupes head']); conv_message($lang_convert['Error info 1']); conv_message($lang_convert['Error info 2']); foreach ($_SESSION['converter']['dupe_users'] as $id => $cur_user) { conv_message("\t" . $lang_convert['was renamed to'], $cur_user['old_username'], $cur_user['username']); } conv_message(); conv_message($lang_convert['Convert username dupes question']); $handle = fopen('php://stdin', 'r'); $line = trim(fgets($handle)); if ($line == 'yes') { alert_dupe_users(); } } if (!empty($alerts)) { conv_message("\n" . '---------------------------' . "\n"); conv_message($lang_convert['Notes'] . ':' . "\n" . implode("\n", $alerts)); } conv_message(); conv_message($lang_convert['Conversion completed in'], round($session['time'], 4)); conv_log('Conversion completed in ' . $session['time'], false, true); exit(0);
/** * Recount all posts, topics after conversion * * @return type */ function sync_db() { conv_log('Updating post count for each user'); $start = get_microtime(); // Update user post count $result = $this->db->query_build(array('SELECT' => 'p.poster_id, COUNT(p.id) AS post_count, u.num_posts', 'JOINS' => array(array('INNER JOIN' => 'users AS u', 'ON' => 'u.id = p.poster_id')), 'FROM' => 'posts AS p', 'GROUP BY' => 'p.poster_id', 'WHERE' => 'p.poster_id > 0')) or conv_error('Unable to fetch user posts', __FILE__, __LINE__, $this->db->error()); while ($cur_user = $this->db->fetch_assoc($result)) { if ($cur_user['num_posts'] == $cur_user['post_count']) { continue; } $this->db->query_build(array('UPDATE' => 'users', 'SET' => 'num_posts = ' . $cur_user['post_count'], 'WHERE' => 'id = ' . $cur_user['poster_id'])) or conv_error('Unable to update user post count', __FILE__, __LINE__, $this->db->error()); } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); conv_log('Updating post count for each topic'); $start = get_microtime(); // Update post count for each topic $result = $this->db->query_build(array('SELECT' => 'p.topic_id, COUNT(p.id) AS post_count, t.num_replies', 'JOINS' => array(array('INNER JOIN' => 'topics AS t', 'ON' => 't.id = p.topic_id')), 'FROM' => 'posts AS p', 'GROUP BY' => 'p.topic_id')) or conv_error('Unable to fetch topic posts', __FILE__, __LINE__, $this->db->error()); while ($cur_topic = $this->db->fetch_assoc($result)) { if ($cur_topic['num_replies'] == $cur_topic['post_count'] - 1) { continue; } $this->db->query_build(array('UPDATE' => 'topics', 'SET' => 'num_replies = ' . ($cur_topic['post_count'] - 1), 'WHERE' => 'id = ' . $cur_topic['topic_id'])) or conv_error('Unable to update topic post count', __FILE__, __LINE__, $this->db->error()); } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); conv_log('Updating last post for each topic'); $start = get_microtime(); // Update last post for each topic $subquery = array('SELECT' => 'topic_id, MAX(posted) AS last_post', 'FROM' => 'posts', 'GROUP BY' => 'topic_id'); $result = $this->db->query_build(array('SELECT' => 'p.topic_id, p.id, p.posted, p.poster, t.last_post, t.last_post_id, t.last_poster', 'JOINS' => array(array('INNER JOIN' => $this->db->prefix . 'posts AS p', 'ON' => 'p.topic_id = s.topic_id AND p.posted = s.last_post'), array('INNER JOIN' => $this->db->prefix . 'topics AS t', 'ON' => 'p.topic_id = t.id')), 'FROM' => '(' . $this->db->query_build($subquery, true) . ') AS s', 'PARAMS' => array('NO_PREFIX' => true))) or conv_error('Unable to fetch topic last post', __FILE__, __LINE__, $this->db->error()); while ($cur_topic = $this->db->fetch_assoc($result)) { $values = array(); if ($cur_topic['posted'] != $cur_topic['last_post']) { $values[] = 'last_post = ' . $cur_topic['posted']; } if ($cur_topic['poster'] != $cur_topic['last_poster']) { $values[] = 'last_poster = \'' . $this->db->escape($cur_topic['poster']) . '\''; } if ($cur_topic['id'] != $cur_topic['last_post_id']) { $values[] = 'last_post_id = ' . $cur_topic['id']; } if (!empty($values)) { $this->db->query_build(array('UPDATE' => 'topics', 'SET' => implode(', ', $values), 'WHERE' => 'id = ' . $cur_topic['topic_id'])) or conv_error('Unable to update last post for topic', __FILE__, __LINE__, $this->db->error()); } } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); conv_log('Updating num topics and num posts for each forum'); $start = get_microtime(); // Update num_topics and num_posts for each forum $result = $this->db->query_build(array('SELECT' => 't.forum_id, COUNT(t.id) AS topic_count, SUM(t.num_replies) + COUNT(t.id) AS post_count, f.num_posts, f.num_topics', 'JOINS' => array(array('INNER JOIN' => 'forums AS f', 'ON' => 'f.id = t.forum_id')), 'FROM' => 'topics AS t', 'GROUP BY' => 't.forum_id')) or conv_error('Unable to fetch topics for forum', __FILE__, __LINE__, $this->db->error()); while ($cur_forum = $this->db->fetch_assoc($result)) { $values = array(); if ($cur_forum['topic_count'] != $cur_forum['num_topics']) { $values[] = 'num_topics = ' . $cur_forum['topic_count']; } if ($cur_forum['post_count'] != $cur_forum['num_posts']) { $values[] = 'num_posts = ' . $cur_forum['post_count']; } if (!empty($values)) { $this->db->query_build(array('UPDATE' => 'forums', 'SET' => implode(', ', $values), 'WHERE' => 'id = ' . $cur_forum['forum_id'])) or conv_error('Unable to update topic count for forum', __FILE__, __LINE__, $this->db->error()); } } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); conv_log('Updating last post for each forum'); $start = get_microtime(); // Update last post for each forum $subquery = array('SELECT' => 'forum_id, MAX(last_post) AS last_post', 'FROM' => 'topics', 'GROUP BY' => 'forum_id'); $result = $this->db->query_build(array('SELECT' => 't.forum_id, t.last_post_id AS new_last_post_id, t.last_post AS new_last_post, t.last_poster AS new_last_poster, f.last_post_id, f.last_poster, f.last_post', 'JOINS' => array(array('INNER JOIN' => $this->db->prefix . 'topics AS t', 'ON' => 't.forum_id = s.forum_id AND s.last_post = t.last_post'), array('INNER JOIN' => $this->db->prefix . 'forums AS f', 'ON' => 't.forum_id = f.id')), 'FROM' => '(' . $this->db->query_build($subquery, true) . ') AS s', 'PARAMS' => array('NO_PREFIX' => true))) or conv_error('Unable to fetch forum last post', __FILE__, __LINE__, $this->db->error()); while ($cur_forum = $this->db->fetch_assoc($result)) { $values = array(); if ($cur_forum['new_last_post'] != $cur_forum['last_post']) { $values[] = 'last_post = ' . $cur_forum['new_last_post']; } if ($cur_forum['new_last_poster'] != $cur_forum['last_poster']) { $values[] = 'last_poster = \'' . $this->db->escape($cur_forum['new_last_poster']) . '\''; } if ($cur_forum['new_last_post_id'] != $cur_forum['last_post_id']) { $values[] = 'last_post_id = ' . $cur_forum['new_last_post_id']; } if (!empty($values)) { $this->db->query_build(array('UPDATE' => 'forums', 'SET' => implode(', ', $values), 'WHERE' => 'id = ' . $cur_forum['forum_id'])) or conv_error('Unable to update last post for forum', __FILE__, __LINE__, $this->db->error()); } } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); }
function finish() { global $session; // Handle users dupe if (!empty($session['dupe_users'])) { conv_log('Converting dupe users'); $start = get_microtime(); foreach ($session['dupe_users'] as $cur_user) { $this->fluxbb->convert_users_dupe($cur_user); } conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); } $this->fluxbb->sync_db(); conv_log('Generate cache'); $start = get_microtime(); $this->generate_cache(); conv_log('Done in ' . round(get_microtime() - $start, 6) . "\n"); $session['fluxbb_count'] = $this->fluxbb->fetch_item_count(); $session['time'] = get_microtime() - $session['start_time']; }
/** * Copy avatar file to the FluxBB avatars dir */ function convert_avatar($cur_user) { static $avatars_config; if (!isset($this->path)) { return false; } // TODO: do not hardcode avatars path // if (!isset($avatars_config)) // { // $avatars_config = array(); // $result = $this->db->query_build(array( // 'SELECT' => 'config_name, config_value', // 'FROM' => 'config', // 'WHERE' => 'config_name IN (\'avatar_path\', \'avatar_salt\', \'avatar_gallery_path\')' // )) or conv_error('Unable to fetch config', __FILE__, __LINE__, $this->db->error()); // while ($cur_config = $this->db->fetch_assoc($result)) // $avatars_config[$cur_config['config_name']] = $cur_config['config_value']; // } // Look for user avatar from gallery $cur_avatar_file = $this->path . 'images/avatars/' . $cur_user['user_avatar']; if (file_exists($cur_avatar_file)) { $extension = substr($cur_user['user_avatar'], strrpos($cur_user['user_avatar'], '.')); if (!copy($cur_avatar_file, $this->fluxbb->avatars_dir . $cur_user['id'] . $extension)) { conv_log('Saving avatar ' . $cur_avatar_file . ' for user ' . $cur_user['id'] . ' failed'); return false; } return true; } else { conv_log('Avatar file ' . $cur_avatar_file . ' for user ' . $cur_user['id'] . ' does not exist'); } }
/** * Converter error handler * Writes messages to the log file * * @param integer $errno * @param string $errstr * @param string $errfile * @param integer $errline * @return type */ function conv_error_handler($errno, $errstr, $errfile, $errline) { ob_start(); if (function_exists('debug_print_backtrace')) { debug_print_backtrace(); } else { echo $errno, $errstr, $errfile, $errline; } conv_log("\n" . ob_get_clean()); /* Don't execute PHP internal error handler */ return true; }
/** * Redirect to the next stage */ function conv_redirect($step, $start_at = 0, $time = 0) { global $lang_convert, $default_style, $fluxbb, $forum; if (isset($fluxbb)) { $fluxbb->close_database(); } if (isset($forum)) { $forum->close_database(); } $contents = ob_get_clean(); $url = 'index.php?step=' . htmlspecialchars($step) . ($start_at > 0 ? '&start_at=' . $start_at : ''); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="refresh" content="<?php echo $time; ?> ; url=<?php echo $url; ?> "> <title><?php echo sprintf($lang_convert['FluxBB converter'], CONV_VERSION); ?> </title> <link rel="stylesheet" type="text/css" href="../style/<?php echo $default_style; ?> .css" /> </head> <body> <div id="puninstall" class="pun"> <div class="top-box"><div><!-- Top Corners --></div></div> <div class="punwrap"> <div class="blockform"> <h2><span><?php echo $lang_convert['Converting header']; ?> </span></h2> <div class="box"> <div class="fakeform"> <div class="inform"> <div class="forminfo"> <?php echo $contents; ?> </div> </div> </div> </div> </div> </div> </div> <div class="end-box"><div><!-- Bottom Corners --></div></div> </div> </body> </html> <?php conv_log('Redirect'); conv_log(); conv_log('-----------------'); conv_log('', false, true); exit; }