Drupal → Пример миграции контента из vBulletin 3 в Drupal 7: темы (топики)
Пример класса для Migrate, для переноса тем из vBulletin 3.8.x в Drupal 7.x с сохранением вложений (импорт ответов в темах будет в следующем посте):
class ThreadsMigration extends Migration { public function __construct($arguments) { parent::__construct($arguments); $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) { if (parent::prepareRow($row) === FALSE) { return FALSE; } // 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';
Комментарии
О, круто, спасибо :)
Не догнал пока две вещи.
1) Как ограничиться миграцией одной ветки, вместо кучи. Здесь копать?
2) "Импорт вложений происходит вручную"
Вообще не догнал, не высыпаюсь похоже :D
1. $query->condition('forumid', ...);
2. код по переносу вложений написан руками. если бы атачи в вобле имели нормальные имена, можно было бы возложить эту работу на migrate
Наверное, тут ошибка
->condition('postid', $postid)
->execute()
->fetchAll(); // не хватает
Оставить комментарий