Версия для печати
Журналы: FatCat -> Коты онлайн
09 ноября 2008
 19:33   Мигратор...
... начал делать.

Скрипт миграции (перенос с добавлением) из движка 2.3.6 в наш движок.

Не знаю, пригодится ли нам хоть когда-нибудь. Но раз делаю, сохраню инфу и у нас: пусть будет.

Комментарий FatCat - 9.11.2008 - 20:38:
Пока что сделано:
Код
<?php

/*
Скрипт переноса и добавления данных
из IP.Board 2.3.6 (с другими версиями не тестировался
в IPB 1.3 final / FatCat edition

NB:
Если есть форумы более второго уровня вложенности - под них создается новая категория, и туда они сваливаются навалом.
Права доступа - только администраторы. Скины не присваиваются, ибо не совместимы в принципе.

КАК ПОЛЬЗОВАТЬСЯ:

1. Установить таблицы вторичного форума в ту же БД с префиксом ibf2_
  Утилита BigDump и текстовые редакторы автозамены в руки.
2.

*/


//-----------------------------------------------
// USER CONFIGURABLE ELEMENTS
//-----------------------------------------------

// Root path

$root_path = "../";

error_reporting  (E_ERROR | E_WARNING | E_PARSE);
set_magic_quotes_runtime(0);

class info {

var $input      = array();
var $base_url   = "";
var $vars       = "";
function info() {
 global $sess, $std, $DB, $root_path, $INFO;
 
 $this->vars = &$INFO;
 
}
}

//--------------------------------
// Import $INFO, now!
//--------------------------------

require $root_path."conf_global.php";

//--------------------------------
// Require our global functions
//--------------------------------

require $root_path."sources/functions.php";

$std   = new FUNC;

//--------------------------------
// Load the DB driver and such
//--------------------------------

$INFO['sql_driver'] = !$INFO['sql_driver'] ? 'mySQL' : $INFO['sql_driver'];

$to_require = $root_path."sources/Drivers/".$INFO['sql_driver'].".php";
require ($to_require);

$DB = new db_driver;

$DB->obj['sql_database']     = $INFO['sql_database'];
$DB->obj['sql_user']         = $INFO['sql_user'];
$DB->obj['sql_pass']         = $INFO['sql_pass'];
$DB->obj['sql_host']         = $INFO['sql_host'];
$DB->obj['sql_tbl_prefix']   = $INFO['sql_tbl_prefix'];

// Get a DB connection

$DB->connect();

//--------------------------------
// Wrap it all up in a nice easy to
// transport super class
//--------------------------------

$ibforums             = new info();

//--------------------------------
//  Set up our vars
//--------------------------------

$ibforums->input      = $std->parse_incoming();
$ibforums->base_url   = $ibforums->vars['board_url'].'/index.'.$ibforums->vars['php_ext'];

//--------------------------------
// What to do?
//--------------------------------

echo("Делаем миграцию форума 2.3.6 =&gt; 1.3<hr>");


get_info();

$cat_struct=do_cats(); //  Тащим структуру категорий/форумов.

echo($cat_struct);

//-------------------------------------------------
//  Тянем инфу реципиента.
//-------------------------------------------------

function get_info() {
global $DB, $ibforums, $root_path, $std, $INFO;
// Тянем структуру категорий реципиента
$DB->query( "SELECT max( id ) AS mid, max( position ) AS pos FROM ibf_categories" );
$out = $DB->fetch_row();
define('MAX_CAT_ID',  $out['mid']);  // Последний айдишник категории реципиента
define('MAX_CAT_POS',  $out['pos']); // Последняя позиция категории реципиента

// Тянем структуру форумов реципиента
$DB->query( "SELECT max( id ) AS mid, max( position ) AS pos FROM ibf_forums" );
$out = $DB->fetch_row();
define('MAX_FORUM_ID',  $out['mid']); // Последний айдишник форума реципиента
define('MAX_FORUM_POS',  $out['pos']); // Последняя позиция форума реципиента

// Тянем настройки мемберов реципиента
$DB->query( "SELECT max( id ) AS mid FROM ibf_members" );
$out = $DB->fetch_row();
define('MAX_MEMBER_ID',  $out['mid']); // Последний айдишник мембера реципиента

// Тянем настройки топиков реципиента
$DB->query( "SELECT max( tid ) AS mid FROM ibf_topics" );
$out = $DB->fetch_row();
define('MAX_TOPICS_ID',  $out['mid']); // Последний айдишник топиков реципиента
}


//-------------------------------------------------
//  Тащим структуру категорий/форумов.
//-------------------------------------------------

