示例#1
0
 /**
  * Export each table one at a time.
  *
  * @param ExportModel $Ex
  */
 protected function ForumExport($Ex)
 {
     // Allow limited export of 1 category via ?forumid=ID
     $ForumID = $this->Param('forumid');
     if ($ForumID) {
         $ForumWhere = ' and t.forumid ' . (strpos($ForumID, ', ') === false ? "= {$ForumID}" : "in ({$ForumID})");
     } else {
         $ForumWhere = '';
     }
     // Determine the character set
     $CharacterSet = $Ex->GetCharacterSet('post');
     if ($CharacterSet) {
         $Ex->CharacterSet = $CharacterSet;
     }
     // Begin
     $Ex->BeginExport('', 'vBulletin 3.* and 4.*');
     $this->ExportBlobs($this->Param('files'), $this->Param('avatars'), $ForumWhere);
     if ($this->Param('noexport')) {
         $Ex->Comment('Skipping the export.');
         $Ex->EndExport();
         return;
     }
     // Check to see if there is a max date.
     $MinDate = $this->Param('mindate');
     if ($MinDate) {
         $MinDate = strtotime($MinDate);
         $Ex->Comment("Min topic date ({$MinDate}): " . date('c', $MinDate));
     }
     $Now = time();
     $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' => array('Column' => 'Title', 'Filter' => function ($Value) {
         return trim(strip_tags(str_replace(' ', ' ', $Value)));
     }), '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';
     }
     $Ex->ExportTable('User', "select u.*,\n            ipaddress as ipaddress2,\n            concat(`password`, salt) as password2,\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            'vbulletin' as HashMethod\n         from :_user u\n         left join :_customavatar a\n            on u.userid = a.userid\n         left join :_avatar av\n            on u.avatarid = av.avatarid\n         left join :_userban ub\n              on u.userid = ub.userid and ub.liftdate <= now() ", $User_Map);
     // ":_" will be replace by database prefix
     // 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) {
                     if (!$GroupID) {
                         continue;
                     }
                     $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);
     //      $Ex->EndExport();
     //      return;
     // 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)\n               select userid, 'Profile." . $Name . "', " . $Column . " from :_userfield where " . $Column . " != ''";
         }
         foreach ($ProfileQueries as $Query) {
             $Ex->Query($Query);
         }
     }
     // Signatures
     $Sql = "\n         select\n            userid as UserID,\n            'Plugin.Signatures.Sig' as Name,\n            signature as Value\n         from :_usertextfield\n         where nullif(signature, '') is not null\n\n         union\n\n         select\n            userid,\n            'Plugin.Signatures.Format',\n            'BBCode'\n         from :_usertextfield\n         where nullif(signature, '') is not null";
     $Ex->ExportTable('UserMeta', $Sql);
     // 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 ut.*, ut.title as title2, 0 as level\n         from :_usertitle ut\n         order by ut.minposts", $Rank_Map);
     // Categories
     $Category_Map = array('forumid' => 'CategoryID', 'description' => 'Description', 'Name2' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'displayorder' => array('Column' => 'Sort', 'Type' => 'int'), 'parentid' => 'ParentCategoryID');
     $Ex->ExportTable('Category', "select f.*, title as Name2\n         from :_forum f\n         where 1 = 1 {$ForumWhere}", $Category_Map);
     $MinDiscussionID = false;
     $MinDiscussionWhere = false;
     if ($MinDate) {
         $MinDiscussionID = $Ex->GetValue("\n            select max(threadid)\n            from :_thread\n            where dateline < {$MinDate}\n            ", false);
         $MinDiscussionID2 = $Ex->GetValue("\n            select min(threadid)\n            from :_thread\n            where dateline >= {$MinDate}\n            ", false);
         // The two discussion IDs should be the same, but let's average them.
         $MinDiscussionID = floor(($MinDiscussionID + $MinDiscussionID2) / 2);
         $Ex->Comment('Min topic id: ' . $MinDiscussionID);
     }
     // Discussions
     $Discussion_Map = array('threadid' => 'DiscussionID', 'forumid' => 'CategoryID', 'postuserid' => 'InsertUserID', 'postuserid2' => 'UpdateUserID', 'title' => array('Column' => 'Name', 'Filter' => 'HTMLDecoder'), 'Format' => 'Format', 'views' => 'CountViews', 'ipaddress' => 'InsertIPAddress');
     if ($Ex->Destination == 'database') {
         // Remove the filter from the title so that this doesn't take too long.
         $Ex->HTMLDecoderDb('thread', 'title', 'threadid');
         unset($Discussion_Map['title']['Filter']);
     }
     if ($MinDiscussionID) {
         $MinDiscussionWhere = "and t.threadid > {$MinDiscussionID}";
     }
     $Ex->ExportTable('Discussion', "select t.*,\n            t.postuserid as postuserid2,\n            p.ipaddress,\n            p.pagetext as Body,\n            'BBCode' as Format,\n            replycount+1 as CountComments,\n            convert(ABS(open-1),char(1)) as Closed,\n            if(convert(sticky,char(1))>0,2,0) as Announce,\n            FROM_UNIXTIME(t.dateline) as DateInserted,\n            FROM_UNIXTIME(lastpost) as DateUpdated,\n            FROM_UNIXTIME(lastpost) as DateLastComment\n         from :_thread t\n            left join :_deletionlog d on (d.type='thread' and d.primaryid=t.threadid)\n            left join :_post p on p.postid = t.firstpostid\n         where d.primaryid is null\n            and t.visible = 1\n            {$MinDiscussionWhere}\n            {$ForumWhere}", $Discussion_Map);
     // Comments
     $Comment_Map = array('postid' => 'CommentID', 'threadid' => 'DiscussionID', 'pagetext' => 'Body', 'Format' => 'Format', 'ipaddress' => 'InsertIPAddress');
     if ($MinDiscussionID) {
         $MinDiscussionWhere = "and p.threadid > {$MinDiscussionID}";
     }
     $Ex->ExportTable('Comment', "select p.*,\n            'BBCode' as Format,\n            p.userid as InsertUserID,\n            p.userid as UpdateUserID,\n         FROM_UNIXTIME(p.dateline) as DateInserted,\n            FROM_UNIXTIME(p.dateline) as DateUpdated\n         from :_post p\n         inner join :_thread t\n            on p.threadid = t.threadid\n         left join :_deletionlog d\n            on (d.type='post' and d.primaryid=p.postid)\n         where p.postid <> t.firstpostid\n            and d.primaryid is null\n            and p.visible = 1\n            {$MinDiscussionWhere}\n            {$ForumWhere}", $Comment_Map);
     // UserDiscussion
     if ($MinDiscussionID) {
         $MinDiscussionWhere = "where st.threadid > {$MinDiscussionID}";
     }
     $Ex->ExportTable('UserDiscussion', "select\n            st.userid as UserID,\n            st.threadid as DiscussionID,\n            '1' as Bookmarked,\n            FROM_UNIXTIME(tr.readtime) as DateLastViewed\n         from :_subscribethread st\n         left join :_threadread tr on tr.userid = st.userid and tr.threadid = st.threadid\n         {$MinDiscussionWhere}");
     /*$Ex->ExportTable('UserDiscussion', "select
         tr.userid as UserID,
         tr.threadid as DiscussionID,
         FROM_UNIXTIME(tr.readtime) as DateLastViewed,
         case when st.threadid is not null then 1 else 0 end as Bookmarked
       from :_threadread tr
       left join :_subscribethread st on tr.userid = st.userid and tr.threadid = st.threadid");*/
     // Activity (from visitor messages in vBulletin 3.8+)
     if ($Ex->Exists('visitormessage')) {
         if ($MinDiscussionID) {
             $MinDiscussionWhere = "and dateline > {$MinDiscussionID}";
         }
         $Activity_Map = array('postuserid' => 'RegardingUserID', 'userid' => 'ActivityUserID', 'pagetext' => 'Story', 'NotifyUserID' => 'NotifyUserID', 'Format' => 'Format');
         $Ex->ExportTable('Activity', "select *,\n               '{RegardingUserID,you} &rarr; {ActivityUserID,you}' as HeadlineFormat,\n               FROM_UNIXTIME(dateline) as DateInserted,\n               FROM_UNIXTIME(dateline) as DateUpdated,\n               INET_NTOA(ipaddress) as InsertIPAddress,\n               postuserid as InsertUserID,\n               -1 as NotifyUserID,\n               'BBCode' as Format,\n               'WallPost' as ActivityType\n            from :_visitormessage\n            where state='visible'\n               {$MinDiscussionWhere}", $Activity_Map);
     }
     $this->_ExportConversations($MinDate);
     $this->_ExportPolls();
     // Media
     if ($Ex->Exists('attachment')) {
         $this->ExportMedia($MinDiscussionID);
     }
     // IP Ban list
     $IpBanlist = $this->Param('ipbanlist');
     if ($IpBanlist) {
         $Ex->Query("DROP TABLE IF EXISTS `z_ipbanlist` ");
         $Ex->Query("CREATE TABLE `z_ipbanlist` (\n            `id` int(11) unsigned NOT NULL AUTO_INCREMENT,\n            `ipaddress` varchar(50) DEFAULT NULL,\n           PRIMARY KEY (`id`),\n           UNIQUE KEY `ipaddress` (`ipaddress`)\n\n         ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
         $Result = $Ex->Query("select value from :_setting where varname = 'banip'");
         $Row = mysql_fetch_assoc($Result);
         if ($Row) {
             $InsertSql = 'INSERT IGNORE INTO `z_ipbanlist` (`ipaddress`) values ';
             $IpString = str_replace("\r", "", $Row['value']);
             $IPs = explode("\n", $IpString);
             foreach ($IPs as $IP) {
                 $IP = trim($IP);
                 if (empty($IP)) {
                     continue;
                 }
                 $InsertSql .= '(\'' . mysql_real_escape_string($IP) . '\'), ';
             }
             $InsertSql = substr($InsertSql, 0, -2);
             $Ex->Query($InsertSql);
             $Ban_Map = array();
             $Ex->ExportTable('Ban', "select 'IPAddress' as BanType, ipaddress as BanValue, 'Imported ban' as Notes, NOW() as DateInserted\n                  FROM `z_ipbanlist`", $Ban_Map);
             $Ex->Query('DROP table if exists `z_ipbanlist` ');
         }
     }
     // End
     $Ex->EndExport();
 }