Файл: library/XenForo/Importer/vBulletin.php
Строк: 2128
<?php
class XenForo_Importer_vBulletin extends XenForo_Importer_Abstract
{
/**
* Source database connection.
*
* @var Zend_Db_Adapter_Abstract
*/
protected $_sourceDb;
protected $_prefix;
protected $_charset = 'windows-1252';
protected $_config;
protected $_groupMap = null;
protected $_userFieldMap = null;
public static function getName()
{
return 'vBulletin 3.7/3.8';
}
public function configure(XenForo_ControllerAdmin_Abstract $controller, array &$config)
{
if ($config)
{
$errors = $this->validateConfiguration($config);
if ($errors)
{
return $controller->responseError($errors);
}
if (isset($config['attachmentPath']) || isset($config['avatarPath']))
{
// already configured
return true;
}
$this->_bootstrap($config);
$settings = $this->_sourceDb->fetchPairs('
SELECT varname, value
FROM ' . $this->_prefix . 'setting
WHERE varname IN ('attachpath', 'attachfile', 'avatarpath', 'usefileavatar')
');
if (($settings['attachfile'] && $settings['attachpath'])
|| ($settings['usefileavatar'] && $settings['avatarpath']))
{
return $controller->responseView('XenForo_ViewAdmin_Import_vBulletin_Config', 'import_vbulletin_config', array(
'config' => $config,
'attachmentPath' => ($settings['attachfile'] ? $settings['attachpath'] : ''),
'avatarPath' => ($settings['usefileavatar'] ? $settings['avatarpath'] : ''),
'retainKeys' => $config['retain_keys'],
));
}
return true;
}
else
{
$configPath = getcwd() . '/includes/config.php';
if (file_exists($configPath) && is_readable($configPath))
{
$config = array();
include($configPath);
$viewParams = array('input' => $config);
}
else
{
$viewParams = array('input' => array
(
'MasterServer' => array
(
'servername' => 'localhost',
'port' => 3306,
'username' => '',
'password' => '',
),
'Database' => array
(
'dbname' => '',
'tableprefix' => ''
),
'Mysqli' => array
(
'charset' => ''
),
));
}
return $controller->responseView('XenForo_ViewAdmin_Import_vBulletin_Config', 'import_vbulletin_config', $viewParams);
}
}
public function validateConfiguration(array &$config)
{
$errors = array();
$config['db']['prefix'] = preg_replace('/[^a-z0-9_]/i', '', $config['db']['prefix']);
try
{
$db = Zend_Db::factory('mysqli',
array(
'host' => $config['db']['host'],
'port' => $config['db']['port'],
'username' => $config['db']['username'],
'password' => $config['db']['password'],
'dbname' => $config['db']['dbname'],
'charset' => $config['db']['charset']
)
);
$db->getConnection();
}
catch (Zend_Db_Exception $e)
{
$errors[] = new XenForo_Phrase('source_database_connection_details_not_correct_x', array('error' => $e->getMessage()));
}
if ($errors)
{
return $errors;
}
try
{
$db->query('
SELECT userid
FROM ' . $config['db']['prefix'] . 'user
LIMIT 1
');
}
catch (Zend_Db_Exception $e)
{
if ($config['db']['dbname'] === '')
{
$errors[] = new XenForo_Phrase('please_enter_database_name');
}
else
{
$errors[] = new XenForo_Phrase('table_prefix_or_database_name_is_not_correct');
}
}
if (!empty($config['attachmentPath']))
{
if (!file_exists($config['attachmentPath']) || !is_dir($config['attachmentPath']))
{
$errors[] = new XenForo_Phrase('attachments_directory_not_found');
}
}
if (!empty($config['avatarPath']))
{
if (!file_exists($config['avatarPath']) || !is_dir($config['avatarPath']))
{
$errors[] = new XenForo_Phrase('avatars_directory_not_found');
}
}
if (!$errors)
{
$defaultLanguageId = $db->fetchOne('
SELECT value
FROM ' . $config['db']['prefix'] . 'setting
WHERE varname = 'languageid'
');
$defaultCharset = $db->fetchOne('
SELECT charset
FROM ' . $config['db']['prefix'] . 'language
WHERE languageid = ?
', $defaultLanguageId);
if (!$defaultCharset || str_replace('-', '', strtolower($defaultCharset)) == 'iso88591')
{
$config['charset'] = 'windows-1252';
}
else
{
$config['charset'] = strtolower($defaultCharset);
}
}
return $errors;
}
public function getSteps()
{
return array(
'userGroups' => array(
'title' => new XenForo_Phrase('import_user_groups')
),
'userFields' => array(
'title' => new XenForo_Phrase('import_custom_user_fields'),
),
'users' => array(
'title' => new XenForo_Phrase('import_users'),
'depends' => array('userGroups', 'userFields')
),
'avatars' => array(
'title' => new XenForo_Phrase('import_custom_avatars'),
'depends' => array('users')
),
'buddyIgnore' => array(
'title' => new XenForo_Phrase('import_buddy_ignore_lists'),
'depends' => array('users')
),
'paidSubscriptions' => array(
'title' => new XenForo_Phrase('import_paid_subscriptions'),
'depends' => array('users')
),
'privateMessages' => array(
'title' => new XenForo_Phrase('import_private_messages'),
'depends' => array('users')
),
'visitorMessages' => array(
'title' => new XenForo_Phrase('import_profile_comments'),
'depends' => array('users')
),
'forums' => array(
'title' => new XenForo_Phrase('import_forums'),
'depends' => array('userGroups')
),
'moderators' => array(
'title' => new XenForo_Phrase('import_moderators'),
'depends' => array('forums', 'users')
),
'threadPrefixes' => array(
'title' => new XenForo_Phrase('import_thread_prefixes'),
'depends' => array('forums')
),
'threads' => array(
'title' => new XenForo_Phrase('import_threads_and_posts'),
'depends' => array('forums', 'users', 'threadPrefixes')
),
'postEditHistory' => array(
'title' => new XenForo_Phrase('import_post_edit_history'),
'depends' => array('threads')
),
'polls' => array(
'title' => new XenForo_Phrase('import_polls'),
'depends' => array('threads')
),
'attachments' => array(
'title' => new XenForo_Phrase('import_attached_files'),
'depends' => array('threads')
),
'reputation' => array(
'title' => new XenForo_Phrase('import_positive_reputation'),
'depends' => array('threads')
),
'infractions' => array(
'title' => new XenForo_Phrase('import_infractions'),
'depends' => array('threads')
),
);
// deferred: albums/comments, announcements, custom bb code, calendars/events, social groups, tags
}
protected function _bootstrap(array $config)
{
if ($this->_sourceDb)
{
// already run
return;
}
@set_time_limit(0);
$this->_config = $config;
$this->_sourceDb = Zend_Db::factory('mysqli',
array(
'host' => $config['db']['host'],
'port' => $config['db']['port'],
'username' => $config['db']['username'],
'password' => $config['db']['password'],
'dbname' => $config['db']['dbname'],
'charset' => $config['db']['charset']
)
);
if (empty($config['db']['charset']))
{
$this->_sourceDb->query('SET character_set_results = NULL');
}
$this->_prefix = preg_replace('/[^a-z0-9_]/i', '', $config['db']['prefix']);
if (!empty($config['charset']))
{
$this->_charset = $config['charset'];
}
}
public function stepUserGroups($start, array $options)
{
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
$model->retainableKeys[] = 'user_group_id';
$userGroups = $sDb->fetchAll('
SELECT *
FROM ' . $prefix . 'usergroup
ORDER BY usergroupid
');
$total = 0;
XenForo_Db::beginTransaction();
foreach ($userGroups AS $userGroup)
{
$titlePriority = 5;
switch ($userGroup['usergroupid'])
{
case 1: // guests
$model->logImportData('userGroup', $userGroup['usergroupid'], XenForo_Model_User::$defaultGuestGroupId);
break;
case 2: // registered users
case 3: // email confirm
case 4: // moderation
$model->logImportData('userGroup', $userGroup['usergroupid'], XenForo_Model_User::$defaultRegisteredGroupId);
break;
case 6: // admins
$model->logImportData('userGroup', $userGroup['usergroupid'], XenForo_Model_User::$defaultAdminGroupId);
continue;
case 7: // mods
$model->logImportData('userGroup', $userGroup['usergroupid'], XenForo_Model_User::$defaultModeratorGroupId);
continue;
case 5: // super mods
$titlePriority = 910;
default:
$import = array(
'title' => $this->_convertToUtf8($userGroup['title']),
'user_title' => $this->_convertToUtf8($userGroup['usertitle']),
'display_style_priority' => $titlePriority,
'permissions' => $this->_calculateUserGroupPermissions($userGroup)
);
if ($model->importUserGroup($userGroup['usergroupid'], $import))
{
$total++;
}
}
}
XenForo_Model::create('XenForo_Model_UserGroup')->rebuildDisplayStyleCache();
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return true;
}
protected function _calculateUserGroupPermissions(array $userGroup)
{
$perms = array();
$userGroup['forumpermissions'] = intval($userGroup['forumpermissions']);
$userGroup['genericpermissions'] = intval($userGroup['genericpermissions']);
$userGroup['adminpermissions'] = intval($userGroup['adminpermissions']);
if ($userGroup['forumpermissions'] & 1)
{
$perms['general']['view'] = 'allow';
$perms['general']['viewNode'] = 'allow';
$perms['forum']['like'] = 'allow';
}
if ($userGroup['forumpermissions'] & 524288)
{
$perms['forum']['viewContent'] = 'allow';
}
if ($userGroup['forumpermissions'] & 2)
{
$perms['forum']['viewOthers'] = 'allow';
}
if ($userGroup['genericpermissions'] & 1)
{
$perms['general']['viewProfile'] = 'allow';
}
if (($userGroup['adminpermissions'] & 1) || ($userGroup['adminpermissions'] & 2))
{
$perms['general']['bypassFloodCheck'] = 'allow';
}
if ($userGroup['forumpermissions'] & 4)
{
$perms['general']['search'] = 'allow';
}
if ($userGroup['forumpermissions'] & 131072)
{
$perms['general']['followModerationRules'] = 'allow';
}
if ($userGroup['forumpermissions'] & 16)
{
$perms['forum']['postThread'] = 'allow';
}
if ($userGroup['forumpermissions'] & 32)
{
$perms['forum']['postReply'] = 'allow';
}
if ($userGroup['forumpermissions'] & 256)
{
$perms['forum']['deleteOwnPost'] = 'allow';
}
if ($userGroup['forumpermissions'] & 512)
{
$perms['forum']['deleteOwnThread'] = 'allow';
}
if ($userGroup['forumpermissions'] & 128)
{
$perms['forum']['editOwnPost'] = 'allow';
}
if ($userGroup['forumpermissions'] & 4096)
{
$perms['forum']['viewAttachment'] = 'allow';
}
if ($userGroup['forumpermissions'] & 8192)
{
$perms['forum']['uploadAttachment'] = 'allow';
}
if ($userGroup['forumpermissions'] & 32768)
{
$perms['forum']['votePoll'] = 'allow';
}
if ($userGroup['pmsendmax'])
{
$perms['conversation']['start'] = 'allow';
$perms['conversation']['receive'] = 'allow';
$perms['conversation']['maxRecipients'] = $userGroup['pmsendmax'];
if ($perms['conversation']['maxRecipients'] > 2147483647)
{
$perms['conversation']['maxRecipients'] = -1;
}
}
if ($userGroup['genericpermissions'] & 512)
{
$perms['avatar']['allowed'] = 'allow';
$perms['avatar']['maxFileSize'] = ($userGroup['avatarmaxsize'] > 0 ? $userGroup['avatarmaxsize'] : -1);
if ($perms['avatar']['maxFileSize'] > 2147483647)
{
$perms['avatar']['maxFileSize'] = -1;
}
}
if (isset($userGroup['visitormessagepermissions']))
{
$userGroup['visitormessagepermissions'] = intval($userGroup['visitormessagepermissions']);
if ($userGroup['visitormessagepermissions'] & 1)
{
$perms['profilePost']['view'] = 'allow'; // this checks against "can message own", which isn't perfect
$perms['profilePost']['like'] = 'allow';
}
if ($userGroup['visitormessagepermissions'] & 2)
{
$perms['profilePost']['post'] = 'allow'; // this checks against "can message others"
$perms['profilePost']['comment'] = 'allow';
}
if ($userGroup['visitormessagepermissions'] & 4)
{
$perms['profilePost']['editOwn'] = 'allow';
}
if ($userGroup['visitormessagepermissions'] & 8)
{
$perms['profilePost']['deleteOwn'] = 'allow';
}
if ($userGroup['visitormessagepermissions'] & 32)
{
$perms['profilePost']['manageOwn'] = 'allow';
}
}
else
{
// vBulletin 3.6
if (isset($perms['general']['view']))
{
$perms['profilepost']['view'] = $perms['general']['view'];
}
if (isset($perms['forum']['like']))
{
$perms['profilepost']['like'] = $perms['forum']['like'];
}
if (isset($perms['forum']['postReply']))
{
$perms['profilePost']['post'] = $perms['forum']['postReply'];
}
if (isset($perms['forum']['editOwnPost']))
{
$perms['profilePost']['editOwn'] = $perms['forum']['editOwnPost'];
}
if (isset($perms['forum']['deleteOwnPost']))
{
$perms['profilePost']['deleteOwn'] = $perms['forum']['deleteOwnPost'];
}
}
return $perms;
}
public function stepUserFields($start, array $options)
{
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
// fetch all profile fields except 1-4, for which we already have analogues
$profileFields = $sDb->fetchAll('
SELECT *
FROM ' . $prefix . 'profilefield
WHERE profilefieldid > 4
');
$phrases = $sDb->fetchPairs('
SELECT varname, text
FROM ' . $prefix . 'phrase
WHERE languageid = 0
AND fieldname = ?
', 'cprofilefield');
$existingFields = XenForo_Model::create('XenForo_Model_UserField')->getUserFields();
$userFieldLookups = array();
$total = 0;
XenForo_Db::beginTransaction($this->_db);
foreach ($profileFields AS $profileField)
{
$title = $this->_convertToUtf8($phrases["field$profileField[profilefieldid]_title"]);
$description = $this->_convertToUtf8($phrases["field$profileField[profilefieldid]_desc"]);
$fieldId = $model->getUniqueFieldId(
str_replace('-', '_', XenForo_Link::getTitleForUrl($title, true)),
$existingFields,
25);
$import = array(
'field_id' => $fieldId,
'title' => $title,
'description' => $description,
'display_order' => $profileField['displayorder'],
'max_length' => $profileField['maxlength'],
'viewable_profile' => !$profileField['hidden'],
);
switch ($profileField['type'])
{
case 'select':
case 'radio':
case 'checkbox':
$import['field_type'] = $profileField['type'];
$import['field_choices'] = $this->_convertUserFieldChoices($profileField, $userFieldLookups);
if (!$import['field_choices'])
{
continue;
}
break;
case 'select_multiple':
$import['field_type'] = 'multiselect';
$import['field_choices'] = $this->_convertUserFieldChoices($profileField, $userFieldLookups);
if (!$import['field_choices'])
{
continue;
}
break;
case 'textarea':
$import['field_type'] = 'textarea';
break;
case 'input':
default:
$import['field_type'] = 'textbox';
break;
}
switch ($profileField['required'])
{
case 3: // yes, always
case 1: // yes, at registration and profile update
$import['required'] = 1;
$import['show_registration'] = 1;
break;
case 2: // no, but display at registration
$import['required'] = 0;
$import['show_registration'] = 1;
break;
case 0: // no
default:
$import['required'] = 0;
$import['show_registration'] = 0;
break;
}
switch ($profileField['editable'])
{
case 0: // no
$import['user_editable'] = 'never';
break;
case 2: // only at registration
$import['user_editable'] = 'once';
break;
case 1: // yes
default:
$import['user_editable'] = 'yes';
break;
}
switch ($profileField['form'])
{
case 0: // edit your details
$import['display_group'] = 'personal';
break;
case 1: // options: login / privacy
case 2: // options: messaging
case 3: // options: thread viewing
case 4: // options: date / time
case 5: // options: other
default:
$import['display_group'] = 'preferences';
break;
}
if ($profileField['regex'])
{
$import['match_type'] = 'regex';
$import['match_regex'] = $this->_convertToUtf8($profileField['regex']);
}
else
{
$import['match_type'] = 'none';
}
if ($imported = $model->importUserField($profileField['profilefieldid'], $import))
{
$total++;
}
}
XenForo_Db::commit($this->_db);
$this->_session->setExtraData('userFieldLookups', $userFieldLookups);
$this->_session->incrementStepImportTotal($total);
return true;
}
protected function _convertUserFieldChoices(array $profileField, array &$fieldChoiceLookups)
{
try
{
$choiceData = @unserialize($profileField['data']);
}
catch (Exception $e)
{
// this is either corrupted data or an invalid char set. The latter isn't something we can automatically detect
return array();
}
if (!is_array($choiceData))
{
return array();
}
$choices = array();
foreach ($choiceData AS $key => $choice)
{
$choice = $this->_convertToUtf8($choice);
$choiceId = XenForo_Helper_String::wholeWordTrim($choice, 23, 0, '');
if ($choiceId != '')
{
$choiceId = str_replace('-', '_', XenForo_Link::getTitleForUrl($choiceId, true));
$i = 1;
$choiceIdBase = $choiceId;
while (isset($choices[$choiceId]))
{
$choiceId = $choiceIdBase . '_' . ++$i;
}
}
else
{
$choiceId = $key;
}
$choices[$choiceId] = $choice;
}
$lookUps = array();
switch ($profileField['type'])
{
case 'checkbox':
case 'select_multiple':
$multiple = true;
$i = 1;
foreach ($choices AS $key => $value)
{
$lookUps[$i] = $key;
$i = $i * 2;
}
break;
case 'select':
case 'radio':
default:
$multiple = false;
foreach ($choices AS $key => $value)
{
$lookUps[$value] = $key;
}
break;
}
$fieldChoiceLookups[$profileField['profilefieldid']] = array(
'multiple' => $multiple,
'choices' => $lookUps
);
return $choices;
}
public function configStepUsers(array $options)
{
if ($options)
{
return false;
}
return $this->_controller->responseView('XenForo_ViewAdmin_Import_vBulletin_ConfigUsers', 'import_config_users');
}
public function stepUsers($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'max' => false,
// all checkbox options must default to false as they may not be submitted
'mergeEmail' => false,
'mergeName' => false,
'gravatar' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(userid)
FROM ' . $prefix . 'user
');
}
$users = $sDb->fetchAll(
$sDb->limit($this->_getSelectUserSql('user.userid > ' . $sDb->quote($start)), $options['limit'])
);
if (!$users)
{
return $this->_getNextUserStep();
}
XenForo_Db::beginTransaction();
$next = 0;
$total = 0;
foreach ($users AS $user)
{
$next = $user['userid'];
$imported = $this->_importOrMergeUser($user, $options);
if ($imported)
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepBuddyIgnore($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'max' => false,
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(userid)
FROM ' . $prefix . 'user
');
}
$users = $sDb->fetchAll(
$sDb->limit($this->_getSelectUserSql('user.userid > ' . $sDb->quote($start)
. " AND (usertextfield.buddylist <> '' OR usertextfield.ignorelist <> '')"), $options['limit'])
);
if (!$users)
{
return $this->_getNextUserStep();
}
XenForo_Db::beginTransaction();
$next = 0;
$total = 0;
foreach ($users AS $user)
{
$next = $user['userid'];
if ($this->_importBuddyIgnore($user, $options))
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
protected function _importBuddyIgnore(array $user, array $options)
{
$userIds = $user['userid'] . ' ' . $user['buddylist'] . ' ' . $user['ignorelist'];
$userIds = preg_split('/s+/', $userIds, -1, PREG_SPLIT_NO_EMPTY);
$userMap = $this->_importModel->getImportContentMap('user', $userIds);
$importedUserId = $this->_mapLookUp($userMap, $user['userid']);
if (!$importedUserId)
{
return false;
}
if ($user['buddylist'])
{
$buddyIds = preg_split('/s/', $user['buddylist'], -1, PREG_SPLIT_NO_EMPTY);
$buddyIds = $this->_mapLookUpList($userMap, $buddyIds);
$this->_importModel->importFollowing($importedUserId, $buddyIds);
}
if ($user['ignorelist'])
{
$ignoreIds = preg_split('/s/', $user['ignorelist'], -1, PREG_SPLIT_NO_EMPTY);
$ignoreIds = $this->_mapLookUpList($userMap, $ignoreIds);
$this->_importModel->importIgnored($importedUserId, $ignoreIds);
}
return $importedUserId;
}
public function stepUsersMerge($start, array $options)
{
$sDb = $this->_sourceDb;
$manual = $this->_session->getExtraData('userMerge');
if ($manual)
{
$merge = $sDb->fetchAll($this->_getSelectUserSql('user.userid IN (' . $sDb->quote(array_keys($manual)) . ')'));
$resolve = $this->_controller->getInput()->filterSingle('resolve', XenForo_Input::ARRAY_SIMPLE);
if ($resolve && !empty($options['shownForm']))
{
$this->_session->unsetExtraData('userMerge');
$this->_resolveUserConflicts($merge, $resolve);
}
else
{
// prevents infinite loop if redirected back to step
$options['shownForm'] = true;
$this->_session->setStepInfo(0, $options);
$users = array();
foreach ($merge AS $user)
{
$users[$user['userid']] = array(
'username' => $this->_convertToUtf8($user['username'], true),
'email' => $this->_convertToUtf8($user['email']),
'message_count' => $user['posts'],
'register_date' => $user['joindate'],
'conflict' => $manual[$user['userid']]
);
}
return $this->_controller->responseView(
'XenForo_ViewAdmin_Import_MergeUsers', 'import_merge_users', array('users' => $users)
);
}
}
return $this->_getNextUserStep();
}
public function stepUsersFailed($start, array $options)
{
$sDb = $this->_sourceDb;
$manual = $this->_session->getExtraData('userFailed');
if ($manual)
{
$users = $this->_sourceDb->fetchAll($this->_getSelectUserSql('user.userid IN (' . $sDb->quote(array_keys($manual)) . ')'));
$resolve = $this->_controller->getInput()->filterSingle('resolve', XenForo_Input::ARRAY_SIMPLE);
if ($resolve && !empty($options['shownForm']))
{
$this->_session->unsetExtraData('userFailed');
$this->_resolveUserConflicts($users, $resolve);
}
else
{
// prevents infinite loop if redirected back to step
$options['shownForm'] = true;
$this->_session->setStepInfo(0, $options);
$failedUsers = array();
foreach ($users AS $user)
{
$failedUsers[$user['userid']] = array(
'username' => $this->_convertToUtf8($user['username'], true),
'email' => $this->_convertToUtf8($user['email']),
'message_count' => $user['posts'],
'register_date' => $user['joindate'],
'failure' => $manual[$user['userid']]
);
}
return $this->_controller->responseView(
'XenForo_ViewAdmin_Import_FailedUsers', 'import_failed_users', array('users' => $failedUsers)
);
}
}
return $this->_getNextUserStep();
}
protected function _resolveUserConflicts(array $users, array $resolve)
{
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
$total = 0;
XenForo_Db::beginTransaction();
foreach ($users AS $user)
{
if (empty($resolve[$user['userid']]))
{
continue;
}
$info = $resolve[$user['userid']];
if (empty($info['action']) || $info['action'] == 'change')
{
if (isset($info['email']))
{
$user['email'] = $info['email'];
}
if (isset($info['username']))
{
$user['username'] = $info['username'];
}
$imported = $this->_importOrMergeUser($user);
if ($imported)
{
$total++;
}
}
else if ($info['action'] == 'merge')
{
$im = $this->_importModel;
if ($match = $im->getUserIdByEmail($this->_convertToUtf8($user['email'])))
{
$this->_mergeUser($user, $match);
}
else if ($match = $im->getUserIdByUserName($this->_convertToUtf8($user['username'], true)))
{
$this->_mergeUser($user, $match);
}
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total, 'users');
}
protected function _getNextUserStep()
{
if ($this->_session->getExtraData('userMerge'))
{
return 'usersMerge';
}
if ($this->_session->getExtraData('userFailed'))
{
return 'usersFailed';
}
return true;
}
protected function _importOrMergeUser(array $user, array $options = array())
{
$im = $this->_importModel;
if ($user['email'] && $emailMatch = $im->getUserIdByEmail($this->_convertToUtf8($user['email'])))
{
if (!empty($options['mergeEmail']))
{
return $this->_mergeUser($user, $emailMatch);
}
else
{
if ($im->getUserIdByUserName($this->_convertToUtf8($user['username'], true)))
{
$this->_session->setExtraData('userMerge', $user['userid'], 'both');
}
else
{
$this->_session->setExtraData('userMerge', $user['userid'], 'email');
}
return false;
}
}
$name = utf8_substr($this->_convertToUtf8(trim($user['username']), true), 0, 50);
if ($nameMatch = $im->getUserIdByUserName($name))
{
if (!empty($options['mergeName']))
{
return $this->_mergeUser($user, $nameMatch);
}
else
{
$this->_session->setExtraData('userMerge', $user['userid'], 'name');
return false;
}
}
return $this->_importUser($user, $options);
}
protected function _importUser(array $user, array $options)
{
if ($this->_groupMap === null)
{
$this->_groupMap = $this->_importModel->getImportContentMap('userGroup');
}
if ($this->_userFieldMap === null)
{
$this->_userFieldMap = $this->_importModel->getImportContentMap('userField');
}
$user['options'] = intval($user['options']);
$import = array(
'username' => $this->_convertToUtf8($user['username'], true),
'email' => $this->_convertToUtf8($user['email']),
'user_group_id' => $this->_mapLookUp($this->_groupMap, $user['usergroupid'], XenForo_Model_User::$defaultRegisteredGroupId),
'secondary_group_ids' => $this->_mapLookUpList($this->_groupMap, explode(',', $user['membergroupids'])),
'authentication' => array(
'scheme_class' => 'XenForo_Authentication_vBulletin',
'data' => array(
'hash' => $user['password'],
'salt' => $user['salt']
)
),
'homepage' => $this->_convertToUtf8($user['homepage']),
'last_activity' => $user['lastactivity'],
'register_date' => $user['joindate'],
'ip' => $user['ipaddress'],
'message_count' => $user['posts'],
'is_admin' => $user['is_admin'],
'is_banned' => $user['is_banned'],
'warning_points' => isset($user['ipoints']) ? $user['ipoints'] : 0,
'signature' => $this->_convertToUtf8($user['signature']),
'timezone' => $this->_importModel->resolveTimeZoneOffset($user['timezoneoffset'], $user['options'] & 64), // 64 = dstauto
'content_show_signature' => (($user['options'] & 1) ? 1 : 0), // 1 = showsignatures
'receive_admin_email' => (($user['options'] & 16) ? 1 : 0), // 16 = adminemail
);
if ($user['customtitle'])
{
$import['custom_title'] = $this->_convertToUtf8($user['usertitle']);
if ($user['customtitle'] == 2) // admin set
{
$import['custom_title'] = htmlspecialchars_decode($import['custom_title']);
$import['custom_title'] = preg_replace('#<brs*/?>#i', ', ', $import['custom_title']);
$import['custom_title'] = strip_tags($import['custom_title']);
}
}
if (!($user['options'] & 2048)) // 2048 = receivepm
{
$import['allow_send_personal_conversation'] = 'none';
}
else if ($user['options'] & 131072) // 131072 = receivepmbuddies
{
$import['allow_send_personal_conversation'] = 'followed';
}
if (!($user['options'] & 8388608)) // 8388608 = vm_enable
{
$import['allow_post_profile'] = 'none';
}
else if ($user['options'] & 16777216) // 16777216 = vm_contactonly
{
$import['allow_post_profile'] = 'followed';
}
if ($user['birthday'])
{
$parts = explode('-', $user['birthday']);
if (count($parts) == 3)
{
$import['dob_day'] = $parts[1];
$import['dob_month'] = $parts[0];
$import['dob_year'] = ($parts[2] === '0000' ? 0 : $parts[2]);
}
}
// try to give users without an avatar that have actually posted a gravatar
if (!empty($options['gravatar']))
{
if (!$user['has_custom_avatar'] && $user['email'] && $user['lastpost'] && XenForo_Model_Avatar::gravatarExists($user['email']))
{
$import['gravatar'] = $import['email'];
}
}
$import['about'] = '';
if (isset($user['field1']))
{
$import['about'] .= $this->_convertToUtf8($user['field1'], true) . "nn";
}
if (isset($user['field3']))
{
$import['about'] .= $this->_convertToUtf8($user['field3'], true) . "nn";
}
$import['about'] = trim($import['about']);
if (isset($user['field2']))
{
$import['location'] = $this->_convertToUtf8($user['field2'], true);
}
if (isset($user['field4']))
{
$import['occupation'] = $this->_convertToUtf8($user['field4'], true);
}
switch ($user['usergroupid'])
{
case 3: $import['user_state'] = 'email_confirm'; break;
case 4: $import['user_state'] = 'moderated'; break;
default: $import['user_state'] = 'valid';
}
switch ($user['autosubscribe'])
{
case -1: $import['default_watch_state'] = ''; break;
case 0: $import['default_watch_state'] = 'watch_no_email'; break;
default: $import['default_watch_state'] = 'watch_email';
}
switch ($user['showbirthday'])
{
case 0: $import['show_dob_year'] = 0; $import['show_dob_date'] = 0; break;
case 1: $import['show_dob_year'] = 1; $import['show_dob_date'] = 0; break;
case 2: $import['show_dob_year'] = 1; $import['show_dob_date'] = 1; break;
case 3: $import['show_dob_year'] = 0; $import['show_dob_date'] = 1; break;
}
// custom user fields
$userFieldDefinitions = $this->_importModel->getUserFieldDefinitions();
foreach (array('icq', 'aim', 'yahoo', 'msn', 'skype') AS $identityType)
{
if (isset($userFieldDefinitions[$identityType]))
{
$import[XenForo_Model_Import::USER_FIELD_KEY][$identityType] = $this->_convertToUtf8($user[$identityType]);
}
}
$userFieldLookups = $this->_session->getExtraData('userFieldLookups');
foreach ($this->_userFieldMap AS $oldFieldId => $newFieldId)
{
if (!isset($userFieldDefinitions[$newFieldId]))
{
continue;
}
$userFieldValue = '';
if ($user["field$oldFieldId"] !== '')
{
if (isset($userFieldLookups[$oldFieldId]))
{
$fieldInfo = $userFieldLookups[$oldFieldId];
// use the lookup info to resolve the value
if ($fieldInfo['multiple'])
{
$userFieldValue = array();
foreach ($fieldInfo['choices'] AS $bitValue => $stringValue)
{
if ($user["field$oldFieldId"] & $bitValue)
{
$userFieldValue[$stringValue] = $stringValue;
}
}
}
else
{
$fieldChoiceId = $this->_convertToUtf8($user["field$oldFieldId"]);
if (isset($fieldInfo['choices'][$fieldChoiceId]))
{
$userFieldValue = $fieldInfo['choices'][$fieldChoiceId];
}
}
}
else
{
// set the field value directly
$userFieldValue = $this->_convertToUtf8($user["field$oldFieldId"], true);
}
}
$import[XenForo_Model_Import::USER_FIELD_KEY][$newFieldId] = $userFieldValue;
}
if ($user['is_admin'] && $user['admin_permissions'])
{
$user['admin_permissions'] = intval($user['admin_permissions']);
$aPerms = array();
if ($user['admin_permissions'] & 4) { $aPerms[] = 'option'; }
if ($user['admin_permissions'] & 8) { $aPerms[] = 'style'; }
if ($user['admin_permissions'] & 16) { $aPerms[] = 'language'; }
if ($user['admin_permissions'] & 32) { $aPerms[] = 'node'; }
if ($user['admin_permissions'] & 256)
{
$aPerms[] = 'user';
$aPerms[] = 'ban';
$aPerms[] = 'identityService';
$aPerms[] = 'trophy';
$aPerms[] = 'userUpgrade';
}
if ($user['admin_permissions'] & 512) { $aPerms[] = 'userGroup'; } // actually, user permissions
if ($user['admin_permissions'] & 4096) { $aPerms[] = 'bbCodeSmilie'; }
if ($user['admin_permissions'] & 8192) { $aPerms[] = 'cron'; }
if ($user['admin_permissions'] & 16384)
{
$aPerms[] = 'import';
$aPerms[] = 'upgradeXenForo';
}
if ($user['admin_permissions'] & 65536) { $aPerms[] = 'addOn'; }
$import['admin_permissions'] = $aPerms;
}
$importedUserId = $this->_importModel->importUser($user['userid'], $import, $failedKey);
if ($importedUserId)
{
if ($user['is_banned'])
{
$this->_importModel->importBan(array(
'user_id' => $importedUserId,
'ban_user_id' => $this->_importModel->mapUserId($user['ban_user_id'], 0),
'ban_date' => $user['ban_date'],
'end_date' => $user['ban_end_date'],
'user_reason' => $this->_convertToUtf8($user['ban_reason'])
));
}
if ($user['is_super_moderator'])
{
$this->_session->setExtraData('superMods', $user['userid'], $importedUserId);
}
}
else if ($failedKey)
{
$this->_session->setExtraData('userFailed', $user['userid'], $failedKey);
}
return $importedUserId;
}
protected function _getSelectUserSql($where)
{
return '
SELECT user.*, userfield.*, usertextfield.*,
IF(admin.userid IS NULL, 0, 1) AS is_admin,
admin.adminpermissions AS admin_permissions,
IF(userban.userid IS NULL, 0, 1) AS is_banned,
userban.bandate AS ban_date,
userban.liftdate AS ban_end_date,
userban.reason AS ban_reason,
userban.adminid AS ban_user_id,
IF(usergroup.adminpermissions & 1, 1, 0) AS is_super_moderator,
IF(customavatar.userid, 1, 0) AS has_custom_avatar
FROM ' . $this->_prefix . 'user AS user
STRAIGHT_JOIN ' . $this->_prefix . 'userfield AS userfield ON (user.userid = userfield.userid)
STRAIGHT_JOIN ' . $this->_prefix . 'usertextfield AS usertextfield ON (user.userid = usertextfield.userid)
LEFT JOIN ' . $this->_prefix . 'administrator AS admin ON (user.userid = admin.userid)
LEFT JOIN ' . $this->_prefix . 'userban AS userban ON (user.userid = userban.userid)
LEFT JOIN ' . $this->_prefix . 'usergroup AS usergroup ON (user.usergroupid = usergroup.usergroupid)
LEFT JOIN ' . $this->_prefix . 'customavatar AS customavatar ON (user.userid = customavatar.userid)
WHERE ' . $where . '
ORDER BY user.userid
';
}
protected function _mergeUser(array $user, $targetUserId)
{
$this->_db->query('
UPDATE xf_user SET
message_count = message_count + ?,
register_date = IF(register_date > ?, ?, register_date)
WHERE user_id = ?
', array($user['posts'], $user['joindate'], $user['joindate'], $targetUserId));
$this->_importModel->logImportData('user', $user['userid'], $targetUserId);
return $targetUserId;
}
public function stepPaidSubscriptions($start, array $options)
{
$options = array_merge(array(
'limit' => 200,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(subscriptionlogid)
FROM ' . $prefix . 'subscriptionlog
');
XenForo_Db::beginTransaction();
$userGroupMap = $model->getImportContentMap('userGroup');
$subs = $sDb->fetchAll('
SELECT sub.*, title.text AS title, description.text AS description
FROM ' . $prefix . 'subscription AS sub
INNER JOIN ' . $prefix . 'phrase AS title ON (title.languageid = 0
AND title.varname = CONCAT('sub', sub.subscriptionid, '_title'))
INNER JOIN ' . $prefix . 'phrase AS description ON (description.languageid = 0
AND description.varname = CONCAT('sub', sub.subscriptionid, '_desc'))
');
foreach ($subs AS $sub)
{
$import = array(
'title' => $this->_convertToUtf8($sub['title']),
'description' => $this->_convertToUtf8($sub['description']),
'display_order' => $sub['displayorder'],
'extra_group_ids' => '',
'can_purchase' => 0, // never be active as the admin probably needs to verify/setup their configs
'recurring' => 0,
'cost_amount' => 1,
'cost_currency' => 'usd',
'length_amount' => 1,
'length_unit' => 'year'
);
if ($sub['membergroupids'])
{
$groupIds = array();
foreach (explode(',', $sub['membergroupids']) AS $groupId)
{
if (isset($userGroupMap[$groupId]))
{
$groupIds[] = $userGroupMap[$groupId];
}
}
$import['extra_group_ids'] = implode(',', $groupIds);
}
$def = @unserialize($sub['cost']);
if (is_array($def))
{
if (isset($def[0]))
{
$def = $def[0];
}
if (!empty($def['cost']) && is_array($def['cost']))
{
foreach ($def['cost'] AS $currency => $cost)
{
if (floatval($cost) > 0)
{
$import['cost_amount'] = floatval($cost);
$import['cost_currency'] = $currency;
break;
}
}
}
if (!empty($def['units']))
{
$import['length_amount'] = $def['length'];
switch ($def['units'])
{
case 'Y': $import['length_unit'] = 'year'; break;
case 'M': $import['length_unit'] = 'month'; break;
case 'D': $import['length_unit'] = 'day'; break;
default:
$import['length_amount'] = 0;
$import['length_unit'] = '';
}
}
else
{
$import['length_amount'] = 0;
$import['length_unit'] = '';
}
$import['recurring'] = !empty($def['recurring']) ? 1 : 0;
}
$model->importUserUpgradeDefinition($sub['subscriptionid'], $import);
}
XenForo_Db::commit();
}
$logs = $sDb->fetchAll($sDb->limit(
'
SELECT *
FROM ' . $prefix . 'subscriptionlog
WHERE subscriptionlogid > ' . $sDb->quote($start) . '
AND status = 1
ORDER BY subscriptionlogid
', $options['limit']
));
if (!$logs)
{
return true;
}
$userIdMap = $model->getUserIdsMapFromArray($logs, 'userid');
$upgradeMap = $model->getImportContentMap('userUpgrade');
$upgrades = $model->getModelFromCache('XenForo_Model_UserUpgrade')->getAllUserUpgrades();
$next = 0;
$total = 0;
XenForo_Db::beginTransaction();
foreach ($logs AS $log)
{
$next = $log['subscriptionlogid'];
$newUserId = $this->_mapLookUp($userIdMap, $log['userid']);
if (!$newUserId)
{
continue;
}
$newUpgradeId = $this->_mapLookUp($upgradeMap, $log['subscriptionid']);
if (!$newUpgradeId)
{
continue;
}
$import = array(
'user_id' => $newUserId,
'user_upgrade_id' => $newUpgradeId,
'extra' => 'a:0:{}',
'start_date' => $log['regdate'],
'end_date' => $log['expirydate']
);
$extraGroupIds = isset($upgrades[$newUpgradeId]) ? $upgrades[$newUpgradeId]['extra_group_ids'] : '';
if ($model->importActiveUserUpgrade($import, $extraGroupIds))
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepAvatars($start, array $options)
{
$options = array_merge(array(
'path' => isset($this->_config['avatarPath']) ? $this->_config['avatarPath'] : '',
'limit' => 50,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(userid)
FROM ' . $prefix . 'customavatar
');
}
$avatars = $sDb->fetchAll($sDb->limit(
'
SELECT customavatar.userid, user.avatarrevision
FROM ' . $prefix . 'customavatar AS customavatar
INNER JOIN ' . $prefix . 'user AS user ON (user.userid = customavatar.userid)
WHERE customavatar.userid > ' . $sDb->quote($start) . '
ORDER BY customavatar.userid
', $options['limit']
));
if (!$avatars)
{
return true;
}
$userIdMap = $model->getUserIdsMapFromArray($avatars, 'userid');
$next = 0;
$total = 0;
foreach ($avatars AS $avatar)
{
$next = $avatar['userid'];
$newUserId = $this->_mapLookUp($userIdMap, $avatar['userid']);
if (!$newUserId)
{
continue;
}
if (!$options['path'])
{
$fData = $sDb->fetchOne('
SELECT filedata
FROM ' . $prefix . 'customavatar
WHERE userid = ' . $sDb->quote($avatar['userid'])
);
if ($fData === '')
{
continue;
}
$avatarFile = tempnam(XenForo_Helper_File::getTempDir(), 'xf');
if (!$avatarFile || !@file_put_contents($avatarFile, $fData))
{
continue;
}
$isTemp = true;
}
else
{
$avatarFileOrig = "$options[path]/avatar$avatar[userid]_$avatar[avatarrevision].gif";
if (!file_exists($avatarFileOrig))
{
continue;
}
$avatarFile = tempnam(XenForo_Helper_File::getTempDir(), 'xf');
copy($avatarFileOrig, $avatarFile);
$isTemp = true;
}
if ($this->_importModel->importAvatar($avatar['userid'], $newUserId, $avatarFile))
{
$total++;
}
if ($isTemp)
{
@unlink($avatarFile);
}
}
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepPrivateMessages($start, array $options)
{
$options = array_merge(array(
'limit' => 300,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(pmtextid)
FROM ' . $prefix . 'pmtext
');
}
$pmTexts = $sDb->fetchAll($sDb->limit(
'
SELECT *
FROM ' . $prefix . 'pmtext
WHERE pmtextid > ' . $sDb->quote($start) . '
ORDER BY pmtextid
', $options['limit']
));
if (!$pmTexts)
{
return true;
}
$next = 0;
$total = 0;
XenForo_Db::beginTransaction();
foreach ($pmTexts AS $pmText)
{
$next = $pmText['pmtextid'];
$readState = $sDb->fetchPairs('
SELECT userid, IF(folderid >= 0, messageread, 1)
FROM ' . $prefix . 'pm
WHERE pmtextid = ' . $sDb->quote($pmText['pmtextid'])
);
try
{
$toUser = @unserialize($pmText['touserarray']);
}
catch (Exception $e)
{
// this is either corrupted data or an invalid char set. The latter isn't something we can automatically detect
continue;
}
if (!is_array($toUser))
{
continue;
}
$users = array(
$pmText['fromuserid'] => $pmText['fromusername']
);
foreach ($toUser AS $key => $toUser)
{
if (is_array($toUser))
{
foreach ($toUser AS $subKey => $username)
{
$users[$subKey] = $username;
}
}
else
{
$users[$key] = $toUser;
}
}
$mapUserIds = $model->getImportContentMap('user', array_keys($users));
$newFromUserId = $this->_mapLookUp($mapUserIds, $pmText['fromuserid']);
if (!$newFromUserId)
{
continue;
}
$fromUserName = $this->_convertToUtf8($pmText['fromusername'], true);
$recipients = array();
foreach ($users AS $userId => $username)
{
$newUserId = $this->_mapLookUp($mapUserIds, $userId);
if (!$newUserId)
{
continue;
}
if (isset($readState[$userId]))
{
$lastReadDate = ($readState[$userId] ? $pmText['dateline'] : 0);
$deleted = false;
}
else
{
$lastReadDate = $pmText['dateline'];
$deleted = true;
}
$recipients[$newUserId] = array(
'username' => $this->_convertToUtf8($username, true),
'last_read_date' => $lastReadDate,
'recipient_state' => ($deleted ? 'deleted' : 'active')
);
}
$conversation = array(
'title' => $this->_convertToUtf8($pmText['title'], true),
'user_id' => $newFromUserId,
'username' => $fromUserName,
'start_date' => $pmText['dateline'],
'open_invite' => 0,
'conversation_open' => 1
);
$messages = array(
array(
'message_date' => $pmText['dateline'],
'user_id' => $newFromUserId,
'username' => $fromUserName,
'message' => $this->_convertToUtf8($pmText['message'])
)
);
if ($model->importConversation($pmText['pmtextid'], $conversation, $recipients, $messages))
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepVisitorMessages($start, array $options)
{
$options = array_merge(array(
'limit' => 200,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(vmid)
FROM ' . $prefix . 'visitormessage
');
}
$vms = $sDb->fetchAll($sDb->limit(
'
SELECT vm.*,
IF(user.username IS NULL, vm.postusername, user.username) AS username
FROM ' . $prefix . 'visitormessage AS vm
LEFT JOIN ' . $prefix . 'user AS user ON (vm.postuserid = user.userid)
WHERE vm.vmid > ' . $sDb->quote($start) . '
ORDER BY vm.vmid
', $options['limit']
));
if (!$vms)
{
return true;
}
$next = 0;
$total = 0;
$userIds = array();
foreach ($vms AS $vm)
{
$userIds[] = $vm['userid'];
$userIds[] = $vm['postuserid'];
}
$userIdMap = $model->getImportContentMap('user', $userIds);
XenForo_Db::beginTransaction();
$formatter = XenForo_BbCode_Formatter_Base::create('XenForo_BbCode_Formatter_Text');
$parser = XenForo_BbCode_Parser::create($formatter);
foreach ($vms AS $vm)
{
if (trim($vm['postusername']) === '')
{
continue;
}
$next = $vm['vmid'];
$profileUserId = $this->_mapLookUp($userIdMap, $vm['userid']);
if (!$profileUserId)
{
continue;
}
$postUserId = $this->_mapLookUp($userIdMap, $vm['postuserid'], 0);
$import = array(
'profile_user_id' => $profileUserId,
'user_id' => $postUserId,
'username' => $this->_convertToUtf8($vm['postusername'], true),
'post_date' => $vm['dateline'],
'message' => $parser->render($this->_convertToUtf8($vm['pagetext'])),
'ip' => XenForo_Helper_Ip::convertIpBinaryToString($vm['ipaddress'])
);
switch ($vm['state'])
{
case 'deleted': $import['message_state'] = 'deleted'; break;
case 'moderation': $import['message_state'] = 'moderated'; break;
default: $import['message_state'] = 'visible';
}
if ($model->importProfilePost($vm['vmid'], $import))
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepForums($start, array $options)
{
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($start > 0)
{
// after importing everything, rebuild the full permission cache so forums appear
XenForo_Model::create('XenForo_Model_Node')->updateNestedSetInfo();
XenForo_Model::create('XenForo_Model_Permission')->rebuildPermissionCache();
return true;
}
$forums = $sDb->fetchAll('
SELECT *
FROM ' . $prefix . 'forum
');
if (!$forums)
{
return true;
}
$forumTree = array();
foreach ($forums AS $forum)
{
$forumTree[$forum['parentid']][$forum['forumid']] = $forum;
}
$forumPermissions = array();
$forumPermissionSql = $sDb->query('
SELECT *
FROM ' . $prefix . 'forumpermission
');
while ($forumPermission = $forumPermissionSql->fetch())
{
$forumPermissions[$forumPermission['forumid']][$forumPermission['usergroupid']] = $forumPermission['forumpermissions'];
}
XenForo_Db::beginTransaction();
$total = $this->_importForumTree(-1, $forumTree, $forumPermissions);
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array(1, array(), '');
}
protected function _importForumTree($parentId, array $forumTree, array $forumPermissions, array $forumIdMap = array())
{
if (!isset($forumTree[$parentId]))
{
return 0;
}
XenForo_Db::beginTransaction();
$total = 0;
foreach ($forumTree[$parentId] AS $forum)
{
$forum['options'] = intval($forum['options']);
$import = array(
'title' => $this->_convertToUtf8($forum['title'], true),
'description' => $this->_convertToUtf8($forum['description'], true),
'display_order' => $forum['displayorder'],
'parent_node_id' => $this->_mapLookUp($forumIdMap, $forum['parentid'], 0),
'display_in_list' => (($forum['options'] & 1) && $forum['displayorder'] > 0) // active
);
if ($forum['link'])
{
$import['node_type_id'] = 'LinkForum';
$import['link_url'] = $forum['link'];
$nodeId = $this->_importModel->importLinkForum($forum['forumid'], $import);
}
else if ($forum['options'] & 4) // cancontainthreads
{
$import['node_type_id'] = 'Forum';
$import['discussion_count'] = $forum['threadcount'];
$import['message_count'] = $forum['replycount'] + $forum['threadcount'];
$import['last_post_date'] = $forum['lastpost'];
$import['last_post_username'] = $this->_convertToUtf8($forum['lastposter'], true);
$import['last_thread_title'] = $this->_convertToUtf8($forum['lastthread'], true);
$nodeId = $this->_importModel->importForum($forum['forumid'], $import);
}
else
{
$import['node_type_id'] = 'Category';
$nodeId = $this->_importModel->importCategory($forum['forumid'], $import);
}
if ($nodeId)
{
if (!empty($forumPermissions[$forum['forumid']]))
{
$this->_importForumPermissions($nodeId, $forumPermissions[$forum['forumid']]);
}
$forumIdMap[$forum['forumid']] = $nodeId;
$total++;
$total += $this->_importForumTree($forum['forumid'], $forumTree, $forumPermissions, $forumIdMap);
}
}
XenForo_Db::commit();
return $total;
}
protected function _importForumPermissions($nodeId, array $groupPerms)
{
if ($this->_groupMap === null)
{
$this->_groupMap = $this->_importModel->getImportContentMap('userGroup');
}
XenForo_Db::beginTransaction();
foreach ($groupPerms AS $oldGroupId => $perms)
{
if ($oldGroupId == 3 || $oldGroupId == 4)
{
continue; // skip these. they'll be treated as guests
}
$newGroupId = $this->_mapLookUp($this->_groupMap, $oldGroupId);
if (!$newGroupId)
{
continue;
}
$newPerms = $this->_calculateForumPermissions($perms);
if ($newPerms)
{
$this->_importModel->insertNodePermissionEntries($nodeId, $newGroupId, 0, $newPerms);
}
}
XenForo_Db::commit();
}
protected $_nodePermissionsGrouped = null;
protected function _calculateForumPermissions($perms)
{
$output = array();
if ($this->_nodePermissionsGrouped === null)
{
$this->_nodePermissionsGrouped = $this->_importModel->getNodePermissionsGrouped();
}
$perms = intval($perms);
if ($perms & 1)
{
// viewable
$output['general']['viewNode'] = 'content_allow';
$output['forum']['viewContent'] = ($perms & 524288 ? 'content_allow' : 'reset');
$output['forum']['viewOthers'] = ($perms & 2 ? 'content_allow' : 'reset');
$output['forum']['postThread'] = ($perms & 16 ? 'content_allow' : 'reset');
$output['forum']['postReply'] = ($perms & 32 ? 'content_allow' : 'reset');
$output['forum']['editOwnPost'] = ($perms & 128 ? 'content_allow' : 'reset');
$output['forum']['deleteOwnPost'] = ($perms & 256 ? 'content_allow' : 'reset');
$output['forum']['deleteOwnThread'] = ($perms & 512 ? 'content_allow' : 'reset');
$output['forum']['viewAttachment'] = ($perms & 4096 ? 'content_allow' : 'reset');
$output['forum']['uploadAttachment'] = ($perms & 8192 ? 'content_allow' : 'reset');
$output['forum']['votePoll'] = ($perms & 32768 ? 'content_allow' : 'reset');
}
else
{
// not viewable, reset all permissions
$output['general']['viewNode'] = 'reset';
foreach ($this->_nodePermissionsGrouped AS $groupId => $permissions)
{
foreach ($permissions AS $permissionId => $perm)
{
if ($perm['permission_type'] == 'flag')
{
$output[$groupId][$permissionId] = 'reset';
}
}
}
}
return $output;
}
public function stepModerators($start, array $options)
{
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
$moderators = $sDb->fetchAll('
SELECT moderator.*,
IF(usergroup.adminpermissions & 1, 1, 0) AS is_super_moderator
FROM ' . $prefix . 'moderator AS moderator
INNER JOIN ' . $prefix . 'user AS user ON (moderator.userid = user.userid)
LEFT JOIN ' . $this->_prefix . 'usergroup AS usergroup ON (user.usergroupid = usergroup.usergroupid)
');
if (!$moderators)
{
return true;
}
$modGrouped = array();
foreach ($moderators AS $moderator)
{
if (!array_key_exists('permissions2', $moderator))
{
$moderator['permissions2'] = 0;
}
$modGrouped[$moderator['userid']][$moderator['forumid']] = $moderator;
}
$superMods = $this->_session->getExtraData('superMods');
if ($superMods)
{
foreach ($superMods AS $oldUserId => $newUserId)
{
if (!isset($modGrouped[$oldUserId]))
{
// no record in mod table, but imported as super mod - has everything
$modGrouped[$oldUserId][-1] = array(
'userid' => $oldUserId,
'is_super_moderator' => true,
'forumid' => -1,
'permissions' => -1, // bitwise, all 1s
'permissions2' => -1 // bitwise, all 1s
);
}
}
}
$nodeMap = $model->getImportContentMap('node');
$userIdMap = $model->getImportContentMap('user', array_keys($modGrouped));
$total = 0;
XenForo_Db::beginTransaction();
foreach ($modGrouped AS $userId => $forums)
{
$newUserId = $this->_mapLookUp($userIdMap, $userId);
if (!$newUserId)
{
continue;
}
$globalModPermissions = array();
$inserted = false;
if (!empty($forums[-1]['is_super_moderator']))
{
$perms = $this->_calculateModeratorPermissions($forums[-1]['permissions'], $forums[-1]['permissions2']);
$globalModPermissions += $perms['global'] + $perms['forum'];
$isSuperMod = true;
$total++;
$inserted = true;
}
else
{
$isSuperMod = false;
}
unset($forums[-1]);
foreach ($forums AS $forumId => $moderator)
{
$newNodeId = $this->_mapLookUp($nodeMap, $forumId);
if (!$newNodeId)
{
continue;
}
$perms = $this->_calculateModeratorPermissions($moderator['permissions'], $moderator['permissions2']);
$globalModPermissions += $perms['global'];
$mod = array(
'content_id' => $newNodeId,
'user_id' => $newUserId,
'moderator_permissions' => $perms['forum']
);
$model->importNodeModerator($forumId, $userId, $mod);
$total++;
$inserted = true;
}
if ($inserted)
{
$mod = array(
'user_id' => $newUserId,
'is_super_moderator' => $isSuperMod,
'moderator_permissions' => $globalModPermissions
);
$model->importGlobalModerator($userId, $mod);
}
}
$this->_session->incrementStepImportTotal($total);
XenForo_Db::commit();
return true;
}
protected function _calculateModeratorPermissions($perms1, $perms2)
{
$global = array();
$forum = array();
$perms1 = intval($perms1);
$perms2 = intval($perms2);
if ($perms2 & 1)
{
$global['profilePost']['editAny'] = true;
}
if ($perms2 & 2)
{
$global['profilePost']['deleteAny'] = true;
$global['profilePost']['undelete'] = true;
if ($perms2 & 4)
{
$global['profilePost']['hardDeleteAny'] = true;
}
}
if ($perms2 & 8)
{
$global['profilePost']['approveUnapprove'] = true;
$global['profilePost']['viewDeleted'] = true;
$global['profilePost']['viewModerated'] = true;
}
if ($perms1 & 1)
{
$forum['forum']['editAnyPost'] = true;
}
if ($perms1 & 2)
{
$forum['forum']['deleteAnyPost'] = true;
$forum['forum']['deleteAnyThread'] = true;
$forum['forum']['undelete'] = true;
if ($perms1 & 131072)
{
$forum['forum']['hardDeleteAnyPost'] = true;
$forum['forum']['hardDeleteAnyThread'] = true;
}
// these don't really fit. give them to mods that can delete stuff
$forum['general']['viewIps'] = true;
$forum['general']['cleanSpam'] = true;
$forum['general']['bypassUserPrivacy'] = true;
}
if ($perms1 & 4)
{
$forum['forum']['lockUnlockThread'] = true;
}
if ($perms1 & 16)
{
$forum['forum']['manageAnyThread'] = true;
$forum['forum']['stickUnstickThread'] = true;
}
if ($perms1 & 64)
{
$forum['forum']['approveUnapprove'] = true;
$forum['forum']['viewModerated'] = true;
}
$forum['forum']['viewDeleted'] = true; // this was given automatically to mods
return array(
'global' => $global,
'forum' => $forum
);
}
public function stepThreadPrefixes($start, array $options)
{
$options = array_merge(array(), $options);
$sDb = $this->_sourceDb;
$tablePrefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
$nodeMap = $model->getImportContentMap('node');
$userGroupMap = $model->getImportContentMap('userGroup');
$prefixSets = $sDb->fetchAll("
SELECT prefixset.*, phrase.text AS title
FROM {$tablePrefix}prefixset AS prefixset
LEFT JOIN {$tablePrefix}phrase AS phrase ON
(phrase.languageid = 0 AND phrase.varname = CONCAT('prefixset_', prefixset.prefixsetid, '_title'))
ORDER BY prefixset.displayorder
");
$prefixUserGroups = array();
try // vB 3.7 has no prefix permissions, so catch the error that will occur when we try to query them
{
foreach ($sDb->fetchAll('SELECT * FROM ' . $tablePrefix . 'prefixpermission') AS $pug)
{
$prefixUserGroups[$pug['prefixid']][$pug['usergroupid']] = true;
}
}
catch (Exception $e) {}
$prefixSetForums = array();
foreach ($sDb->fetchAll('SELECT * FROM ' . $tablePrefix . 'forumprefixset') AS $psf)
{
$prefixSetForums[$psf['prefixsetid']][$psf['forumid']] = $psf['forumid'];
}
$prefixes = $sDb->fetchAll("
SELECT prefix.*, phrase.text AS title
FROM {$tablePrefix}prefix AS prefix
INNER JOIN {$tablePrefix}prefixset AS prefixset ON
(prefixset.prefixsetid = prefix.prefixsetid)
LEFT JOIN {$tablePrefix}phrase AS phrase ON
(phrase.languageid = 0 AND phrase.varname = CONCAT('prefix_', prefix.prefixid, '_title_plain'))
ORDER BY prefixset.displayorder, prefix.displayorder
");
// get the list of nodes to which each prefix set applies
$prefixNodes = array();
foreach ($prefixes AS $prefix)
{
$prefixSetId = $prefix['prefixsetid'];
if (empty($prefixNodes[$prefixSetId]))
{
$prefixNodes[$prefixSetId] = array();
if (isset($prefixSetForums[$prefixSetId]))
{
foreach ($prefixSetForums[$prefixSetId] AS $prefixSetForumId)
{
$nodeId = $this->_mapLookUp($nodeMap, $prefixSetForumId);
if ($nodeId)
{
$prefixNodes[$prefixSetId][] = $nodeId;
}
}
}
}
}
$total = 0;
XenForo_Db::beginTransaction($this->_db);
$prefixGroupMap = array();
foreach ($prefixSets AS $prefixSet)
{
$prefixSetId = strtolower($prefixSet['prefixsetid']);
$import = array(
'display_order' => $prefixSet['displayorder'],
XenForo_Model_Import::EXTRA_DATA_KEY => array(
XenForo_DataWriter_ThreadPrefixGroup::DATA_TITLE => $this->_convertToUtf8($prefixSet['title'])
)
);
$prefixGroupMap[$prefixSetId] = $model->importThreadPrefixGroup($prefixSetId, $import);
}
foreach ($prefixes AS $order => $prefix)
{
$prefixId = $prefix['prefixid'];
$prefixSetId = $prefix['prefixsetid'];
if (empty($prefixUserGroups[$prefixId]))
{
$allowedUserGroupIds = '-1';
}
else
{
$allowedUserGroupIds = array();
foreach ($userGroupMap AS $oldUgId => $newUgId)
{
if (!isset($prefixUserGroups[$prefixId][$oldUgId]))
{
$allowedUserGroupIds[] = $newUgId;
}
}
$allowedUserGroupIds = implode(',', $allowedUserGroupIds);
}
$import = array(
'display_order' => $order * 10,
'css_class' => 'prefix prefixPrimary',
'allowed_user_group_ids' => $allowedUserGroupIds,
'prefix_group_id' => $this->_mapLookUp($prefixGroupMap, $prefixSetId, 0),
);
$model->importThreadPrefix(strtolower($prefixId), $import,
$this->_convertToUtf8($prefix['title']),
$prefixNodes[$prefixSetId]);
$total++;
}
// build the prefix caches
$prefixModel = XenForo_Model::create('XenForo_Model_ThreadPrefix');
$prefixModel->rebuildPrefixMaterializedOrder();
$prefixModel->rebuildPrefixCache();
XenForo_Db::commit($this->_db);
$this->_session->incrementStepImportTotal($total);
return true;
}
public function stepThreads($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'postDateStart' => 0,
'postLimit' => 800,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(threadid)
FROM ' . $prefix . 'thread
');
}
// pull threads from things we actually imported as forums
$threads = $sDb->fetchAll($sDb->limit(
'
SELECT thread.*,
IF(user.username IS NULL, thread.postusername, user.username) AS postusername
FROM ' . $prefix . 'thread AS thread FORCE INDEX (PRIMARY)
LEFT JOIN ' . $prefix . 'user AS user ON (thread.postuserid = user.userid)
INNER JOIN ' . $prefix . 'forum AS forum ON
(thread.forumid = forum.forumid AND forum.link = '' AND forum.options & 4)
WHERE thread.threadid >= ' . $sDb->quote($start) . '
AND thread.open <> 10
ORDER BY thread.threadid
', $options['limit']
));
if (!$threads)
{
return true;
}
$next = 0;
$total = 0;
$totalPosts = 0;
$nodeMap = $model->getImportContentMap('node');
$threadPrefixMap = $model->getImportContentMap('threadPrefix');
XenForo_Db::beginTransaction();
foreach ($threads AS $thread)
{
if (trim($thread['title']) === '')
{
continue;
}
$postDateStart = $options['postDateStart'];
$next = $thread['threadid'] + 1; // uses >=, will be moved back down if need to continue
$options['postDateStart'] = 0;
$maxPosts = $options['postLimit'] - $totalPosts;
$posts = $sDb->fetchAll($sDb->limit(
'
SELECT post.*,
IF(user.username IS NULL, post.username, user.username) AS username,
editlog.dateline AS editdate, editlog.userid AS edituserid
FROM ' . $prefix . 'post AS post
LEFT JOIN ' . $prefix . 'user AS user ON (post.userid = user.userid)
LEFT JOIN ' . $prefix . 'editlog AS editlog ON (post.postid = editlog.postid)
WHERE post.threadid = ' . $sDb->quote($thread['threadid']) . '
AND post.dateline > ' . $sDb->quote($postDateStart) . '
ORDER BY post.dateline
', $maxPosts
));
if (!$posts)
{
if ($postDateStart)
{
// continuing thread but it has no more posts
$total++;
}
continue;
}
if ($postDateStart)
{
// continuing thread we already imported
$threadId = $model->mapThreadId($thread['threadid']);
$position = $this->_db->fetchOne('
SELECT MAX(position)
FROM xf_post
WHERE thread_id = ?
', $threadId);
}
else
{
$forumId = $this->_mapLookUp($nodeMap, $thread['forumid']);
if (!$forumId)
{
continue;
}
if (trim($thread['postusername']) === '')
{
$thread['postusername'] = 'Guest';
}
$import = array(
'title' => $this->_convertToUtf8($thread['title'], true),
'node_id' => $forumId,
'user_id' => $model->mapUserId($thread['postuserid'], 0),
'username' => $this->_convertToUtf8($thread['postusername'], true),
'discussion_open' => $thread['open'],
'post_date' => $thread['dateline'],
'reply_count' => $thread['replycount'],
'view_count' => $thread['views'],
'sticky' => $thread['sticky'],
'last_post_date' => $thread['lastpost'],
'last_post_username' => $this->_convertToUtf8($thread['lastposter'], true),
);
if (isset($thread['prefixid']))
{
$import['prefix_id'] = $this->_mapLookUp($threadPrefixMap, $thread['prefixid'], 0);
}
switch ($thread['visible'])
{
case 0: $import['discussion_state'] = 'moderated'; break;
case 2: $import['discussion_state'] = 'deleted'; break;
default: $import['discussion_state'] = 'visible'; break;
}
$threadId = $model->importThread($thread['threadid'], $import);
if (!$threadId)
{
continue;
}
$position = -1;
$subs = $sDb->fetchPairs('
SELECT userid, emailupdate
FROM ' . $prefix . 'subscribethread
WHERE threadid = ' . $sDb->quote($thread['threadid'])
);
if ($subs)
{
$userIdMap = $model->getImportContentMap('user', array_keys($subs));
foreach ($subs AS $userId => $emailUpdate)
{
$newUserId = $this->_mapLookUp($userIdMap, $userId);
if (!$newUserId)
{
continue;
}
$model->importThreadWatch($newUserId, $threadId, ($emailUpdate ? 1 : 0));
}
}
}
if ($threadId)
{
$quotedPostIds = array();
$threadTitleRegex = '#^(re:s*)?' . preg_quote($thread['title'], '#') . '$#i';
$userIdMap = $model->getUserIdsMapFromArray($posts, 'userid');
foreach ($posts AS $i => $post)
{
if ($post['title'] !== '' && !preg_match($threadTitleRegex, $post['title']))
{
$post['pagetext'] = '[b]' . htmlspecialchars_decode($post['title']) . "[/b]nn" . ltrim($post['pagetext']);
}
if (trim($post['username']) === '')
{
$post['username'] = 'Guest';
}
$post['pagetext'] = $this->_convertToUtf8($post['pagetext']);
$import = array(
'thread_id' => $threadId,
'user_id' => $this->_mapLookUp($userIdMap, $post['userid'], 0),
'username' => $this->_convertToUtf8($post['username'], true),
'post_date' => $post['dateline'],
'message' => $post['pagetext'],
'attach_count' => 0,
'ip' => $post['ipaddress'],
'last_edit_date' => !empty($post['editdate']) ? $post['editdate'] : 0,
'last_edit_user_id' => !empty($post['editdate']) ? $post['edituserid'] : 0,
'edit_count' => !empty($post['editdate']) ? 1 : 0
);
switch ($post['visible'])
{
case 0: $import['message_state'] = 'moderated'; $import['position'] = $position; break;
case 2: $import['message_state'] = 'deleted'; $import['position'] = $position; break;
default: $import['message_state'] = 'visible'; $import['position'] = ++$position; break;
}
$post['xf_post_id'] = $model->importPost($post['postid'], $import);
$options['postDateStart'] = $post['dateline'];
$totalPosts++;
if (stripos($post['pagetext'], '[quote=') !== false)
{
if (preg_match_all('/[quote=("|'|)(?P<username>[^;n]]*);s*(?P<postid>d+)s*1]/siU', $post['pagetext'], $quotes, PREG_SET_ORDER))
{
$post['quotes'] = array();
foreach ($quotes AS $quote)
{
$quotedPostId = intval($quote['postid']);
$quotedPostIds[] = $quotedPostId;
$post['quotes'][$quote[0]] = array($quote['username'], $quotedPostId);
}
}
}
$posts[$i] = $post;
}
$postIdMap = (empty($quotedPostIds) ? array() : $model->getImportContentMap('post', $quotedPostIds));
$db = XenForo_Application::getDb();
foreach ($posts AS $post)
{
if (!empty($post['quotes']))
{
$postQuotesRewrite = $this->_rewriteQuotes($post['pagetext'], $post['quotes'], $postIdMap);
if ($post['pagetext'] != $postQuotesRewrite)
{
$db->update('xf_post', array('message' => $postQuotesRewrite), 'post_id = ' . $db->quote($post['xf_post_id']));
}
}
}
}
if (count($posts) < $maxPosts)
{
// done this thread
$total++;
$options['postDateStart'] = 0;
}
else
{
// not necessarily done the thread; need to pick it up next page
break;
}
}
if ($options['postDateStart'])
{
// not done this thread, need to continue with it
$next--;
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next - 1, $options['max']));
}
protected function _rewriteQuotes($message, array $quotes, array $postIdMap)
{
foreach ($quotes AS $quote => &$replace)
{
list($username, $postId) = $replace;
$replace = sprintf('[quote="%s, post: %d"]', $username, $this->_mapLookUp($postIdMap, $postId));
}
return str_replace(array_keys($quotes), $quotes, $message);
}
public function stepPostEditHistory($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(postid)
FROM ' . $prefix . 'postedithistory
');
}
// fetch the next 100 posts
$postIds = $sDb->fetchCol($sDb->limit(
'
SELECT DISTINCT postid
FROM ' . $prefix . 'postedithistory
WHERE postid > ' . $sDb->quote($start) . '
ORDER BY postid
', $options['limit']
));
if (!$postIds)
{
return true;
}
$edits = $sDb->fetchAll(
'
SELECT *
FROM ' . $prefix . 'postedithistory
WHERE postid IN (' . $sDb->quote($postIds) . ')
ORDER BY postedithistoryid
'
);
if (!$edits)
{
return true;
}
$next = 0;
$total = 0;
$postIdMap = $model->getPostIdsMapFromArray($edits, 'postid');
$userIdMap = $model->getUserIdsMapFromArray($edits, 'userid');
// assemble an array
$orderedEdits = array();
foreach ($edits AS $edit)
{
$orderedEdits[$edit['postid']][$edit['postedithistoryid']] = $edit;
}
unset($edits);
XenForo_Db::beginTransaction();
foreach ($orderedEdits AS $postId => $edits)
{
$pageText = false;
$next = max($next, $postId);
foreach ($edits AS $edit)
{
if ($pageText)
{
$newPostId = $this->_mapLookUp($postIdMap, $edit['postid']);
if (!$newPostId)
{
continue;
}
if ($pageText !== false)
{
$import = array(
'content_type' => 'post',
'content_id' => $newPostId,
'edit_user_id' => $this->_mapLookUp($userIdMap, $edit['userid'], 0),
'edit_date' => $edit['dateline'],
'old_text' => $this->_convertToUtf8($pageText),
);
$model->importEditHistory($edit['postedithistoryid'], $import);
$total++;
}
}
$pageText = $edit['pagetext'];
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepPolls($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(pollid)
FROM ' . $prefix . 'poll
');
}
$polls = $sDb->fetchAll($sDb->limit(
'
SELECT poll.*, thread.threadid
FROM ' . $prefix . 'poll AS poll
INNER JOIN ' . $prefix . 'thread AS thread ON (thread.pollid = poll.pollid AND thread.open <> 10)
WHERE poll.pollid > ' . $sDb->quote($start) . '
ORDER BY poll.pollid
', $options['limit']
));
if (!$polls)
{
return true;
}
$next = 0;
$total = 0;
$threadIdMap = $model->getThreadIdsMapFromArray($polls, 'threadid');
$donePolls = array();
XenForo_Db::beginTransaction();
foreach ($polls AS $poll)
{
$next = $poll['pollid'];
$newThreadId = $this->_mapLookUp($threadIdMap, $poll['threadid']);
if (!$newThreadId)
{
continue;
}
if (isset($donePolls[$poll['pollid']]))
{
// some times the pollid in the thread table isn't unique so it can try to import dupes
continue;
}
$import = array(
'question' => $this->_convertToUtf8($poll['question'], true),
'public_votes' => $poll['public'],
'multiple' => $poll['multiple'],
'close_date' => ($poll['timeout'] ? $poll['dateline'] + 86400 * $poll['timeout'] : 0)
);
$responses = explode('|||', $this->_convertToUtf8($poll['options'], true));
$newPollId = $model->importThreadPoll($poll['pollid'], $newThreadId, $import, $responses, $responseIds);
if ($newPollId)
{
$donePolls[$poll['pollid']] = $newPollId;
$votes = $sDb->fetchAll('
SELECT userid, votedate, voteoption
FROM ' . $prefix . 'pollvote
WHERE pollid = ' . $sDb->quote($poll['pollid'])
);
$userIdMap = $model->getUserIdsMapFromArray($votes, 'userid');
foreach ($votes AS $vote)
{
$userId = $this->_mapLookUp($userIdMap, $vote['userid']);
if (!$userId)
{
continue;
}
$voteOption = max(0, $vote['voteoption'] - 1);
if (!isset($responseIds[$voteOption]))
{
continue;
}
$model->importPollVote($newPollId, $userId, $responseIds[$voteOption], $vote['votedate']);
}
}
$total++;
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepAttachments($start, array $options)
{
$options = array_merge(array(
'path' => isset($this->_config['attachmentPath']) ? $this->_config['attachmentPath'] : '',
'limit' => 50,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(attachmentid)
FROM ' . $prefix . 'attachment
');
}
$attachments = $sDb->fetchAll($sDb->limit(
'
SELECT attachmentid, userid, dateline, filename, counter, postid
FROM ' . $prefix . 'attachment
WHERE attachmentid > ' . $sDb->quote($start) . '
AND visible = 1
ORDER BY attachmentid
', $options['limit']
));
if (!$attachments)
{
return true;
}
$next = 0;
$total = 0;
$userIdMap = $model->getUserIdsMapFromArray($attachments, 'userid');
$postIdMap = $model->getPostIdsMapFromArray($attachments, 'postid');
$posts = $model->getModelFromCache('XenForo_Model_Post')->getPostsByIds($postIdMap);
foreach ($attachments AS $attachment)
{
$next = $attachment['attachmentid'];
$newPostId = $this->_mapLookUp($postIdMap, $attachment['postid']);
if (!$newPostId)
{
continue;
}
if (!$options['path'])
{
$fData = $sDb->fetchOne('
SELECT filedata
FROM ' . $prefix . 'attachment
WHERE attachmentid = ' . $sDb->quote($attachment['attachmentid'])
);
if ($fData === '')
{
continue;
}
$attachFile = tempnam(XenForo_Helper_File::getTempDir(), 'xf');
if (!$attachFile || !@file_put_contents($attachFile, $fData))
{
continue;
}
$isTemp = true;
}
else
{
$attachFileOrig = "$options[path]/" . implode('/', str_split($attachment['userid'])) . "/$attachment[attachmentid].attach";
if (!file_exists($attachFileOrig))
{
continue;
}
$attachFile = tempnam(XenForo_Helper_File::getTempDir(), 'xf');
copy($attachFileOrig, $attachFile);
$isTemp = true;
}
$success = $model->importPostAttachment(
$attachment['attachmentid'],
$this->_convertToUtf8($attachment['filename']),
$attachFile,
$this->_mapLookUp($userIdMap, $attachment['userid'], 0),
$newPostId,
$attachment['dateline'],
array('view_count' => $attachment['counter']),
array($this, 'processAttachmentTags'),
$posts[$newPostId]['message']
);
if ($success)
{
$total++;
}
if ($isTemp)
{
@unlink($attachFile);
}
}
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public static function processAttachmentTags($oldAttachmentId, $newAttachmentId, $messageText)
{
if (stripos($messageText, '[ATTACH') !== false)
{
/**
* Note: We use '$newAttachmentId.vB' as the attachment id in the XenForo replacement
* to avoid it being replaced again when we come across an attachment whose source id
* is the same as this one's imported id.
*
* @var string
*/
$newTag = sprintf('[ATTACH]%d.vB[/ATTACH]', $newAttachmentId);
$messageText = preg_replace("#[ATTACH[^]]*]{$oldAttachmentId}[/ATTACH]#siU", $newTag, $messageText);
}
return $messageText;
}
public function configStepReputation(array $options)
{
if ($options)
{
return false;
}
return $this->_controller->responseView('XenForo_ViewAdmin_Import_vBulletin_ConfigReputation', 'import_config_likes');
}
public function stepReputation($start, array $options)
{
$options = array_merge(array(
'fetchLikeUsers' => false,
'limit' => 100,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(reputationid)
FROM ' . $prefix . 'reputation
WHERE reputation > 0
');
}
$reputations = $sDb->fetchAll($sDb->limit(
'
SELECT *
FROM ' . $prefix . 'reputation
WHERE reputationid > ' . $sDb->quote($start) . '
AND reputation > 0
ORDER BY reputationid
', $options['limit']
));
if (!$reputations)
{
return true;
}
$next = 0;
$total = 0;
$userIds = array();
foreach ($reputations AS $rep)
{
$userIds[] = $rep['userid'];
$userIds[] = $rep['whoadded'];
}
$postIdMap = $model->getPostIdsMapFromArray($reputations, 'postid');
$userIdMap = $model->getImportContentMap('user', $userIds);
XenForo_Db::beginTransaction();
foreach ($reputations AS $rep)
{
$next = $rep['reputationid'];
$newPostId = $this->_mapLookUp($postIdMap, $rep['postid']);
if (!$newPostId)
{
continue;
}
$model->importLike(
'post',
$newPostId,
$this->_mapLookUp($userIdMap, $rep['userid']),
$this->_mapLookUp($userIdMap, $rep['whoadded']),
$rep['dateline'],
$options['fetchLikeUsers']
);
$total++;
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
public function stepInfractions($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'max' => false
), $options);
$sDb = $this->_sourceDb;
$prefix = $this->_prefix;
/* @var $model XenForo_Model_Import */
$model = $this->_importModel;
if ($options['max'] === false)
{
$options['max'] = $sDb->fetchOne('
SELECT MAX(infractionid)
FROM ' . $prefix . 'infraction
WHERE infractionid > 0
');
}
$infractions = $sDb->fetchAll($sDb->limit(
'
SELECT infraction.*,
user.username AS username,
COALESCE(thread.title, '') AS thread_title,
COALESCE(phrase.text, '') AS title
FROM ' . $prefix . 'infraction AS infraction
INNER JOIN ' . $prefix . 'user AS user ON (user.userid = infraction.userid)
LEFT JOIN ' . $prefix . 'post AS post ON (infraction.postid = post.postid)
LEFT JOIN ' . $prefix . 'thread AS thread ON (post.threadid = thread.threadid)
LEFT JOIN ' . $prefix . 'phrase AS phrase ON (phrase.varname = CONCAT('infractionlevel', infraction.infractionlevelid, '_title') AND phrase.languageid = 0)
WHERE infractionid > ' . $sDb->quote($start) . '
ORDER BY infractionid
', $options['limit']
));
if (!$infractions)
{
return true;
}
$next = 0;
$total = 0;
$userIds = array();
foreach ($infractions AS $infraction)
{
$userIds[] = $infraction['userid'];
$userIds[] = $infraction['whoadded'];
}
$postIdMap = $model->getPostIdsMapFromArray($infractions, 'postid');
$userIdMap = $model->getImportContentMap('user', $userIds);
XenForo_Db::beginTransaction();
foreach ($infractions AS $infraction)
{
$next = $infraction['infractionid'];
if ($infraction['postid'])
{
$newPostId = $this->_mapLookUp($postIdMap, $infraction['postid']);
if (!$newPostId)
{
continue;
}
}
else
{
$newPostId = 0;
}
$newUserId = $this->_mapLookUp($userIdMap, $infraction['userid']);
if (!$newUserId)
{
continue;
}
$newWarnUserId = $this->_mapLookUp($userIdMap, $infraction['whoadded']);
if (!$newWarnUserId)
{
$newWarnUserId = 0;
}
$import = array(
'content_type' => $infraction['postid'] ? 'post' : 'user',
'content_id' => $infraction['postid'] ? $newPostId : $newUserId,
'content_title' => $this->_convertToUtf8($infraction['postid'] ? $infraction['thread_title'] : $infraction['username'], true),
'user_id' => $newUserId,
'warning_date' => $infraction['dateline'],
'warning_user_id' => $newWarnUserId,
'warning_definition_id' => 0,
'title' => $this->_convertToUtf8($infraction['title']),
'notes' => $this->_convertToUtf8($infraction['note']),
'points' => $infraction['points'],
'expiry_date' => $infraction['action'] == 2 ? $infraction['dateline'] : $infraction['expires'],
'is_expired' => !empty($infraction['action']) ? 1 : 0,
'extra_user_group_ids' => ''
);
if ($model->importWarning($infraction['infractionid'], $import))
{
$total++;
}
}
XenForo_Db::commit();
$this->_session->incrementStepImportTotal($total);
return array($next, $options, $this->_getProgressOutput($next, $options['max']));
}
}