require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
while(ob_end_flush());
$APPLICATION->SetTitle("Миграция");
if ($_REQUEST['go'])
{
CModule::IncludeModule("forum");
// ошибки будут фиксироваться в лог файле и выводиться пользователю в iframe
define('LOG_FILENAME',$_SERVER["DOCUMENT_ROOT"].'/log.txt');
// $BREAK_POINT - метка в которой хранится позиция с которой
// будет начинаться следующий шаг минрации
if ($_REQUEST['break_point']) $BREAK_POINT = $_REQUEST['break_point'];
else @unlink(LOG_FILENAME);
if ($_REQUEST['START']) $START = $_REQUEST['START'];
// Функция миграции групп пользователей,
// пользователи выгружаются пока не будет импортирован последний
// На последнем шаге функции MigrateUserGroups устанавливается $START = 'Users'
// и скрипт переходит к функции MigrateUsers
if (!$START) MigrateUserGroups($BREAK_POINT);
if ($START == 'Users') MigrateUsers($BREAK_POINT);
if ($START == 'ForumGroups') MigrateForumGroups($BREAK_POINT);
if ($START == 'Forums') MigrateForums($BREAK_POINT);
if ($START == 'Topics') MigrateTopics($BREAK_POINT);
if ($START == 'Posts') MigratePosts($BREAK_POINT);
// Форма которая отпраляет запрос для запуска нового шага
// Отправка формы реализуется яваскриптом
// В запросе хранится метка break_point и метка START
if ($BREAK_POINT && !defined('END'))
{?>
//текст показывает текущий статус импорта?>
Идет импорт ...
=$TEXT?>
}
// iframe выводит содержимое файла log.txt
// который содержит ошибки возникающие в процессе выгрузки
$iframe = "";
if (file_exists(LOG_FILENAME))
echo $iframe;
}
else
{
global $DB;
// создаем таблицу для хранения данных авторизации пользователей,
// полученных методом кодирования паролей в MyBB(см. задача №3)
$DB -> Query("CREATE TABLE IF NOT EXISTS old_user (
LOGIN varchar(60) NOT NULL,
PASSWORD varchar(64) NOT NULL,
SALT varchar(64) NOT NULL,
PRIMARY KEY (LOGIN));"
);
// Эта форма запускает сам скрипт
echo"";
}
// Далее пройдемся по самим функциям переноса разных объектов.
// Начнем с групп пользователей.
// Тут все просто.
function MigrateUserGroups($ID)
{
global $BREAK_POINT, $START, $TEXT;
// подключение к БД вынес в отдельную функцию
$link = ConnectDb();
if (!$ID) $ID=0;
// один шаг = одна запись в из таблицы групп пользователей в MyBB
$step = 1;
// получаем одну запись из таблицы mybb_usergroups,
// где ID больше чем ID на котором завершился прошлый шаг выполнения этой функции
$query ="SELECT * FROM mybb_usergroups where gid > $ID LIMIT $step";
$resUserGroups = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
// устанавливаем флаг окончания работы функции MigrateUserGroups в true
$bFinish = true;
$ObGroup = new CGroup;
while ($userGroup = mysql_fetch_assoc($resUserGroups))
{
// пока $bFinish!=true на следующем шаге будет выполняться MigrateUserGroups
$bFinish = false;
$arFields = Array(
"ACTIVE" => "Y",
"C_SORT" => 100,
"NAME" => $userGroup['title'],
"DESCRIPTION" => $userGroup['description'],
"STRING_ID" => $userGroup['gid']//сюда записываем id из старой БД(см. задача №2)
);
$GID = $ObGroup->Add($arFields);
if (strlen($ObGroup -> LAST_ERROR)>0)
{ //записываем в файл log.txt ошибки, которые будут выводится во фрейме
AddMessage2Log($ObGroup -> LAST_ERROR);
}
//запоминаем id группы с которого будет начинаться следующий шаг
$BREAK_POINT = $userGroup['gid'];
}
// Если заходили в цикл while ($userGroup = mysql_fetch_assoc($resUserGroups)),
// то $bFinish = false;
// Если не заходили в цикл, то группы закончились, $bFinish = true, переходим к функции MigrateUsers
if ($bFinish)
{
//если все группы пользователей импортированы,
//то переходим к выгрузке самих пользователей
$START = 'Users';
$BREAK_POINT = 0;
}
else
$TEXT = "Импортируется группа пользователей: $BREAK_POINT";
}
//Далее пользователи:
function MigrateUsers($ID)
{
global $BREAK_POINT, $START, $TEXT, $DB;
$link = ConnectDb();
$ObUser = new CUser;
// один шаг = 100 записей
$step = 100;
$query ="SELECT * FROM mybb_users where uid > $ID and username != 'admin' LIMIT $step";
$resUsers = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
$bFinish = true;
while ($user = mysql_fetch_assoc($resUsers))
{
$bFinish = false;
$avatarPath = substr($user['avatar'], 1, strlen($user['avatar']));
// получаем новые id групп пользователей по старому id в MyBB, хранящемуся в STRING_ID(см. задача №2)
$obGroups = CGroup::GetList(($by="ID"), ($order="desc"), array('STRING_ID' => $user['usergroup']));
while ($arGroup=$obGroups->GetNext()) :
$groupId[] = $arGroup['ID'];
endwhile;
$arFields = Array(
"XML_ID" => $user['uid'],//сюда записываем id из старой БД(см. задача №2)
"LOGIN" => $user['username'],
"PASSWORD" => $user['password'],
"CONFIRM_PASSWORD" => $user['password'],
"ACTIVE" => "Y",
"NAME" => $user['username'],
"SECOND_NAME" => '',
"LAST_NAME" => '',
"EMAIL" => $user['email'],
"LAST_LOGIN" => ConvertTimeStamp($user['lastactive'],"FULL"),
"LAST_ACTIVITY_DATE" => ConvertTimeStamp($user['lastactive'],"FULL"),
"LID" => 's1',
"GROUP_ID" => $groupId,//записываем актуальные id групп пользователей
"PERSONAL_ICQ" => !$user['icq'] ? '' : $user['icq'],
"PERSONAL_PHOTO" => CFile::MakeFileArray('/home/blablabla/'.$avatarPath),
);
$UID = $ObUser->Add($arFields);
//Если, при добавлении пользователя, возникла ошибка, то пишем её в log.txt
if (strlen($ObUser->LAST_ERROR)>0)
{
AddMessage2Log($ObUser->LAST_ERROR);
}
//иначе добавляем пользователя форума
else
{
$arFields = Array(
"USER_ID" => $UID,
"DESCRIPTION" => $user['usertitle'],
"IP_ADDRESS" => $user['lastip'],
"AVATAR" => CFile::MakeFileArray('/home/blablabla/'.$avatarPath),
"NUM_POSTS" => $user['postnum'],
"LAST_POST" => $user['lastpost'],
"LAST_VISIT" => ConvertTimeStamp($user['lastvisit'],"FULL"),
"DATE_REG" => ConvertTimeStamp($user['regdate'],"FULL"),
"REAL_IP_ADDRESS" => $user['lastip'],
"SIGNATURE" => $user['signature'],
);
if (!CForumUser::Add($arFields))
{
$e = $GLOBALS['APPLICATION']->GetException();
if ($e && $str = $e->GetString())
AddMessage2Log("Ошибка: ".$str);
else
AddMessage2Log("Неизвестная ошибка");
}
// Добавляем в таблицу old_user данные авторизации
//закодированные алгоритмом MyBB(см. задача № 3)
$DB->Insert("old_user",
array(
"LOGIN" => "'".$DB->ForSQL($user['username'])."'",
"PASSWORD" => "'".$DB->ForSQL($user['password'])."'",
"SALT" => "'".$DB->ForSQL($user['salt'])."'",
)
);
}
$BREAK_POINT = $user['uid'];
}
if ($bFinish)
{
$START = 'ForumGroups';
$BREAK_POINT = 0;
}
else
$TEXT = "Группы пользователей импортированы.
Импортируется пользователь: $BREAK_POINT";
}
//Перенос групп форумов
function MigrateForumGroups($ID)
{
global $BREAK_POINT, $START, $TEXT;
$link = ConnectDb();
$step = 1;
// группы форумов и сами форумы хранятся в MyBB в одной таблице
// отличаются они значением в поле type, для групп форумов type = 'c'
$query = "SELECT * from mybb_forums where fid > $ID and type = 'c' LIMIT $step";
$resForumGroups = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
$arSysLangs = array();
$arGroupForumsId = array();
// Получам языки сайта
$ObLangs = CLanguage::GetList($by="lid", $order="desc", Array());
while($lang = $ObLangs->Fetch())
{
$arSysLangs[] = $lang['LID'];
}
$bFinish = true;
while ($forumGroup = mysql_fetch_assoc($resForumGroups))
{
$bFinish = false;
for ($i = 0; $i $arSysLangs[$i],
"NAME" => $forumGroup['name'],
"DESCRIPTION" => $forumGroup['description'],
);
$arFields["XML_ID"] = $forumGroup['fid'];
}
$FGID = CForumGroup::Add($arFields);
if (!$FGID)
{
$e = $GLOBALS['APPLICATION']->GetException();
if ($e && $str = $e->GetString())
AddMessage2Log("Ошибка: $str");
else
AddMessage2Log("Неизвестная ошибка");
}
$BREAK_POINT = $forumGroup['fid'];
}
if ($bFinish)
{
$START = 'Forums';
$BREAK_POINT = 0;
}
else
$TEXT = "Группы пользователей импортированы
Пользователи импортированы
Импортируется группа $BREAK_POINT форума";
}
//Перенос форумов
function MigrateForums($ID)
{
global $BREAK_POINT, $START, $TEXT;
$link = ConnectDb();
$step = 5;
// группы форумов и сами форумы хранятся в MyBB в одной таблице
// отличаются они значением в поле type, для форумов type = 'f'
$query = "SELECT * from mybb_forums where fid > $ID and type = 'f' LIMIT $step" ;
$resForums = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
$Sites = CSite::GetList();
while ($Site = $Sites->Fetch())
{
$arSites[$Site['LID']] = '/forum/index.php?PAGE_NAME=message&FID=#FORUM_ID#&TID=#TOPIC_ID#&MID=#MESSAGE_ID#';
}
$bFinish = true;
while ($forum = mysql_fetch_array($resForums))
{
$bFinish = false;
// Получаем новые id групп пользователей, по старым, хранящимся в XML_ID (см. задача №2)
// Стандартно не работает фильтрация групп форумов по xml_id
// Нужно в \bitrix\modules\forum\classes\general\forum_new.php
// для функции CForumGroup::GetList(строка 2014) добавить case "XML_ID":
$obForumGroup = CForumGroup::GetList(array(), array('XML_ID' => $forum['pid']));
$forumGroup=$obForumGroup->GetNext();
$forumGroupId = $forumGroup['ID'];
$arFields = Array(
"ACTIVE" => "Y",
"NAME" => $forum['name'],
"DESCRIPTION" => $forum['description'],
"FORUM_GROUP_ID" => $forumGroupId,
"SITES" => $arSites,
"TOPICS" => $forum['threads'],
"POSTS" => $forum['posts'],
"LAST_POSTER_ID" => $forum['lastposteruid'],
"LAST_POSTER_NAME" => $forum['lastposter'],
"LAST_MESSAGE_ID" => $forum['lastpost'],
"XML_ID" => $forum['fid']
);
if (!CForumNew::Add($arFields))
{
$e = $GLOBALS['APPLICATION']->GetException();
if ($e && $str = $e->GetString())
AddMessage2Log("Ошибка: ".$str);
else
AddMessage2Log("Неизвестная ошибка");
}
$BREAK_POINT = $forum['fid'];
}
if ($bFinish)
{
$START = 'Topics';
$BREAK_POINT = 0;
}
else
$TEXT = "Группы пользователей импортированы
Пользователи импортированы
Группы форумов импортированы
Импортируется форум: $BREAK_POINT";
}
//Перенос тем форумов
function MigrateTopics($ID)
{
global $BREAK_POINT, $START, $TEXT;
$link = ConnectDb();
$step = 100;
$query = "SELECT * from mybb_threads where tid > $ID LIMIT $step" ;
$resTopics = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
$bFinish = true;
while ($topic = mysql_fetch_assoc($resTopics))
{
$bFinish = false;
$obForum = CForumNew::GetList(array(), array('XML_ID' => $topic['fid']));
$forum=$obForum->GetNext();
$forumId = $forum['ID'];
$obUser = CUser::GetList(($by="ID"), ($order="desc"), array('XML_ID' => $topic['uid']), array('FIELDS' => array('ID')));
$user=$obUser->GetNext();
$userId = $user['ID'];
$obLastPoster = CUser::GetList(($by="ID"), ($order="desc"), array('XML_ID' => $topic['lastposteruid']), array('FIELDS' => array('ID')));
$lastPoster = $obLastPoster->GetNext();
$lastPosterId = $lastPoster['ID'];
$arFields = Array(
"XML_ID" => $topic["tid"],
"TITLE" => $topic["subject"],
"STATE" => $topic["closed"] === 0 ? 'N' : 'Y',
"USER_START_ID" => $userId,
"USER_START_NAME" => $topic["username"],
"START_DATE" => ConvertTimeStamp($topic["dateline"],"FULL"),
"POSTS" => $topic["replies"],
"VIEWS" => $topic["views"],
"FORUM_ID" => $forumId,
"APPROVED" => 'Y',
"LAST_POSTER_ID" => $lastPosterId,
"LAST_POSTER_NAME" => $topic["lastposter"],
"LAST_POST_DATE" => ConvertTimeStamp($topic["lastpost"],"FULL"),
);
if (!CForumTopic::Add($arFields))
AddMessage2Log("Ошибка и мпорта топика");
$BREAK_POINT = $topic['tid'];
}
if ($bFinish)
{
$START = 'Posts';
$BREAK_POINT = 0;
}
else
$TEXT = "Группы пользователей импортированы
Пользователи импортированы
Группы форумов импортированы
Форумы импортированы
Импортируется топик: $BREAK_POINT";
}
// Перенос сообщений в темах форумов
function MigratePosts($ID)
{
global $BREAK_POINT, $START, $TEXT;
$link = ConnectDb();
$step = 100;
$query = "SELECT * from mybb_posts where pid > $ID LIMIT $step" ;
$resPosts = mysql_query($query , $link) or die("Invalid query: " . mysql_error());
$bFinish = true;
while ($post = mysql_fetch_assoc($resPosts))
{
$bFinish = false;
$obForum = CForumNew::GetList(array(), array('XML_ID' => $post['fid']));
$forum=$obForum->GetNext();
$forumId = $forum['ID'];
$obTopic = CForumTopic::GetList(array(), array('XML_ID' => $post['tid']));
$topic=$obTopic->GetNext();
$topicId = $topic['ID'];
$obUser = CUser::GetList(($by="ID"), ($order="desc"), array('XML_ID' => $post['uid']), array('FIELDS' => array('ID')));
$user=$obUser->GetNext();
$userId = $user['ID'];
$arFields = Array(
"AUTHOR_ID" => $userId,
"AUTHOR_NAME" => $post["username"],
"AUTHOR_IP" => $post["ipaddress"],
"USE_SMILES" => 'Y',
"POST_DATE" => ConvertTimeStamp($post["dateline"],"FULL"),
"POST_MESSAGE" => $post["message"],
"FORUM_ID" => $forumId,
"TOPIC_ID" => $topicId,
"APPROVED" => 'Y',
);
if (!CForumMessage::Add($arFields))
{
$e = $GLOBALS['APPLICATION']->GetException();
if ($e && $str = $e->GetString())
AddMessage2Log("Ошибка: $str");
else
AddMessage2Log("Неизвестная ошибка");
}
$BREAK_POINT = $post['pid'];
}
if ($bFinish)
{
//define('END', true); для завершения миграции
define('END', true);
$TEXT = "Группы пользователей импортированы
Пользователи импортированы.
Группы форумов импортированы.
Форумы импортированы.
Топики импортированы.
Посты импортированы.
Миграция завершена";
}
else
$TEXT = "Группы пользователей импортированы
Пользователи импортированы.
Группы форумов импортированы.
Форумы импортированы.
Топики импортированы.
Импортируется пост: $BREAK_POINT";
}
//функция для подключения к БД MyBB
function ConnectDb()
{
$link = mysql_connect('localhost:31006', 'root', '', true);
mysql_query("SET NAMES 'utf-8'", $link);
$db_selected = mysql_select_db('sitemanager', $link);
if (!$db_selected)
{
echo('Ошибка подключения к БД');
die();
}
return ($link);
}
?>