From b3d1540f6ea63d6a3a6d19b0dd6bed462b7f3254 Mon Sep 17 00:00:00 2001 From: Yu 'noyle' Liu Date: Mon, 18 Nov 2019 20:57:35 +0800 Subject: [PATCH] XenForo 2 Module (#236) * Fix column length check for negative integer during an insert. * XenForo 2 Module --- boards/xenforo2.php | 143 ++++++++++++++ boards/xenforo2/attachments.php | 144 ++++++++++++++ boards/xenforo2/avatars.php | 95 ++++++++++ boards/xenforo2/bbcode_parser.php | 223 ++++++++++++++++++++++ boards/xenforo2/forums.php | 123 ++++++++++++ boards/xenforo2/index.html | 8 + boards/xenforo2/moderators.php | 67 +++++++ boards/xenforo2/polls.php | 103 ++++++++++ boards/xenforo2/pollvotes.php | 115 ++++++++++++ boards/xenforo2/posts.php | 110 +++++++++++ boards/xenforo2/privatemessages.php | 149 +++++++++++++++ boards/xenforo2/settings.php | 268 +++++++++++++++++++++++++++ boards/xenforo2/threads.php | 116 ++++++++++++ boards/xenforo2/usergroups.php | 66 +++++++ boards/xenforo2/users.php | 98 ++++++++++ resources/class_converter_module.php | 20 +- 16 files changed, 1842 insertions(+), 6 deletions(-) create mode 100644 boards/xenforo2.php create mode 100644 boards/xenforo2/attachments.php create mode 100644 boards/xenforo2/avatars.php create mode 100644 boards/xenforo2/bbcode_parser.php create mode 100644 boards/xenforo2/forums.php create mode 100644 boards/xenforo2/index.html create mode 100644 boards/xenforo2/moderators.php create mode 100644 boards/xenforo2/polls.php create mode 100644 boards/xenforo2/pollvotes.php create mode 100644 boards/xenforo2/posts.php create mode 100644 boards/xenforo2/privatemessages.php create mode 100644 boards/xenforo2/settings.php create mode 100644 boards/xenforo2/threads.php create mode 100644 boards/xenforo2/usergroups.php create mode 100644 boards/xenforo2/users.php diff --git a/boards/xenforo2.php b/boards/xenforo2.php new file mode 100644 index 0000000..4dfb1b3 --- /dev/null +++ b/boards/xenforo2.php @@ -0,0 +1,143 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter extends Converter +{ + /** + * String of the bulletin board name + * + * @var string + */ + var $bbname = "Xenforo 2"; + + /** + * String of the plain bulletin board name + * + * @var string + */ + var $plain_bbname = "Xenforo 2"; + + /** + * Whether or not this module requires the loginconvert.php plugin + * + * @var boolean + */ + var $requires_loginconvert = true; + + /** + * Array of all of the modules + * + * @var array + */ + var $modules = array( + "db_configuration" => array("name" => "Database Configuration", "dependencies" => ""), + "import_settings" => array("name" => "Settings", "dependencies" => "db_configuration"), + "import_usergroups" => array("name" => "Usergroups", "dependencies" => "db_configuration"), + "import_users" => array("name" => "Users", "dependencies" => "db_configuration,import_usergroups"), + "import_forums" => array("name" => "Forums", "dependencies" => "db_configuration,import_users"), + "import_moderators" => array("name" => "Moderators", "dependencies" => "db_configuration,import_forums,import_users"), + "import_threads" => array("name" => "Threads", "dependencies" => "db_configuration,import_forums"), + "import_polls" => array("name" => "Polls", "dependencies" => "db_configuration,import_threads"), + "import_pollvotes" => array("name" => "Poll Votes", "dependencies" => "db_configuration,import_polls"), + "import_posts" => array("name" => "Posts", "dependencies" => "db_configuration,import_threads"), + "import_privatemessages" => array("name" => "Private Messages", "dependencies" => "db_configuration,import_users"), + "import_avatars" => array("name" => "Avatars", "dependencies" => "db_configuration,import_users"), + "import_attachments" => array("name" => "Attachments", "dependencies" => "db_configuration,import_posts"), + ); + + /** + * The table we check to verify it's "our" database + * + * @var String + */ + var $check_table = "ip"; + + /** + * The table prefix we suggest to use + * + * @var String + */ + var $prefix_suggestion = "xf_"; + + /** + * An array of xenforo -> mybb groups + * + * @var array + */ + var $groups = array( + 1 => MYBB_GUESTS, // Guests + 2 => MYBB_REGISTERED, // Registered + 3 => MYBB_ADMINS, // Administrators + 4 => MYBB_MODS, // Moderators + ); + + /** + * An array of supported databases + * XenForo only supports MySQL + */ + var $supported_databases = array("mysql"); + + var $column_length_to_check = array( + "user_group" => array( + "usergroups" => array( + "title" => "title", + "username_css" => "namestyle", + ), + ), + "user" => array( + "users" => array( + "username" => "username", + "email" => "email", + ), + ), + "user_profile" => array( + "users" => array( + "website" => "website", + ), + ), + "thread" => array( + "threads" => array( + "title" => "subject", + ), + ), + "post" => array( + "posts" => array( + "message" => "message", + ), + ), + ); + + /** + * Get imported thread and cache it during script processing. + */ + var $cache_threads = array(); + function get_thread($tid) + { + global $db; + + if(isset($this->cache_threads[$tid])) + { + return $this->cache_threads[$tid]; + } + + $query = $db->simple_select("threads", "fid,subject,dateline,visible", "tid='{$tid}'", array("limit" => 1)); + $thread = $db->fetch_array($query); + $db->free_result($query); + + $this->cache_threads[$tid] = $thread; + return $this->cache_threads[$tid]; + } +} + diff --git a/boards/xenforo2/attachments.php b/boards/xenforo2/attachments.php new file mode 100644 index 0000000..2604a52 --- /dev/null +++ b/boards/xenforo2/attachments.php @@ -0,0 +1,144 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Attachments extends Converter_Module_Attachments +{ + var $settings = array( + 'friendly_name' => 'attachments', + 'progress_column' => 'attachment_id', + 'default_per_screen' => 20, + ); + + public $path_column = "attachment_id, data_id"; + + public $test_table = "attachment"; + + function get_upload_path() + { + $query = $this->old_db->simple_select("option", "option_value", "option_id='boardUrl'"); + $uploadspath = $this->old_db->fetch_field($query, "option_value") . "/internal_data/attachments/"; + $this->old_db->free_result($query); + return $uploadspath; + } + + function import() + { + global $import_session; + + $query = $this->old_db->query("SELECT * + FROM ".OLD_TABLE_PREFIX."attachment a + LEFT JOIN ".OLD_TABLE_PREFIX."attachment_data d ON (d.data_id=a.data_id) + WHERE a.content_type='post' + LIMIT {$this->trackers['start_attachments']}, {$import_session['attachments_per_screen']}"); + while($attachment = $this->old_db->fetch_array($query)) + { + $this->insert($attachment); + } + } + + function convert_data($data) + { + global $db; + + $insert_data = array(); + + // Xenforo 2 values + $insert_data['import_aid'] = $data['attachment_id']; + + $ext = get_extension($data['filename']); + $query = $db->simple_select("attachtypes", "mimetype", "extension='{$ext}'"); + $insert_data['filetype'] = $db->fetch_field($query, "mimetype"); + $db->free_result($query); + + // Check if it is it an image + switch(strtolower($insert_data['filetype'])) + { + case "image/gif": + case "image/jpeg": + case "image/x-jpg": + case "image/x-jpeg": + case "image/pjpeg": + case "image/jpg": + case "image/png": + case "image/x-png": + $is_image = 1; + break; + default: + $is_image = 0; + break; + } + + // Should have thumbnail if it's an image + if($is_image == 1) + { + $insert_data['thumbnail'] = 'SMALL'; + } + else + { + $insert_data['thumbnail'] = ''; + } + + $insert_data['uid'] = $this->get_import->uid($data['user_id']); + $insert_data['filename'] = $data['filename']; + $insert_data['filesize'] = $data['file_size']; + $insert_data['downloads'] = $data['view_count']; + + $attach_details = $this->get_import->post_attachment_details($data['content_id']); + + $insert_data['pid'] = $attach_details['pid']; + $insert_data['posthash'] = md5($attach_details['tid'].$attach_details['uid'].random_str()); + + // Build name and check whether it's already in use + $insert_data['attachname'] = "post_".$insert_data['uid']."_".$data['attach_date'].".attach"; + $query = $db->simple_select("attachments", "aid", "attachname='".$db->escape_string($insert_data['attachname'])."'"); + if($db->num_rows($query) > 0) + { + $insert_data['attachname'] = "post_".$insert_data['uid']."_".$data['attach_date']."_".$data['attachment_id'].".attach"; + } + + return $insert_data; + } + + function generate_raw_filename($attach) + { + if(!isset($attach['file_hash'])) + { + $query = $this->old_db->simple_select("attachment_data", "file_hash", "data_id='{$attach['data_id']}'"); + $data = $this->old_db->fetch_array($query); + $this->old_db->free_result($query); + $attach = array_merge($attach, $data); + } + $name = floor($attach['data_id']/1000)."/{$attach['data_id']}-{$attach['file_hash']}.data"; + + return $name; + } + + function fetch_total() + { + global $import_session; + + // Get number of attachments + if(!isset($import_session['total_attachments'])) + { + $query = $this->old_db->simple_select("attachment", "COUNT(*) as count", "content_type='post'"); + $import_session['total_attachments'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_attachments']; + } +} + + diff --git a/boards/xenforo2/avatars.php b/boards/xenforo2/avatars.php new file mode 100644 index 0000000..4fadb72 --- /dev/null +++ b/boards/xenforo2/avatars.php @@ -0,0 +1,95 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Avatars extends Converter_Module_Avatars +{ + var $settings = array( + 'friendly_name' => 'avatars', + 'progress_column' => 'user_id', + 'default_per_screen' => 20, + ); + + function get_avatar_path() + { + $query = $this->old_db->simple_select("option", "option_value", "option_id='boardUrl'"); + $uploadspath = $this->old_db->fetch_field($query, "option_value") . "/data/avatars/"; + $this->old_db->free_result($query); + return $uploadspath; + } + + function import() + { + global $import_session; + + $query = $this->old_db->simple_select("user", "*", "avatar_date > 0 OR gravatar != ''", array('limit_start' => $this->trackers['start_avatars'], 'limit' => $import_session['avatars_per_screen'])); + while($avatar = $this->old_db->fetch_array($query)) + { + $this->insert($avatar); + } + } + + function convert_data($data) + { + global $mybb; + + $insert_data = array(); + + // Xenforo 2 values + $insert_data['uid'] = $this->get_import->uid($data['user_id']); + + if(!empty($data['gravatar'])) + { + $insert_data['avatartype'] = AVATAR_TYPE_GRAVATAR; + $insert_data['avatar'] = $this->get_gravatar_url($data['gravatar']); + + if(!$mybb->settings['maxavatardims']) + { + $mybb->settings['maxavatardims'] = '100x100'; // Hard limit of 100 if there are no limits + } + + list($maxwidth, $maxheight) = explode("x", my_strtolower($mybb->settings['maxavatardims'])); + $this->dimension = "{$maxheight}|{$maxwidth}"; + } + else + { + $insert_data['avatar'] = $this->get_upload_avatar_name($insert_data['uid'], $this->generate_raw_filename($data)); + $insert_data['avatartype'] = AVATAR_TYPE_UPLOAD; + $insert_data['avatardimensions'] = "{$data['avatar_height']}|{$data['avatar_width']}"; + } + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of users with avatar + if(!isset($import_session['total_avatars'])) + { + $query = $this->old_db->simple_select("user", "COUNT(*) as count", "avatar_date > 0 OR gravatar != ''"); + $import_session['total_avatars'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_avatars']; + } + + function generate_raw_filename($avatar) + { + // TODO: or "o/" for original? + return "l/".floor($avatar['user_id']/1000)."/{$avatar['user_id']}.jpg"; + } +} diff --git a/boards/xenforo2/bbcode_parser.php b/boards/xenforo2/bbcode_parser.php new file mode 100644 index 0000000..389808c --- /dev/null +++ b/boards/xenforo2/bbcode_parser.php @@ -0,0 +1,223 @@ +
Please make sure IN_MYBB is defined."); +} + +class BBCode_Parser extends BBCode_Parser_Plain +{ + // This contains the attachment bbcode which is handled as special code as the id needs to be changed too + // Xenforo 2 has different in-post attachment forms. + var $attachment = "\[attach.*?\]([0-9]+)\[/attach\]"; + + function convert($text) + { + // Attachment codes have an optional parameters which we need to remove + $text = preg_replace("#\[attach.*?\]([0-9]+)\[/attach\]#i", "[attach]$1[/attach]", $text); + + // Try to handle most of Xenforo 2's bbcodes. + $text = $this->convert_bbcode($text); + $text = $this->convert_bbcode_callback($text); + + $text = parent::convert($text); + + $text = preg_replace("#\[html\](.*?)\[/html\]#si", "[php]$1[/php]", $text); + + // Seems inline code is not supported by MyBB 1.8, better leave it untouched. + //$text = preg_replace("#\[icode\](.*?)\[/icode\]#i", "[code]$1[/code]", $text); + + return $text; + } + + function convert_bbcode($text) + { + $convert_standards = array( + // xf 2.1, [URL unfurl="true"]...[/URL] + array( + 'find' => "#\[url\s*(.*?)\](.*?)\[/url\]#i", + 'replacement' => "[url]$2[/url]", + ), + ); + + foreach($convert_standards as $convert) + { + $text = preg_replace($convert['find'], $convert['replacement'], $text); + } + + $convert_nestables = array( + ); + + foreach($convert_nestables as $convert) + { + while(preg_match($convert['find'], $text)) + { + $text = preg_replace($convert['find'], $convert['replacement'], $text); + } + + } + + return $text; + } + + function convert_bbcode_callback($text) + { + $convert_standards = array( + // [MEDIA=abc]xyz[/MEDIA] + array( + 'find' => "#\[media=([\w,]+)\]\s*([^\[\<\r\n]+?)\s*\[\/media\]#i", + 'callback' => "handle_media", + ), + ); + + foreach($convert_standards as $convert) + { + $text = preg_replace_callback($convert['find'], array($this, $convert['callback']), $text); + } + + $convert_nestables = array( + // [COLOR=rgb(r, g, b)]...[/COLOR] + array( + 'find' => "#\[color=(rgb\([\d\s,]+?\))\](.*?)\[/color\]#si", + 'callback' => 'handle_color_rgb', + ), + // [size=X]...[/size] + array( + 'find' => "#\[size=(\d{1,2}?)\](.*?)\[/size\]#i", + 'callback' => 'handle_size_value', + ), + ); + + foreach($convert_nestables as $convert) + { + while(preg_match($convert['find'], $text)) + { + $text = preg_replace_callback($convert['find'], array($this, $convert['callback']), $text); + } + } + + return $text; + } + + /** + * Callback for media handling. + * + * @param array $matches + * + * @return string + */ + function handle_media($matches) + { + // array( $provider_xf => array( 'provider_mybb' => $provider_mybb, 'provider_url' => $provider_url ), ); + // TODO: Only handle videos supported by MyBB 1.8? Or return formal URL? + $supported_media = array( + "youtube" => array( + "provider_mybb" => "youtube", + "provider_url" => "https://www.youtube.com/watch?v=$1", + ), + "dailymotion" => array( + "provider_mybb" => "dailymotion", + "provider_url" => "https://www.dailymotion.com/video/$1", + ), + "liveleak" => array( + "provider_mybb" => "liveleak", + "provider_url" => "https://www.liveleak.com/view?t=$1", + ), + "facebook" => array( + "provider_mybb" => "facebook", + "provider_url" => "http://www.facebook.com/video/video.php?v=$1", + ), + "metacafe" => array( + "provider_mybb" => "metacafe", + "provider_url" => "https://www.metacafe.com/watch/$1/", + ), + "vimeo" => array( + "provider_mybb" => "vimeo", + "provider_url" => "https://vimeo.com/$1", + ), + "twitch" => array( + "provider_mybb" => "twitch", + "provider_url" => "https://www.twitch.tv/$1", + ), + ); + + if(array_key_exists($matches[1], $supported_media)) + { + if(!empty($supported_media[$matches[1]]['provider_mybb'])) + { + $provider_mybb = $supported_media[$matches[1]]['provider_mybb']; + $provider_url = str_replace("$1", $matches[2], $supported_media[$matches[1]]['provider_url']); + return "[video={$provider_mybb}]{$provider_url}[/video]"; + } + } + return $matches[0]; // TODO: just return $matches[0]? + } + + /** + * Callback for color using a RGB() value. + * + * @param array $matches + * + * @return string + */ + function handle_color_rgb($matches) + { + $color = '#'; + $rgb_colors = array_filter(explode(",", substr(trim($matches[1]), 4, -1))); + for($i = 0; $i < 3; $i++) + { + $rgb_color = dechex(abs(intval(trim($rgb_colors[$i])))); + while(strlen($rgb_color) < 2) + { + $rgb_color = '0' . $rgb_color; + } + $color .= $rgb_color; + } + return "[color={$color}]{$matches[2]}[/color]"; + } + + /** + * Callback for size attribute without a unit. + * + * @param array $matches + * + * @return string + */ + function handle_size_value($matches) + { + $size = (int)$matches[1]; + switch($size) + { + case 1: + $size = 'x-small'; + break; + case 2: + $size = 'small'; + break; + case 3: + $size = 'medium'; + break; + case 4: + $size = 'large'; + break; + case 5: + $size = 'x-large'; + break; + case 6: + $size = 'xx-large'; + break; + default: + $size = 'medium'; + break; + } + return "[size={$size}]{$matches[2]}[/size]"; + } +} diff --git a/boards/xenforo2/forums.php b/boards/xenforo2/forums.php new file mode 100644 index 0000000..c719dbc --- /dev/null +++ b/boards/xenforo2/forums.php @@ -0,0 +1,123 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Forums extends Converter_Module_Forums +{ + var $settings = array( + 'friendly_name' => 'forums', + 'progress_column' => 'node_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session, $db; + + // Get forums.. + $query = $this->old_db->query("SELECT n.*, + f.allow_posting, f.count_messages, + lf.link_url + FROM ".OLD_TABLE_PREFIX."node n + LEFT JOIN ".OLD_TABLE_PREFIX."forum f ON(f.node_id=n.node_id) + LEFT JOIN ".OLD_TABLE_PREFIX."link_forum lf ON(lf.node_id=n.node_id) + WHERE node_type_id in ('Category','Forum','LinkForum') + ORDER BY n.node_id ASC + LIMIT {$this->trackers['start_forums']}, {$import_session['forums_per_screen']}"); + while($forum = $this->old_db->fetch_array($query)) + { + $fid = $this->insert($forum); + + // Update parent list. + if($forum['parent_node_id'] == '0') + { + $db->update_query("forums", array('parentlist' => $fid), "fid = '{$fid}'"); + } + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['import_fid'] = $data['node_id']; + $insert_data['name'] = encode_to_utf8($this->fix_ampersand($data['title']), "node", "forums"); + $insert_data['description'] = encode_to_utf8($this->fix_ampersand($data['description']), "node", "forums"); + $insert_data['disporder'] = $data['display_order']; + + // Category, forums, link forums. + switch($data['node_type_id']) + { + case "Category": + $insert_data['type'] = 'c'; + break; + case "Forum": + $insert_data['open'] = $data['allow_posting']; + $insert_data['usepostcounts'] = $data['count_messages']; + case "LinkForum": + if(!empty($data['link_url'])) + { + $insert_data['linkto'] = $data['link_url']; + } + default: + $insert_data['type'] = 'f'; + $insert_data['import_pid'] = $data['parent_node_id']; + break; + } + + // xf's active forums can be accessed via URLs but MyBB's can't. + $insert_data['active'] = $data['display_in_list']; + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of forums including only categories, forums, link forums. + if(!isset($import_session['total_forums'])) + { + $query = $this->old_db->simple_select("node", "COUNT(*) as count", "node_type_id in ('Category','Forum','LinkForum')"); + $import_session['total_forums'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_forums']; + } + + /** + * Correctly associate any forums with their correct parent ids. This is automagically run after importing + * forums. + */ + function cleanup() + { + global $db; + + $query = $db->query(" + SELECT f.fid, f2.fid as updatefid, f.import_fid + FROM ".TABLE_PREFIX."forums f + LEFT JOIN ".TABLE_PREFIX."forums f2 ON (f2.import_fid=f.import_pid) + WHERE f.import_pid != '0' AND f.pid = '0' + "); + while($forum = $db->fetch_array($query)) + { + $db->update_query("forums", array('pid' => $forum['updatefid'], 'parentlist' => make_parent_list($forum['import_fid'])), "fid='{$forum['fid']}'", 1); + } + + parent::cleanup(); + } +} + diff --git a/boards/xenforo2/index.html b/boards/xenforo2/index.html new file mode 100644 index 0000000..efd2f36 --- /dev/null +++ b/boards/xenforo2/index.html @@ -0,0 +1,8 @@ + + + + + +  + + \ No newline at end of file diff --git a/boards/xenforo2/moderators.php b/boards/xenforo2/moderators.php new file mode 100644 index 0000000..7a41a4e --- /dev/null +++ b/boards/xenforo2/moderators.php @@ -0,0 +1,67 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Moderators extends Converter_Module_Moderators +{ + var $settings = array( + 'friendly_name' => 'moderators', + 'progress_column' => 'moderator_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + $query = $this->old_db->simple_select("moderator_content", "*", "content_type='node'", array('limit_start' => $this->trackers['start_moderators'], 'limit' => $import_session['moderators_per_screen'])); + while($moderator = $this->old_db->fetch_array($query)) + { + // Not a standard forum. + if(!$this->get_import->fid($moderator['content_id'])) + { + $this->increment_tracker('moderators'); + continue; + } + $this->insert($moderator); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['fid'] = $this->get_import->fid($data['content_id']); + $insert_data['id'] = $this->get_import->uid($data['user_id']); + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of moderators + if(!isset($import_session['total_moderators'])) + { + $query = $this->old_db->simple_select("moderator_content", "COUNT(*) as count", "content_type='node'"); + $import_session['total_moderators'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_moderators']; + } +} + diff --git a/boards/xenforo2/polls.php b/boards/xenforo2/polls.php new file mode 100644 index 0000000..3047eab --- /dev/null +++ b/boards/xenforo2/polls.php @@ -0,0 +1,103 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Polls extends Converter_Module_Polls +{ + var $settings = array( + 'friendly_name' => 'polls', + 'progress_column' => 'poll_id', + 'default_per_screen' => 1000, + ); + + var $cache_tid_polls = null; + + function import() + { + global $import_session, $db; + + $query = $this->old_db->simple_select("poll", "*", "content_type='thread'", array('limit_start' => $this->trackers['start_polls'], 'limit' => $import_session['polls_per_screen'])); + while($poll = $this->old_db->fetch_array($query)) + { + $pid = $this->insert($poll); + + // Restore connections + $db->update_query("threads", array('poll' => $pid), "import_tid = '".$poll['content_id']."'"); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $responses = json_decode($data['responses'], true); + + $seperator = ''; + $options = ''; + $votes = ''; + $vote_count = 0; + $options_count = 0; + + foreach($responses as $response) + { + $options .= $seperator.$response['response']; + $votes .= $seperator.$response['response_vote_count']; + ++$options_count; + $vote_count += $response['response_vote_count']; + $seperator = '||~|~||'; + } + + $insert_data['import_pid'] = $data['poll_id']; + $insert_data['import_tid'] = $data['content_id']; + $insert_data['tid'] = $this->get_import->tid($data['content_id']); + $insert_data['question'] = $data['question']; + $insert_data['options'] = $options; + $insert_data['votes'] = $votes; + $insert_data['numoptions'] = $options_count; + $insert_data['numvotes'] = $vote_count; + $insert_data['multiple'] = $data['max_votes'] > 1 ? 1 : 0; + $insert_data['public'] = $data['public_votes']; + $insert_data['maxoptions'] = $data['max_votes'] > 1 ? $data['max_votes'] : 0; + + $thread = $this->board->get_thread($insert_data['tid']); + $insert_data['dateline'] = $thread['dateline']; + + // XenForo saves the end timestamp, time for some math + if($data['close_date'] != 0) + { + $period = $data['close_date'] - $insert_data['dateline']; // Timeout in seconds + $insert_data['timeout'] = (int)($period / (24*3600)); + } + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of polls + if(!isset($import_session['total_polls'])) + { + $query = $this->old_db->simple_select("poll", "COUNT(*) as count", "content_type='thread'"); + $import_session['total_polls'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_polls']; + } +} + + diff --git a/boards/xenforo2/pollvotes.php b/boards/xenforo2/pollvotes.php new file mode 100644 index 0000000..511b154 --- /dev/null +++ b/boards/xenforo2/pollvotes.php @@ -0,0 +1,115 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Pollvotes extends Converter_Module_Pollvotes +{ + var $settings = array( + 'friendly_name' => 'poll votes', + 'progress_column' => 'poll_response_id', + 'default_per_screen' => 1000, + ); + + var $poll_response_cache = array(); + + function import() + { + global $import_session; + + $query = $this->old_db->query("SELECT v.*, p.response + FROM ".OLD_TABLE_PREFIX."poll_vote v + LEFT JOIN ".OLD_TABLE_PREFIX."poll_response p ON(p.poll_response_id=v.poll_response_id) + LIMIT {$this->trackers['start_pollvotes']}, {$import_session['pollvotes_per_screen']}"); + while($pollvote = $this->old_db->fetch_array($query)) + { + if($this->cache_vote_id($pollvote['poll_id']) === false) + { + $this->increment_tracker('pollvotes'); + continue; + } + $this->insert($pollvote); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['uid'] = $this->get_import->uid($data['user_id']); + $insert_data['dateline'] = $data['vote_date']; + $insert_data['voteoption'] = $this->get_vote_id($data['poll_id'], $data['response']); + $insert_data['pid'] = $this->get_import->pollid($data['poll_id']); + + return $insert_data; + } + + function cache_vote_id($pid) + { + if(!isset($this->poll_response_cache[$pid]) || empty($this->poll_response_cache[$pid])) + { + $query = $this->old_db->simple_select("poll", "responses", "poll_id='{$pid}' AND content_type='thread'"); + $responses = json_decode($this->old_db->fetch_field($query, "responses"), true); + $this->old_db->free_result($query); + + // This generates an array with mybb_id => response + foreach($responses as $response) + { + $this->poll_response_cache[$pid][] = $response['response']; + } + } + // TODO: Could there be any poll that is not attached to a thread? See poll's 'content_type'. + if(!isset($this->poll_response_cache[$pid]) || empty($this->poll_response_cache[$pid])) + { + return false; + } + return true; + } + + function get_vote_id($pid, $answer) + { + // XenForo saves the "responseid" which is an autoincremented column so it ignores the poll. + // However we increment the id per poll (starts at 1 every time). So we need some magic to get "our" id + if(!isset($this->poll_response_cache[$pid]) || empty($this->poll_response_cache[$pid])) + { + $this->cache_vote_id($pid); + } + + foreach($this->poll_response_cache[$pid] as $id => $response) + { + if($response == $answer) + { + return $id+1; // As said: we start with 1, not 0 + } + } + + return false; + } + + function fetch_total() + { + global $import_session; + + // Get number of poll votes + if(!isset($import_session['total_pollvotes'])) + { + $query = $this->old_db->simple_select("poll_vote", "COUNT(*) as count"); + $import_session['total_pollvotes'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_pollvotes']; + } +} + diff --git a/boards/xenforo2/posts.php b/boards/xenforo2/posts.php new file mode 100644 index 0000000..f2b9f26 --- /dev/null +++ b/boards/xenforo2/posts.php @@ -0,0 +1,110 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Posts extends Converter_Module_Posts +{ + var $settings = array( + 'friendly_name' => 'posts', + 'progress_column' => 'post_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + $query = $this->old_db->query("SELECT p.*, t.node_id, t.title, i.ip + FROM ".OLD_TABLE_PREFIX."post p + LEFT JOIN ".OLD_TABLE_PREFIX."thread t ON(t.thread_id=p.thread_id) + LEFT JOIN ".OLD_TABLE_PREFIX."ip i ON(i.ip_id=p.ip_id) + ORDER BY p.post_id ASC + LIMIT {$this->trackers['start_posts']}, {$import_session['posts_per_screen']}"); + while($post = $this->old_db->fetch_array($query)) + { + $this->insert($post); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['import_pid'] = $data['post_id']; + $insert_data['tid'] = $this->get_import->tid($data['thread_id']); + $insert_data['uid'] = $this->get_import->uid($data['user_id']); + $insert_data['import_uid'] = $data['user_id']; + $insert_data['username'] = $this->get_import->username($insert_data['import_uid'], encode_to_utf8($data['username'], "post", "posts")); + $insert_data['dateline'] = $data['post_date']; + $insert_data['message'] = encode_to_utf8($this->bbcode_parser->convert($data['message']), "post", "posts"); + $insert_data['ipaddress'] = $data['ip']; + + // xf has deprecated more fields, retrieve them from thread. + $thread = $this->board->get_thread($insert_data['tid']); + $insert_data['fid'] = $thread['fid']; + $insert_data['subject'] = "RE: ".$thread['subject']; // TODO: MyBB 1.8 Hardcoded this. + + // Visibility. + if($data['discussion_state'] == "deleted") + { + // Soft deleted. + $insert_data['visible'] = -1; + } + else if($data['discussion_state'] == "moderated") + { + // Moderated, should be equivalent to unapproved in MyBB. + $insert_data['visible'] = 0; + } + // Set 'visible' posts' visibility to its thread's setting. + else if($thread['visible'] != 1) + { + $insert_data['visible'] = $thread['visible']; + } + + return $insert_data; + } + + function after_insert($data, $insert_data, $pid) + { + global $db; + + // Restore first post connections + $db->update_query("threads", array('firstpost' => $pid), "tid = '{$insert_data['tid']}' AND import_firstpost = '{$insert_data['import_pid']}'"); + if($db->affected_rows() == 0) + { + $query = $db->simple_select("threads", "firstpost", "tid = '{$insert_data['tid']}'"); + $first_post = $db->fetch_field($query, "firstpost"); + $db->free_result($query); + $db->update_query("posts", array('replyto' => $first_post), "pid = '{$pid}'"); + } + } + + function fetch_total() + { + global $import_session; + + // Get number of posts + if(!isset($import_session['total_posts'])) + { + $query = $this->old_db->simple_select("post", "COUNT(*) as count"); + $import_session['total_posts'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_posts']; + } +} + + diff --git a/boards/xenforo2/privatemessages.php b/boards/xenforo2/privatemessages.php new file mode 100644 index 0000000..98faa2d --- /dev/null +++ b/boards/xenforo2/privatemessages.php @@ -0,0 +1,149 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Privatemessages extends Converter_Module_Privatemessages +{ + var $settings = array( + 'friendly_name' => 'private messages', + 'progress_column' => 'message_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + $query = $this->old_db->query(" + SELECT m.*, c.title, r.recipient_state + FROM ".OLD_TABLE_PREFIX."conversation_message m + LEFT JOIN ".OLD_TABLE_PREFIX."conversation_master c ON(c.conversation_id=m.conversation_id) + LEFT JOIN ".OLD_TABLE_PREFIX."conversation_recipient r ON(r.conversation_id=m.conversation_id AND r.user_id=m.user_id) + LEFT JOIN ".OLD_TABLE_PREFIX."ip i ON(i.ip_id=m.ip_id) + LIMIT ".$this->trackers['start_privatemessages'].", ".$import_session['privatemessages_per_screen'] + ); + while($pm = $this->old_db->fetch_array($query)) + { + $this->insert($pm); + } + } + + function convert_data($data) + { + global $db; + + $insert_data = array(); + + // Xenforo 2 values + $insert_data['fromid'] = $this->get_import->uid($data['user_id']); + $insert_data['subject'] = encode_to_utf8($data['title'], "conversation_master", "privatemessages"); + $insert_data['dateline'] = $data['message_date']; + $insert_data['message'] = encode_to_utf8($this->bbcode_parser->convert($data['message']), "conversation_message", "privatemessages"); + $insert_data['ipaddress'] = $data['ip']; + + // Now build our recipients list + $rec_query = $this->old_db->simple_select("conversation_recipient", "*", "conversation_id='{$data['conversation_id']}' AND user_id!='{$data['user_id']}'"); + $to_send = $recipients = array(); + while($rec = $this->old_db->fetch_array($rec_query)) + { + $rec['user_id'] = $this->get_import->uid($rec['user_id']); + + // "deleted_ignored" means he left the conversation and doesn't want to receive new messages + if($rec['recipient_status'] != 'deleted_ignored') + { + $to_send[] = $rec; + } + + $recipients['to'][] = $rec['user_id']; + } + + $insert_data['recipients'] = serialize($recipients); + + // Now save a copy for every user involved in this pm + // First one for the sender - if he hasn't deleted it + if($data['recipient_status'] != 'deleted_ignored') + { + $insert_data['uid'] = $insert_data['fromid']; + if (count($recipients['to']) == 1) + { + $insert_data['toid'] = $recipients['to'][0]; + } + else + { + $insert_data['toid'] = 0; // multiple recipients + } + $insert_data['status'] = PM_STATUS_READ; // Read - of course + $insert_data['readtime'] = 0; + + if($data['recipient_state'] == 'deleted') + { + $insert_data['folder'] = PM_FOLDER_TRASH; + } + else + { + $insert_data['folder'] = PM_FOLDER_OUTBOX; + } + + if(count($to_send) > 0) + { + $data = $this->prepare_insert_array($insert_data, 'privatemessages'); + $db->insert_query("privatemessages", $data); + } + } + + foreach($to_send as $key => $rec) + { + $insert_data['uid'] = $rec['user_id']; + $insert_data['toid'] = $rec['user_id']; + + $insert_data['status'] = PM_STATUS_UNREAD; + if($rec['last_read_date'] > $insert_data['dateline']) + { + $insert_data['status'] = PM_STATUS_READ; + } + $insert_data['readtime'] = $rec['last_read_date']; + + if($rec['recipient_state'] == 'deleted') + { + $insert_data['folder'] = PM_FOLDER_TRASH; + } + else + { + $insert_data['folder'] = PM_FOLDER_INBOX; + } + + // The last pm will be inserted by the main method, so we only insert x-1 here + if($key < count($to_send)-1) + { + $data = $this->prepare_insert_array($insert_data, 'privatemessages'); + $db->insert_query("privatemessages", $data); + } + } + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of private messages + if(!isset($import_session['total_privatemessages'])) + { + $query = $this->old_db->simple_select("conversation_message", "COUNT(*) as count"); + $import_session['total_privatemessages'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + } +} diff --git a/boards/xenforo2/settings.php b/boards/xenforo2/settings.php new file mode 100644 index 0000000..01319f0 --- /dev/null +++ b/boards/xenforo2/settings.php @@ -0,0 +1,268 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Settings extends Converter_Module_Settings +{ + var $settings = array( + 'friendly_name' => 'settings', + 'default_per_screen' => 1000, + ); + + // What settings do we need to get and what is their MyBB equivalent? + var $convert_settings = array( + /* Options - Board active */ + "boardActive" => "boardclosed", // Inverted + "boardInactiveMessage" => "boardclosed_reason", + + /* Options - Basic board information */ + "boardTitle" => "bbname", + "defaultEmailAddress" => "adminemail", + "contactEmailAddress" => "contactemail", + "homePageUrl" => "homeurl", + "guestTimeZone" => "timezoneoffset", // City => GMT +/-X + + /* Options - Performance */ + "floodCheckLength" => "pmfloodsecs", // Seconds. xf's is for messaging, including posting/pm/etc.. + "floodCheckLengthDiscussion" => "postfloodsecs", // Seconds + + /* Options - Email options */ + "emailTransport" => array( + "emailTransport" => "mail_handler", + "smtpHost" => "smtp_host", + "smtpPort" => "smtp_port", + // "smtpAuth": login + "smtpLoginUsername" => "smtp_user", + "smtpLoginPassword" => "smtp_pass", + "smtpEncrypt" => "secure_smtp", + ), + + /* Options - User registration */ + "registrationSetup" => array( + "enabled" => "disableregs", // Inverted + "emailConfirmation" => "regtype", + "moderation" => "regtype", + ), + "usernameLength" => array( + "min" => "minnamelength", + "max" => "maxnamelength", + ), + "registrationTimer" => "regtime", // Seconds + + /* Options - User options */ + "enableMemberList" => "enablememberlist", + "membersPerPage" => "membersperpage", + "onlineStatusTimeout" => "wolcutoffmins", // Minutes + + /* Options - Threads, discussions and conversations */ + "discussionsPerPage" => "threadsperpage", + "pollMaximumResponses" => "polloptionlimit", + "messageMaxLength" => "maxmessagelength", + "messagesPerPage" => "postsperpage", + "messageMaxImages" => "maxpostimages", + "messageMaxMedia" => "maxpostvideos", + + /* Options - Attachments */ + //"attachmentMaxFileSize" => "", // KB + "attachmentMaxPerMessage" => "maxattachments", + //"attachmentExtensions" => "", // By line + "attachmentThumbnailDimensions" => "attachthumbw|attachthumbh", + ); + + function import() + { + global $import_session; + + // TODO: utf8 conversion? Should be checked but xf 2 only uses utf8mb4. Other board converters can check this. + $utf8_encode_field = array( + "boardInactiveMessage", + "boardTitle", + "homePageUrl", + ); + + // Use MyBB's option name. + $int_to_yes_no = array( + "boardclosed" => 0, + "disableregs" => 0, + "enablememberlist" => 1, + ); + + // xf's options that may be imported. + $query = $this->old_db->simple_select("option", "option_id, option_value, data_type", "option_id IN('".implode("','", array_keys($this->convert_settings))."')", array('limit_start' => $this->trackers['start_settings'], 'limit' => $import_session['settings_per_screen'])); + while($option = $this->old_db->fetch_array($query)) + { + $xf_option_name = $option['option_id']; + $xf_option_value = $option['option_value']; + + if($option['data_type'] == "array" && isset($this->convert_settings[$xf_option_name]) && is_array($this->convert_settings[$xf_option_name])) + { + $xf_option_value = json_decode($xf_option_value, true); + if($xf_option_name == "registrationSetup") + { + global $mybb; + $mybb_regtype = $mybb->settings['regtype']; + } + foreach($this->convert_settings[$xf_option_name] as $xf_sub_option_name => $mybb_option_name) + { + if(!isset($xf_option_value[$xf_sub_option_name])) + { + continue; + } + $mybb_option_value = $xf_option_value[$xf_sub_option_name]; + if(is_array($mybb_option_value)) + { + continue; + } + + if($xf_option_name == "emailTransport") + { + if($xf_sub_option_name == "emailTransport") + { + if($mybb_option_value == "smtp") + { + $mybb_option_value = "smtp"; + } + else if($mybb_option_value == "sendmail") + { + $mybb_option_value = "mail"; + } + // For compatibility. + else + { + $mybb_option_value = "mail"; + } + } + + if($xf_sub_option_name == "smtpEncrypt") + { + if($mybb_option_value == "tls") + { + $mybb_option_value = 2; + } + else if($mybb_option_value == "ssl") + { + $mybb_option_value = 1; + } + else + { + $mybb_option_value = 0; + } + } + } + if($xf_option_name == "registrationSetup") + { + if($xf_sub_option_name == "emailConfirmation") + { + if($mybb_option_value) + { + if($mybb_regtype == "admin") + { + $mybb_regtype = "both"; + } + else if($mybb_regtype == "instant") + { + $mybb_regtype = "verify"; + } + } + $mybb_option_value = $mybb_regtype; + } + if($xf_sub_option_name == "moderation") + { + if($mybb_option_value) + { + if($mybb_regtype == "verify") + { + $mybb_regtype = "both"; + } + else if($mybb_regtype == "instant") + { + $mybb_regtype = "admin"; + } + } + $mybb_option_value = $mybb_regtype; + } + } + if(($mybb_option_value == 0 || $mybb_option_value == 1) && isset($int_to_yes_no[$mybb_option_name])) + { + $mybb_option_value = int_to_yes_no($mybb_option_value, $int_to_yes_no[$mybb_option_name]); + } + $this->update_setting($mybb_option_name, $mybb_option_value); + } + } + else if(isset($this->convert_settings[$xf_option_name])) + { + $mybb_option_name = $this->convert_settings[$xf_option_name]; + $mybb_option_value = $xf_option_value; + + if($xf_option_name == "guestTimeZone") + { + $mybb_option_value = get_timezone($mybb_option_value); + } + + if($xf_option_name == "attachmentThumbnailDimensions") + { + $mybb_option_name = explode("|", $mybb_option_name); + $this->update_setting($mybb_option_name[0], $mybb_option_value); + $mybb_option_name = $mybb_option_name[1]; + } + + if(($mybb_option_value == 0 || $mybb_option_value == 1) && isset($int_to_yes_no[$mybb_option_name])) + { + $mybb_option_value = int_to_yes_no($mybb_option_value, $int_to_yes_no[$mybb_option_name]); + } + + if(in_array($xf_option_name, $utf8_encode_field)) + { + $mybb_option_value = encode_to_utf8($mybb_option_value, "option", "settings"); + } + $this->update_setting($mybb_option_name, $mybb_option_value); + } + $this->increment_tracker('settings'); + } + } + + function fetch_total() + { + global $import_session; + + // Get number of settings. + if(!isset($import_session['total_settings'])) + { + $query = $this->old_db->simple_select("option", "COUNT(*) as count", "option_id IN('".implode("','", array_keys($this->convert_settings))."')"); + $import_session['total_settings'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_settings']; + } + + public function update_setting($name, $value) + { + global $db, $output, $lang; + + $this->debug->log->trace0("Updating setting {$name}"); + $output->print_progress("start", $lang->sprintf($lang->module_settings_updating, htmlspecialchars_uni($name))); + + $modify = array( + 'value' => $db->escape_string($value) + ); + $this->debug->log->datatrace('$value', $value); + $db->update_query("settings", $modify, "name='{$name}'"); + // Increase the tracker manually. + //$this->increment_tracker('settings'); + $output->print_progress("end"); + } +} + + diff --git a/boards/xenforo2/threads.php b/boards/xenforo2/threads.php new file mode 100644 index 0000000..fa53367 --- /dev/null +++ b/boards/xenforo2/threads.php @@ -0,0 +1,116 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Threads extends Converter_Module_Threads +{ + var $settings = array( + 'friendly_name' => 'threads', + 'progress_column' => 'thread_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + $query = $this->old_db->simple_select("thread", "*", "", array('limit_start' => $this->trackers['start_threads'], 'limit' => $import_session['threads_per_screen'])); + while($thread = $this->old_db->fetch_array($query)) + { + $this->insert($thread); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['import_tid'] = $data['thread_id']; + $insert_data['fid'] = $this->get_import->fid($data['node_id']); + $insert_data['import_firstpost'] = $data['first_post_id']; + $insert_data['dateline'] = $data['post_date']; + $insert_data['subject'] = encode_to_utf8($data['title'], "thread", "threads"); + $insert_data['uid'] = $this->get_import->uid($data['user_id']); + $insert_data['username'] = encode_to_utf8($data['username'], "thread", "threads"); + $insert_data['import_uid'] = $data['user_id']; + $insert_data['views'] = $data['view_count']; + $insert_data['replies'] = $data['reply_count']; + + $insert_data['closed'] = int_to_01($data['discussion_open']); + $insert_data['sticky'] = $data['sticky']; + + // Moved thread. + if($data['discussion_type'] == "redirect") + { + $redirect_info = $this->xf_get_redirect($data['thread_id']); + if($redirect_info !== false) + { + $insert_data['closed'] = "moved|".$redirect_info['thread_id']; + $insert_data['deletetime'] = $redirect_info['expiry_date']; + } + } + + // Visibility. + if($data['discussion_state'] == "deleted") + { + // Soft deleted. + $insert_data['visible'] = -1; + } + else if($data['discussion_state'] == "moderated") + { + // Moderated, might be equivalent to unapproved in MyBB. + $insert_data['visible'] = 0; + } + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of threads + if(!isset($import_session['total_threads'])) + { + $query = $this->old_db->simple_select("thread", "COUNT(*) as count"); + $import_session['total_threads'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_threads']; + } + + function xf_get_redirect($thread_id) + { + $query = $this->old_db->simple_select("thread_redirect", "redirect_key,expiry_date", "", array("limit" => 1)); + $redirect = $this->old_db->fetch_array($query); + $this->old_db->free_result($query); + + $redirect_kyes = explode("-", $redirect['redirect_key']); + if($redirect_kyes[0] != "thread") + { + return false; + } + $redirect_info = array( + "thread_id" => $redirect_kyes[1], + "thread_fid" => $redirect_kyes[2], + "expiry_date" => $redirect['expiry_date'], + "data" => $redirect, + ); + + return $redirect_info; + } +} + diff --git a/boards/xenforo2/usergroups.php b/boards/xenforo2/usergroups.php new file mode 100644 index 0000000..e83ebd9 --- /dev/null +++ b/boards/xenforo2/usergroups.php @@ -0,0 +1,66 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Usergroups extends Converter_Module_Usergroups +{ + var $settings = array( + 'friendly_name' => 'usergroups', + 'progress_column' => 'user_group_id', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + // Get only non-staff groups. + $query = $this->old_db->simple_select("user_group", "*", "user_group_id > 4", array('limit_start' => $this->trackers['start_usergroups'], 'limit' => $import_session['usergroups_per_screen'])); + while($group = $this->old_db->fetch_array($query)) + { + $this->insert($group); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['import_gid'] = $data['user_group_id']; + $insert_data['title'] = $data['title']; + $insert_data['usertitle'] = $data['user_title']; + $insert_data['description'] = "XenForo 2 imported usergroup"; + $insert_data['namestyle'] = '{username}'; + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of usergroups + if(!isset($import_session['total_usergroups'])) + { + $query = $this->old_db->simple_select("user_group", "COUNT(*) as count", "user_group_id > 4"); + $import_session['total_usergroups'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_usergroups']; + } +} + + diff --git a/boards/xenforo2/users.php b/boards/xenforo2/users.php new file mode 100644 index 0000000..44a0eb4 --- /dev/null +++ b/boards/xenforo2/users.php @@ -0,0 +1,98 @@ +
Please make sure IN_MYBB is defined."); +} + +class XENFORO2_Converter_Module_Users extends Converter_Module_Users +{ + var $settings = array( + 'friendly_name' => 'users', + 'progress_column' => 'user_id', + 'encode_table' => 'user', + 'postnum_column' => 'message_count', // TODO: Search it! + 'username_column' => 'username', + 'email_column' => 'email', + 'default_per_screen' => 1000, + ); + + function import() + { + global $import_session; + + // Get members + $query = $this->old_db->query("SELECT * + FROM ".OLD_TABLE_PREFIX."user u + LEFT JOIN ".OLD_TABLE_PREFIX."user_profile p ON(p.user_id=u.user_id) + LEFT JOIN ".OLD_TABLE_PREFIX."user_authenticate a ON(a.user_id=u.user_id) + LIMIT {$this->trackers['start_users']}, {$import_session['users_per_screen']}"); + while($user = $this->old_db->fetch_array($query)) + { + $this->insert($user); + } + } + + function convert_data($data) + { + $insert_data = array(); + + // Xenforo 2 values + $insert_data['usergroup'] = $this->board->get_gid($data['user_group_id']); + $insert_data['additionalgroups'] = $this->board->get_group_id($data['secondary_group_ids']); + $insert_data['displaygroup'] = $this->board->get_gid($data['display_style_group_id']); + $insert_data['import_usergroup'] = $data['user_group_id']; + $insert_data['import_additionalgroups'] = $data['secondary_group_ids']; + $insert_data['import_displaygroup'] = $data['display_style_group_id']; + $insert_data['import_uid'] = $data['user_id']; + $insert_data['username'] = encode_to_utf8($data['username'], "user", "users"); + $insert_data['email'] = $data['email']; + $insert_data['regdate'] = $data['register_date']; + $insert_data['lastactive'] = $data['last_activity']; + $insert_data['lastvisit'] = $data['last_activity']; + $insert_data['website'] = $data['website']; + $insert_data['signature'] = encode_to_utf8($this->bbcode_parser->convert($data['signature']), "user_profile", "users"); + if($data['dob_day'] != 0 && $data['dob_month'] != 0) + { + $insert_data['birthday'] = $data['dob_day']."-".$data['dob_month']."-".$data['dob_year']; + } + $insert_data['timezone'] = get_timezone($data['timezone']); + + if($data['scheme_class'] == "XenForo_Authentication_Core") + { + $insert_data['passwordconverttype'] = "xf"; + } + else if($data['scheme_class'] == "XenForo_Authentication_Core12" || $data['scheme_class'] == "XF:Core12") + { + $insert_data['passwordconverttype'] = "xf12"; // Yeah, they changed their password hashing method in a minor release... + } + $password_data = unserialize($data['data']); + $insert_data['passwordconvert'] = $password_data['hash']; + + return $insert_data; + } + + function fetch_total() + { + global $import_session; + + // Get number of members + if(!isset($import_session['total_users'])) + { + $query = $this->old_db->simple_select("user", "COUNT(*) as count"); + $import_session['total_users'] = $this->old_db->fetch_field($query, 'count'); + $this->old_db->free_result($query); + } + + return $import_session['total_users']; + } +} + diff --git a/resources/class_converter_module.php b/resources/class_converter_module.php index beba3f3..2949d8b 100644 --- a/resources/class_converter_module.php +++ b/resources/class_converter_module.php @@ -166,12 +166,20 @@ public function prepare_insert_array($values, $table=false) $insert_array[$key] = $db->escape_string($value); } - if(isset($column_length[$key]) && mb_strlen($insert_array[$key]) > $column_length[$key] && (!isset($this->binary_fields) || !in_array($key, $this->binary_fields))) { - if(is_int($insert_array[$key])) { - // TODO: check whether int(10) really can save "9999999999" as maximum - $insert_array[$key] = (int)str_repeat('9', $column_length[$key]); - } else { - $insert_array[$key] = my_substr($insert_array[$key], 0, $column_length[$key]-3)."..."; + if(isset($column_length[$key]) && (!isset($this->binary_fields) || !in_array($key, $this->binary_fields))) { + $insert_field_length = mb_strlen($insert_array[$key]); + if(is_int($insert_array[$key]) && $insert_array[$key] < 0) { + $insert_field_length -= 1; + $insert_field_negative_int = true; + } + if($insert_field_length > $column_length[$key]) { + if(is_int($insert_array[$key])) { + // TODO: check whether int(10) really can save "9999999999" as maximum + $insert_array[$key] = ($insert_field_negative_int ? '-' : '') . str_repeat('9', $column_length[$key]); + $insert_array[$key] = (int)$insert_array[$key]; + } else { + $insert_array[$key] = my_substr($insert_array[$key], 0, $column_length[$key]-3)."..."; + } } } }