function do_cats() {
global $DB, $ibforums, $root_path, $std, $INFO;

// Счетчики:
$cats = "|";
$forum_in_cats = "|";
$cat_count = intval(MAX_CAT_ID);
$pos_count = intval(MAX_CAT_POS);
$for_count = intval(MAX_FORUM_ID);

// Готовим код миграции категорий и форумов
$cat_struc = "";
$DB->query( "SELECT * FROM ibf2_forums ORDER BY parent_id ASC" ); // Не менять ORDER!!! Иначе полетит структура категорий донора.
while( $out = $DB->fetch_row() )
{
 // Создаем sql-запросы создания новых категорий:
 if($out['parent_id'] == "-1")
 {
  $cat_count++;
  $pos_count++;
  $cat_id_curent = intval(MAX_CAT_ID)+intval($out['id']);
  $cats .= $out['id']."|";
  // Миграция категорий:
  $cat_struc .= "INSERT INTO `ibf_categories` VALUES (".$cat_id_curent.", ".$pos_count.", '1', '".$out['name']."', '".$out['description']."', '', '');<br>";
 }
 // Создаем sql-запросы создания новых форумов:
 else
 {
  // Пересчитываем...
  $for_count++;
  $out['last_poster_id'] = intval($out['last_poster_id']) + intval(MAX_MEMBER_ID);
  $out['position'] = intval($out['position']) + intval(MAX_FORUM_POS);
  if($out['newest_id']>0) $out['newest_id'] = intval($out['newest_id']) + intval(MAX_TOPICS_ID);
  if( stristr($cats, "|".$out['parent_id']."|") ) // Форум первого уровня
  {
   // Создаем список форумов первого уровня с категориями:
   $forum_in_cats .= $out['id'].">".$out['parent_id']."|".$for_count."|";
   // Миграция форумов первого уровня в категории:
   $categories = MAX_CAT_ID + intval($out['parent_id']);
   $cat_struc .= "INSERT INTO ibf_forums VALUES (".$for_count.", ".$out['topics'].", ".$out['posts'].", ".$out['last_post'].", ".$out['last_poster_id'].", '".$out['last_poster_name']."', '".$out['name']."', '".$out['description']."', ".$out['position'].", ".$out['use_ibc'].", ".$out['use_html'].", '".$out['status']."', '4', '4', '4', '', ".$categories.", '".$out['newest_title']."', ".$out['newest_id'].", 'last_post', 'Z-A', 100, 0, '4', 0, 1, 0, 1, 0, -1, 0, 1, 1, '".$out['redirect_url']."', ".$out['redirect_on'].", 0, '', '', '', 0, '', '');<br>";
  }
 }
}

// Второй прогон для выявления форумов второго и выше уровней вложенности:
// Перезапускаем счетчики:
$cat_count = intval(MAX_CAT_ID);
$pos_count = intval(MAX_CAT_POS);
$for_count = intval(MAX_FORUM_ID);
// Готовимся запомнить форумы выше второго уровня:
$third_forums = "";
// Пытаем БД донора:
$DB->query( "SELECT * FROM ibf2_forums ORDER BY parent_id ASC" ); // Не менять ORDER!!! Иначе полетит структура категорий донора.
while( $out = $DB->fetch_row() )
{
 if($out['parent_id'] != "-1") // Отсекаем категории
 {
  $for_count++;
  $out['last_poster_id'] = intval($out['last_poster_id']) + intval(MAX_MEMBER_ID);
  $out['position'] = intval($out['position']) + intval(MAX_FORUM_POS);
  if($out['newest_id']>0) $out['newest_id'] = intval($out['newest_id']) + intval(MAX_TOPICS_ID);
  if( !stristr($cats, "|".$out['parent_id']."|") ) // Отсекаем форумы первого уровня
  {
   if( stristr($forum_in_cats, "|".$out['parent_id'].">") ) // Ловим форумы второго уровня
   {
    $find_cat_id = explode("|".$out['parent_id'].">", $forum_in_cats);
    $find_cat_id = $find_cat_id[1];
    $find_cat_id = explode("|", $find_cat_id);
    $parent_forum = $find_cat_id[1];
    $find_cat_id = $find_cat_id[0];
    $find_cat_id = intval($find_cat_id) + intval(MAX_CAT_ID);
    // Миграция форумов второго уровня
    $cat_struc .= "INSERT INTO ibf_forums VALUES (".$for_count.", ".$out['topics'].", ".$out['posts'].", ".$out['last_post'].", ".$out['last_poster_id'].", '".$out['last_poster_name']."', '".$out['name']."', '".$out['description']."', ".$out['position'].", ".$out['use_ibc'].", ".$out['use_html'].", '".$out['status']."', '4', '4', '4', '', ".$find_cat_id.", '".$out['newest_title']."', ".$out['newest_id'].", 'last_post', 'Z-A', 100, 0, '4', 0, 1, 0, 1, 0, ".$parent_forum.", 0, 1, 1, '".$out['redirect_url']."', ".$out['redirect_on'].", 0, '', '', '', 0, '', '');<br>";
    // Делаем отображение дочернего форума в родительском:
    $cat_struc .= "UPDATE ibf_forums SET subwrap = '1' WHERE id = ".$parent_forum.";<br>";
   }
   else // Ловим форумы выше второго уровня
   {
    $third_forums .= "INSERT INTO ibf_forums VALUES (".$for_count.", ".$out['topics'].", ".$out['posts'].", ".$out['last_post'].", ".$out['last_poster_id'].", '".$out['last_poster_name']."', '".$out['name']."', '".$out['description']."', ".$out['position'].", ".$out['use_ibc'].", ".$out['use_html'].", '".$out['status']."', '4', '4', '4', '', will_be_new_cat_id, '".$out['newest_title']."', ".$out['newest_id'].", 'last_post', 'Z-A', 100, 0, '4', 0, 1, 0, 1, 0, -1, 0, 1, 1, '".$out['redirect_url']."', ".$out['redirect_on'].", 0, '', '', '', 0, '', '');<br>";
   }
  }
 }
}
// Если есть форумы выше второго уровня, делаем для них новую категорию:

if($third_forums != "")
{
 $swalka_id = $cat_id_curent +1;
 $cat_struc .= "INSERT INTO ibf_categories VALUES (".$swalka_id.", ".(intval($pos_count) + 1).", '1', 'Временная категоря', 'Сюда мигрировали форумы глубокого вложения, недопустимые в текущей версии ситемы', '', '');<br>";
 $third_forums = str_replace("will_be_new_cat_id", $swalka_id, $third_forums);
 $cat_struc .= $third_forums;
}

//die($third_forums);
return $cat_struc;
}

