public function stepModeratorLog(StepState $state, array $stepConfig)
{
\XF::setMemoryLimit(2048 * 1024 * 1024);
$rows = $this->sourceDb->fetchAll($this->prepareImportSql($this->prefix, "
SELECT m.*,
t.title AS t_title, t.postuserid AS t_userid, t.postusername AS t_username,
p.title AS p_title, p.userid AS p_userid, p.username AS p_username
FROM moderatorlog AS m
LEFT JOIN thread AS t USING (threadid)
LEFT JOIN post AS p USING (postid)
ORDER BY m.dateline, m.moderatorlogid
"));
if (!$rows)
{
return $state->complete();
}
$insert = [];
$visibleState = [];
$openState = [];
$stickyState = [];
foreach ($rows as $row)
{
if (!$row['type'])
{
continue;
}
if (in_array($row['type'], [17, 18, 19, 20, 24, 25, 26]))
{
$content_type = 'post';
$content_id = $row['postid'];
$content_user_id = (int) $row['p_userid'];
$content_username = (string) $row['p_username'];
$content_title = $row['threadtitle'] ?: (string) $row['t_title'];
$content_url = $row['postid'] ? "posts/$row[postid]/" : '';
if (!$content_title)
{
$content_title = $this->buildThreadTitle($row['p_title']);
}
}
else
{
$content_type = 'thread';
$content_id = $row['threadid'];
$content_user_id = (int) $row['t_userid'];
$content_username = (string) $row['t_username'];
$content_title = $row['threadtitle'] ?: (string) $row['t_title'];
$content_url = $row['threadid'] ? "threads/$row[threadid]/" : '';
}
$discussion_content_type = 'thread';
$discussion_content_id = $row['threadid'];
$actions = [];
$action_params = '';
$thread_id = $row['threadid'];
switch ($row['type'])
{
case 1:
$actions = ['lock'];
$openState[$thread_id] = 0;
break;
case 2:
$actions = ['unlock'];
$openState[$thread_id] = 1;
break;
case 3:
$actions = ['move'];
$action_params = ['from' => 'Unbekannt'];
break;
case 4:
$actions = ['move'];
$action_params = ['from' => 'Unbekannt'];
break;
case 5:
$actions = ['move'];
$action_params = ['from' => 'Unbekannt'];
break;
case 6:
list($visible, $open, $sticky) = unserialize($row['action']);
$prevVisible = $visibleState[$thread_id] ?? 1;
$prevOpen = $openState[$thread_id] ?? 1;
$prevSticky = $stickyState[$thread_id] ?? 0;
if ($visible != $prevVisible)
{
}
if ($open != $prevOpen)
{
$actions[] = $open ? 'unlock' : 'lock';
$openState[$thread_id] = $open;
}
if ($sticky != $prevSticky)
{
$actions[] = $sticky ? 'stick' : 'unstick';
$stickyState[$thread_id] = $sticky;
}
break;
case 7:
$actions = ['merge_target'];
$action_params = [
'ids' => $row['action'] ? "'" . html_entity_decode($row['action']) . "'" : 'Unbekannt',
];
break;
case 8:
$actions = ['post_move_source'];
$threadTitle = $this->sourceDb->fetchOne('SELECT title FROM vb_thread
WHERE threadid=?', $row['action']);
$action_params = [
'url' => "threads/$row[action]/",
'title' => html_entity_decode($threadTitle) ?: "Thema $row[action]",
];
break;
case 1008:
$actions = ['post_move_target_existing'];
$action_params = ['ids' => ctype_digit($row['action']) ?
'Thema mit ID ' . $row['action'] : 'Unbekanntes Thema'];
break;
case 9:
$actions = ['unstick'];
$stickyState[$thread_id] = 0;
break;
case 10:
$actions = ['stick'];
$stickyState[$thread_id] = 1;
break;
case 11:
break;
case 12:
break;
case 13:
$actions = ['poll_edit'];
break;
case 14:
$actions = ['delete_soft'];
$action_params = ['reason' => ''];
$visibleState[$thread_id] = 0;
break;
case 15:
$actions = ['delete_hard'];
break;
case 16:
$actions = ['undelete'];
$visibleState[$thread_id] = 1;
break;
case 17:
$actions = ['delete_soft'];
$action_params = ['reason' => ''];
$_action = unserialize($row['action']);
list($content_title, $content_username) = $_action;
break;
case 18:
$actions = ['delete_hard'];
$_action = unserialize($row['action']);
list($content_title, $content_username) = $_action;
break;
case 19:
$actions = ['undelete'];
$_action = unserialize($row['action']);
list($content_title, $content_username) = $_action;
break;
case 20:
$actions = ['edit'];
if ($row['action'])
{
$content_title = $this->buildThreadTitle($row['action']);
}
break;
case 21:
$actions = ['approve'];
break;
case 22:
$actions = ['unapprove'];
break;
case 23:
$actions = ['merge_target'];
$action_params = ['ids' => 'Mehrere Themen'];
break;
case 24:
$actions = ['unapprove'];
if ($row['action'])
{
$content_title = $this->buildThreadTitle($row['action']);
}
break;
case 25:
$actions = ['approve'];
if ($row['action'])
{
$content_title = $this->buildThreadTitle($row['action']);
}
break;
case 26:
$actions = ['merge_target'];
if ($row['action'])
{
$content_title = $this->buildThreadTitle($row['action']);
}
$action_params = ['ids' => 'Mehrere Beiträge'];
break;
case 27:
break;
case 28:
break;
case 29:
$actions = ['title'];
$action_params = ['old' => html_entity_decode($row['action'])];
break;
case 30:
break;
case 31:
$actions = ['post_copy_target_existing'];
$action_params = ['ids' => '…'];
break;
}
$ip_address = @inet_pton(str_replace('::ffff:', '', $row['ipaddress'])) ?: '';
$action_params = $action_params ? json_encode($action_params) : '';
foreach ($actions as $action)
{
$insert[] = [
'log_date' => $row['dateline'],
'user_id' => $row['userid'],
'ip_address' => $ip_address,
'content_type' => $content_type,
'content_id' => $content_id,
'content_user_id' => $content_user_id,
'content_username' => $content_username,
'content_title' => $content_title,
'content_url' => $content_url,
'discussion_content_type' => $discussion_content_type,
'discussion_content_id' => $discussion_content_id,
'action' => $action,
'action_params' => $action_params,
];
}
if (count($insert) >= 1000)
{
$this->db()->insertBulk('xf_moderator_log', $insert);
$state->imported += count($insert);
$insert = [];
}
}
if (!empty($insert))
{
$this->db()->insertBulk('xf_moderator_log', $insert);
$state->imported += count($insert);
$insert = [];
}
return $state->complete();
}
protected function buildThreadTitle($str)
{
return html_entity_decode(preg_replace('/^(AW|Re): /', '', $str));
}