public function stepPrivateMessages($start, array $options)
{
$options = array_merge(array(
'limit' => 100,
'pmDateStart' => 0,
'pmLimit' => 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(id_pm_head)
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head = id_pm AND id_member_from != 0
');
}
$conversations = $sDb->fetchAll($sDb->limit(
'
SELECT *
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head >= ' . $sDb->quote($start) . '
AND id_pm_head = id_pm AND id_member_from != 0
ORDER BY id_pm_head
', $options['limit']
));
if (!$conversations)
{
return true;
}
$next = 0;
$total = 0;
$totalPosts = 0;
XenForo_Db::beginTransaction();
foreach ($conversations AS $conversation)
{
/* Количество ответов в каждой переписке */
$countPost = $sDb->fetchOne('
SELECT COUNT(*)
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head = ' . $conversation['id_pm_head'] . '
');
$reply_count = $countPost - 1;
/* Выборка данных из первой строки в диалоге */
$pmDataFirstSql = $sDb->fetchAll('
SELECT *
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head = ' . $sDb->quote($conversation['id_pm_head']) . '
ORDER BY msgtime ASC LIMIT 1'
);
$pmdata = array();
foreach ($pmDataFirstSql AS $data)
{
# Первое сообщение в переписке: first_post
# Дата первого сообщения: start_date
$pmdata = array(
'first_post' => $data['id_pm'],
'start_date' => $data['msgtime']
);
}
/* Выборка данных из последней строки в диалоге */
$pmDataLastSql = $sDb->fetchAll('
SELECT *
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head = ' . $sDb->quote($conversation['id_pm_head']) . '
ORDER BY msgtime DESC LIMIT 1'
);
foreach ($pmDataLastSql AS $data)
{
# ID замыкающего диалог пользователя (последний): last_message_user_id
# Ник замыкающего диалог пользователя (последний): last_message_username
# Последнее сообщение в переписке: last_post
# Дата последнего сообщения в диалоге: last_read_date
$pmdata += array(
'last_message_user_id' => $data['id_member_from'],
'last_message_username' => $data['from_name'],
'last_post' => $data['id_pm'],
'last_read_date' => $data['msgtime']
);
}
/* Участники диалога */
$toUsers = $sDb->fetchPairs('
SELECT recip.id_member, member.member_name
FROM ' . $prefix . 'pm_recipients AS recip
INNER JOIN ' . $prefix . 'members AS member ON
(recip.id_member = member.id_member)
WHERE recip.id_pm = ?
', $conversation['id_pm_head']);
if (!$toUsers)
{
continue;
}
$users = array(
$conversation['id_member_from'] => $conversation['from_name']
) + $toUsers;
$mapUserIds = $model->getImportContentMap('user', array_keys($users));
$newFromUserId = $this->_mapLookUp($mapUserIds, $conversation['id_member_from']);
if (!$newFromUserId)
{
continue;
}
$fromUserName = $this->_convertToUtf8($conversation['from_name'], true);
/* Количество получателей в переписке */
$recipient_count = count($users);
/* Захват сообщений */
$pmDateStart = $options['pmDateStart'];
$next = $conversation['id_pm_head'] + 1; // uses >=, will be moved back down if need to continue
$options['pmDateStart'] = 0;
$maxPosts = $options['pmLimit'] - $totalPosts;
$postsPm = $sDb->fetchAll($sDb->limit(
'
SELECT *
FROM ' . $prefix . 'personal_messages
WHERE id_pm_head = ' . $sDb->quote($conversation['id_pm_head']) . '
AND msgtime > ' . $sDb->quote($pmDateStart) . '
ORDER BY id_pm
', $maxPosts
));
if (!$postsPm)
{
if ($pmDateStart)
{
// continuing conversation but it has no more posts
$total++;
}
continue;
}
/* Импорт конференции */
if ($pmDateStart)
{
// continuing conversation we already imported
$conversationId = $model->mapConversationId($conversation['id_pm_head']);
}
else
{
/* Формирование конференции */
$import = array(
'recipient_count' => $recipient_count,
'reply_count' => $reply_count,
'start_date' => $pmdata['start_date'], #
'last_message_id' => $pmdata['last_post'], #
'last_message_date' => $pmdata['last_read_date'], #
'last_message_user_id' => $pmdata['last_message_user_id'],
'last_message_username' => utf8_substr($pmdata['last_message_username'], 0, 50), #
'title' => $this->_convertToUtf8($conversation['subject'], true),
'user_id' => $newFromUserId,
'username' => $fromUserName,
'open_invite' => 0,
'conversation_open' => 1
);
/* Делает выборку всех последних ЛС (включая удалённые), - прочтённые непрочтённые */
$unreadState = $sDb->fetchPairs('
SELECT rec.id_member, rec.is_read
FROM ' . $prefix . 'pm_recipients AS rec
LEFT JOIN ' . $prefix . 'personal_messages as pm ON (pm.id_pm = rec.id_pm)
WHERE pm.id_pm_head = ' . $sDb->quote($conversation['id_pm_head']) . '
ORDER BY pm.id_pm DESC LIMIT 1
');
$recipients = array();
foreach ($users AS $userId => $username)
{
$newUserId = $this->_mapLookUp($mapUserIds, $userId);
if (!$newUserId)
{
continue;
}
/* Вернём все удалённые обратно и правильно отметим непрочитаные перенесенные переписки (если надо, пользователи удалят снова, а то каша получается из переписок) */
if (isset($unreadState[$userId]))
{
$lastReadDate = $unreadState[$userId] ? $pmdata['last_read_date'] : 0;
$deleted = false;
$isUnread = $unreadState[$userId] == 0 ? 1 : 0;
}
else
{
$lastReadDate = $pmdata['last_read_date'];
$deleted = false;
$isUnread = 0;
}
$recipients[$newUserId] = array(
'username' => $this->_convertToUtf8($username, true),
'last_read_date' => $lastReadDate,
# Отмечаем все ЛС как активные
'recipient_state' => ($deleted ? 'deleted' : 'active'),
'is_unread' => $isUnread
);
}
$conversationId = $model->importConversation($conversation['id_pm_head'], $recipients, $import);
if (!$conversationId)
{
continue;
}
}
/* Импорт сообщений конференции */
if ($conversationId)
{
$userIdMap = $model->getUserIdsMapFromArray($postsPm, 'id_member_from');
foreach ($postsPm AS $i => $postPm)
{
$messages = array(
array(
'conversation_id' => $conversationId,
'message_date' => $postPm['msgtime'],
'user_id' => $this->_mapLookUp($userIdMap, $postPm['id_member_from'], 0),
'username' => $this->_convertToUtf8($postPm['from_name'], true),
'message' => $this->_sanitizeBbCode($postPm['body'])
)
);
$model->importConversationPost($postPm['id_pm'], $messages);
$options['pmDateStart'] = $postPm['msgtime'];
$totalPosts++;
}
if (count($postsPm) < $maxPosts)
{
// done this conversation
$total++;
$options['pmDateStart'] = 0;
}
else
{
// not necessarily done the conversation; need to pick it up next page
break;
}
}
if (count($postsPm) < $maxPosts)
{
// done this conversation
$total++;
$options['pmDateStart'] = 0;
}
else
{
// not necessarily done the conversation; need to pick it up next page
break;
}
}
if ($options['pmDateStart'])
{
// 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']));
}