?>


Скрипт пока ничего не модернизирует, а лишь выводит на экран sql-запросы миграции структуры форумов и категорий.
Комментарий Кибоко - 10.11.2008 - 15:20:
Воще какие-то слова фантастические. Ну надо же! Вот Кот понимает, что пишет! А я ни фига не рублю тему smile.gif
Комментарий FatCat - 12.11.2008 - 23:03:
Сделал миграцию топиков. Пока мигрируют пустыми, без постов, миграцию постов сделаю позже.
Опять пришлось изрядно потрахаться, чтобы топики легли не свалкой, а в свои собственные форумы.
Был какой-то глюк, когда топик был не виден в форуме, но появился при смене скина с дефолтного на форумный.
При последующих прогонах глюк не повторялся...

Голосования не мигрируют - у двушек другой формат голосований, с поддержкой многоуровневости, на нашем движке такое не пойдет.
Если уж очень присрется, придется делать вызов топиков по http, парсить таблицу результатов голосований и добавлять ее в начало первого поста. Геморрой преизряднейший; и главное, тормозить конвертер будет так, что мама не горюй...
Комментарий FatCat - 14.11.2008 - 16:52:
Сдалал миграцию постов.

Параллельно понял, как конвертировать аттачи.

В двушках мультиаттач сделан по кею в таблице постов: Сами аттачи пишутся в таблицу аттачей и сопоставляются посту по кею поста.
В однушках все аттачи пишутся в таблицу постов.

Пока в двушке в посте один аттач - конвертировать возможно.
Если в двушке несколько аттачей на один пост - конвертировать невозможно.

Вывод печальный: придется делать двухходовой сценарий:
если (кей в таблице аттачей уникальный) => конвертировать в 1.3;
эльзе => перезаписывать аттач "незащищенный" файл, генерировать линк и добавлять в конец поста.

Но с аттачами наверное позже. Следующая задача - миграция юзеров.
Тут уже никакой совместимости. Придется в движок вставлять вторичную авторизацию по алгоритму "двушки", делать вызов вторичной авторизации если в первичной авторизации пустой пароль; в случае успешной вторичной авторизации перехватывать пароль, шифровать и писать в первичную авторизацию; и затем удалять строку вторичной авторизации...
Комментарий FatCat - 16.11.2008 - 03:21:
Опробовал на реальной базе phpforum миграцию категорий, форумов, топиков и постов.
Пол-дня разбирался с ошибками sql...
У двушки другой парсер постов - разрешает спецсимволы без перевода в метасимволы. Намучался с одиночными кавычками и обратными слэшами. Особливо, когда запостили код, содержащий отслэшенную кавычку; и она в БД так и лежит отслешенной кавычкой... Мрак, убил кучу времени на репарсер; потом плюнул и разделил пробелом... Может потом что лучше в голову придет...
Комментарий FatCat - 16.11.2008 - 20:59:
День убил на миграцию аттачей.
Но зато и вправду классно получилось.
Множественные аттачи в одном сообщении сохранены незащищенными и без счетчика, зато первые и единственные аттачи сохранены и с защитой, и со счетчиком.

Картинки совсем красиво: двушечные превьюшки встали в заголовок спойлера, а под спойлером полноформатные.
Комментарий FatCat - 21.11.2008 - 15:25:
Собственно, сделал еще вчера. Как раз к 5-летнему юбилею нашего движка.


Комментарии :0

Нет комментариев к выбранной записи.

mJournal v1.05   © 2003-2004 by UriSoft and IBResource.ru