Пример класса для Migrate, для переноса тем из vBulletin 3.8.x в Drupal 7.x с сохранением вложений (импорт ответов в темах будет в следующем посте):
class ThreadsMigration extends Migration {
public function __construct() {
parent::__construct();
$this->dependencies = array(
'Structure', // http://xandeadx.ru/blog/drupal/512
'Users', // http://xandeadx.ru/blog/drupal/510
);
// Source
$query = Database::getConnection('default', 'vbulletin')->select('thread', 't');
$query->leftJoin('post', 'p', 'p.postid = t.firstpostid');
$query->fields('t', array('threadid', 'title', 'forumid', 'open', 'visible', 'postuserid', 'dateline', 'sticky', 'firstpostid'));
$query->fields('p', array('pagetext'));
$query->condition('open', 10, '!=');
$this->source = new MigrateSourceSQL($query, drupal_map_assoc(array('attachments', 'attachments_name')), NULL, array('map_joinable' => FALSE));
// Destination
$this->destination = new MigrateDestinationNode('post');
// Key schema
$source_key_schema = array('threadid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
$this->map = new MigrateSQLMap($this->machineName, $source_key_schema, MigrateDestinationNode::getKeySchema());
// Mapping
$this->addFieldMapping('title', 'title');
$this->addFieldMapping('uid', 'userid')->sourceMigration('Users');
$this->addFieldMapping('is_new')->defaultValue(TRUE);
$this->addFieldMapping('created', 'dateline');
$this->addFieldMapping('status', 'visible');
$this->addFieldMapping('sticky', 'sticky');
$this->addFieldMapping('comment', 'open');
$this->addFieldMapping('body', 'pagetext');
$this->addFieldMapping('body:format')->defaultValue('filtered_html');
$this->addFieldMapping('field_section', 'forumid')->sourceMigration('Structure');
$this->addFieldMapping('field_section:source_type')->defaultValue('tid');
$this->addFieldMapping('field_section:create_term')->defaultValue(FALSE);
$this->addFieldMapping('field_attachments', 'attachments');
$this->addFieldMapping('field_attachments:destination_dir')->defaultValue('public://attachments');
$this->addFieldMapping('field_attachments:destination_file', 'attachments_name');
$this->addFieldMapping('field_attachments:file_replace')->defaultValue(FILE_EXISTS_ERROR);
$this->addFieldMapping('field_attachments:source_dir')->defaultValue('/path/to/vbulletin/attachments/');
}
public function prepareRow($row) {
// Title
$row->title = htmlspecialchars_decode($row->title);
// Comment status
if ($row->open == 1) {
$row->open = 2;
}
else {
$row->open = 1;
}
// Body
$row->pagetext = bbcode_to_html($row->pagetext); // http://bit.ly/OrFVN5
// Attachments
$attachments = Database::getConnection('default', 'vbulletin')
->select('attachment', 'a')
->fields('a', array('attachmentid', 'filename', 'extension', 'userid'))
->condition('postid', $postid)
->execute();
foreach ($attachments as $attachment) {
$row->attachments[] = $attachment->userid . '/' . $attachment->attachmentid . '.attach';
$row->attachments_name[] = $attachment->filename;
}
}
}
Перед импортом нужно:
Создать тип материала post, или вписать существующий в MigrateDestinationNode('post').
Добавить материалу поле field_section типа Term reference, или вписать существующее в $this->addFieldMapping('field_section', 'forumid').
Добавить материалу поле field_attachments типа File, или вписать существующее в $this->addFieldMapping('field_attachments', 'attachments').
В строчке ...->defaultValue('/path/to/vbulletin/attachments/'); прописать полный путь к папке с атачами.
В vBulletin есть опция, которая позволяет хранить вложения в папках вида attachments/1/2/3/4, где цифры берутся из идентификатора пользователя. Если опция включена, то вместо
$row->attachments[] = $attachment->userid . '/' . $attachment->attachmentid . '.attach';
пишем:
$row->attachments[] = implode('/', preg_split('//', $attachment->userid, -1, PREG_SPLIT_NO_EMPTY)) . '/' . $attachment->attachmentid . '.attach';
Написанное актуально для
Migrate 7.x-2.4