/** * Forum-specific export format. * @param ExportModel $Ex */ protected function ForumExport($Ex) { // Begin $Ex->BeginExport('', 'phpBB 3.*', array('HashMethod' => 'phpBB')); // Users $User_Map = array('user_id' => 'UserID', 'username' => 'Name', 'user_password' => 'Password', 'user_email' => 'Email', 'user_timezone' => 'HourOffset', 'user_posts' => array('Column' => 'CountComments', 'Type' => 'int')); $Ex->ExportTable('User', "select *,\n FROM_UNIXTIME(nullif(user_regdate, 0)) as DateFirstVisit,\n FROM_UNIXTIME(nullif(user_lastvisit, 0)) as DateLastActive,\n FROM_UNIXTIME(nullif(user_regdate, 0)) as DateInserted\n from :_users", $User_Map); // ":_" will be replace by database prefix // Roles $Role_Map = array('group_id' => 'RoleID', 'group_name' => 'Name', 'group_desc' => 'Description'); $Ex->ExportTable('Role', 'select * from :_groups', $Role_Map); // UserRoles $UserRole_Map = array('user_id' => 'UserID', 'group_id' => 'RoleID'); $Ex->ExportTable('UserRole', 'select user_id, group_id from :_users union select user_id, group_id from :_user_group', $UserRole_Map); // Categories $Category_Map = array('forum_id' => 'CategoryID', 'forum_name' => 'Name', 'forum_desc' => 'Description', 'left_id' => 'Sort'); $Ex->ExportTable('Category', "select *,\n nullif(parent_id,0) as ParentCategoryID\n from :_forums", $Category_Map); // Discussions $Discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'topic_poster' => 'InsertUserID', 'topic_title' => 'Name', 'Format' => 'Format', 'topic_views' => 'CountViews', 'topic_first_post_id' => array('Column' => 'FirstCommentID', 'Type' => 'int')); $Ex->ExportTable('Discussion', "select t.*,\n\t\t\t\t'BBCode' as Format,\n topic_replies+1 as CountComments,\n case t.topic_status when 1 then 1 else 0 end as Closed,\n case t.topic_type when 1 then 1 else 0 end as Announce,\n FROM_UNIXTIME(t.topic_time) as DateInserted,\n FROM_UNIXTIME(t.topic_last_post_time) as DateUpdated,\n FROM_UNIXTIME(t.topic_last_post_time) as DateLastComment\n from :_topics t", $Discussion_Map); // Comments $Comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'post_text' => array('Column' => 'Body', 'Filter' => array($this, 'RemoveBBCodeUIDs')), 'Format' => 'Format', 'poster_id' => 'InsertUserID', 'post_edit_user' => 'UpdateUserID'); $Ex->ExportTable('Comment', "select p.*,\n\t\t\t\t'BBCode' as Format,\n FROM_UNIXTIME(p.post_time) as DateInserted,\n FROM_UNIXTIME(nullif(p.post_edit_time,0)) as DateUpdated\n from :_posts p", $Comment_Map); // UserDiscussion $UserDiscussion_Map = array('user_id' => 'UserID', 'topic_id' => 'DiscussionID'); $Ex->ExportTable('UserDiscussion', "select b.*,\n 1 as Bookmarked\n from :_bookmarks b", $UserDiscussion_Map); // End $Ex->EndExport(); }
/** * Logic for export process */ public function DoExport() { // Test connection $Msg = $this->TestDatabase(); if ($Msg === true) { // Create db object $Ex = new ExportModel(); $Dsn = 'mysql:dbname=' . $this->DbInfo['dbname'] . ';host=' . $this->DbInfo['dbhost']; $Ex->PDO($Dsn, $this->DbInfo['dbuser'], $this->DbInfo['dbpass']); $Ex->Prefix = $this->DbInfo['prefix']; // Test src tables' existence structure $Msg = $Ex->VerifySource($this->_SourceTables); if ($Msg === true) { // Good src tables - Start dump $Ex->UseCompression = TRUE; set_time_limit(60 * 2); $this->ForumExport($Ex); } else { ViewForm($Msg); } // Back to form with error } else { ViewForm($Msg); } // Back to form with error }
/** * Main export process. * * @param ExportModel $ex * @see $_Structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('node'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'Advanced Forum 7.x-2.*'); $filePath = $cdn = $this->param('filepath', ''); // User. $user_Map = array(); $ex->exportTable('User', "\n select `u`.`uid` as `UserID`, `u`.`name` as `Name`, `u`.`mail` as `Email`, `u`.`pass` as `Password`,\n 'drupal' as `HashMethod`, from_unixtime(`created`) as `DateInserted`,\n if(`fm`.`filename` is not null, concat('{$filePath}', `fm`.`filename`), NULL) as `Photo`\n from `:_users` `u`\n left join `:_file_managed` `fm` on `u`.`picture` = `fm`.`fid`", $user_Map); // Role. $role_Map = array(); $ex->exportTable('Role', "\n SELECT `name` AS `Name`, `rid` AS `RoleID`\n FROM `:_role` `r`\n ORDER BY `weight` ASC", $role_Map); // User Role. $userRole_Map = array(); $ex->exportTable('UserRole', "\n SELECT `rid` AS `RoleID`, `uid` AS `UserID`\n FROM `:_users_roles` `ur`", $userRole_Map); // Category. $category_Map = array(); $ex->exportTable('Category', "\n SELECT `ttd`.`tid` AS `CategoryID`, `tth`.`parent` AS `ParentCategoryID`,\n `ttd`.`name` AS `Name`, `ttd`.`weight` AS `Sort`\n FROM `:_taxonomy_term_data` `ttd`\n LEFT JOIN `:_taxonomy_vocabulary` `tv` USING (`vid`)\n LEFT JOIN `:_taxonomy_term_hierarchy` `tth` USING (`tid`)\n WHERE `tv`.`name` = 'Forums'\n ORDER BY `ttd`.`weight` ASC", $category_Map); // Discussion. $discussion_Map = array('body_format' => array('Column' => 'Format', 'Filter' => array(__CLASS__, 'translateFormatType'))); $ex->exportTable('Discussion', "\n SELECT `fi`.`nid` AS `DiscussionID`, `fi`.`tid` AS `CategoryID`, `fi`.`title` AS `Name`,\n `fi`.`comment_count` AS `CountComments`, `fdb`.`body_value` AS `Body`,\n from_unixtime(`n`.`created`) AS `DateInserted`,\n if (`n`.`created`< `n`.`changed`, from_unixtime(`n`.`changed`), NULL) AS `DateUpdated`,\n if (`fi`.`sticky` > 0,2,0) AS `Announce`,\n `n`.`uid` AS `InsertUserID`, `fdb`.`body_format`\n FROM `:_forum_index` `fi`\n JOIN `:_field_data_body` `fdb` ON (`fdb`.`bundle` = 'forum' AND `fi`.`nid`=`fdb`.`entity_id`)\n LEFT JOIN `:_node` `n` USING (`nid`)\n ", $discussion_Map); // Comment. $comment_Map = array('comment_body_format' => array('Column' => 'Format', 'Filter' => array(__CLASS__, 'translateFormatType'))); $ex->exportTable('Comment', "\n SELECT `c`.`cid` AS `CommentID`, `c`.`nid` AS `DiscussionID`, `c`.`uid` AS `InsertUserID`,\n from_unixtime(`c`.`created`) AS `DateInserted`,\n if(`c`.`created` < `c`.`changed`, from_unixtime(`c`.`changed`), NULL) AS `DateUpdated`,\n `fdcb`.`comment_body_value` AS `Body`, `fdcb`.`comment_body_format`\n FROM `:_comment` `c` JOIN `:_field_data_comment_body` `fdcb` ON (`c`.`cid` = `fdcb`.`entity_id`)\n ORDER BY `cid` ASC", $comment_Map); $ex->endExport(); }
/** * Logic for export process. */ public function doExport() { global $supported; // Test connection $msg = $this->testDatabase(); if ($msg === true) { // Test src tables' existence structure $msg = $this->ex->verifySource($this->sourceTables); if ($msg === true) { // Good src tables - Start dump $this->ex->useCompression(true); $this->ex->filenamePrefix = $this->dbInfo['dbname']; set_time_limit(60 * 60); // ob_start(); $this->forumExport($this->ex); // $Errors = ob_get_clean(); $msg = $this->ex->comments; // Write the results. Send no path if we don't know where it went. $relativePath = $this->param('destpath', false) ? false : $this->ex->path; viewExportResult($msg, 'Info', $relativePath); } else { viewForm(array('Supported' => $supported, 'Msg' => $msg, 'Info' => $this->dbInfo)); } // Back to form with error } else { viewForm(array('Supported' => $supported, 'Msg' => $msg, 'Info' => $this->dbInfo)); } // Back to form with error }
/** * Logic for export process */ public function DoExport() { global $Supported; // Test connection $Msg = $this->TestDatabase(); if ($Msg === true) { // Create db object $Ex = new ExportModel(); $Ex->SetConnection($this->DbInfo['dbhost'], $this->DbInfo['dbuser'], $this->DbInfo['dbpass'], $this->DbInfo['dbname']); $Ex->Prefix = $this->DbInfo['prefix']; $Ex->UseStreaming = $this->UseStreaming; // Test src tables' existence structure $Msg = $Ex->VerifySource($this->SourceTables); if ($Msg === true) { // Good src tables - Start dump $Ex->UseCompression(TRUE); $Ex->FilenamePrefix = $this->DbInfo['dbname']; set_time_limit(60 * 60); $this->ForumExport($Ex); // Write the results. if ($Ex->UseStreaming) { exit; } else { ViewExportResult($Ex->Comments, 'Info', $Ex->Path); } } else { ViewForm(array('Supported' => $Supported, 'Msg' => $Msg, 'Info' => $this->DbInfo)); } // Back to form with error } else { ViewForm(array('Supported' => $Supported, 'Msg' => $Msg, 'Info' => $this->DbInfo)); } // Back to form with error }
/** * * @param ExportModel $ex * @param string $tableName */ protected function exportTable($ex, $tableName) { // Make sure the table exists. if (!$ex->exists($tableName)) { return; } $ex->exportTable($tableName, "select * from :_{$tableName}"); }
public function actionAdmin() { $model = new ExportModel(); if (isset($_POST['ExportModel'])) { $model->attributes = $_POST['ExportModel']; if ($model->validate()) { $export_key = $model->export_type; if ($export_key != 'cm') { $this->exportDecisions($export_key); } else { $this->exportCommonMarket(); } } } $this->render('export_data', ['model' => $model]); }
/** * Main export process. * * @param ExportModel $ex * @see $_Structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { // Get the characterset for the comments. // Usually the comments table is the best target for this. $characterSet = $ex->getCharacterSet('messages'); if ($characterSet) { $ex->characterSet = $characterSet; } // Reiterate the platform name here to be included in the porter file header. $ex->beginExport('', 'FuseTalk'); $ex->comment("Creating indexes... "); $result = $ex->query('show index from :_users where Key_name = "ix_users_userid"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_users_userid on :_users (iuserid)'); } $result = $ex->query('show index from :_banning where Key_name = "ix_banning_banstring"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_banning_banstring on :_banning (vchbanstring)'); } $result = $ex->query('show index from :_forumusers where Key_name = "ix_forumusers_userid"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_forumusers_userid on :_forumusers (iuserid)'); } $result = $ex->query('show index from :_groupusers where Key_name = "ix_groupusers_userid"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_groupusers_userid on :_groupusers (iuserid)'); } $result = $ex->query('show index from :_privatemessages where Key_name = "ix_privatemessages_vchusagestatus"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_privatemessages_vchusagestatus on :_privatemessages (vchusagestatus)'); } $result = $ex->query('show index from :_threads where Key_name = "ix_threads_id_pollflag"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_threads_id_pollflag on :_threads (ithreadid, vchpollflag)'); } $result = $ex->query('show index from :_threads where Key_name = "ix_threads_poll"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_threads_poll on :_threads (vchpollflag)'); } $ex->comment("Indexes done!"); // Users $user_Map = array(); $ex->exportTable('User', "\n select\n user.iuserid as UserID,\n user.vchnickname as Name,\n user.vchemailaddress as Email,\n user.vchpassword as Password,\n 'md5' as HashMethod,\n if (forumusers.vchauthoricon is not null, concat('authoricons/', forumusers.vchauthoricon), null) as Photo,\n user.dtinsertdate as DateInserted,\n user.dtlastvisiteddate as DateLastActive,\n user.bapproved as Confirmed,\n if (user.iuserlevel = 0, 1, 0) as Admin,\n if (coalesce(bemail.vchbanstring, bname.vchbanstring, 0) != 0, 1, 0) as Banned\n from :_users as user\n left join :_forumusers as forumusers using (iuserid)\n left join :_banning as bemail on b.vchbanstring = user.vchemailaddress\n left join :_banning as bname on b.vchbanstring = user.vchnickname\n group by user.iuserid\n ;", $user_Map); // ":_" will be replaced by database prefix $memberRoleID = 1; $result = $ex->query("select max(igroupid) as maxRoleID from :_groups", true); if ($row = mysql_fetch_assoc($result)) { $memberRoleID += $row['maxRoleID']; } // UserMeta. (Signatures) $ex->exportTable('UserMeta', "\n select\n user.iuserid as UserID,\n 'Plugin.Signatures.Sig' as Name,\n user.txsignature as Value\n from :_users as user\n where nullif(nullif(user.txsignature, ''), char(0)) is not null\n\n union all\n\n select\n user.iuserid,\n 'Plugin.Signatures.Format',\n 'Html'\n from :_users as user\n where nullif(nullif(user.txsignature, ''), char(0)) is not null\n "); // Role. $role_Map = array(); $ex->exportTable('Role', "\n select\n groups.igroupid as RoleID,\n groups.vchgroupname as Name\n from :_groups as groups\n\n union all\n\n select\n {$memberRoleID} as RoleID,\n 'Members'\n from dual\n ", $role_Map); // User Role. $userRole_Map = array(); $ex->exportTable('UserRole', "\n select\n user.iuserid as UserID,\n ifnull (user_role.igroupid, {$memberRoleID}) as RoleID\n from :_users as user\n left join :_groupusers as user_role using (iuserid)\n ", $userRole_Map); $ex->query("drop table if exists zConversations;"); $ex->query("\n create table zConversations(\n `ConversationID` int(11) not null AUTO_INCREMENT,\n `User1` int(11) not null,\n `User2` int(11) not null,\n `DateInserted` datetime not null,\n primary key (`ConversationID`),\n key `IX_zConversation_User1_User2` (`User1`,`User2`)\n );\n "); $ex->query("\n insert into zConversations(`User1`, `User2`, `DateInserted`)\n select\n if (pm.iuserid < pm.iownerid, pm.iuserid, pm.iownerid) as User1,\n if (pm.iuserid < pm.iownerid, pm.iownerid, pm.iuserid) as User2,\n min(pm.dtinsertdate)\n from :_privatemessages as pm\n group by\n User1,\n User2\n "); // Conversations. $conversation_Map = array(); $ex->exportTable('Conversation', "\n select\n c.ConversationID as ConversationID,\n c.User1 as InsertUserID,\n c.DateInserted as DateInserted\n from zConversations as c\n ;", $conversation_Map); // Conversation Messages. $conversationMessage_Map = array('txmessage' => array('Column' => 'Body', 'Filter' => array($this, 'fixSmileysURL'))); $ex->exportTable('ConversationMessage', "\n select\n pm.imessageid as MessageID,\n c.ConversationID,\n pm.txmessage,\n 'Html' as Format,\n pm.iownerid as InsertUserID,\n pm.dtinsertdate as DateInserted\n from zConversations as c\n inner join :_privatemessages as pm on pm.iuserid = c.User1 and pm.iownerid = c.User2\n where vchusagestatus = 'sent'\n\n union all\n\n select\n pm.imessageid as MessageID,\n c.ConversationID,\n pm.txmessage,\n 'Html' as Format,\n pm.iownerid as InsertUserID,\n pm.dtinsertdate as DateInserted\n from zConversations as c\n inner join :_privatemessages as pm on pm.iuserid = c.User2 and pm.iownerid = c.User1\n where vchusagestatus = 'sent'\n ;", $conversationMessage_Map); // User Conversation. $userConversation_Map = array(); $ex->exportTable('UserConversation', "\n select\n c.ConversationID,\n c.User1 as UserID,\n now() as DateLastViewed\n from zConversations as c\n\n union all\n\n select\n c.ConversationID,\n c.User2 as UserID,\n now() as DateLastViewed\n from zConversations as c\n ;", $userConversation_Map); // Category. $category_Map = array(); $ex->exportTable('Category', "\n select\n categories.icategoryid as CategoryID,\n categories.vchcategoryname as Name,\n categories.vchdescription as Description,\n -1 as ParentCategoryID\n from :_categories as categories\n ", $category_Map); // Discussion. /* Skip "Body". It will be fixed at import. * The first comment is going to be used to fill the missing data and will then be deleted */ $discussion_Map = array(); $ex->exportTable('Discussion', "\n select\n threads.ithreadid as DiscussionID,\n threads.vchthreadname as Name,\n threads.icategoryid as CategoryID,\n threads.iuserid as InsertUserID,\n threads.dtinsertdate as DateInserted,\n 'HTML' as Format,\n if (threads.vchalertthread = 'Yes' and threads.dtstaydate > now(), 2, 0) as Announce,\n if (threads.vchthreadlock = 'Locked', 1, 0) as Closed\n from :_threads as threads\n ", $discussion_Map); // Comment. /* * The iparentid column doesn't make any sense since the display is ordered by date only (there are no "sub" comment) */ $comment_Map = array('txmessage' => array('Column' => 'Body', 'Filter' => array($this, 'fixSmileysURL'))); $ex->exportTable('Comment', "\n select\n messages.imessageid as CommentID,\n messages.ithreadid as DiscussionID,\n messages.iuserid as InsertUserID,\n messages.txmessage,\n 'Html' as Format,\n messages.dtmessagedate as DateInserted\n from :_messages as messages\n ", $comment_Map); $ex->endExport(); }
/** * * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('topics'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'Expression Engine'); $ex->sourcePrefix = 'forum_'; $this->exportConversations(); // Permissions. $permission_Map = array('group_id' => 'RoleID', 'can_access_cp' => 'Garden.Settings.View', 'can_access_edit' => 'Vanilla.Discussions.Edit', 'can_edit_all_comments' => 'Vanilla.Comments.Edit', 'can_access_admin' => 'Garden.Settings.Manage', 'can_admin_members' => 'Garden.Users.Edit', 'can_moderate_comments' => 'Garden.Moderation.Manage', 'can_view_profiles' => 'Garden.Profiles.View', 'can_post_comments' => 'Vanilla.Comments.Add', 'can_view_online_system' => 'Vanilla.Discussions.View', 'can_sign_in' => 'Garden.SignIn.Allow', 'can_view_profiles3' => 'Garden.Activity.View', 'can_post_comments2' => 'Vanilla.Discussions.Add'); $permission_Map = $ex->fixPermissionColumns($permission_Map); foreach ($permission_Map as $column => &$info) { if (is_array($info) && isset($info['Column'])) { $info['Filter'] = array($this, 'YNBool'); } } $ex->exportTable('Permission', "\n SELECT\n g.can_view_profiles AS can_view_profiles2,\n g.can_view_profiles AS can_view_profiles3,\n g.can_post_comments AS can_post_comments2,\n g.can_post_comments AS can_sign_in,\n CASE WHEN can_access_admin = 'y' THEN 'all' WHEN can_view_online_system = 'y' THEN 'view' END AS _Permissions,\n g.*\n FROM forum_member_groups g\n ", $permission_Map); // User. $user_Map = array('member_id' => 'UserID', 'username' => array('Column' => 'Username', 'Type' => 'varchar(50)'), 'screen_name' => array('Column' => 'Name', 'Filter' => array($ex, 'HTMLDecoder')), 'Password2' => 'Password', 'email' => 'Email', 'ipaddress' => 'InsertIPAddress', 'join_date' => array('Column' => 'DateInserted', 'Filter' => array($ex, 'timestampToDate')), 'last_activity' => array('Column' => 'DateLastActive', 'Filter' => array($ex, 'timestampToDate')), 'timezone' => 'HourOffset', 'location' => 'Location'); $ex->exportTable('User', "\n SELECT\n 'django' AS HashMethod,\n concat('sha1\$\$', password) AS Password2,\n CASE WHEN bday_y > 1900 THEN concat(bday_y, '-', bday_m, '-', bday_d) ELSE NULL END AS DateOfBirth,\n from_unixtime(join_date) AS DateFirstVisit,\n ip_address AS LastIPAddress,\n CASE WHEN avatar_filename = '' THEN NULL ELSE concat('imported/', avatar_filename) END AS Photo,\n u.*\n FROM forum_members u", $user_Map); // Role. $role_Map = array('group_id' => 'RoleID', 'group_title' => 'Name', 'group_description' => 'Description'); $ex->exportTable('Role', "\n SELECT *\n FROM forum_member_groups", $role_Map); // User Role. $userRole_Map = array('member_id' => 'UserID', 'group_id' => 'RoleID'); $ex->exportTable('UserRole', "\n SELECT *\n FROM forum_members u", $userRole_Map); // UserMeta $ex->exportTable('UserMeta', "\n SELECT\n member_id AS UserID,\n 'Plugin.Signatures.Sig' AS Name,\n signature AS Value\n FROM forum_members\n WHERE signature <> ''"); // Category. $category_Map = array('forum_id' => 'CategoryID', 'forum_name' => 'Name', 'forum_description' => 'Description', 'forum_parent' => 'ParentCategoryID', 'forum_order' => 'Sort'); $ex->exportTable('Category', "\n SELECT * FROM forum_forums", $category_Map); // Discussion. $discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'author_id' => 'InsertUserID', 'title' => array('Column' => 'Name', 'Filter' => array($ex, 'HTMLDecoder')), 'ip_address' => 'InsertIPAddress', 'body' => array('Column' => 'Body', 'Filter' => array($this, 'cleanBodyBrackets')), 'body2' => array('Column' => 'Format', 'Filter' => array($this, 'guessFormat')), 'topic_date' => array('Column' => 'DateInserted', 'Filter' => array($ex, 'timestampToDate')), 'topic_edit_date' => array('Column' => 'DateUpdated', 'Filter' => array($ex, 'timestampToDate')), 'topic_edit_author' => 'UpdateUserID'); $ex->exportTable('Discussion', "\n SELECT\n CASE WHEN announcement = 'y' THEN 1 WHEN sticky = 'y' THEN 2 ELSE 0 END AS Announce,\n CASE WHEN status = 'c' THEN 1 ELSE 0 END AS Closed,\n t.body AS body2,\n t.*\n FROM forum_forum_topics t", $discussion_Map); // Comment. $comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'author_id' => 'InsertUserID', 'ip_address' => 'InsertIPAddress', 'body' => array('Column' => 'Body', 'Filter' => array($this, 'cleanBodyBrackets')), 'body2' => array('Column' => 'Format', 'Filter' => array($this, 'guessFormat')), 'post_date' => array('Column' => 'DateInserted', 'Filter' => array($ex, 'timestampToDate')), 'post_edit_date' => array('Column' => 'DateUpdated', 'Filter' => array($ex, 'timestampToDate')), 'post_edit_author' => 'UpdateUserID'); $ex->exportTable('Comment', "\n SELECT\n 'Html' AS Format,\n p.body AS body2,\n p.*\n FROM forum_forum_posts p", $comment_Map); // Media. $media_Map = array('filename' => 'Name', 'extension' => array('Column' => 'Type', 'Filter' => 'mimeTypeFromExtension'), 'thumb_path' => array('Column' => 'ThumbPath', 'Filter' => array($this, 'filterThumbnailData')), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData')), 'filesize' => 'Size', 'member_id' => 'InsertUserID', 'attachment_date' => array('Column' => 'DateInserted', 'Filter' => array($ex, 'timestampToDate')), 'filehash' => array('Column' => 'FileHash', 'Type' => 'varchar(100)')); $ex->exportTable('Media', "\n SELECT\n concat('imported/', filename) AS Path,\n concat('imported/', filename) as thumb_path,\n 128 as thumb_width,\n CASE WHEN post_id > 0 THEN post_id ELSE topic_id END AS ForeignID,\n CASE WHEN post_id > 0 THEN 'comment' ELSE 'discussion' END AS ForeignTable,\n a.*\n FROM forum_forum_attachments a", $media_Map); $ex->endExport(); }
/** * Export core Vanilla and Conversations tables. * * @since 2.0.0 * @access public */ public function export() { $this->permission('Garden.Export'); // This permission doesn't exist, so only users with Admin == '1' will succeed. set_time_limit(60 * 2); $Ex = new ExportModel(); $Ex->pdo(Gdn::database()->connection()); $Ex->Prefix = Gdn::database()->DatabasePrefix; /// 2. Do the export. /// $Ex->UseCompression = true; $Ex->beginExport(PATH_ROOT . DS . 'uploads' . DS . 'export ' . date('Y-m-d His') . '.txt.gz', 'Vanilla 2.0'); $Ex->exportTable('User', 'select * from :_User'); // ":_" will be replace by database prefix $Ex->exportTable('Role', 'select * from :_Role'); $Ex->exportTable('UserRole', 'select * from :_UserRole'); $Ex->exportTable('Category', 'select * from :_Category'); $Ex->exportTable('Discussion', 'select * from :_Discussion'); $Ex->exportTable('Comment', 'select * from :_Comment'); $Ex->exportTable('Conversation', 'select * from :_Conversation'); $Ex->exportTable('UserConversation', 'select * from :_UserConversation'); $Ex->exportTable('ConversationMessage', 'select * from :_ConversationMessage'); $Ex->endExport(); }
/** * Main export process. * * @param ExportModel $ex * @see $_Structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('post'); if ($characterSet) { $ex->characterSet = $characterSet; } // Reiterate the platform name here to be included in the porter file header. $ex->beginExport('', 'esotalk'); // User. $user_Map = array('memberId' => 'UserID', 'username' => 'Name', 'email' => 'Email', 'confirmed' => 'Verified', 'password' => 'Password'); $ex->exportTable('User', "\n select u.*, 'crypt' as HashMethod,\n FROM_UNIXTIME(joinTime) as DateInserted,\n FROM_UNIXTIME(lastActionTime) as DateLastActive,\n if(account='suspended',1,0) as Banned\n from :_member u", $user_Map); // Role. $role_Map = array('groupId' => 'RoleID', 'name' => 'Name'); $ex->exportTable('Role', "\n select groupId, name\n from :_group\n union select max(groupId)+1, 'Member' from :_group\n union select max(groupId)+2, 'Administrator' from :_group\n ", $role_Map); // User Role. $userRole_Map = array('memberId' => 'UserID', 'groupId' => 'RoleID'); // Create fake 'member' and 'administrator' roles to account for them being set separately on member table. $ex->exportTable('UserRole', "\n select u.memberId, u.groupId\n from :_member_group u\n union all\n select memberId, (select max(groupId)+1 from :_group) from :_member where account='member'\n union all\n select memberId, (select max(groupId)+2 from :_group) from :_member where account='administrator'\n ", $userRole_Map); // Category. $category_Map = array('channelId' => 'CategoryID', 'title' => 'Name', 'slug' => 'UrlCode', 'description' => 'Description', 'parentId' => 'ParentCategoryID', 'countConversations' => 'CountDiscussions'); $ex->exportTable('Category', "\n select *\n from :_channel c", $category_Map); // Discussion. $discussion_Map = array('conversationId' => 'DiscussionID', 'title' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'channelId' => 'CategoryID', 'memberId' => 'InsertUserID', 'sticky' => 'Announce', 'locked' => 'Closed', 'lastPostMemberId' => 'LastCommentUserID', 'content' => 'Body'); // The body of the OP is in the post table. $ex->exportTable('Discussion', "\n\t\t\tselect\n\t\t\t\tc.conversationId,\n\t\t\t\tc.title,\n\t\t\t\tc.channelId,\n\t\t\t\tp.memberId,\n\t\t\t\tc.sticky,\n\t\t\t\tc.locked,\n\t\t\t\tc.lastPostMemberId,\n\t\t\t\tp.content,\n\t\t\t\t'BBCode' as Format,\n\t\t\t\tfrom_unixtime(startTime) as DateInserted,\n\t\t\t\tfrom_unixtime(lastPostTime) as DateLastComment\n\t\t\tfrom :_conversation c\n\t\t\tleft join :_post p\n\t\t\t\ton p.conversationId = c.conversationId\n\t\t\twhere private = 0\n\t\t\tgroup by c.conversationId\n\t\t\tgroup by p.time", $discussion_Map); // Comment. $comment_Map = array('postId' => 'CommentID', 'conversationId' => 'DiscussionID', 'content' => 'Body', 'memberId' => 'InsertUserID', 'editMemberId' => 'UpdateUserID'); // Now we need to omit the comments we used as the OP. $ex->exportTable('Comment', "\n\t\tselect p.*,\n\t\t\t\t'BBCode' as Format,\n\t\t\t\tfrom_unixtime(time) as DateInserted,\n\t\t\t\tfrom_unixtime(editTime) as DateUpdated\n\t\tfrom :_post p\n\t\tinner join :_conversation c ON c.conversationId = p.conversationId\n\t\tand c.private = 0\n\t\tjoin\n\t\t\t( select conversationId,\n\t\t\t\tmin(postId) as m\n\t\t\tfrom :_post\n\t\t\tgroup by conversationId) r on r.conversationId = c.conversationId\n\t\twhere p.postId<>r.m", $comment_Map); // UserDiscussion. $userDiscussion_Map = array('id' => 'UserID', 'conversationId' => 'DiscussionID'); $ex->exportTable('UserDiscussion', "\n select *\n from :_member_conversation\n where starred = 1", $userDiscussion_Map); // Permission. // :_channel_group // Media. // :_attachment // Conversation. $conversation_map = array('conversationId' => 'ConversationID', 'countPosts' => 'CountMessages', 'startMemberId' => 'InsertUserID', 'countPosts' => 'CountMessages'); $ex->exportTable('Conversation', "\n select p.*,\n 'BBCode' as Format,\n from_unixtime(time) as DateInserted,\n from_unixtime(lastposttime) as DateUpdated\n from :_post p\n inner join :_conversation c on c.conversationId = p.conversationId\n and c.private = 1", $conversation_map); $userConversation_map = array('conversationId' => 'ConversationID', 'memberId' => 'UserID'); $ex->exportTable('UserConversation', "\n select distinct a.fromMemberId as memberId, a.type, c.private, c.conversationId from :_activity a\n inner join :_conversation c on c.conversationId = a.conversationId\n and c.private = 1 and a.type = 'privateAdd'\n union all\n select distinct a.memberId as memberId, a.type, c.private, c.conversationId from :_activity a\n inner join :_conversation c on c.conversationId = a.conversationId\n and c.private = 1 and a.type = 'privateAdd'", $userConversation_map); $userConversationMessage_map = array('postId' => 'MessageID', 'conversationId' => 'ConversationID', 'content' => 'Body', 'memberId' => 'InsertUserID'); $ex->exportTable('ConversationMessage', "\n select p.*,\n 'BBCode' as Format,\n from_unixtime(time) as DateInserted\n from :_post p\n inner join :_conversation c on c.conversationId = p.conversationId and c.private = 1", $userConversationMessage_map); $ex->endExport(); }
/** * Setup. */ public function __construct() { self::$mb = function_exists('mb_detect_encoding'); // Set the search and replace to escape strings. self::$escapeSearch = array(self::ESCAPE, self::DELIM, self::NEWLINE, self::QUOTE); // escape must go first self::$escapeReplace = array(self::ESCAPE . self::ESCAPE, self::ESCAPE . self::DELIM, self::ESCAPE . self::NEWLINE, self::ESCAPE . self::QUOTE); // Load structure. $this->_structures = vanillaStructure(); }
/** * Forum-specific export format. * @param ExportModel $Ex */ protected function ForumExport($Ex) { // Begin $Ex->BeginExport('', 'phpBB 3.*', array('HashMethod' => 'phpBB')); // Users $User_Map = array( 'user_id'=>'UserID', 'username'=>'Name', 'user_password'=>'Password', 'user_email'=>'Email', 'user_timezone'=>'HourOffset', 'user_posts'=>array('Column' => 'CountComments', 'Type' => 'int') ); $Ex->ExportTable('User', "select *, FROM_UNIXTIME(nullif(user_regdate, 0)) as DateFirstVisit, FROM_UNIXTIME(nullif(user_lastvisit, 0)) as DateLastActive, FROM_UNIXTIME(nullif(user_regdate, 0)) as DateInserted from :_users", $User_Map); // ":_" will be replace by database prefix // Roles $Role_Map = array( 'group_id'=>'RoleID', 'group_name'=>'Name', 'group_desc'=>'Description' ); $Ex->ExportTable('Role', 'select * from :_groups', $Role_Map); // UserRoles $UserRole_Map = array( 'user_id'=>'UserID', 'group_id'=>'RoleID' ); $Ex->ExportTable('UserRole', 'select user_id, group_id from :_users union select user_id, group_id from :_user_group', $UserRole_Map); // Categories $Category_Map = array( 'forum_id'=>'CategoryID', 'forum_name'=>'Name', 'forum_desc'=>'Description', 'left_id'=>'Sort' ); $Ex->ExportTable('Category', "select *, nullif(parent_id,0) as ParentCategoryID from :_forums", $Category_Map); // Discussions $Discussion_Map = array( 'topic_id'=>'DiscussionID', 'forum_id'=>'CategoryID', 'topic_poster'=>'InsertUserID', 'topic_title'=>'Name', 'Format'=>'Format', 'topic_views'=>'CountViews', 'topic_first_post_id'=>array('Column'=>'FirstCommentID','Type'=>'int') ); $Ex->ExportTable('Discussion', "select t.*, 'BBCode' as Format, topic_replies+1 as CountComments, case t.topic_status when 1 then 1 else 0 end as Closed, case t.topic_type when 1 then 1 else 0 end as Announce, FROM_UNIXTIME(t.topic_time) as DateInserted, FROM_UNIXTIME(t.topic_last_post_time) as DateUpdated, FROM_UNIXTIME(t.topic_last_post_time) as DateLastComment from :_topics t", $Discussion_Map); // Comments $Comment_Map = array( 'post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'post_text' => array('Column'=>'Body','Filter'=>array($this, 'RemoveBBCodeUIDs')), 'Format' => 'Format', 'poster_id' => 'InsertUserID', 'post_edit_user' => 'UpdateUserID' ); $Ex->ExportTable('Comment', "select p.*, 'BBCode' as Format, FROM_UNIXTIME(p.post_time) as DateInserted, FROM_UNIXTIME(nullif(p.post_edit_time,0)) as DateUpdated from :_posts p", $Comment_Map); // UserDiscussion $UserDiscussion_Map = array( 'user_id' => 'UserID', 'topic_id' => 'DiscussionID'); $Ex->ExportTable('UserDiscussion', "select b.*, 1 as Bookmarked from :_bookmarks b", $UserDiscussion_Map); // Media if ($Ex->Exists('attachments')) { $Media_Map = array( 'attach_id' => 'MediaID', 'real_filename' => 'Name', 'mimetype' => 'Type', 'filesize' => 'Size', 'physical_filename' => array('Column' => 'Path', 'Filter' => array($this, 'BuildMediaPath')), 'poster_id' => 'InsertUserID' ); $Ex->ExportTable('Media', "select a.*, p.post_id as post_id, 'local' as StorageMethod, IF(p.post_id != p.topic_id, 'comment', 'discussion') as ForeignTable, IF(p.post_id != p.topic_id, post_id, a.topic_id) as ForeignID, FROM_UNIXTIME(a.filetime) as DateInserted from :_attachments a left join :_posts p ON a.post_msg_id = p.post_id", $Media_Map); } // End $Ex->EndExport(); }
/** * Main export process. * * @param ExportModel $ex * @see $_structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { // Get the characterset for the comments. // Usually the comments table is the best target for this. $characterSet = $ex->getCharacterSet('network6_nodes'); if ($characterSet) { $ex->characterSet = $characterSet; } // Reiterate the platform name here to be included in the porter file header. $ex->beginExport('', 'AnswerHub'); $result = $ex->query("select c_reserved as lastID from :_id_generators where c_identifier = 'AUTHORITABLE'", true); if ($row = mysql_fetch_assoc($result)) { $lastID = $row['lastID']; } if (!isset($lastID)) { die('Something went wrong :S' . PHP_EOL); } // User. $user_Map = array('c_email' => array('Column' => 'Email', 'Filter' => array($this, 'generateEmail'))); $ex->exportTable('User', "\n select\n user.c_id as UserID,\n user.c_name as Name,\n sha2(concat(user.c_name, now()), 256) as Password,\n 'Reset' as HashMethod,\n user.c_creation_date as DateInserted,\n user.c_birthday as DateOfBirth,\n user.c_last_seen as DateLastActive,\n user_email.c_email,\n 0 as Admin\n from :_network6_authoritables as user\n left join :_network6_user_emails as user_email on user_email.c_user = user.c_id\n where user.c_type = 'user'\n and user.c_name != '\$\$ANON_USER\$\$'\n\n union all\n\n select\n su.c_id + {$lastID},\n su.c_username,\n sha2(concat(su.c_username, now()), 256),\n 'Reset',\n su.c_creation_date,\n null,\n null,\n su.c_email,\n 1 as Admin\n from :_system_users as su\n where su.c_active = 1\n\n ", $user_Map); // Role. $role_Map = array(); $ex->exportTable('Role', "\n select\n groups.c_id as RoleID,\n groups.c_name as Name,\n groups.c_description as Description\n from :_network6_authoritables as groups\n where groups.c_type = 'group'\n\n union all\n\n select\n {$lastID} + 1,\n 'System Administrator',\n 'System users from AnswerHub'\n from dual\n ", $role_Map); // User Role. $userRole_Map = array(); $ex->exportTable('UserRole', "\n select\n user_role.c_groups as RoleID,\n user_role.c_members as UserID\n from :_network6_authoritable_groups as user_role\n\n union all\n\n select\n {$lastID} + 1,\n su.c_id + {$lastID}\n from :_system_users as su\n where su.c_active = 1\n ", $userRole_Map); // Category. $category_Map = array(); $ex->exportTable('Category', "\n select\n containers.c_id as CategoryID,\n case\n when parents.c_type = 'space' then containers.c_parent\n else null\n end as ParentCategoryID,\n containers.c_name as Name\n from :_containers as containers\n left join :_containers as parents on parents.c_id = containers.c_parent\n where containers.c_type = 'space'\n and containers.c_active = 1\n ", $category_Map); // Discussion. $discussion_Map = array(); // The query works fine but it will probably be slow for big tables $ex->exportTable('Discussion', "\n select\n questions.c_id as DiscussionID,\n 'Question' as Type,\n questions.c_primaryContainer as CategoryID,\n questions.c_author as InsertUserID,\n questions.c_creation_date as DateInserted,\n questions.c_title as Name,\n coalesce(nullif(questions.c_body, ''), questions.c_title) as Body,\n 'HTML' as Format,\n if(locate('[closed]', questions.c_normalized_state) > 0, 1, 0) as Closed,\n if(count(answers.c_id) > 0,\n if (locate('[accepted]', group_concat(ifnull(answers.c_normalized_state, ''))) = 0,\n if (locate('[rejected]', group_concat(ifnull(answers.c_normalized_state, ''))) = 0,\n 'Answered',\n 'Rejected'\n ),\n 'Accepted'\n ),\n 'Unanswered'\n ) as QnA\n from :_network6_nodes as questions\n\t left join :_network6_nodes as answers on\n\t answers.c_parent = questions.c_id\n\t and answers.c_type = 'answer'\n\t and answers.c_visibility = 'full'\n where questions.c_type = 'question'\n and questions.c_visibility = 'full'\n group by questions.c_id\n ", $discussion_Map); // Comment. $comment_Map = array(); $ex->exportTable('Comment', "\n select\n answers.c_id as CommentID,\n answers.c_parent as DiscussionID,\n answers.c_author as InsertUserID,\n answers.c_body as Body,\n 'Html' as Format,\n answers.c_creation_date as DateInserted,\n if(locate('[accepted]', answers.c_normalized_state) = 0,\n if(locate('[rejected]', answers.c_normalized_state) = 0,\n null,\n 'Rejected'\n ),\n 'Accepted'\n ) as QnA\n from :_network6_nodes as answers\n where answers.c_type = 'answer'\n and answers.c_visibility = 'full'\n ", $comment_Map); $ex->endExport(); }
/** * * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('Topic'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'Web Wiz Forums'); $ex->sourcePrefix = 'tbl'; // // Permissions. // $Permission_Map = array( // 'group_id' => 'RoleID', // 'can_access_cp' => 'Garden.Settings.View', // 'can_access_edit' => 'Vanilla.Discussions.Edit', // 'can_edit_all_comments' => 'Vanilla.Comments.Edit', // 'can_access_admin' => 'Garden.Settings.Manage', // 'can_admin_members' => 'Garden.Users.Edit', // 'can_moderate_comments' => 'Garden.Moderation.Manage', // 'can_view_profiles' => 'Garden.Profiles.View', // 'can_post_comments' => 'Vanilla.Comments.Add', // 'can_view_online_system' => 'Vanilla.Discussions.View', // 'can_sign_in' => 'Garden.SignIn.Allow', // 'can_view_profiles3' => 'Garden.Activity.View', // 'can_post_comments2' => 'Vanilla.Discussions.Add' // ); // $Permission_Map = $ex->FixPermissionColumns($Permission_Map); // foreach ($Permission_Map as $Column => &$Info) { // if (is_array($Info) && isset($Info['Column'])) // $Info['Filter'] = array($this, 'Bool'); // } // // $ex->ExportTable('Permission', " // select // g.can_view_profiles as can_view_profiles2, // g.can_view_profiles as can_view_profiles3, // g.can_post_comments as can_post_comments2, // g.can_post_comments as can_sign_in, // case when can_access_admin = 'y' then 'all' when can_view_online_system = 'y' then 'view' end as _Permissions, // g.* // from forum_member_groups g // ", $Permission_Map); // User. $user_Map = array('Author_ID' => 'UserID', 'Username' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'Real_name' => array('Column' => 'FullName', 'Type' => 'varchar(50)', 'Filter' => 'HTMLDecoder'), 'Password2' => 'Password', 'Gender2' => 'Gender', 'Author_email' => 'Email', 'Photo2' => array('Column' => 'Photo', 'Filter' => 'HTMLDecoder'), 'Login_IP' => 'LastIPAddress', 'Banned' => 'Banned', 'Join_date' => array('Column' => 'DateInserted'), 'Last_visit' => array('Column' => 'DateLastActive'), 'Location' => array('Column' => 'Location', 'Filter' => 'HTMLDecoder'), 'DOB' => 'DateOfBirth', 'Show_email' => 'ShowEmail'); $ex->exportTable('User', "\n select\n concat(Salt, '\$', Password) as Password2,\n case u.Gender when 'Male' then 'm' when 'Female' then 'f' else 'u' end as Gender2,\n case when Avatar like 'http%' then Avatar when Avatar > '' then concat('webwiz/', Avatar) else null end as Photo2,\n 'webwiz' as HashMethod,\n u.*\n from :_Author u\n ", $user_Map); // Role. $role_Map = array('Group_ID' => 'RoleID', 'Name' => 'Name'); $ex->exportTable('Role', "\n select *\n from :_Group", $role_Map); // User Role. $userRole_Map = array('Author_ID' => 'UserID', 'Group_ID' => 'RoleID'); $ex->exportTable('UserRole', "\n select u.*\n from :_Author u", $userRole_Map); // UserMeta $ex->exportTable('UserMeta', "\n select\n Author_ID as UserID,\n 'Plugin.Signatures.Sig' as `Name`,\n Signature as `Value`\n from :_Author\n where Signature <> ''"); // Category. $category_Map = array('Forum_ID' => 'CategoryID', 'Forum_name' => 'Name', 'Forum_description' => 'Description', 'Parent_ID' => 'ParentCategoryID', 'Forum_order' => 'Sort'); $ex->exportTable('Category', "\n select\n f.Forum_ID,\n f.Cat_ID * 1000 as Parent_ID,\n f.Forum_order,\n f.Forum_name,\n f.Forum_description\n from :_Forum f\n\n union all\n\n select\n c.Cat_ID * 1000,\n null,\n c.Cat_order,\n c.Cat_name,\n null\n from :_Category c\n ", $category_Map); // Discussion. $discussion_Map = array('Topic_ID' => 'DiscussionID', 'Forum_ID' => 'CategoryID', 'Author_ID' => 'InsertUserID', 'Subject' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'IP_addr' => 'InsertIPAddress', 'Message' => array('Column' => 'Body'), 'Format' => 'Format', 'Message_date' => array('Column' => 'DateInserted'), 'No_of_views' => 'CountViews', 'Locked' => 'Closed'); $ex->exportTable('Discussion', "\n select\n th.Author_ID,\n th.Message,\n th.Message_date,\n th.IP_addr,\n 'Html' as Format,\n t.*\n from :_Topic t\n join :_Thread th\n on t.Start_Thread_ID = th.Thread_ID", $discussion_Map); // Comment. $comment_Map = array('Thread_ID' => 'CommentID', 'Topic_ID' => 'DiscussionID', 'Author_ID' => 'InsertUserID', 'IP_addr' => 'InsertIPAddress', 'Message' => array('Column' => 'Body'), 'Format' => 'Format', 'Message_date' => array('Column' => 'DateInserted')); $ex->exportTable('Comment', "\n select\n th.*,\n 'Html' as Format\n from :_Thread th\n join :_Topic t\n on t.Topic_ID = th.Topic_ID\n where th.Thread_ID <> t.Start_Thread_ID", $comment_Map); $this->exportConversations(); $ex->endExport(); }
/** * Forum-specific export format. * @param ExportModel $Ex */ protected function ForumExport($Ex) { // Begin $Ex->BeginExport('', 'SimplePress 1.*', array('HashMethod' => 'Vanilla')); // Users $User_Map = array('user_id' => 'UserID', 'display_name' => 'Name', 'user_pass' => 'Password', 'user_email' => 'Email', 'user_registered' => 'DateInserted'); $Ex->ExportTable('User', "select m.*, u.user_pass, u.user_email\n from :_users u\n join :_sfmembers m\n on u.ID = m.user_id", $User_Map); // ":_" will be replace by database prefix // Roles $Role_Map = array('usergroup_id' => 'RoleID', 'usergroup_name' => 'Name', 'usergroup_desc' => 'Description'); $Ex->ExportTable('Role', "select * from :_sfusergroups", $Role_Map); // UserRoles $UserRole_Map = array('user_id' => 'UserID', 'usergroup_id' => 'RoleID'); $Ex->ExportTable('UserRole', "select * from :_sfmemberships", $UserRole_Map); // Categories $Category_Map = array('forum_id' => 'CategoryID', 'forum_name' => 'Name', 'forum_desc' => 'Description', 'form_slug' => 'UrlCode'); $Ex->ExportTable('Category', "select *,\n nullif(parent,0) as ParentCategoryID\n from :_sfforums", $Category_Map); // Discussions $Discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'user_id' => 'InsertUserID', 'topic_name' => 'Name', 'Format' => 'Format', 'topic_date' => 'DateInserted', 'topic_pinned' => 'Announce'); $Ex->ExportTable('Discussion', "select t.*,\n\t\t\t\t'Html' as Format\n from :_sftopics t", $Discussion_Map); // Comments $Comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'post_content' => 'Body', 'Format' => 'Format', 'user_id' => 'InsertUserID', 'post_date' => 'DateInserted'); $Ex->ExportTable('Comment', "select p.*,\n\t\t\t\t'Html' as Format\n from :_sfposts p", $Comment_Map); // Conversation. $Conv_Map = array('message_id' => 'ConversationID', 'from_id' => 'InsertUserID', 'sent_date' => 'DateInserted'); $Ex->ExportTable('Conversation', "select *\n from :_sfmessages\n where is_reply = 0", $Conv_Map); // ConversationMessage. $ConvMessage_Map = array('message_id' => 'MessageID', 'from_id' => 'InsertUserID', 'message' => array('Column' => 'Body')); $Ex->ExportTable('ConversationMessage', 'select c.message_id as ConversationID, m.* from :_sfmessages c join :_sfmessages m on (m.is_reply = 0 and m.message_id = c.message_id) or (m.is_reply = 1 and c.is_reply = 0 and m.message_slug = c.message_slug and m.from_id in (c.from_id, c.to_id) and m.to_id in (c.from_id, c.to_id));', $ConvMessage_Map); // UserConversation $UserConv_Map = array('message_id' => 'ConversationID', 'from_id' => 'UserID'); $Ex->ExportTable('UserConversation', 'select message_id, from_id from :_sfmessages where is_reply = 0 union select message_id, to_id from :_sfmessages where is_reply = 0', $UserConv_Map); // End $Ex->EndExport(); }
/** * Forum-specific export format. * @param ExportModel $ex */ protected function forumExport($ex) { $characterSet = $ex->getCharacterSet('messages'); if ($characterSet) { $ex->characterSet = $characterSet; } // Begin $ex->beginExport('', 'SMF 2.*', array('HashMethod' => 'Django')); // Users $user_Map = array('id_member' => 'UserID', 'member_name' => 'Name', 'password' => 'Password', 'email_address' => 'Email', 'DateInserted' => 'DateInserted', 'timeOffset' => 'HourOffset', 'posts' => 'CountComments', 'Photo' => 'Photo', 'birthdate' => 'DateOfBirth', 'DateFirstVisit' => 'DateFirstVisit', 'DateLastActive' => 'DateLastActive', 'DateUpdated' => 'DateUpdated'); $ex->exportTable('User', "\n select m.*,\n from_unixtime(date_registered) as DateInserted,\n from_unixtime(date_registered) as DateFirstVisit,\n from_unixtime(last_login) as DateLastActive,\n from_unixtime(last_login) as DateUpdated,\n concat('sha1\$', lower(member_name), '\$', passwd) as `password`,\n if(m.avatar <> '', m.avatar, concat('attachments/', a.filename)) as Photo\n from :_members m\n left join :_attachments a on a.id_member = m.id_member ", $user_Map); // Roles $role_Map = array('id_group' => 'RoleID', 'group_name' => 'Name'); $ex->exportTable('Role', "select * from :_membergroups", $role_Map); // UserRoles $userRole_Map = array('id_member' => 'UserID', 'id_group' => 'RoleID'); $ex->exportTable('UserRole', "select * from :_members", $userRole_Map); // Categories $category_Map = array('Name' => array('Column' => 'Name', 'Filter' => array($this, 'decodeNumericEntity'))); $ex->exportTable('Category', "\n select\n (`id_cat` + 1000000) as `CategoryID`,\n `name` as `Name`,\n '' as `Description`,\n null as `ParentCategoryID`,\n `cat_order` as `Sort`\n from :_categories\n\n union\n\n select\n b.`id_board` as `CategoryID`,\n\n b.`name` as `Name`,\n b.`description` as `Description`,\n (CASE WHEN b.`id_parent` = 0 THEN (`id_cat` + 1000000) ELSE `id_parent` END) as `ParentCategoryID`,\n b.`board_order` as `Sort`\n from :_boards b\n\n ", $category_Map); // Discussions $discussion_Map = array('id_topic' => 'DiscussionID', 'subject' => array('Column' => 'Name', 'Filter' => array($this, 'decodeNumericEntity')), 'body' => array('Column' => 'Body'), 'Format' => 'Format', 'id_board' => 'CategoryID', 'DateInserted' => 'DateInserted', 'DateUpdated' => 'DateUpdated', 'id_member' => 'InsertUserID', 'DateLastComment' => 'DateLastComment', 'UpdateUserID' => 'UpdateUserID', 'locked' => 'Closed', 'isSticky' => 'Announce', 'CountComments' => 'CountComments', 'numViews' => 'CountViews', 'LastCommentUserID' => 'LastCommentUserID', 'id_last_msg' => 'LastCommentID'); $ex->exportTable('Discussion', "\n select t.*,\n (t.num_replies + 1) as CountComments,\n m.subject,\n m.body,\n from_unixtime(m.poster_time) as DateInserted,\n from_unixtime(m.modified_time) as DateUpdated,\n m.id_member,\n from_unixtime(m_end.poster_time) AS DateLastComment,\n m_end.id_member AS UpdateUserID,\n m_end.id_member AS LastCommentUserID,\n 'BBCode' as Format\n from :_topics t\n join :_messages as m on t.id_first_msg = m.id_msg\n join :_messages as m_end on t.id_last_msg = m_end.id_msg\n\n -- where t.spam = 0 AND m.spam = 0;\n\n ", $discussion_Map); // Comments $comment_Map = array('id_msg' => 'CommentID', 'id_topic' => 'DiscussionID', 'Format' => 'Format', 'body' => array('Column' => 'Body'), 'id_member' => 'InsertUserID', 'DateInserted' => 'DateInserted'); $ex->exportTable('Comment', "select m.*,\n from_unixtime(m.poster_time) AS DateInserted,\n 'BBCode' as Format\n from :_messages m\n join :_topics t on m.id_topic = t.id_topic\n where m.id_msg <> t.id_first_msg;\n ", $comment_Map); // Media $media_Map = array('ID_ATTACH' => 'MediaID', 'id_msg' => 'ForeignID', 'size' => 'Size', 'height' => 'ImageHeight', 'width' => 'ImageWidth', 'extract_mimetype' => array('Column' => 'Type', 'Filter' => function ($value, $field, $row) { return $this->getMimeTypeFromFileName($row['Path']); }), 'thumb_path' => array('Column' => 'ThumbPath', 'Filter' => array($this, 'filterThumbnailData')), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData'))); $ex->exportTable('Media', "\n select a.*,\n concat('attachments/', a.filename) as Path,\n IF(b.filename is not null, concat('attachments/', b.filename), null) as thumb_path,\n null as extract_mimetype,\n b.width as thumb_width,\n if(t.id_topic is null, 'Comment', 'Discussion') as ForeignTable\n from :_attachments a\n left join :_attachments b on b.ID_ATTACH = a.ID_THUMB\n left join :_topics t on a.id_msg = t.id_first_msg\n where a.attachment_type = 0\n and a.id_msg > 0\n ", $media_Map); // Conversations $conversation_Map = array('id_pm_head' => 'ConversationID', 'subject' => 'Subject', 'id_member_from' => 'InsertUserID', 'unixmsgtime' => 'DateInserted'); $ex->exportTable('Conversation', "select\n pm.*,\n from_unixtime(pm.msgtime) as unixmsgtime\n from :_personal_messages pm\n ", $conversation_Map); $convMsg_Map = array('id_pm' => 'MessageID', 'id_pm_head' => 'ConversationID', 'body' => 'Body', 'format' => 'Format', 'id_member_from' => 'InsertUserID', 'unixmsgtime' => 'DateInserted'); $ex->exportTable('ConversationMessage', "select\n pm.*,\n from_unixtime(pm.msgtime) as unixmsgtime ,\n 'BBCode' as format\n from :_personal_messages pm\n ", $convMsg_Map); $userConv_Map = array('id_member2' => 'UserId', 'id_pm_head' => 'ConversationID', 'deleted2' => 'Deleted'); $ex->exportTable('UserConversation', "(select\n pm.id_member_from as id_member2,\n pm.id_pm_head,\n pm.deleted_by_sender as deleted2\n from :_personal_messages pm )\n UNION ALL\n (select\n pmr.id_member as id_member2,\n pm.id_pm_head,\n pmr.deleted as deleted2\n from :_personal_messages pm join :_pm_recipients pmr on pmr.id_pm = pm.id_pm\n )\n ", $userConv_Map); // End $ex->endExport(); }
/** * Main export process. * * @param ExportModel $ex * @see $_Structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('posts'); if ($characterSet) { $ex->characterSet = $characterSet; } // Reiterate the platform name here to be included in the porter file header. $ex->beginExport('', 'jforum'); // User. $user_Map = array(); $ex->exportTable('User', "\n select\n u.user_id as UserID,\n u.username as Name,\n 'Reset' as HashMethod,\n u.user_email as Email,\n u.user_regdate as DateInserted,\n u.user_regdate as DateFirstVisit,\n u.user_posts as CountComments,\n u.user_avatar as Photo,\n u.deleted as Deleted,\n u.user_from as Location,\n u.user_biography as About\n from :_users as u\n ", $user_Map); // Role. $role_Map = array(); $ex->exportTable('Role', "\n select\n g.group_id as RoleID,\n g.group_name as Name,\n g.group_description as Description\n from :_groups as g\n ", $role_Map); // User Role. $userRole_Map = array(); $ex->exportTable('UserRole', "\n select\n u.user_id as UserID,\n u.group_id as RoleID\n from :_user_groups as u\n ", $userRole_Map); // UserMeta. $ex->exportTable('UserMeta', "\n select\n user_id as UserID,\n 'Profile.Website' as `Name`,\n user_website as `Value`\n from :_users\n where user_website is not null\n\n union\n\n select\n user_id,\n 'Plugins.Signatures.Sig',\n user_sig\n from :_users\n where user_sig is not null\n\n union\n\n select\n user_id,\n 'Plugins.Signatures.Format',\n 'BBCode'\n from :_users\n where user_sig is not null\n\n union\n\n select\n user_id,\n 'Profile.Occupation',\n user_occ\n from :_users\n where user_occ is not null\n\n union\n\n select\n user_id,\n 'Profile.Interests',\n user_interests\n from :_users\n where user_interests is not null\n "); // Category. // _categories is tier 1, _forum is tier 2. // Overlapping IDs, so fast-forward _categories by 1000. $category_Map = array(); $ex->exportTable('Category', "\n select\n c.categories_id+1000 as CategoryID,\n -1 as ParentCategoryID,\n c.title as Name,\n null as Description,\n 1 as Depth,\n c.display_order as Sort\n from :_categories as c\n\n union\n\n select\n f.forum_id as CategoryID,\n f.categories_id+1000 as ParentCategoryID,\n f.forum_name as Name,\n f.forum_desc as Description,\n 2 as Depth,\n null as Sort\n from :_forums as f\n ", $category_Map); if ($ex->exists(':_posts_text')) { $postTextColumm = 't.post_text as Body'; $postTextSource = 'left join :_posts_text t on p.post_id = t.post_id'; } else { $postTextColumm = 'p.post_text as Body'; $postTextSource = ''; } // Discussion. $discussion_Map = array('topic_title' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder')); // It's easier to convert between Unix time and MySQL datestamps during the db query. $ex->exportTable('Discussion', "\n select\n t.topic_id as DiscussionID,\n t.forum_id as CategoryID,\n t.user_id as InsertUserID,\n t.topic_time as DateInserted,\n t.topic_title,\n t.topic_views as CountViews,\n t.topic_replies as CountComments,\n t.topic_status as Closed,\n if (t.topic_type > 0, 1, 0) as Announce,\n {$postTextColumm},\n 'BBCode' as Format\n from :_topics as t\n left join :_posts p on t.topic_first_post_id = p.post_id\n {$postTextSource}\n ", $discussion_Map); // Comment. $comment_Map = array(); $ex->exportTable('Comment', "\n select\n p.post_id as CommentID,\n p.topic_id as DiscussionID,\n p.user_id as InsertUserID,\n p.poster_ip as InsertIPAddress,\n p.post_time as DateInserted,\n p.post_edit_time as DateUpdated,\n 'BBCode' as Format,\n {$postTextColumm}\n from :_posts as p\n {$postTextSource}\n left join jforum_topics as t on t.topic_first_post_id = p.post_id\n where t.topic_first_post_id is null\n ", $comment_Map); // UserDiscussion. // Guessing table is called "_watch" because they are all bookmarks. $userDiscussion_Map = array('topic_id' => 'DiscussionID', 'user_id' => 'UserID'); $ex->exportTable('UserDiscussion', "\n select\n w.topic_id as DiscussionID,\n w.user_id as UserID,\n 1 as Bookmarked,\n if (w.is_read, now(), null) as DateLastViewed\n from :_topics_watch as w\n ", $userDiscussion_Map); // Conversation. // Thread using tmp table based on the pair of users talking. $result = $ex->query('show index from :_privmsgs where Key_name = "ix_zconversation_from_to"', true); if (!mysql_num_rows($result)) { $ex->query('create index ix_zconversation_from_to on :_privmsgs (privmsgs_from_userid, privmsgs_to_userid)'); } $ex->query("drop table if exists z_conversation;"); $ex->query("\n create table z_conversation (\n ConversationID int unsigned not null auto_increment,\n LowUserID int unsigned,\n HighUserID int unsigned,\n primary key (ConversationID),\n index idx_lowuser_highuser (LowUserID, HighUserID)\n ) engine=InnoDB default charset=utf8 collate=utf8_unicode_ci;\n "); $ex->query("\n insert into z_conversation (LowUserID, HighUserID)\n select\n least(privmsgs_from_userid, privmsgs_to_userid),\n greatest(privmsgs_from_userid, privmsgs_to_userid)\n from :_privmsgs\n group by\n least(privmsgs_from_userid, privmsgs_to_userid),\n greatest(privmsgs_from_userid, privmsgs_to_userid)\n "); // Replying on /dba/counts to rebuild most of this data later. $conversation_Map = array('privmsgs_from_userid' => 'InsertUserID', 'privmsgs_date' => 'DateInserted', 'privmsgs_subject' => 'Subject'); $ex->exportTable('Conversation', "\n select\n p.privmsgs_from_userid as InsertUserID,\n p.privmsgs_date as DateInserted,\n p.privmsgs_subject as Subject,\n c.ConversationID\n from :_privmsgs as p\n left join z_conversation as c on c.HighUserID = greatest(p.privmsgs_from_userid, p.privmsgs_to_userid)\n and c.LowUserID = least(p.privmsgs_from_userid, p.privmsgs_to_userid)\n group by\n least(privmsgs_from_userid, privmsgs_to_userid),\n greatest(privmsgs_from_userid, privmsgs_to_userid)\n ", $conversation_Map); // Conversation Message. // Messages with the same timestamps are sent/received copies. // Yes that'd probably break down on huge sites but it's too convenient to pass up for now. $message_Map = array('privmsgs_id' => 'MessageID', 'privmsgs_from_userid' => 'InsertUserID', 'privmsgs_date' => 'DateInserted', 'privmsgs_text' => 'Body'); $ex->exportTable('ConversationMessage', "\n select\n p.privmsgs_id as MessageID,\n p.privmsgs_from_userid as InsertUserID,\n p.privmsgs_date as DateInserted,\n t.privmsgs_text as Body,\n c.ConversationID,\n 'BBCode' as Format\n from :_privmsgs p\n left join :_privmsgs_text t on t.privmsgs_id = p.privmsgs_id\n left join z_conversation c on c.LowUserID = least(privmsgs_from_userid, privmsgs_to_userid)\n and c.HighUserID = greatest(privmsgs_from_userid, privmsgs_to_userid)\n group by privmsgs_date\n ", $message_Map); // UserConversation $ex->exportTable('UserConversation', "\n select\n ConversationID,\n LowUserID as UserID,\n now() as DateLastViewed\n from z_conversation\n\n union\n\n select\n ConversationID,\n HighUserID as UserID,\n now() as DateLastViewed\n from z_conversation\n "); $ex->comment('Run the following query after the import: '); $ex->comment('update GDN_UserConversation set CountReadMessages = (select count(MessageID) from GDN_ConversationMessage where GDN_ConversationMessage.ConversationID = GDN_UserConversation.ConversationID)'); $ex->endExport(); }
/** * * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('Post'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'Toast Forum'); $ex->sourcePrefix = 'tstdb_'; // User. $user_Map = array('ID' => 'UserID', 'Username' => 'Name', 'Email' => 'Email', 'LastLoginDate' => array('Column' => 'DateLastActive', 'Type' => 'datetime'), 'IP' => 'LastIPAddress'); $ex->exportTable('User', "\n select\n *,\n NOW() as DateInserted\n from :_Member u", $user_Map); // Determine safe RoleID to use for non-existant Member role $lastRoleID = 1001; $lastRoleResult = $ex->query("select max(ID) as LastID from :_Group"); if ($lastRoleResult) { $lastRole = mysql_fetch_array($lastRoleResult); $lastRoleID = $lastRole['LastID'] + 1; } // Role. // Add default Member role. $role_Map = array('ID' => 'RoleID', 'Name' => 'Name'); $ex->exportTable('Role', "\n select\n ID,\n Name\n from :_Group\n\n union all\n\n select\n {$lastRoleID} as ID,\n 'Member' as Name\n from :_Group;", $role_Map); // UserRole. // Users without roles get put into new Member role. $userRole_Map = array('MemberID' => 'UserID', 'GroupID' => 'RoleID'); $ex->exportTable('UserRole', "\n select\n GroupID,\n MemberID\n from :_MemberGroupLink\n\n union all\n\n select\n {$lastRoleID} as GroupID,\n m.ID as MemberID\n from :_Member m\n left join :_MemberGroupLink l\n on l.MemberID = m.ID\n where l.GroupID is null", $userRole_Map); // Signatures. $ex->exportTable('UserMeta', "\n select\n ID as UserID,\n 'Plugin.Signatures.Sig' as `Name`,\n Signature as `Value`\n from :_Member\n where Signature <> ''\n\n union all\n\n select\n ID as UserID,\n 'Plugin.Signatures.Format' as `Name`,\n 'BBCode' as `Value`\n from :_Member\n where Signature <> '';"); // Category. $category_Map = array('ID' => 'CategoryID', 'CategoryID' => 'ParentCategoryID', 'ForumName' => 'Name', 'Description' => 'Description'); $ex->exportTable('Category', "\n select\n f.ID,\n f.CategoryID * 1000 as CategoryID,\n f.ForumName,\n f.Description\n from :_Forum f\n\n union all\n\n select\n c.ID * 1000 as ID,\n -1 as CategoryID,\n c.Name as ForumName,\n null as Description\n from :_Category c;", $category_Map); // Discussion. $discussion_Map = array('ID' => 'DiscussionID', 'ForumID' => 'CategoryID', 'MemberID' => 'InsertUserID', 'PostDate' => 'DateInserted', 'ModifyDate' => 'DateUpdated', 'LastPostDate' => 'DateLastComment', 'Subject' => 'Name', 'Message' => 'Body', 'Hits' => 'CountViews', 'ReplyCount' => 'CountComments'); $ex->exportTable('Discussion', "\n select p.*,\n 'Html' as Format\n from :_Post p\n where p.Topic = 1\n and p.Deleted = 0;", $discussion_Map); // Comment. $comment_Map = array('ID' => 'CommentID', 'TopicID' => 'DiscussionID', 'MemberID' => 'InsertUserID', 'PostDate' => 'DateInserted', 'ModifyDate' => 'DateUpdated', 'Message' => 'Body'); $ex->exportTable('Comment', "\n select *,\n 'Html' as Format\n from :_Post p\n where Topic = 0 and Deleted = 0;", $comment_Map); $ex->endExport(); }
/** * Forum-specific export format. * @param ExportModel $Ex */ protected function ForumExport($Ex) { // Begin $Ex->BeginExport('', 'SMF 2.*', array('HashMethod' => 'smf')); // Users $User_Map = array('id_member' => 'UserID', 'member_name' => 'Name', 'passwd' => 'Password', 'email_address' => 'Email', 'timezone_offset' => 'HourOffset', 'posts' => array('Column' => 'CountComments', 'Type' => 'int'), 'birthdate' => 'DateOfBirth'); $Ex->ExportTable('User', "select m.*,\n FROM_UNIXTIME(nullif(m.date_registered, 0)) as DateFirstVisit,\n FROM_UNIXTIME(nullif(m.date_registered, 0)) as DateInserted,\n FROM_UNIXTIME(nullif(m.last_login,0)) as DateLastActive,\n case a.file_hash\n when '' then concat('userpics/',nullif(a.filename,m.avatar))\n else concat('userpics/',a.id_attach,'_',a.file_hash,'.',fileext)\n end as Photo\n from :_members m left join :_attachments a on m.id_member = a.id_member", $User_Map); // ":_" will be replace by database prefix // Roles $Role_Map = array('id_group' => 'RoleID', 'group_name' => 'Name', 'description' => 'Description'); $Ex->ExportTable('Role', "select * from :_membergroups", $Role_Map); // UserRoles $UserRole_Map = array('id_member' => 'UserID', 'id_group' => 'RoleID'); $Ex->ExportTable('UserRole', "select id_member, id_group from :_members where id_group !=0\n union select m.id_member,g.id_group from :_members m join :_membergroups g on find_in_set(g.id_group,m.additional_groups)", $UserRole_Map); // Categories $Category_Map = array('id_board' => 'CategoryID', 'id_parent' => 'ParentCategoryID', 'name' => 'Name', 'description' => 'Description', 'board_order' => 'Sort'); $Ex->ExportTable('Category', "select name,'' description, cat_order board_order, id_cat id_board, 0 id_parent from :_categories\n union select name, description, board_order, id_board+(select max(id_cat) from :_categories) id_board,\n case id_parent when 0 then id_cat else id_parent+(select max(id_cat) from :_categories) end id_parent\n from :_boards b", $Category_Map); // Discussions $Discussion_Map = array('id_topic' => 'DiscussionID', 'id_member_started' => 'InsertUserID', 'num_views' => 'CountViews', 'id_first_msg' => array('Column' => 'FirstCommentID', 'Type' => 'int')); $Ex->ExportTable('Discussion', "select t.*,\n t.id_board+(select max(id_cat) from :_categories) as CategoryID,\n\t\t\t'BBCode' as Format,\n t.num_replies+1 as CountComments,\n case t.locked when 1 then 1 else 0 end as Closed,\n case t.is_sticky when 1 then 1 else 0 end as Announce,\n fm.subject as Name,\n fm.body as Body,\n FROM_UNIXTIME(fm.poster_time) as DateInserted,\n FROM_UNIXTIME(lm.poster_time) as DateUpdated,\n FROM_UNIXTIME(lm.poster_time) as DateLastComment\n from :_topics t\n inner join :_messages fm on t.id_first_msg = fm.id_msg\n inner join :_messages lm on t.id_last_msg = lm.id_msg", $Discussion_Map); // Comments $Comment_Map = array('id_msg' => 'CommentID', 'id_topic' => 'DiscussionID', 'body' => 'Body', 'id_member' => 'InsertUserID'); $Ex->ExportTable('Comment', "select m.*,\n\t\t\t'BBCode' as Format,\n\t\t\tmm.id_member as UpdateUserID,\n FROM_UNIXTIME(m.poster_time) as DateInserted,\n FROM_UNIXTIME(nullif(m.modified_time,0)) as DateUpdated\n from :_messages m left join :_members mm on m.modified_name = mm.member_name\n where m.id_msg not in (select id_first_msg from :_topics)", $Comment_Map); //Media $Media_Map = array('id_attach' => 'MediaID', 'id_msg' => 'ForeignID', 'filename' => 'Name', 'file_hash' => array('Column' => 'Path', 'Filter' => array($this, 'BuildMediaPath')), 'size' => 'Size'); $Ex->ExportTable('Media', "select a.*,\n case fileext\n when 'jpg' then 'image/jpeg'\n when 'jpeg' then 'image/jpeg'\n when 'gif' then 'image/gif'\n when 'png' then 'image/png'\n when 'bmp' then 'image/bmp'\n when 'txt' then 'text/plan'\n when 'htm' then 'text/html'\n when 'html' then 'text/html'\n else 'application/octet-stream'\n end Type,\n m.id_member InsertUserID,\n from_unixtime(m.poster_time) DateInserted,\n 'discussion' ForeignTable\n from :_attachments a join :_messages m on m.id_msg = a.id_msg join :_topics t on a.id_msg = t.id_first_msg\n where attachment_type = 0\n union select a.*,\n case fileext\n when 'jpg' then 'image/jpeg'\n when 'jpeg' then 'image/jpeg'\n when 'gif' then 'image/gif'\n when 'png' then 'image/png'\n when 'bmp' then 'image/bmp'\n when 'txt' then 'text/plan'\n when 'htm' then 'text/html'\n when 'html' then 'text/html'\n else 'application/octet-stream'\n end Type,\n m.id_member InsertUserID,\n from_unixtime(poster_time) DateInserted,\n 'comment' ForeignTable\n from :_attachments a join :_messages m on m.id_msg = a.id_msg\n where a.id_msg not in (select id_first_msg from :_topics t) and attachment_type = 0\n ", $Media_Map); // Conversations $Conversation_Map = array('id_pm_head' => 'ConversationID', 'id_pm' => 'FirstMessageID', 'id_member_from' => 'InsertUserID'); $Ex->ExportTable('Conversation', "select pm.id_pm_head, pm.id_pm,\n from_unixtime(pm.msgtime) DateInserted,\n pm.id_member_from,\n pm_last.id_member_from UpdateUserID,\n from_unixtime(pm_last.msgtime) DateUpdated\n from :_personal_messages pm\n join (select pm.id_pm_head,pm.id_member_from, max(pm.msgtime) msgtime\n from :_personal_messages pm\n group by pm.id_pm_head,pm.id_member_from) pm_last\n on pm_last.id_pm_head = pm.id_pm_head\n where pm.id_pm = pm.id_pm_head", $Conversation_Map); // Conversation Messages $ConversationMessage_Map = array('id_pm' => 'MessageID', 'id_pm_head' => 'ConversationID', 'body' => 'Body', 'id_member_from' => 'InsertUserID'); $Ex->ExportTable('ConversationMessage', "select pm.*,\n 'BBCode' Format,\n from_unixtime(pm.msgtime) DateInserted\n from :_personal_messages pm", $ConversationMessage_Map); // User Conversation $UserConversation_Map = array('id_member_from' => 'UserID', 'id_pm_head' => 'ConversationID', 'id_pm' => 'LastMessageID'); $Ex->ExportTable('UserConversation', "\n select pm.id_member_from,\n pm.id_pm_head, pm.deleted_by_sender Deleted, pm_agr.id_pm, pm_agr.count CountReadMessages\n from :_personal_messages pm\n join (select id_pm_head, max(id_pm) id_pm, count(id_pm) count\n from :_personal_messages\n group by id_pm_head) pm_agr\n on pm.id_pm_head = pm_agr.id_pm_head\n union\n select pmr.id_member id_member_from,pm.id_pm_head,\n pmr.deleted Deleted, pm_agr.id_pm, pm_agr.count CountReadMessages\n from :_personal_messages pm\n join :_pm_recipients pmr on pm.id_pm = pmr.id_pm\n join (select id_pm_head, max(id_pm) id_pm, count(id_pm) count\n from :_personal_messages\n group by id_pm_head) pm_agr\n on pm.id_pm_head = pm_agr.id_pm_head", $UserConversation_Map); // End $Ex->EndExport(); }
/** * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('mbox'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->destPrefix = 'jos'; $ex->beginExport('', 'Joomla Kunena', array('HashMethod' => 'joomla')); // User. $user_Map = array('id' => 'UserID', 'name' => 'Name', 'email' => 'Email', 'registerDate' => 'DateInserted', 'lastvisitDate' => 'DateLastActive', 'password' => 'Password', 'showemail' => 'ShowEmail', 'birthdate' => 'DateOfBirth', 'banned' => 'Banned', 'admin' => array('Column' => 'Admin', 'Type' => 'tinyint(1)'), 'Photo' => 'Photo'); $ex->exportTable('User', "\n SELECT\n u.*,\n case when ku.avatar <> '' then concat('kunena/avatars/', ku.avatar) else null end as `Photo`,\n case u.usertype when 'superadministrator' then 1 else 0 end as admin,\n coalesce(ku.banned, 0) as banned,\n ku.birthdate,\n !ku.hideemail as showemail\n FROM :_users u\n left join :_kunena_users ku\n on ku.userid = u.id", $user_Map); // Role. $role_Map = array('rank_id' => 'RoleID', 'rank_title' => 'Name'); $ex->exportTable('Role', "select * from :_kunena_ranks", $role_Map); // UserRole. $userRole_Map = array('id' => 'UserID', 'rank' => 'RoleID'); $ex->exportTable('UserRole', "\n select *\n from :_users u", $userRole_Map); // Permission. // $ex->ExportTable('Permission', // "select 2 as RoleID, 'View' as _Permissions // union // select 3 as RoleID, 'View' as _Permissions // union // select 16 as RoleID, 'All' as _Permissions", array('_Permissions' => array('Column' => '_Permissions', 'Type' => 'varchar(20)'))); // Category. $category_Map = array('id' => 'CategoryID', 'parent' => 'ParentCategoryID', 'name' => 'Name', 'ordering' => 'Sort', 'description' => 'Description'); $ex->exportTable('Category', "\n select * from :_kunena_categories", $category_Map); // Discussion. $discussion_Map = array('id' => 'DiscussionID', 'catid' => 'CategoryID', 'userid' => 'InsertUserID', 'subject' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'time' => array('Column' => 'DateInserted', 'Filter' => 'timestampToDate'), 'ip' => 'InsertIPAddress', 'locked' => 'Closed', 'hits' => 'CountViews', 'modified_by' => 'UpdateUserID', 'modified_time' => array('Column' => 'DateUpdated', 'Filter' => 'timestampToDate'), 'message' => 'Body', 'Format' => 'Format'); $ex->exportTable('Discussion', "\n select\n t.*,\n txt.message,\n 'BBCode' as Format\n from :_kunena_messages t\n left join :_kunena_messages_text txt\n on t.id = txt.mesid\n where t.thread = t.id", $discussion_Map); // Comment. $comment_Map = array('id' => 'CommentID', 'thread' => 'DiscussionID', 'userid' => 'InsertUserID', 'time' => array('Column' => 'DateInserted', 'Filter' => 'timestampToDate'), 'ip' => 'InsertIPAddress', 'modified_by' => 'UpdateUserID', 'modified_time' => array('Column' => 'DateUpdated', 'Filter' => 'timestampToDate'), 'message' => 'Body', 'Format' => 'Format'); $ex->exportTable('Comment', "\n select\n t.*,\n txt.message,\n 'BBCode' as Format\n from :_kunena_messages t\n left join :_kunena_messages_text txt\n on t.id = txt.mesid\n where t.thread <> t.id", $comment_Map); // UserDiscussion. $userDiscussion_Map = array('thread' => 'DiscussionID', 'userid' => 'UserID'); $ex->exportTable('UserDiscussion', "\n select t.*, 1 as Bookmarked\n from :_kunena_subscriptions t", $userDiscussion_Map); // Media. $media_Map = array('id' => 'MediaID', 'mesid' => 'ForeignID', 'userid' => 'InsertUserID', 'size' => 'Size', 'path2' => array('Column' => 'Path', 'Filter' => 'urlDecode'), 'thumb_path' => array('Column' => 'ThumbPath', 'Filter' => array($this, 'filterThumbnailData')), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData')), 'filetype' => 'Type', 'filename' => array('Column' => 'Name', 'Filter' => 'urlDecode'), 'time' => array('Column' => 'DateInserted', 'Filter' => 'timestampToDate')); $ex->exportTable('Media', "\n select\n a.*,\n concat(a.folder, '/', a.filename) as path2,\n case when m.id = m.thread then 'discussion' else 'comment' end as ForeignTable,\n m.time,\n concat(a.folder, '/', a.filename) as thumb_path,\n 128 as thumb_width\n from :_kunena_attachments a\n join :_kunena_messages m\n on m.id = a.mesid", $media_Map); $ex->endExport(); }
/** * Forum-specific export format * * @todo Project file size / export time and possibly break into multiple files * * @param ExportModel $ex * */ protected function forumExport($ex) { $characterSet = $ex->getCharacterSet('posts'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'PunBB 1.*', array('HashMethod' => 'punbb')); $this->cdn = $this->param('cdn', ''); if ($avatarPath = $this->param('avatarpath', false)) { if (!($avatarPath = realpath($avatarPath))) { echo "Unable to access path to avatars: {$avatarPath}\n"; exit(1); } $this->avatarPath = $avatarPath; } unset($avatarPath); // User. $user_Map = array('AvatarID' => array('Column' => 'Photo', 'Filter' => array($this, 'getAvatarByID')), 'id' => 'UserID', 'username' => 'Name', 'email' => 'Email', 'timezone' => 'HourOffset', 'registration_ip' => 'InsertIPAddress', 'PasswordHash' => 'Password'); $ex->exportTable('User', "\n SELECT\n u.*, u.id AS AvatarID,\n concat(u.password, '\$', u.salt) AS PasswordHash,\n from_unixtime(registered) AS DateInserted,\n from_unixtime(last_visit) AS DateLastActive\n FROM :_users u\n WHERE group_id <> 2", $user_Map); // Role. $role_Map = array('g_id' => 'RoleID', 'g_title' => 'Name'); $ex->exportTable('Role', "SELECT * FROM :_groups", $role_Map); // Permission. $permission_Map = array('g_id' => 'RoleID', 'g_modertor' => 'Garden.Moderation.Manage', 'g_mod_edit_users' => 'Garden.Users.Edit', 'g_mod_rename_users' => 'Garden.Users.Delete', 'g_read_board' => 'Vanilla.Discussions.View', 'g_view_users' => 'Garden.Profiles.View', 'g_post_topics' => 'Vanilla.Discussions.Add', 'g_post_replies' => 'Vanilla.Comments.Add', 'g_pun_attachment_allow_download' => 'Plugins.Attachments.Download.Allow', 'g_pun_attachment_allow_upload' => 'Plugins.Attachments.Upload.Allow'); $permission_Map = $ex->fixPermissionColumns($permission_Map); $ex->exportTable('Permission', "\n SELECT\n g.*,\n g_post_replies AS `Garden.SignIn.Allow`,\n g_mod_edit_users AS `Garden.Users.Add`,\n CASE WHEN g_title = 'Administrators' THEN 'All' ELSE NULL END AS _Permissions\n FROM :_groups g", $permission_Map); // UserRole. $userRole_Map = array('id' => 'UserID', 'group_id' => 'RoleID'); $ex->exportTable('UserRole', "SELECT\n CASE u.group_id WHEN 2 THEN 0 ELSE id END AS id,\n u.group_id\n FROM :_users u", $userRole_Map); // Signatures. $ex->exportTable('UserMeta', "\n SELECT\n id,\n 'Plugin.Signatures.Sig' AS Name,\n signature\n FROM :_users u\n WHERE u.signature IS NOT NULL", array('id ' => 'UserID', 'signature' => 'Value')); // Category. $category_Map = array('id' => 'CategoryID', 'forum_name' => 'Name', 'forum_desc' => 'Description', 'disp_position' => 'Sort', 'parent_id' => 'ParentCategoryID'); $ex->exportTable('Category', "\n SELECT\n id,\n forum_name,\n forum_desc,\n disp_position,\n cat_id * 1000 AS parent_id\n FROM :_forums f\n UNION\n\n SELECT\n id * 1000,\n cat_name,\n '',\n disp_position,\n NULL\n FROM :_categories", $category_Map); // Discussion. $discussion_Map = array('id' => 'DiscussionID', 'poster_id' => 'InsertUserID', 'poster_ip' => 'InsertIPAddress', 'closed' => 'Closed', 'sticky' => 'Announce', 'forum_id' => 'CategoryID', 'subject' => 'Name', 'message' => 'Body'); $ex->exportTable('Discussion', "\n SELECT t.*,\n from_unixtime(p.posted) AS DateInserted,\n p.poster_id,\n p.poster_ip,\n p.message,\n from_unixtime(p.edited) AS DateUpdated,\n eu.id AS UpdateUserID,\n 'BBCode' AS Format\n FROM :_topics t\n LEFT JOIN :_posts p\n ON t.first_post_id = p.id\n LEFT JOIN :_users eu\n ON eu.username = p.edited_by", $discussion_Map); // Comment. $comment_Map = array('id' => 'CommentID', 'topic_id' => 'DiscussionID', 'poster_id' => 'InsertUserID', 'poster_ip' => 'InsertIPAddress', 'message' => 'Body'); $ex->exportTable('Comment', "\n SELECT p.*,\n 'BBCode' AS Format,\n from_unixtime(p.posted) AS DateInserted,\n from_unixtime(p.edited) AS DateUpdated,\n eu.id AS UpdateUserID\n FROM :_topics t\n JOIN :_posts p\n ON t.id = p.topic_id\n LEFT JOIN :_users eu\n ON eu.username = p.edited_by\n WHERE p.id <> t.first_post_id;", $comment_Map); if ($ex->exists('tags')) { // Tag. $tag_Map = array('id' => 'TagID', 'tag' => 'Name'); $ex->exportTable('Tag', "SELECT * FROM :_tags", $tag_Map); // TagDisucssion. $tagDiscussionMap = array('topic_id' => 'DiscussionID', 'tag_id' => 'TagID'); $ex->exportTable('TagDiscussion', "SELECT * FROM :_topic_tags", $tagDiscussionMap); } if ($ex->exists('attach_files')) { // Media. $media_Map = array('id' => 'MediaID', 'filename' => 'Name', 'file_mime_type' => 'Type', 'size' => 'Size', 'owner_id' => 'InsertUserID', 'thumb_path' => array('Column' => 'ThumbPath', 'Filter' => array($this, 'filterThumbnailData')), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData'))); $ex->exportTable('Media', "\n select f.*,\n concat({$this->cdn}, 'FileUpload/', f.file_path) as Path,\n concat({$this->cdn}, 'FileUpload/', f.file_path) as thumb_path,\n 128 as thumb_width,\n from_unixtime(f.uploaded_at) as DateInserted,\n case when post_id is null then 'Discussion' else 'Comment' end as ForeignTable,\n coalesce(post_id, topic_id) as ForieignID\n from :_attach_files f\n ", $media_Map); } // End $ex->endExport(); }
/** * Export the attachments as Media. * * In vBulletin 4.x, the filedata table was introduced. */ public function exportMedia($minDiscussionID = false) { $ex = $this->ex; $instance = $this; if ($minDiscussionID) { $discussionWhere = "and t.threadid > {$minDiscussionID}"; } else { $discussionWhere = ''; } $media_Map = array('attachmentid' => 'MediaID', 'filename' => 'Name', 'filesize' => 'Size', 'userid' => 'InsertUserID', 'extension' => array('Column' => 'Type', 'Filter' => array($this, 'buildMimeType')), 'filehash' => array('Column' => 'Path', 'Filter' => array($this, 'buildMediaPath')), 'filethumb' => array('Column' => 'ThumbPath', 'Filter' => function ($value, $field, $row) use($instance) { $filteredData = $this->filterThumbnailData($value, $field, $row); if ($filteredData) { return $instance->buildMediaPath($value, $field, $row); } else { return null; } }), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData')), 'height' => array('Column' => 'ImageHeight', 'Filter' => array($this, 'buildMediaDimension')), 'width' => array('Column' => 'ImageWidth', 'Filter' => array($this, 'buildMediaDimension'))); // Add hash fields if they exist (from 2.x) $attachColumns = array('hash', 'filehash'); $missing = $ex->exists('attachment', $attachColumns); $attachColumnsString = ''; foreach ($attachColumns as $columnName) { if (in_array($columnName, $missing)) { $attachColumnsString .= ", null as {$columnName}"; } else { $attachColumnsString .= ", a.{$columnName}"; } } // Do the export if ($ex->exists('attachment', array('contenttypeid', 'contentid')) === true) { // Exporting 4.x with 'filedata' table. // Build an index to join on. $result = $ex->query('show index from :_thread where Key_name = "ix_thread_firstpostid"'); if (!$result) { $ex->query('create index ix_thread_firstpostid on :_thread (firstpostid)'); } $mediaSql = "\n select\n case\n when t.threadid is not null then 'discussion'\n when ct.class = 'Post' then 'comment'\n when ct.class = 'Thread' then 'discussion'\n else ct.class\n end as ForeignTable,\n case\n when t.threadid is not null then t.threadid\n else a.contentid\n end as ForeignID,\n FROM_UNIXTIME(a.dateline) as DateInserted,\n a.*,\n f.extension,\n f.filesize/*,*/\n {$attachColumnsString},\n f.width,\n f.height,\n 'mock_value' as filethumb,\n 128 as thumb_width\n from :_attachment a\n join :_contenttype ct on a.contenttypeid = ct.contenttypeid\n join :_filedata f on f.filedataid = a.filedataid\n left join :_thread t on t.firstpostid = a.contentid and a.contenttypeid = 1\n where a.contentid > 0\n {$discussionWhere}\n "; $ex->exportTable('Media', $mediaSql, $media_Map); } else { // Exporting 3.x without 'filedata' table. // Do NOT grab every field to avoid 'filedata' blob in 3.x. // Left join 'attachment' because we can't left join 'thread' on firstpostid (not an index). // Lie about the height & width to spoof FileUpload serving generic thumbnail if they aren't set. $extension = ExportModel::fileExtension('a.filename'); $mediaSql = "\n select\n a.attachmentid,\n a.filename,\n {$extension} as extension/*,*/\n {$attachColumnsString},\n a.userid,\n 'discussion' as ForeignTable,\n t.threadid as ForeignID,\n FROM_UNIXTIME(a.dateline) as DateInserted,\n '1' as height,\n '1' as width,\n 'mock_value' as filethumb,\n 128 as thumb_width\n from :_thread t\n left join :_attachment a ON a.postid = t.firstpostid\n where a.attachmentid > 0\n\n union all\n\n select\n a.attachmentid,\n a.filename,\n {$extension} as extension/*,*/\n {$attachColumnsString},\n a.userid,\n 'comment' as ForeignTable,\n a.postid as ForeignID,\n FROM_UNIXTIME(a.dateline) as DateInserted,\n '1' as height,\n '1' as width,\n 'mock_value' as filethumb,\n 128 as thumb_width\n from :_post p\n inner join :_thread t ON p.threadid = t.threadid\n left join :_attachment a ON a.postid = p.postid\n where p.postid <> t.firstpostid and a.attachmentid > 0\n "; $ex->exportTable('Media', $mediaSql, $media_Map); } // files named .attach need to be named properly. // file needs to be renamed and db updated. // if its an images; we need to include .thumb $attachmentPath = $this->param('filepath'); if ($attachmentPath) { $missingFiles = array(); if (is_dir($attachmentPath)) { $ex->comment("Checking files"); $result = $ex->query($mediaSql); while ($row = mysql_fetch_assoc($result)) { $filePath = $this->buildMediaPath('', '', $row); $cdn = $this->param('cdn', ''); if (!empty($cdn)) { $filePath = str_replace($cdn, '', $filePath); } $fullPath = $attachmentPath . $filePath; if (file_exists($fullPath)) { continue; } //check if named .attach $p = explode('.', $fullPath); $attachFilename = str_replace(end($p), 'attach', $fullPath); if (file_exists($attachFilename)) { // rename file rename($attachFilename, $fullPath); continue; } //check if md5 hash in root if (getValue('hash', $row)) { $md5Filename = $attachmentPath . $row['hash'] . '.' . $row['extension']; if (file_exists($md5Filename)) { // rename file rename($md5Filename, $fullPath); continue; } } $missingFiles[] = $filePath; } } else { $ex->comment('Attachment Path not found'); } $totalMissingFiles = count($missingFiles); if ($totalMissingFiles > 0) { $ex->comment('Missing files detected. See ./missing_files.txt for full list.'); $ex->comment(sprintf('Total missing files %d', $totalMissingFiles)); file_put_contents('missing-files.txt', implode("\n", $missingFiles)); } } }
/** * * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('nodes'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'vBulletin 5 Connect'); $this->exportBlobs($this->param('files'), $this->param('avatars')); if ($this->param('noexport')) { $ex->comment('Skipping the export.'); $ex->endExport(); return; } $cdn = $this->param('cdn', ''); // Grab all of the ranks. $ranks = $ex->get("select * from :_usertitle order by minposts desc", 'usertitleid'); // Users $user_Map = array('userid' => 'UserID', 'username' => 'Name', 'password2' => 'Password', 'email' => 'Email', 'referrerid' => 'InviteUserID', 'timezoneoffset' => 'HourOffset', 'ipaddress' => 'LastIPAddress', 'ipaddress2' => 'InsertIPAddress', 'usertitle' => 'Title', 'posts' => array('Column' => 'RankID', 'Filter' => function ($value) use($ranks) { // Look up the posts in the ranks table. foreach ($ranks as $rankID => $row) { if ($value >= $row['minposts']) { return $rankID; } } return null; })); // Use file avatar or the result of our blob export? if ($this->getConfig('usefileavatar')) { $user_Map['filephoto'] = 'Photo'; } else { $user_Map['customphoto'] = 'Photo'; } // vBulletin 5.1 changes the hash to crypt(md5(password), hash). // Switches from password & salt to token (and scheme & secret). // The scheme appears to be crypt()'s default and secret looks uselessly redundant. if ($ex->exists('user', 'token') !== true) { $passwordSQL = "concat(`password`, salt) as password2, 'vbulletin' as HashMethod,"; } else { // vB 5.1 already concats the salt to the password as token, BUT ADDS A SPACE OF COURSE. $passwordSQL = "replace(token, ' ', '') as password2, case when scheme = 'legacy' then 'vbulletin' else 'vbulletin5' end as HashMethod,"; } $ex->exportTable('User', "\n select\n u.*,\n ipaddress as ipaddress2,\n {$passwordSQL}\n DATE_FORMAT(birthday_search,GET_FORMAT(DATE,'ISO')) as DateOfBirth,\n FROM_UNIXTIME(joindate) as DateFirstVisit,\n FROM_UNIXTIME(lastvisit) as DateLastActive,\n FROM_UNIXTIME(joindate) as DateInserted,\n FROM_UNIXTIME(lastactivity) as DateUpdated,\n case when avatarrevision > 0 then concat('{$cdn}', 'userpics/avatar', u.userid, '_', avatarrevision, '.gif')\n when av.avatarpath is not null then av.avatarpath\n else null\n end as filephoto,\n {$this->avatarSelect},\n case when ub.userid is not null then 1 else 0 end as Banned\n from :_user u\n left join :_customavatar a on u.userid = a.userid\n left join :_avatar av on u.avatarid = av.avatarid\n left join :_userban ub\n on u.userid = ub.userid\n and ub.liftdate <= now()\n ;", $user_Map); // ":_" will be replace by database prefix //ipdata - contains all IP records for user actions: view,visit,register,logon,logoff // Roles $role_Map = array('usergroupid' => 'RoleID', 'title' => 'Name', 'description' => 'Description'); $ex->exportTable('Role', 'select * from :_usergroup', $role_Map); // UserRoles $userRole_Map = array('userid' => 'UserID', 'usergroupid' => 'RoleID'); $ex->query("CREATE TEMPORARY TABLE VbulletinRoles (userid INT UNSIGNED not null, usergroupid INT UNSIGNED not null)"); # Put primary groups into tmp table $ex->query("insert into VbulletinRoles (userid, usergroupid) select userid, usergroupid from :_user"); # Put stupid CSV column into tmp table $secondaryRoles = $ex->query("select userid, usergroupid, membergroupids from :_user", true); if (is_resource($secondaryRoles)) { while (($row = @mysql_fetch_assoc($secondaryRoles)) !== false) { if ($row['membergroupids'] != '') { $groups = explode(',', $row['membergroupids']); foreach ($groups as $groupID) { $ex->query("insert into VbulletinRoles (userid, usergroupid) values({$row['userid']},{$groupID})", true); } } } } # Export from our tmp table and drop $ex->exportTable('UserRole', 'select distinct userid, usergroupid from VbulletinRoles', $userRole_Map); $ex->query("DROP TABLE IF EXISTS VbulletinRoles"); // Permissions. $permissions_Map = array('usergroupid' => 'RoleID', 'title' => array('Column' => 'Garden.SignIn.Allow', 'Filter' => array($this, 'signInPermission')), 'genericpermissions' => array('Column' => 'GenericPermissions', 'type' => 'int'), 'forumpermissions' => array('Column' => 'ForumPermissions', 'type' => 'int')); $this->addPermissionColumns(self::$permissions, $permissions_Map); $ex->exportTable('Permission', 'select * from :_usergroup', $permissions_Map); // UserMeta /*$ex->Query("CREATE TEMPORARY TABLE VbulletinUserMeta (`UserID` INT not null ,`Name` VARCHAR( 255 ) not null ,`Value` text not null)"); # Standard vB user data $UserFields = array('usertitle' => 'Title', 'homepage' => 'Website', 'skype' => 'Skype', 'styleid' => 'StyleID'); foreach($UserFields as $Field => $InsertAs) $ex->Query("insert into VbulletinUserMeta (UserID, Name, Value) select userid, 'Profile.$InsertAs', $Field from :_user where $Field != ''"); # Dynamic vB user data (userfield) $ProfileFields = $ex->Query("select varname, text from :_phrase where product='vbulletin' and fieldname='cprofilefield' and varname like 'field%_title'"); if (is_resource($ProfileFields)) { $ProfileQueries = array(); while ($Field = @mysql_fetch_assoc($ProfileFields)) { $Column = str_replace('_title', '', $Field['varname']); $Name = preg_replace('/[^a-zA-Z0-9_-\s]/', '', $Field['text']); $ProfileQueries[] = "insert into VbulletinUserMeta (UserID, Name, Value) select userid, 'Profile.".$Name."', ".$Column." from :_userfield where ".$Column." != ''"; } foreach ($ProfileQueries as $Query) { $ex->Query($Query); } }*/ // Ranks $rank_Map = array('usertitleid' => 'RankID', 'title' => 'Name', 'title2' => 'Label', 'minposts' => array('Column' => 'Attributes', 'Filter' => function ($value) { $result = array('Criteria' => array('CountPosts' => $value)); return serialize($result); }), 'level' => array('Column' => 'Level', 'Filter' => function ($value) { static $level = 1; return $level++; })); $ex->exportTable('Rank', "\n select\n ut.*,\n ut.title as title2,\n 0 as level\n from :_usertitle ut\n order by ut.minposts\n ;", $rank_Map); /// Signatures // usertextfields.signature // Ignore // usertextfields.ignorelist /// Notes /// Warnings /// Activity (Wall) // Category. $channels = array(); $categoryIDs = array(); $homeID = 0; $privateMessagesID = 0; // Filter Channels down to Forum tree $channelResult = $ex->query("\n select\n n.*\n from :_node n\n left join :_contenttype ct on n.contenttypeid = ct.contenttypeid\n where ct.class = 'Channel'\n ;"); while ($channel = mysql_fetch_array($channelResult)) { $channels[$channel['nodeid']] = $channel; if ($channel['title'] == 'Forum') { $homeID = $channel['nodeid']; } if ($channel['title'] == 'Private Messages') { $privateMessagesID = $channel['nodeid']; } } if (!$homeID) { exit("Missing node 'Forum'"); } // Go thru the category list 6 times to build a (up to) 6-deep hierarchy $categoryIDs[] = $homeID; for ($i = 0; $i < 6; $i++) { foreach ($channels as $channel) { if (in_array($channel['nodeid'], $categoryIDs)) { continue; } if (in_array($channel['parentid'], $categoryIDs)) { $categoryIDs[] = $channel['nodeid']; } } } // Drop 'Forum' from the tree if (($key = array_search($homeID, $categoryIDs)) !== false) { unset($categoryIDs[$key]); } $category_Map = array('nodeid' => 'CategoryID', 'title' => 'Name', 'description' => 'Description', 'userid' => 'InsertUserID', 'parentid' => 'ParentCategoryID', 'urlident' => 'UrlCode', 'displayorder' => array('Column' => 'Sort', 'Type' => 'int'), 'lastcontentid' => 'LastDiscussionID', 'textcount' => 'CountComments', 'totalcount' => 'CountDiscussions'); // Categories are Channels that were found in the Forum tree // If parent was 'Forum' set the parent to Root instead (-1) $ex->exportTable('Category', "\n select\n n.*,\n FROM_UNIXTIME(publishdate) as DateInserted,\n if(parentid={$homeID},-1,parentid) as parentid\n from :_node n\n where nodeid in (" . implode(',', $categoryIDs) . ")\n ;", $category_Map); /// Permission //permission - nodeid,(user)groupid, and it gets worse from there. // Discussion. $discussion_Map = array('nodeid' => 'DiscussionID', 'type' => 'Type', 'title' => 'Name', 'userid' => 'InsertUserID', 'rawtext' => 'Body', 'parentid' => 'CategoryID', 'lastcontentid' => 'LastCommentID', 'lastauthorid' => 'LastCommentUserID'); $discussionQuery = "\n select\n n.nodeid,\n null as type,\n n.title,\n n.userid,\n t.rawtext,\n n.parentid,\n n.lastcontentid,\n n.lastauthorid,\n 'BBCode' as Format,\n FROM_UNIXTIME(publishdate) as DateInserted,\n v.count as CountViews,\n convert(ABS(n.open-1),char(1)) as Closed,\n if(convert(n.sticky,char(1))>0,2,0) as Announce,\n null as PollID\n from :_node n\n left join :_contenttype ct on n.contenttypeid = ct.contenttypeid\n left join :_nodeview v on v.nodeid = n.nodeid\n left join :_text t on t.nodeid = n.nodeid\n where ct.class = 'Text'\n and n.showpublished = 1\n and parentid in (" . implode(',', $categoryIDs) . ")\n ;"; // Polls need to be wrapped in a discussion so we are gonna need to postpone discussion creations if ($this->_getPollsCount()) { // NOTE: Only polls that are directly under a channel (discussion) will be exported. // Vanilla poll plugin does not support polls as comments. $ex->query("drop table if exists vBulletinDiscussionTable;"); // Create a temporary table to hold old discussions and to create new discussions for polls $ex->query("\n create table `vBulletinDiscussionTable` (\n `nodeid` int(10) unsigned not null AUTO_INCREMENT,\n `type` varchar(10) default null,\n `title` varchar(255) default null,\n `userid` int(10) unsigned default null,\n `rawtext` mediumtext,\n `parentid` int(11) not null,\n `lastcontentid` int(11) not null default '0',\n `lastauthorid` int(10) unsigned not null default '0',\n `Format` varchar(10) not null,\n `DateInserted` datetime not null,\n `CountViews` int(11) not null default '1',\n `Closed` tinyint(4) not null default '0',\n `Announce` tinyint(4) not null default '0',\n `PollID` int(10) unsigned, /* used to create poll->discussion mapping */\n primary key (`nodeid`)\n )\n ;"); $ex->query("insert into vBulletinDiscussionTable {$discussionQuery}"); $this->_generatePollsDiscussion(); // Export discussions $sql = "\n select\n nodeid,\n type,\n title,\n userid,\n rawtext,\n parentid,\n lastcontentid,\n lastauthorid,\n Format,\n DateInserted,\n CountViews,\n Closed,\n Announce\n from vBulletinDiscussionTable\n ;"; $ex->exportTable('Discussion', $sql, $discussion_Map); // Export polls $this->_exportPolls(); // Cleanup tmp table $ex->query("drop table vBulletinDiscussionTable;"); } else { $ex->exportTable('Discussion', $discussionQuery, $discussion_Map); } // UserDiscussion $userDiscussion_Map = array('discussionid' => 'DiscussionID', 'userid' => 'InsertUserID'); // Should be able to inner join `discussionread` for DateLastViewed // but it's blank in my sample data so I don't trust it. $ex->exportTable('UserDiscussion', "\n select\n s.*,\n 1 as Bookmarked,\n NOW() as DateLastViewed\n from :_subscribediscussion s\n ;", $userDiscussion_Map); // Comment. $comment_Map = array('nodeid' => 'CommentID', 'rawtext' => 'Body', 'userid' => 'InsertUserID', 'parentid' => 'DiscussionID'); $ex->exportTable('Comment', "\n select\n n.*,\n t.rawtext,\n 'BBCode' as Format,\n FROM_UNIXTIME(publishdate) as DateInserted\n from :_node n\n left join :_contenttype c on n.contenttypeid = c.contenttypeid\n left join :_text t on t.nodeid = n.nodeid\n where c.class = 'Text'\n and n.showpublished = 1\n and parentid not in (" . implode(',', $categoryIDs) . ")\n ;", $comment_Map); /// Drafts // autosavetext table $instance = $this; // Media $media_Map = array('nodeid' => 'MediaID', 'filename' => 'Name', 'extension' => array('Column' => 'Type', 'Filter' => array($this, 'buildMimeType')), 'Path2' => array('Column' => 'Path', 'Filter' => array($this, 'buildMediaPath')), 'ThumbPath2' => array('Column' => 'ThumbPath', 'Filter' => function ($value, $field, $row) use($instance) { $filteredData = $this->filterThumbnailData($value, $field, $row); if ($filteredData) { return $instance->buildMediaPath($value, $field, $row); } else { return null; } }), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData')), 'width' => 'ImageWidth', 'height' => 'ImageHeight', 'filesize' => 'Size'); $ex->exportTable('Media', "\n select\n a.*,\n filename as Path2,\n filename as ThumbPath2,\n 128 as thumb_width,\n FROM_UNIXTIME(f.dateline) as DateInserted,\n f.userid as userid,\n f.userid as InsertUserID,\n if (f.width,f.width,1) as width,\n if (f.height,f.height,1) as height,\n n.parentid as ForeignID,\n f.extension,\n f.filesize,\n if(n2.parentid in (" . implode(',', $categoryIDs) . "),'discussion','comment') as ForeignTable\n from :_attach a\n left join :_node n on n.nodeid = a.nodeid\n left join :_filedata f on f.filedataid = a.filedataid\n left join :_node n2 on n.parentid = n2.nodeid\n where a.visible = 1\n ;", $media_Map); // left join :_contenttype c on n.contenttypeid = c.contenttypeid // Conversations. $conversation_Map = array('nodeid' => 'ConversationID', 'userid' => 'InsertUserID', 'totalcount' => 'CountMessages', 'title' => 'Subject'); $ex->exportTable('Conversation', "\n select\n n.*,\n n.nodeid as FirstMessageID,\n FROM_UNIXTIME(n.publishdate) as DateInserted\n from :_node n\n left join :_text t on t.nodeid = n.nodeid\n where parentid = {$privateMessagesID}\n and t.rawtext <> ''\n ;", $conversation_Map); // Conversation Messages. $conversationMessage_Map = array('nodeid' => 'MessageID', 'rawtext' => 'Body', 'userid' => 'InsertUserID'); $ex->exportTable('ConversationMessage', "\n select\n n.*,\n t.rawtext,\n 'BBCode' as Format,\n if(n.parentid<>{$privateMessagesID},n.parentid,n.nodeid) as ConversationID,\n FROM_UNIXTIME(n.publishdate) as DateInserted\n from :_node n\n left join :_contenttype c on n.contenttypeid = c.contenttypeid\n left join :_text t on t.nodeid = n.nodeid\n where c.class = 'PrivateMessage'\n and t.rawtext <> ''\n ;", $conversationMessage_Map); // User Conversation. $userConversation_Map = array('userid' => 'UserID', 'nodeid' => 'ConversationID', 'deleted' => 'Deleted'); // would be nicer to do an intermediary table to sum s.msgread for uc.CountReadMessages $ex->exportTable('UserConversation', "\n select\n s.*\n from :_sentto s\n ;", $userConversation_Map); /// Groups // class='SocialGroup' // class='SocialGroupDiscussion' // class='SocialGroupMessage' $ex->endExport(); }
/** * Forum-specific export format. * @param ExportModel $ex */ protected function forumExport($ex) { $characterSet = $ex->getCharacterSet('posts'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->sourcePrefix = 'phpbb_'; // Begin $ex->beginExport('', 'phpBB 3.*', array('HashMethod' => 'phpBB')); // Users. // Grab the avatar salt. $px = $ex->getValue("select config_value from :_config where config_name = 'avatar_salt'", ''); $cdn = $this->param('cdn', ''); $user_Map = array('user_id' => 'UserID', 'username' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'user_password' => 'Password', 'user_email' => 'Email', 'user_timezone' => 'HourOffset', 'user_posts' => array('Column' => 'CountComments', 'Type' => 'int'), 'photo' => 'Photo', 'user_rank' => 'RankID', 'user_ip' => 'LastIPAddress'); $ex->exportTable('User', "select *,\n case user_avatar_type\n when 1 then concat('{$cdn}', 'phpbb/', '{$px}', '_', user_id, substr(user_avatar from locate('.', user_avatar)))\n when 2 then user_avatar\n else null end as photo,\n FROM_UNIXTIME(nullif(user_regdate, 0)) as DateFirstVisit,\n FROM_UNIXTIME(nullif(user_lastvisit, 0)) as DateLastActive,\n FROM_UNIXTIME(nullif(user_regdate, 0)) as DateInserted,\n ban_userid is not null as Banned\n from :_users\n left join :_banlist bl ON (ban_userid = user_id)\n ", $user_Map); // ":_" will be replace by database prefix // Roles $role_Map = array('group_id' => 'RoleID', 'group_name' => 'Name', 'group_desc' => 'Description'); $ex->exportTable('Role', 'select * from :_groups', $role_Map); $this->exportUserNotes(); // Ranks. $rank_Map = array('rank_id' => 'RankID', 'level' => array('Column' => 'Level', 'Filter' => function ($value) { static $level = 0; $level++; return $level; }), 'rank_title' => 'Name', 'title2' => 'Label', 'rank_min' => array('Column' => 'Attributes', 'Filter' => function ($value, $field, $row) { $result = array(); if ($row['rank_min']) { $result['Criteria']['CountPosts'] = $row['rank_min']; } if ($row['rank_special']) { $result['Criteria']['Manual'] = true; } return serialize($result); })); $ex->exportTable('Rank', "\n select r.*, r.rank_title as title2, 0 as level\n from :_ranks r\n order by rank_special, rank_min;", $rank_Map); // Permissions. $ex->exportTable('Permission', "select\n group_id as RoleID,\n case\n when group_name like '%Guest%' or group_name like 'BOTS' then 'View'\n when group_name like '%Mod%' then 'View,Garden.SignIn.Allow,Garden.Profiles.Edit,Garden.Settings.View,Vanilla.Discussions.Add,Vanilla.Comments.Add,Garden.Moderation.Manage'\n when group_name like '%Admin%' then 'All'\n else 'View,Garden.SignIn.Allow,Garden.Profiles.Edit,Vanilla.Discussions.Add,Vanilla.Comments.Add'\n end as _Permissions\n from :_groups"); // UserRoles $userRole_Map = array('user_id' => 'UserID', 'group_id' => 'RoleID'); $ex->exportTable('UserRole', 'select user_id, group_id from :_users union select user_id, group_id from :_user_group', $userRole_Map); // Signatutes. $userMeta_Map = array('user_id' => 'UserID', 'name' => 'Name', 'user_sig' => array('Column' => 'Value', 'Filter' => array($this, 'removeBBCodeUIDs'))); $ex->exportTable('UserMeta', "\n select user_id, 'Plugin.Signatures.Sig' as name, user_sig, user_sig_bbcode_uid as bbcode_uid\n from :_users\n where length(user_sig) > 1\n\n union\n\n select user_id, 'Plugin.Signatures.Format', 'BBCode', null\n from :_users\n where length(user_sig) > 1\n ", $userMeta_Map); // Categories $category_Map = array('forum_id' => 'CategoryID', 'forum_name' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'forum_desc' => 'Description', 'left_id' => 'Sort'); $ex->exportTable('Category', "select *,\n nullif(parent_id,0) as ParentCategoryID\n from :_forums", $category_Map); // Discussions $discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'topic_poster' => 'InsertUserID', 'topic_title' => 'Name', 'Format' => 'Format', 'topic_views' => 'CountViews', 'topic_first_post_id' => array('Column' => 'FirstCommentID', 'Type' => 'int'), 'type' => 'Type'); $ex->exportTable('Discussion', "select t.*,\n 'BBCode' as Format,\n case t.topic_status when 1 then 1 else 0 end as Closed,\n case t.topic_type when 1 then 1 else 0 end as Announce,\n case when t.poll_start > 0 then 'poll' else null end as type,\n FROM_UNIXTIME(t.topic_time) as DateInserted,\n FROM_UNIXTIME(t.topic_last_post_time) as DateUpdated,\n FROM_UNIXTIME(t.topic_last_post_time) as DateLastComment\n from :_topics t", $discussion_Map); // Comments $comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'post_text' => array('Column' => 'Body', 'Filter' => array($this, 'removeBBCodeUIDs')), 'Format' => 'Format', 'poster_id' => 'InsertUserID', 'poster_ip' => array('Column' => 'InsertIPAddress', 'Filter' => 'forceIP4'), 'post_edit_user' => 'UpdateUserID'); $ex->exportTable('Comment', "select p.*,\n 'BBCode' as Format,\n FROM_UNIXTIME(p.post_time) as DateInserted,\n FROM_UNIXTIME(nullif(p.post_edit_time,0)) as DateUpdated\n from :_posts p", $comment_Map); // UserDiscussion $userDiscussion_Map = array('user_id' => 'UserID', 'topic_id' => 'DiscussionID'); $ex->exportTable('UserDiscussion', "select b.*,\n 1 as Bookmarked\n from :_bookmarks b", $userDiscussion_Map); // Conversations tables. $ex->query("drop table if exists z_pmto;"); $ex->query("create table z_pmto (\nid int unsigned,\nuserid int unsigned,\nprimary key(id, userid));"); $ex->query("insert ignore z_pmto (id, userid)\nselect msg_id, author_id\nfrom :_privmsgs;"); $ex->query("insert ignore z_pmto (id, userid)\nselect msg_id, user_id\nfrom :_privmsgs_to;"); $ex->query("insert ignore z_pmto (id, userid)\nselect msg_id, author_id\nfrom :_privmsgs_to;"); $ex->query("drop table if exists z_pmto2;"); $ex->query("create table z_pmto2 (\n id int unsigned,\n userids varchar(250),\n primary key (id)\n);"); $ex->query("insert ignore z_pmto2 (id, userids)\nselect\n id,\n group_concat(userid order by userid)\nfrom z_pmto\ngroup by id;"); $ex->query("drop table if exists z_pm;"); $ex->query("create table z_pm (\n id int unsigned,\n subject varchar(255),\n subject2 varchar(255),\n userids varchar(250),\n groupid int unsigned\n);"); $ex->query("insert z_pm (\n id,\n subject,\n subject2,\n userids\n)\nselect\n pm.msg_id,\n pm.message_subject,\n case when pm.message_subject like 'Re: %' then trim(substring(pm.message_subject, 4)) else pm.message_subject end as subject2,\n t.userids\nfrom :_privmsgs pm\njoin z_pmto2 t\n on t.id = pm.msg_id;"); $ex->query("create index z_idx_pm on z_pm (id);"); $ex->query("drop table if exists z_pmgroup;"); $ex->query("create table z_pmgroup (\n groupid int unsigned,\n subject varchar(255),\n userids varchar(250)\n);"); $ex->query("insert z_pmgroup (\n groupid,\n subject,\n userids\n)\nselect\n min(pm.id),\n pm.subject2,\n pm.userids\nfrom z_pm pm\ngroup by pm.subject2, pm.userids;"); $ex->query("create index z_idx_pmgroup on z_pmgroup (subject, userids);"); $ex->query("create index z_idx_pmgroup2 on z_pmgroup (groupid);"); $ex->query("update z_pm pm\njoin z_pmgroup g\n on pm.subject2 = g.subject and pm.userids = g.userids\nset pm.groupid = g.groupid;"); // Polls. $poll_Map = array('poll_id' => 'PollID', 'poll_title' => 'Name', 'topic_id' => 'DiscussionID', 'topic_time' => array('Column' => 'DateInserted', 'Filter' => 'timestampToDate'), 'topic_poster' => 'InsertUserID', 'anonymous' => 'Anonymous'); $ex->exportTable('Poll', "\n select distinct\n t.*,\n t.topic_id as poll_id,\n 1 as anonymous\n from :_poll_options po\n join :_topics t\n on po.topic_id = t.topic_id", $poll_Map); $pollOption_Map = array('id' => 'PollOptionID', 'poll_option_id' => 'Sort', 'topic_id' => 'PollID', 'poll_option_text' => 'Body', 'format' => 'Format', 'poll_option_total' => 'CountVotes', 'topic_time' => array('Column' => 'DateInserted', 'Filter' => 'timestampToDate'), 'topic_poster' => 'InsertUserID'); $ex->exportTable('PollOption', "\n select\n po.*,\n po.poll_option_id * 1000000 + po.topic_id as id,\n 'Html' as format,\n t.topic_time,\n t.topic_poster\n from :_poll_options po\n join :_topics t\n on po.topic_id = t.topic_id", $pollOption_Map); $pollVote_Map = array('vote_user_id' => 'UserID', 'id' => 'PollOptionID'); $ex->exportTable('PollVote', "\n select v.*, v.poll_option_id * 1000000 + v.topic_id as id\n from :_poll_votes v", $pollVote_Map); // Conversations. $conversation_Map = array('msg_id' => 'ConversationID', 'author_id' => 'InsertUserID', 'RealSubject' => array('Column' => 'Subject', 'Type' => 'varchar(250)', 'Filter' => array('Phpbb2', 'EntityDecode'))); $ex->exportTable('Conversation', "select\n g.subject as RealSubject,\n pm.*,\n from_unixtime(pm.message_time) as DateInserted\nfrom :_privmsgs pm\njoin z_pmgroup g\n on g.groupid = pm.msg_id", $conversation_Map); // Coversation Messages. $conversationMessage_Map = array('msg_id' => 'MessageID', 'groupid' => 'ConversationID', 'message_text' => array('Column' => 'Body', 'Filter' => array($this, 'removeBBCodeUIDs')), 'author_id' => 'InsertUserID'); $ex->exportTable('ConversationMessage', "select\n pm.*,\n pm2.groupid,\n 'BBCode' as Format,\n FROM_UNIXTIME(pm.message_time) as DateInserted\n from :_privmsgs pm\n join z_pm pm2\n on pm.msg_id = pm2.id", $conversationMessage_Map); // User Conversation. $userConversation_Map = array('userid' => 'UserID', 'groupid' => 'ConversationID'); $ex->exportTable('UserConversation', "select\n g.groupid,\n t.userid\n from z_pmto t\n join z_pmgroup g\n on g.groupid = t.id;", $userConversation_Map); $ex->query('drop table if exists z_pmto'); $ex->query('drop table if exists z_pmto2;'); $ex->query('drop table if exists z_pm;'); $ex->query('drop table if exists z_pmgroup;'); // Media. $cdn = $this->param('cdn', ''); $media_Map = array('attach_id' => 'MediaID', 'real_filename' => 'Name', 'thumb_path' => array('Column' => 'ThumbPath', 'Filter' => array($this, 'filterThumbnailData')), 'thumb_width' => array('Column' => 'ThumbWidth', 'Filter' => array($this, 'filterThumbnailData')), 'post_id' => 'InsertUserID', 'mimetype' => 'Type', 'filesize' => 'Size'); $ex->exportTable('Media', "select\n case when a.post_msg_id = t.topic_first_post_id then 'discussion' else 'comment' end as ForeignTable,\n case when a.post_msg_id = t.topic_first_post_id then a.topic_id else a.post_msg_id end as ForeignID,\n concat('{$cdn}','FileUpload/', a.physical_filename, '.', a.extension) as Path,\n concat('{$cdn}','FileUpload/', a.physical_filename, '.', a.extension) as thumb_path,\n 128 as thumb_width,\n FROM_UNIXTIME(a.filetime) as DateInserted,\n a.*\nfrom :_attachments a\njoin :_topics t\n on a.topic_id = t.topic_id", $media_Map); $this->exportBanList(); // End $ex->endExport(); }
/** * Forum-specific export format. * @param ExportModel $ex */ protected function forumExport($ex) { $characterSet = $ex->getCharacterSet('posts'); if ($characterSet) { $ex->characterSet = $characterSet; } // Begin $ex->beginExport('', 'bbPress 1.*', array('HashMethod' => 'Vanilla')); // Users $user_Map = array('ID' => 'UserID', 'user_login' => 'Name', 'user_pass' => 'Password', 'user_email' => 'Email', 'user_registered' => 'DateInserted'); $ex->exportTable('User', "select * from :_users", $user_Map); // ":_" will be replace by database prefix // Roles $ex->exportTable('Role', "select 1 as RoleID, 'Guest' as Name\n union select 2, 'Key Master'\n union select 3, 'Administrator'\n union select 4, 'Moderator'\n union select 5, 'Member'\n union select 6, 'Inactive'\n union select 7, 'Blocked'"); // UserRoles $userRole_Map = array('user_id' => 'UserID'); $ex->exportTable('UserRole', "select distinct\n user_id,\n case when locate('keymaster', meta_value) <> 0 then 2\n when locate('administrator', meta_value) <> 0 then 3\n when locate('moderator', meta_value) <> 0 then 4\n when locate('member', meta_value) <> 0 then 5\n when locate('inactive', meta_value) <> 0 then 6\n when locate('blocked', meta_value) <> 0 then 7\n else 1 end as RoleID\n from :_usermeta\n where meta_key = 'bb_capabilities'", $userRole_Map); // Categories $category_Map = array('forum_id' => 'CategoryID', 'forum_name' => 'Name', 'forum_desc' => 'Description', 'forum_slug' => 'UrlCode', 'left_order' => 'Sort'); $ex->exportTable('Category', "select *,\n lower(forum_slug) as forum_slug,\n nullif(forum_parent,0) as ParentCategoryID\n from :_forums", $category_Map); // Discussions $discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'topic_poster' => 'InsertUserID', 'topic_title' => 'Name', 'Format' => 'Format', 'topic_start_time' => 'DateInserted', 'topic_sticky' => 'Announce'); $ex->exportTable('Discussion', "select t.*,\n 'Html' as Format,\n case t.topic_open when 0 then 1 else 0 end as Closed\n from :_topics t\n where topic_status = 0", $discussion_Map); // Comments $comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'post_text' => array('Column' => 'Body', 'Filter' => 'bbPressTrim'), 'Format' => 'Format', 'poster_id' => 'InsertUserID', 'post_time' => 'DateInserted'); $ex->exportTable('Comment', "select p.*,\n 'Html' as Format\n from :_posts p\n where post_status = 0", $comment_Map); // Conversations. // The export is different depending on the table layout. $PM = $ex->exists('bbpm', array('ID', 'pm_title', 'pm_from', 'pm_to', 'pm_text', 'sent_on', 'pm_thread')); $conversationVersion = ''; if ($PM === true) { // This is from an old version of the plugin. $conversationVersion = 'old'; } elseif (is_array($PM) && count(array_intersect(array('ID', 'pm_from', 'pm_text', 'sent_on', 'pm_thread'), $PM)) == 0) { // This is from a newer version of the plugin. $conversationVersion = 'new'; } if ($conversationVersion) { // Conversation. $conv_Map = array('pm_thread' => 'ConversationID', 'pm_from' => 'InsertUserID'); $ex->exportTable('Conversation', "select *, from_unixtime(sent_on) as DateInserted\n from :_bbpm\n where thread_depth = 0", $conv_Map); // ConversationMessage. $convMessage_Map = array('ID' => 'MessageID', 'pm_thread' => 'ConversationID', 'pm_from' => 'InsertUserID', 'pm_text' => array('Column' => 'Body', 'Filter' => 'bbPressTrim')); $ex->exportTable('ConversationMessage', 'select *, from_unixtime(sent_on) as DateInserted from :_bbpm', $convMessage_Map); // UserConversation. $ex->query("create temporary table bbpmto (UserID int, ConversationID int)"); if ($conversationVersion == 'new') { $to = $ex->query("select object_id, meta_value from :_meta where object_type = 'bbpm_thread' and meta_key = 'to'", true); if (is_resource($to)) { while (($row = @mysql_fetch_assoc($to)) !== false) { $thread = $row['object_id']; $tos = explode(',', trim($row['meta_value'], ',')); $toIns = ''; foreach ($tos as $toID) { $toIns .= "({$toID},{$thread}),"; } $toIns = trim($toIns, ','); $ex->query("insert bbpmto (UserID, ConversationID) values {$toIns}", true); } mysql_free_result($to); $ex->exportTable('UserConversation', 'select * from bbpmto'); } } else { $conUser_Map = array('pm_thread' => 'ConversationID', 'pm_from' => 'UserID'); $ex->exportTable('UserConversation', 'select distinct pm_thread, pm_from, del_sender as Deleted from :_bbpm union select distinct pm_thread, pm_to, del_reciever from :_bbpm', $conUser_Map); } } // End $ex->endExport(); }
/** * * @param ExportModel $ex */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('Threads'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'User Voice'); $ex->sourcePrefix = 'cs_'; // User. $user_Map = array('LastActivity' => array('Column' => 'DateLastActive'), 'UserName' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'CreateDate' => array('Column' => 'DateInserted')); $ex->exportTable('User', "\n select u.*,\n concat('sha1\$', m.PasswordSalt, '\$', m.Password) as Password,\n 'django' as HashMethod,\n if(a.Content is not null, concat('import/userpics/avatar',u.UserID,'.jpg'), NULL) as Photo\n from :_Users u\n left join aspnet_Membership m on m.UserId = u.MembershipID\n left join :_UserAvatar a on a.UserID = u.UserID", $user_Map); // Role. $role_Map = array('RoleId' => array('Column' => 'RoleID', 'Filter' => array($this, 'roleIDConverter')), 'RoleName' => 'Name'); $ex->exportTable('Role', "\n select *\n from aspnet_Roles", $role_Map); // User Role. $userRole_Map = array('RoleId' => array('Column' => 'RoleID', 'Filter' => array($this, 'roleIDConverter'))); $ex->exportTable('UserRole', "\n select u.UserID, ur.RoleId\n from aspnet_UsersInRoles ur\n left join :_Users u on ur.UserId = u.MembershipID\n ", $userRole_Map); // Category. $category_Map = array('SectionID' => 'CategoryID', 'ParentID' => 'ParentCategoryID', 'SortOrder' => 'Sort', 'DateCreated' => 'DateInserted'); $ex->exportTable('Category', "\n select s.*\n from :_Sections s", $category_Map); // Discussion. $discussion_Map = array('ThreadID' => 'DiscussionID', 'SectionID' => 'CategoryID', 'UserID' => 'InsertUserID', 'PostDate' => 'DateInserted', 'ThreadDate' => 'DateLastComment', 'TotalViews' => 'CountViews', 'TotalReplies' => 'CountComments', 'IsLocked' => 'Closed', 'MostRecentPostAuthorID' => 'LastCommentUserID', 'MostRecentPostID' => 'LastCommentID', 'Subject' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'Body' => array('Column' => 'Body', 'Filter' => 'HTMLDecoder'), 'IPAddress' => 'InsertIPAddress'); $ex->exportTable('Discussion', "\n select t.*,\n p.Subject,\n p.Body,\n 'Html' as Format,\n p.IPAddress as InsertIPAddress,\n if(t.IsSticky > 0, 2, 0) as Announce\n from :_Threads t\n left join :_Posts p on p.ThreadID = t.ThreadID\n where p.SortOrder = 1", $discussion_Map); // Comment. $comment_Map = array('PostID' => 'CommentID', 'ThreadID' => 'DiscussionID', 'UserID' => 'InsertUserID', 'IPAddress' => 'InsertIPAddress', 'Body' => array('Column' => 'Body', 'Filter' => 'HTMLDecoder'), 'PostDate' => 'DateInserted'); $ex->exportTable('Comment', "\n select p.*\n from :_Posts p\n where SortOrder > 1", $comment_Map); // Bookmarks $userDiscussion_Map = array('ThreadID' => 'DiscussionID'); $ex->exportTable('UserDiscussion', "\n select t.*,\n '1' as Bookmarked,\n NOW() as DateLastViewed\n from :_TrackedThreads t", $userDiscussion_Map); // Media. /*$Media_Map = array( 'FileName' => 'Name', 'ContentType' => 'Type', 'ContentSize' => 'Size', 'UserID' => 'InsertUserID', 'Created' => 'DateInserted' ); $ex->ExportTable('Media', " select a.*, if(p.SortOrder = 1, 'Discussion', 'Comment') as ForeignTable, if(p.SortOrder = 1, p.ThreadID, a.PostID) as ForeignID, concat('import/attach/', a.FileName) as Path from :_PostAttachments a left join :_Posts p on p.PostID = a.PostID where IsRemote = 0", $Media_Map); */ // Decode files in database. $this->exportHexAvatars(); //$this->ExportHexAttachments(); // El fin. $ex->endExport(); }
/** * Forum-specific export format * @todo Project file size / export time and possibly break into multiple files * @param ExportModel $ex * */ protected function forumExport($ex) { $this->ex = $ex; $characterSet = $ex->getCharacterSet('Comment'); if ($characterSet) { $ex->characterSet = $characterSet; } // Begin $ex->beginExport('', 'Vanilla 1.*'); // Users $user_Map = array('UserID' => 'UserID', 'Name' => 'Name', 'Password' => 'Password', 'Email' => 'Email', 'Icon' => 'Photo', 'CountComments' => 'CountComments', 'Discovery' => 'DiscoveryText'); $ex->exportTable('User', "SELECT * FROM :_User", $user_Map); // ":_" will be replaced by database prefix // Roles // Since the zero role is a valid role in Vanilla 1 then we'll have to reassign it. $r = $ex->query('select max(RoleID) as RoleID from :_Role'); $zeroRoleID = 0; if (is_resource($r)) { while (($row = @mysql_fetch_assoc($r)) !== false) { $zeroRoleID = $row['RoleID']; } } $zeroRoleID++; /* 'RoleID' => 'int', 'Name' => 'varchar(100)', 'Description' => 'varchar(200)' */ $role_Map = array('RoleID' => 'RoleID', 'Name' => 'Name', 'Description' => 'Description'); $ex->exportTable('Role', "select RoleID, Name, Description from :_Role union all select {$zeroRoleID}, 'Applicant', 'Created by the Vanilla Porter'", $role_Map); $permission_Map = array('RoleID' => 'RoleID', 'PERMISSION_SIGN_IN' => 'Garden.SignIn.Allow', 'Permissions' => array('Column' => 'Vanilla.Comments.Add', 'Type' => 'tinyint', 'Filter' => array($this, 'filterPermissions')), 'PERMISSION_START_DISCUSSION' => array('Column' => 'Vanilla.Discussions.Add', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_SINK_DISCUSSION' => array('Column' => 'Vanilla.Discussions.Sink', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_STICK_DISCUSSIONS' => array('Column' => 'Vanilla.Discussions.Announce', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_CLOSE_DISCUSSIONS' => array('Column' => 'Vanilla.Discussions.Close', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_EDIT_DISCUSSIONS' => array('Column' => 'Vanilla.Discussions.Edit', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_EDIT_COMMENTS' => array('Column' => 'Vanilla.Comments.Edit', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_APPROVE_APPLICANTS' => array('Column' => 'Garden.Moderation.Manage', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_EDIT_USERS' => array('Column' => 'Garden.Users.Edit', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool')), 'PERMISSION_CHANGE_APPLICATION_SETTINGS' => array('Column' => 'Garden.Settings.Manage', 'Type' => 'tinyint', 'Filter' => array($this, 'forceBool'))); $ex->exportTable('Permission', "select * from :_Role", $permission_Map); // UserRoles /* 'UserID' => 'int', 'RoleID' => 'int' */ $userRole_Map = array('UserID' => 'UserID', 'RoleID' => 'RoleID'); $ex->exportTable('UserRole', "select UserID, case RoleID when 0 then {$zeroRoleID} else RoleID end as RoleID from :_User", $userRole_Map); // Categories /* 'CategoryID' => 'int', 'Name' => 'varchar(30)', 'Description' => 'varchar(250)', 'ParentCategoryID' => 'int', 'DateInserted' => 'datetime', 'InsertUserID' => 'int', 'DateUpdated' => 'datetime', 'UpdateUserID' => 'int' */ $category_Map = array('CategoryID' => 'CategoryID', 'Name' => 'Name', 'Description' => 'Description'); $ex->exportTable('Category', "select CategoryID, Name, Description from :_Category", $category_Map); // Discussions /* 'DiscussionID' => 'int', 'Name' => 'varchar(100)', 'CategoryID' => 'int', 'Body' => 'text', 'Format' => 'varchar(20)', 'DateInserted' => 'datetime', 'InsertUserID' => 'int', 'DateUpdated' => 'datetime', 'UpdateUserID' => 'int', 'Score' => 'float', 'Announce' => 'tinyint', 'Closed' => 'tinyint' */ $discussion_Map = array('DiscussionID' => 'DiscussionID', 'Name' => 'Name', 'CategoryID' => 'CategoryID', 'DateCreated' => 'DateInserted', 'DateCreated2' => 'DateUpdated', 'AuthUserID' => 'InsertUserID', 'DateLastActive' => 'DateLastComment', 'AuthUserID2' => 'UpdateUserID', 'Closed' => 'Closed', 'Sticky' => 'Announce', 'CountComments' => 'CountComments', 'Sink' => 'Sink', 'LastUserID' => 'LastCommentUserID'); $ex->exportTable('Discussion', "SELECT d.*,\n d.LastUserID as LastCommentUserID,\n d.DateCreated as DateCreated2, d.AuthUserID as AuthUserID2,\n c.Body,\n c.FormatType as Format\n FROM :_Discussion d\n LEFT JOIN :_Comment c\n ON d.FirstCommentID = c.CommentID\n WHERE coalesce(d.WhisperUserID, 0) = 0 and d.Active = 1", $discussion_Map); // Comments /* 'CommentID' => 'int', 'DiscussionID' => 'int', 'DateInserted' => 'datetime', 'InsertUserID' => 'int', 'DateUpdated' => 'datetime', 'UpdateUserID' => 'int', 'Format' => 'varchar(20)', 'Body' => 'text', 'Score' => 'float' */ $comment_Map = array('CommentID' => 'CommentID', 'DiscussionID' => 'DiscussionID', 'AuthUserID' => 'InsertUserID', 'DateCreated' => 'DateInserted', 'EditUserID' => 'UpdateUserID', 'DateEdited' => 'DateUpdated', 'Body' => 'Body', 'FormatType' => 'Format'); $ex->exportTable('Comment', "\n SELECT\n c.*\n FROM :_Comment c\n JOIN :_Discussion d\n ON c.DiscussionID = d.DiscussionID\n WHERE d.FirstCommentID <> c.CommentID\n AND c.Deleted = '0'\n AND coalesce(d.WhisperUserID, 0) = 0\n AND coalesce(c.WhisperUserID, 0) = 0", $comment_Map); $ex->exportTable('UserDiscussion', "\n SELECT\n w.UserID,\n w.DiscussionID,\n w.CountComments,\n w.LastViewed as DateLastViewed,\n case when b.UserID is not null then 1 else 0 end AS Bookmarked\n FROM :_UserDiscussionWatch w\n LEFT JOIN :_UserBookmark b\n ON w.DiscussionID = b.DiscussionID AND w.UserID = b.UserID"); // Conversations // Create a mapping tables for conversations. // These mapping tables are used to group comments that a) are in the same discussion and b) are from and to the same users. $ex->query("drop table if exists z_pmto"); $ex->query("create table z_pmto (\n CommentID int,\n UserID int,\n primary key(CommentID, UserID)\n )"); $ex->query("insert ignore z_pmto (\n CommentID,\n UserID\n)\nselect distinct\n CommentID,\n AuthUserID\nfrom :_Comment\nwhere coalesce(WhisperUserID, 0) <> 0"); $ex->query("insert ignore z_pmto (\n CommentID,\n UserID\n)\nselect distinct\n CommentID,\n WhisperUserID\nfrom :_Comment\nwhere coalesce(WhisperUserID, 0) <> 0"); $ex->query("insert ignore z_pmto (\n CommentID,\n UserID\n)\nselect distinct\n c.CommentID,\n d.AuthUserID\nfrom :_Discussion d\njoin :_Comment c\n on c.DiscussionID = d.DiscussionID\nwhere coalesce(d.WhisperUserID, 0) <> 0"); $ex->query("insert ignore z_pmto (\n CommentID,\n UserID\n)\nselect distinct\n c.CommentID,\n d.WhisperUserID\nfrom :_Discussion d\njoin :_Comment c\n on c.DiscussionID = d.DiscussionID\nwhere coalesce(d.WhisperUserID, 0) <> 0"); $ex->query("insert ignore z_pmto (\n CommentID,\n UserID\n)\nselect distinct\n c.CommentID,\n c.AuthUserID\nfrom :_Discussion d\njoin :_Comment c\n on c.DiscussionID = d.DiscussionID\nwhere coalesce(d.WhisperUserID, 0) <> 0"); $ex->query("drop table if exists z_pmto2"); $ex->query("create table z_pmto2 (\n CommentID int,\n UserIDs varchar(250),\n primary key (CommentID)\n)"); $ex->query("insert z_pmto2 (\n CommentID,\n UserIDs\n)\nselect\n CommentID,\n group_concat(UserID order by UserID)\nfrom z_pmto\ngroup by CommentID"); $ex->query("drop table if exists z_pm"); $ex->query("create table z_pm (\n CommentID int,\n DiscussionID int,\n UserIDs varchar(250),\n GroupID int\n)"); $ex->query("insert ignore z_pm (\n CommentID,\n DiscussionID\n)\nselect\n CommentID,\n DiscussionID\nfrom :_Comment\nwhere coalesce(WhisperUserID, 0) <> 0"); $ex->query("insert ignore z_pm (\n CommentID,\n DiscussionID\n)\nselect\n c.CommentID,\n c.DiscussionID\nfrom :_Discussion d\njoin :_Comment c\n on c.DiscussionID = d.DiscussionID\nwhere coalesce(d.WhisperUserID, 0) <> 0"); $ex->query("update z_pm pm\njoin z_pmto2 t\n on t.CommentID = pm.CommentID\nset pm.UserIDs = t.UserIDs"); $ex->query("drop table if exists z_pmgroup"); $ex->query("create table z_pmgroup (\n GroupID int,\n DiscussionID int,\n UserIDs varchar(250)\n)"); $ex->query("insert z_pmgroup (\n GroupID,\n DiscussionID,\n UserIDs\n)\nselect\n min(pm.CommentID),\n pm.DiscussionID,\n t2.UserIDs\nfrom z_pm pm\njoin z_pmto2 t2\n on pm.CommentID = t2.CommentID\ngroup by pm.DiscussionID, t2.UserIDs"); $ex->query("create index z_idx_pmgroup on z_pmgroup (DiscussionID, UserIDs)"); $ex->query("create index z_idx_pmgroup2 on z_pmgroup (GroupID)"); $ex->query("update z_pm pm\njoin z_pmgroup g\n on pm.DiscussionID = g.DiscussionID and pm.UserIDs = g.UserIDs\nset pm.GroupID = g.GroupID"); $conversation_Map = array('AuthUserID' => 'InsertUserID', 'DateCreated' => 'DateInserted', 'DiscussionID' => array('Column' => 'DiscussionID', 'Type' => 'int'), 'CommentID' => 'ConversationID', 'Name' => array('Column' => 'Subject', 'Type' => 'varchar(255)')); $ex->exportTable('Conversation', "select c.*, d.Name\nfrom :_Comment c\njoin :_Discussion d\n on d.DiscussionID = c.DiscussionID\njoin z_pmgroup g\n on g.GroupID = c.CommentID;", $conversation_Map); // ConversationMessage. $conversationMessage_Map = array('CommentID' => 'MessageID', 'GroupID' => 'ConversationID', 'Body' => 'Body', 'FormatType' => 'Format', 'AuthUserID' => 'InsertUserID', 'DateCreated' => 'DateInserted'); $ex->exportTable('ConversationMessage', "select c.*, pm.GroupID\nfrom z_pm pm\njoin :_Comment c\n on pm.CommentID = c.CommentID", $conversationMessage_Map); // UserConversation /* 'UserID' => 'int', 'ConversationID' => 'int', 'LastMessageID' => 'int' */ $userConversation_Map = array('UserID' => 'UserID', 'GroupID' => 'ConversationID'); $ex->exportTable('UserConversation', "select distinct\n pm.GroupID,\n t.UserID\nfrom z_pmto t\njoin z_pm pm\n on pm.CommentID = t.CommentID", $userConversation_Map); $ex->query("drop table z_pmto"); $ex->query("drop table z_pmto2"); $ex->query("drop table z_pm"); $ex->query("drop table z_pmgroup"); // Media if ($ex->exists('Attachment')) { $media_Map = array('AttachmentID' => 'MediaID', 'Name' => 'Name', 'MimeType' => 'Type', 'Size' => 'Size', 'Path' => array('Column' => 'Path', 'Filter' => array($this, 'stripMediaPath')), 'UserID' => 'InsertUserID', 'DateCreated' => 'DateInserted', 'CommentID' => 'ForeignID'); $ex->exportTable('Media', "select a.*, 'comment' as ForeignTable from :_Attachment a", $media_Map); } // End $ex->endExport(); }
/** * Main export process. * * @param ExportModel $ex * @see $_Structures in ExportModel for allowed destination tables & columns. */ public function forumExport($ex) { $characterSet = $ex->getCharacterSet('posts_text'); if ($characterSet) { $ex->characterSet = $characterSet; } // Reiterate the platform name here to be included in the porter file header. $ex->beginExport('', 'jforum'); // User. $user_Map = array('user_id' => 'UserID', 'username' => 'Name', 'user_email' => 'Email', 'user_regdate' => 'DateInserted', 'user_regdate2' => 'DateFirstVisit', 'user_posts' => 'CountComments', 'user_avatar' => 'Photo', 'deleted' => 'Deleted', 'user_from' => 'Location', 'user_biography' => 'About'); $ex->exportTable('User', "\n select u.*,\n 'Reset' as HashMethod,\n user_regdate as user_regdate2\n from :_users u\n ", $user_Map); // Role. $role_Map = array('group_id' => 'RoleID', 'group_name' => 'Name', 'group_description' => 'Description'); $ex->exportTable('Role', "\n select *\n from :_groups", $role_Map); // User Role. $userRole_Map = array('user_id' => 'UserID', 'group_id' => 'RoleID'); $ex->exportTable('UserRole', "\n select u.*\n from :_user_groups u", $userRole_Map); // UserMeta. $ex->exportTable('UserMeta', "\n select user_id as UserID,\n 'Profile.Website' as `Name`,\n user_website as `Value`\n from :_users\n where user_website is not null\n\n union\n\n select user_id, 'Plugins.Signatures.Sig', user_sig\n from :_users where user_sig is not null\n\n union\n\n select user_id, 'Plugins.Signatures.Format', 'BBCode'\n from :_users where user_sig is not null\n\n union\n\n select user_id, 'Profile.Occupation', user_occ\n from :_users where user_occ is not null\n\n union\n\n select user_id, 'Profile.Interests', user_interests\n from :_users where user_interests is not null\n "); // Category. // _categories is tier 1, _forum is tier 2. // Overlapping IDs, so fast-forward _categories by 1000. $category_Map = array(); $ex->exportTable('Category', "\n select\n c.categories_id+1000 as CategoryID,\n -1 as ParentCategoryID,\n c.title as Name,\n null as Description,\n 1 as Depth,\n c.display_order as Sort\n from :_categories c\n\n union\n\n select\n f.forum_id as CategoryID,\n categories_id+1000 as ParentCategoryID,\n forum_name as Name,\n forum_desc as Description,\n 2 as Depth,\n null as Sort\n from :_forums f\n ", $category_Map); // Discussion. $discussion_Map = array('topic_id' => 'DiscussionID', 'forum_id' => 'CategoryID', 'user_id' => 'InsertUserID', 'topic_time' => 'DateInserted', 'topic_title' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'topic_views' => 'CountViews', 'topic_replies' => 'CountComments', 'topic_status' => 'Closed', 'topic_type' => 'Announce', 'post_text' => 'Body'); // It's easier to convert between Unix time and MySQL datestamps during the db query. $ex->exportTable('Discussion', "\n select *,\n t.forum_id as forum_id,\n if(t.topic_type>0,1,0) as topic_type,\n 'BBCode' as Format\n from :_topics t\n left join :_posts_text p\n on t.topic_first_post_id = p.post_id", $discussion_Map); // Comment. $comment_Map = array('post_id' => 'CommentID', 'topic_id' => 'DiscussionID', 'user_id' => 'InsertUserID', 'poster_ip' => 'InsertIPAddress', 'post_text' => 'Body', 'post_time' => 'DateInserted', 'post_edit_time' => 'DateUpdated'); $ex->exportTable('Comment', "\n select p.*, t.post_text, 'BBCode' as Format\n from :_posts p\n left join :_posts_text t\n on p.post_id = t.post_id\n where p.post_id not in (select topic_first_post_id from :_topics)", $comment_Map); // UserDiscussion. // Guessing table is called "_watch" because they are all bookmarks. $userDiscussion_Map = array('topic_id' => 'DiscussionID', 'user_id' => 'UserID'); $ex->exportTable('UserDiscussion', "\n select *,\n 1 as Bookmarked,\n if(is_read,NOW(),null) as DateLastViewed\n from :_topics_watch w", $userDiscussion_Map); // Conversation. // Thread using tmp table based on the pair of users talking. $ex->query('drop table if exists z_conversation;'); $ex->query('create table z_conversation ( ConversationID int unsigned NOT NULL AUTO_INCREMENT, LowUserID int unsigned, HighUserID int unsigned, PRIMARY KEY (ConversationID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'); $ex->query('insert into z_conversation (LowUserID, HighUserID) select least(privmsgs_from_userid, privmsgs_to_userid), greatest(privmsgs_from_userid, privmsgs_to_userid) from :_privmsgs group by least(privmsgs_from_userid, privmsgs_to_userid), greatest(privmsgs_from_userid, privmsgs_to_userid)'); // Replying on /dba/counts to rebuild most of this data later. $conversation_Map = array('privmsgs_from_userid' => 'InsertUserID', 'privmsgs_date' => 'DateInserted', 'privmsgs_subject' => 'Subject'); $ex->exportTable('Conversation', "\n select p.*, c.ConversationID\n from :_privmsgs p\n left join z_conversation c on c.HighUserID = greatest(p.privmsgs_from_userid, p.privmsgs_to_userid)\n and c.LowUserID = least(p.privmsgs_from_userid, p.privmsgs_to_userid)\n group by least(privmsgs_from_userid, privmsgs_to_userid),\n greatest(privmsgs_from_userid, privmsgs_to_userid)", $conversation_Map); // Conversation Message. // Messages with the same timestamps are sent/received copies. // Yes that'd probably break down on huge sites but it's too convenient to pass up for now. $message_Map = array('privmsgs_id' => 'MessageID', 'privmsgs_from_userid' => 'InsertUserID', 'privmsgs_date' => 'DateInserted', 'privmsgs_text' => 'Body'); $ex->exportTable('ConversationMessage', "\n select *, c.ConversationID, 'BBCode' as Format\n from :_privmsgs p\n left join :_privmsgs_text t on t.privmsgs_id = p.privmsgs_id\n left join z_conversation c on c.LowUserID = least(privmsgs_from_userid, privmsgs_to_userid)\n and c.HighUserID = greatest(privmsgs_from_userid, privmsgs_to_userid)\n group by privmsgs_date", $message_Map); // UserConversation $ex->exportTable('UserConversation', "\n select ConversationID, LowUserID as UserID, NOW() as DateLastViewed from z_conversation\n union\n select ConversationID, HighUserID as UserID, NOW() as DateLastViewed from z_conversation\n "); // Needs afterward: update GDN_UserConversation set CountReadMessages = (select count(MessageID) from GDN_ConversationMessage where GDN_ConversationMessage.ConversationID = GDN_UserConversation.ConversationID) $ex->endExport(); }
/** * @param ExportModel $ex */ protected function forumExport($ex) { $characterSet = $ex->getCharacterSet('topic'); if ($characterSet) { $ex->characterSet = $characterSet; } $ex->beginExport('', 'NodeBB 0.*', array('HashMethod' => 'Vanilla')); // Users $user_Map = array('uid' => 'UserID', 'username' => 'Name', 'password' => 'Password', 'email' => 'Email', 'confirmed' => 'Confirmed', 'showemail' => 'ShowEmail', 'joindate' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate')), 'lastonline' => array('Column' => 'DateLastActive', 'Filter' => array($this, 'tsToDate')), 'lastposttime' => array('Column' => 'DateUpdated', 'Filter' => array($this, 'tsToDate')), 'banned' => 'Banned', 'admin' => 'Admin', 'hm' => 'HashMethod'); $ex->exportTable('User', "\n\n select uid, username, password, email, `email:confirmed` as confirmed, showemail, joindate, lastonline, lastposttime, banned, 0 as admin, 'crypt' as hm\n from :_user\n\n ", $user_Map); //Roles $role_Map = array('_num' => 'RoleID', '_key' => array('Column' => 'Name', 'Filter' => array($this, 'roleNameFromKey')), 'description' => 'Description'); $ex->exportTable('Role', "\n\n select gm._key as _key, gm._num as _num, g.description as description\n from :_group_members gm left join :_group g\n on gm._key like concat(g._key, '%')\n\n ", $role_Map); $userRole_Map = array('id' => 'RoleID', 'members' => 'UserID'); $ex->exportTable('UserRole', "\n\n select *, g._num as id\n from :_group_members g join :_group_members__members m\n on g._id = m._parentid\n\n ", $userRole_Map); // Signatutes. $userMeta_Map = array('uid' => 'UserID', 'name' => 'Name', 'signature' => 'Value'); $ex->exportTable('UserMeta', "\n\n select uid, 'Plugin.Signatures.Sig' as name, signature\n from :_user\n where length(signature) > 1\n\n union\n\n select uid, 'Plugin.Signatures.Format', 'Markdown'\n from :_user\n where length(signature) > 1\n\n union\n\n select uid, 'Profile.Website' as name, website\n from :_user\n where length(website) > 7\n\n union\n\n select uid, 'Profile.Location' as name, location\n from :_user\n where length(location) > 1\n\n ", $userMeta_Map); // Categories $category_Map = array('cid' => 'CategoryID', 'name' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'description' => 'Description', 'order' => 'Sort', 'parentCid' => 'ParentCategoryID', 'slug' => array('Column' => 'UrlCode', 'Filter' => array($this, 'removeNumId')), 'image' => 'Photo', 'disabled' => 'Archived'); $ex->exportTable('Category', "\n\n select *\n from :_category\n\n ", $category_Map); if (!$ex->indexExists('z_idx_topic', ':_topic')) { $ex->query("create index z_idx_topic on :_topic(mainPid);"); } if (!$ex->indexExists('z_idx_post', ':_post')) { $ex->query("create index z_idx_post on :_post(pid);"); } if (!$ex->indexExists('z_idx_poll', ':_poll')) { $ex->query("create index z_idx_poll on :_poll(tid);"); } $ex->query("drop table if exists z_discussionids;"); $ex->query("\n\n create table z_discussionids (\n tid int unsigned,\n primary key(tid)\n );\n\n "); $ex->query("\n\n insert ignore z_discussionids (\n tid\n )\n select mainPid\n from :_topic\n where mainPid is not null\n and deleted != 1;\n\n "); $ex->query("drop table if exists z_reactiontotalsupvote;"); $ex->query("\n\n create table z_reactiontotalsupvote (\n value varchar(50),\n total int,\n primary key (value)\n );\n\n "); $ex->query("drop table if exists z_reactiontotalsdownvote;"); $ex->query("\n\n create table z_reactiontotalsdownvote (\n value varchar(50),\n total int,\n primary key (value)\n );\n\n "); $ex->query("drop table if exists z_reactiontotals;"); $ex->query("\n\n create table z_reactiontotals (\n value varchar(50),\n upvote int,\n downvote int,\n primary key (value)\n );\n\n "); $ex->query("\n\n insert z_reactiontotalsupvote\n select value, count(*) as totals\n from :_uid_upvote\n group by value;\n\n "); $ex->query("\n\n insert z_reactiontotalsdownvote\n select value, count(*) as totals\n from :_uid_downvote\n group by value;\n\n "); $ex->query("\n\n insert z_reactiontotals\n select *\n from (\n select u.value, u.total as up, d.total as down\n from z_reactiontotalsupvote u\n left join z_reactiontotalsdownvote d\n on u.value = d.value\n\n union\n\n select d.value, u.total as up, d.total as down\n from z_reactiontotalsdownvote d\n left join z_reactiontotalsupvote u\n on u.value = d.value\n ) as reactions\n\n "); //Discussions $discussion_Map = array('tid' => 'DiscussionID', 'cid' => 'CategoryID', 'title' => 'Name', 'content' => 'Body', 'uid' => 'InsertUserID', 'locked' => 'Closed', 'pinned' => 'Announce', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate')), 'edited' => array('Column' => 'DateUpdated', 'Filter' => array($this, 'tsToDate')), 'editor' => 'UpdateUserID', 'viewcount' => 'CountViews', 'format' => 'Format', 'votes' => 'Score', 'attributes' => array('Column' => 'Attributes', 'Filter' => array($this, 'serializeReactions')), 'poll' => array('Column' => 'Type', 'Filter' => array($this, 'isPoll'))); $ex->exportTable('Discussion', "\n\n select p.tid, cid, title, content, p.uid, locked, pinned, p.timestamp, p.edited, p.editor, viewcount, votes, poll._id as poll, 'Markdown' as format, concat(ifnull(u.total, 0), ':', ifnull(d.total, 0)) as attributes\n from :_topic t\n left join :_post p\n on t.mainPid = p.pid\n left join z_reactiontotalsupvote u\n on u.value = t.mainPid\n left join z_reactiontotalsdownvote d\n on d.value = t.mainPid\n left join :_poll poll\n on p.tid = poll.tid\n where t.deleted != 1\n\n ", $discussion_Map); $ex->query("drop table if exists z_comments;"); $ex->query("\n\n create table z_comments (\n pid int,\n content text,\n uid varchar(255),\n tid varchar(255),\n timestamp double,\n edited varchar(255),\n editor varchar(255),\n votes int,\n upvote int,\n downvote int,\n primary key(pid)\n );\n\n "); $ex->query("\n\n insert ignore z_comments (\n pid,\n content,\n uid,\n tid,\n timestamp,\n edited,\n editor,\n votes\n )\n select p.pid, p.content, p.uid, p.tid, p.timestamp, p.edited, p.editor, p.votes\n from :_post p\n left join z_discussionids t\n on t.tid = p.pid\n where p.deleted != 1 and t.tid is null;\n\n "); $ex->query("\n\n update z_comments as c\n join z_reactiontotals r\n on r.value = c.pid\n set c.upvote = r.upvote, c.downvote = r.downvote;\n\n "); // Comments $comment_Map = array('content' => 'Body', 'uid' => 'InsertUserID', 'tid' => 'DiscussionID', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate')), 'edited' => array('Column' => 'DateUpdated', 'Filter' => array($this, 'tsToDate')), 'editor' => 'UpdateUserID', 'votes' => 'Score', 'format' => 'Format', 'attributes' => array('Column' => 'Attributes', 'Filter' => array($this, 'serializeReactions'))); $ex->exportTable('Comment', "\n\n select content, uid, tid, timestamp, edited, editor, votes, 'Markdown' as format, concat(ifnull(upvote, 0), ':', ifnull(downvote, 0)) as attributes\n from z_comments\n\n ", $comment_Map); //Polls $poll_Map = array('pollid' => 'PollID', 'title' => 'Name', 'tid' => 'DiscussionID', 'votecount' => 'CountVotes', 'uid' => 'InsertUserID', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate'))); $ex->exportTable('Poll', "\n\n select *\n from :_poll p left join :_poll_settings ps\n on ps._key like concat(p._key, ':', '%')\n\n ", $poll_Map); $pollOption_Map = array('_num' => 'PollOptionID', '_key' => array('Column' => 'PollID', 'Filter' => array($this, 'idFromKey')), 'title' => 'Body', 'sort' => 'Sort', 'votecount' => array('Column' => 'CountVotes', 'Filter' => array($this, 'makeNullZero')), 'format' => 'Format'); $ex->exportTable('PollOption', "\n\n select _num, _key, title, id+1 as sort, votecount, 'Html' as format\n from :_poll_options\n where title is not null\n\n ", $pollOption_Map); $pollVote_Map = array('userid' => 'UserID', 'poll_option_id' => 'PollOptionID'); $ex->exportTable('PollVote', "\n\n select povm.members as userid, po._num as poll_option_id\n from :_poll_options_votes__members povm\n left join :_poll_options_votes pov\n on povm._parentid = pov._id\n left join :_poll_options po\n on pov._key like concat(po._key, ':', '%')\n where po.title is not null\n\n ", $pollVote_Map); //Tags if (!$ex->indexExists('z_idx_topic_key', ':_topic')) { $ex->query("create index z_idx_topic_key on :_topic (_key);"); } $tag_Map = array('slug' => array('Column' => 'Name', 'Filter' => array($this, 'nameToSlug')), 'fullname' => 'FullName', 'count' => 'CountDiscussions', 'tagid' => 'TagID', 'cid' => 'CategoryID', 'type' => 'Type', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate')), 'uid' => 'InsertUserID'); $now = time(); $ex->query("set @rownr=1000;"); $ex->exportTable('Tag', "\n\n select @rownr:=@rownr+1 as tagid, members as fullname, members as slug, '' as type, count, timestamp, uid, cid\n from (\n select members, count(*) as count, _parentid\n from :_topic_tags__members\n group by members\n ) as tags\n join :_topic_tags tt\n on tt._id = _parentid\n left join :_topic t\n on substring(tt._key, 1, length(tt._key) - 5) = t._key\n\n ", $tag_Map); $tagDiscussion_Map = array('tagid' => 'TagID', 'tid' => 'DiscussionID', 'cid' => 'CategoryID', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate'))); $ex->query("set @rownr=1000;"); $ex->exportTable('TagDiscussion', "\n\n select tagid, cid, tid, timestamp\n from :_topic_tags__members two\n join (\n select @rownr:=@rownr+1 as tagid, members as fullname, members as slug, count\n from (\n select members, count(*) as count\n from :_topic_tags__members\n group by members\n ) as tags\n ) as tagids\n on two.members = tagids.fullname\n join :_topic_tags tt\n on tt._id = _parentid\n left join :_topic t\n on substring(tt._key, 1, length(tt._key) - 5) = t._key\n\n ", $tagDiscussion_Map); //Conversations if (!$ex->indexExists('z_idx_message_key', ':_message')) { $ex->query("create index z_idx_message_key on :_message(_key);"); } $ex->query("drop table if exists z_pmto;"); $ex->query("\n\n create table z_pmto (\n pmid int unsigned,\n userid int,\n groupid int,\n primary key(pmid, userid)\n );\n\n "); $ex->query("\n\n insert ignore z_pmto (\n pmid,\n userid\n )\n select substring_index(_key, ':', -1), fromuid\n from :_message;\n\n "); $ex->query("\n\n insert ignore z_pmto (\n pmid,\n userid\n )\n select substring_index(_key, ':', -1), touid\n from :_message;\n\n "); $ex->query("drop table if exists z_pmto2;"); $ex->query("\n\n create table z_pmto2 (\n pmid int unsigned,\n userids varchar(250),\n groupid int unsigned,\n primary key (pmid)\n );\n\n "); $ex->query("\n\n replace z_pmto2 (\n pmid,\n userids\n )\n select pmid, group_concat(userid order by userid)\n from z_pmto\n group by pmid;\n\n "); $ex->query("drop table if exists z_pmgroup;"); $ex->query("\n\n create table z_pmgroup (\n userids varchar(250),\n groupid varchar(255),\n firstmessageid int,\n lastmessageid int,\n countmessages int,\n primary key (userids, groupid)\n );\n\n "); $ex->query("\n\n insert z_pmgroup\n select userids, concat('message:', min(pmid)), min(pmid), max(pmid), count(*)\n from z_pmto2\n group by userids;\n\n "); $ex->query("\n\n update z_pmto2 as p\n left join z_pmgroup g\n on p.userids = g.userids\n set p.groupid = g.firstmessageid;\n\n "); $ex->query("\n\n update z_pmto as p\n left join z_pmto2 p2\n on p.pmid = p2.pmid\n set p.groupid = p2.groupid;\n\n "); $ex->query("create index z_idx_pmto_cid on z_pmto(groupid);"); $ex->query("create index z_idx_pmgroup_cid on z_pmgroup(firstmessageid);"); $conversation_Map = array('conversationid' => 'ConversationID', 'firstmessageid' => 'FirstMessageID', 'lastmessageid' => 'LastMessageID', 'countparticipants' => 'CountParticipants', 'countmessages' => 'CountMessages'); $ex->exportTable('Conversation', "\n\n select *, firstmessageid as conversationid, 2 as countparticipants\n from z_pmgroup\n left join :_message\n on groupid = _key;\n\n ", $conversation_Map); $conversationMessage_Map = array('messageid' => 'MessageID', 'conversationid' => 'ConversationID', 'content' => 'Body', 'format' => 'Format', 'fromuid' => 'InsertUserID', 'timestamp' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate'))); $ex->exportTable('ConversationMessage', "\n\n select groupid as conversationid, pmid as messageid, content, 'Text' as format, fromuid, timestamp\n from z_pmto2\n left join :_message\n on concat('message:', pmid) = _key\n\n ", $conversationMessage_Map); $userConversationMap = array('conversationid' => 'ConversationID', 'userid' => 'UserID', 'lastmessageid' => 'LastMessageID'); $ex->exportTable('UserConversation', "\n\n select p.groupid as conversationid, userid, lastmessageid\n from z_pmto p\n left join z_pmgroup\n on firstmessageid = p.groupid;\n\n ", $userConversationMap); //Bookmarks (watch) $userDiscussion_Map = array('members' => 'UserID', '_key' => array('Column' => 'DiscussionID', 'Filter' => array($this, 'idFromKey')), 'bookmarked' => 'Bookmarked'); $ex->exportTable('UserDiscussion', "\n select members, _key, 1 as bookmarked\n from :_tid_followers__members\n left join :_tid_followers\n on _parentid = _id\n ", $userDiscussion_Map); //Reactions if (!$ex->indexExists('z_idx_topic_mainpid', ':_topic')) { $ex->query("create index z_idx_topic_mainpid on :_topic(mainPid);"); } if (!$ex->indexExists('z_idx_uid_downvote', ':_uid_downvote')) { $ex->query("create index z_idx_uid_downvote on :_uid_downvote(value);"); } if (!$ex->indexExists('z_idx_uid_upvote', ':_uid_upvote')) { $ex->query("create index z_idx_uid_upvote on :_uid_upvote(value);"); } $userTag_Map = array('tagid' => 'TagID', 'recordtype' => 'RecordType', '_key' => array('Column' => 'UserID', 'Filter' => array($this, 'idFromKey')), 'value' => 'RecordID', 'score' => array('Column' => 'DateInserted', 'Filter' => array($this, 'tsToDate')), 'total' => 'Total'); $ex->exportTable('UserTag', "\n\n select 11 as tagid, 'Discussion' as recordtype, u._key, u.value, score, total\n from :_uid_upvote u\n left join z_discussionids t\n on u.value = t.tid\n left join z_reactiontotalsupvote r\n on r.value = u.value\n where u._key != 'uid:NaN:upvote'\n and t.tid is not null\n\n union\n\n select 11 as tagid, 'Comment' as recordtype, u._key, u.value, score, total\n from :_uid_upvote u\n left join z_discussionids t\n on u.value = t.tid\n left join z_reactiontotalsupvote r\n on r.value = u.value\n where u._key != 'uid:NaN:upvote'\n and t.tid is null\n\n union\n\n select 10 as tagid, 'Discussion' as recordtype, u._key, u.value, score, total\n from :_uid_downvote u\n left join z_discussionids t\n on u.value = t.tid\n left join z_reactiontotalsdownvote r\n on r.value = u.value\n where u._key != 'uid:NaN:downvote'\n and t.tid is not null\n\n union\n\n select 10 as tagid, 'Comment' as recordtype, u._key, u.value, score, total\n from :_uid_downvote u\n left join z_discussionids t\n on u.value = t.tid\n left join z_reactiontotalsdownvote r\n on r.value = u.value\n where u._key != 'uid:NaN:downvote'\n and t.tid is null\n\n ", $userTag_Map); //TODO: Permissions $ex->endExport(); }