' . sprintf($user->lang['RETURN_MCP'], '', '');
// Build up return links and acl list
// $acl_src contains the acl list for source forum(s)
// $acl_trg contains the acl list for destination forum(s)
$acl_src = 'm_';
$acl_trg = 'm_';
$return_mode = '
' . sprintf($user->lang['RETURN_MCP'], '', '');
switch ($mode)
{
case 'make_global':
case 'make_announce':
$acl_src = 'f_announce';
break;
case 'make_sticky':
$acl_src = 'f_sticky';
break;
case 'approve':
case 'unapprove':
case 'disapprove':
$acl_src = 'm_approve';
break;
case 'split':
case 'split_all':
case 'split_beyond':
$acl_src = 'a_';
$acl_trg = 'f_post';
$return_mode = '
' . sprintf($user->lang['RETURN_MCP'], '', '');
break;
case 'merge':
case 'merge_posts':
$acl_src = 'm_merge';
$acl_trg = 'm_merge';
$return_mode = '
' . sprintf($user->lang['RETURN_MCP'], '', '');
break;
case 'move':
$acl_src = 'm_move';
$acl_trg = 'f_post';
break;
case 'viewlogs':
$acl_src = array('m_', 'a_');
break;
case 'fork':
$acl_trg = 'f_post';
}
// Check destination forum or topic if applicable
if ($to_topic_id > 0)
{
$sql = 'SELECT *
FROM ' . TOPICS_TABLE . '
WHERE topic_id = ' . $to_topic_id;
$result = $db->sql_query($sql);
if (!$row = $db->sql_fetchrow($result))
{
trigger_error($user->lang['Topic_not_exist'] . $return_mode);
}
$db->sql_freeresult($result);
if (!isset($topic_data[$to_topic_id]))
{
$topic_data[$to_topic_id] = $row;
}
$to_forum_id = $row['forum_id'];
}
if ($to_forum_id > 0)
{
if (!isset($forum_data[$to_forum_id]))
{
$sql = 'SELECT *
FROM ' . FORUMS_TABLE . '
WHERE forum_id = ' . $to_forum_id;
$result = $db->sql_query($sql);
if (!$row = $db->sql_fetchrow($result))
{
trigger_error($user->lang['FORUM_NOT_EXIST'] . $return_mode);
}
$db->sql_freeresult($result);
$forum_data[$to_forum_id] = $row;
}
if (!$auth->acl_get('f_list', $to_forum_id))
{
trigger_error($user->lang['FORUM_NOT_EXIST'] . $return_mode);
}
}
// Reset id lists then rebuild them from verified data
$topic_id_sql = implode(', ', array_unique($topic_id_list));
$post_id_sql = implode(', ', array_unique($post_id_list));
$forum_id_list = $topic_id_list = $post_id_list = array();
$not_moderator = FALSE;
if ($forum_id > 0)
{
if ($auth->acl_gets($acl_src, $forum_id))
{
$forum_id_list[] = $forum_id;
}
else
{
$not_moderator = TRUE;
}
}
if ($topic_id_sql)
{
$sql = 'SELECT *
FROM ' . TOPICS_TABLE . "
WHERE topic_id IN ($topic_id_sql)";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if ($auth->acl_gets($acl_src, $row['forum_id']))
{
$forum_id_list[] = $row['forum_id'];
$topic_id_list[] = $row['topic_id'];
$topic_data[$row['topic_id']] = $row;
}
else
{
$not_moderator = TRUE;
}
}
$db->sql_freeresult($result);
}
if ($post_id_sql)
{
$sql = 'SELECT *
FROM ' . POSTS_TABLE . "
WHERE post_id IN ($post_id_sql)";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if ($auth->acl_gets($acl_src, $row['forum_id']))
{
$forum_id_list[] = $row['forum_id'];
$topic_id_list[] = $row['topic_id'];
$post_id_list[] = $row['post_id'];
$post_data[$row['post_id']] = $row;
}
else
{
$not_moderator = TRUE;
}
}
$db->sql_freeresult($result);
}
$forum_id_list = array_unique($forum_id_list);
$topic_id_list = array_unique($topic_id_list);
$post_id_list = array_unique($post_id_list);
if (count($forum_id_list))
{
$sql = 'SELECT *
FROM ' . FORUMS_TABLE . '
WHERE forum_id IN (' . implode(', ', $forum_id_list) . ')';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$forum_data[$row['forum_id']] = $row;
}
$db->sql_freeresult($result);
// Set infos about current forum/topic/post
// Uses each() because array_unique may unset index 0 if it's a duplicate
if (!isset($_REQUEST['f']) && count($forum_id_list) == 1)
{
// Using isset() rather than !empty() because of the jumpbox having f="0" for "All forums"
list($void, $forum_id) = each($forum_id_list);
}
if (!$topic_id && count($topic_id_list) == 1)
{
list($void, $topic_id) = each($topic_id_list);
}
if (!$post_id && count($post_id_list) == 1)
{
list($void, $post_id) = each($post_id_list);
}
$forum_info = $forum_data[$forum_id];
$topic_info = $topic_data[$topic_id];
$post_info = $post_data[$post_id];
}
else
{
// There's no forums list available so the user either submitted an empty or invalid list of posts/topics or isn't a moderator
if ($not_moderator || !get_forum_list('m_', TRUE, TRUE, TRUE))
{
trigger_error('Not_Moderator');
}
else
{
// TODO: drop this and deal with each mode individually?
$forumless_modes = array('front', 'post_reports', 'mod_queue', 'viewlogs', 'forum_info');
if ($mode != '' && !in_array($mode, $forumless_modes))
{
// The user has submitted invalid post_ids or topic_ids
trigger_error($user->lang['TOPIC_NOT_EXIST'] . $return_mcp);
}
}
}
//
// There we're done validating input.
//
// $post_id_list contains the complete list of post_id's, same for $topic_id_list and $forum_id_list
// $post_id, $topic_id, $forum_id have all been set.
//
// $forum_data is an array where $forum_data[] contains the corresponding row, same for $topic_data and $post_data.
// $forum_info is set to $forum_data[$forum_id] for quick reference, same for topic and post.
//
// We know that the user has m_ or a_ access to all the selected forums/topics/posts but we still have to check for specific authorisations.
//
// Build links and tabs
$mcp_url = "mcp.$phpEx$SID";
$tabs = array(
array(
'mode' => 'front',
'title' => $user->lang['FRONT_PAGE'],
'url' => $mcp_url . '&mode=front'
),
array(
'mode' => 'mod_queue',
'title' => $user->lang['MOD_QUEUE'],
'url' => $mcp_url . '&f=' . $forum_id . '&mode=mod_queue'
),
array(
'mode' => 'post_reports',
'title' => $user->lang['REPORTED_POSTS'],
'url' => $mcp_url . '&f=' . $forum_id . '&mode=post_reports'
)
);
$mcp_url .= ($forum_id) ? '&f=' . $forum_id : '';
$mcp_url .= ($topic_id) ? '&t=' . $topic_id : '';
$mcp_url .= ($post_id) ? '&p=' . $post_id : '';
$return_mcp = '
' . sprintf($user->lang['RETURN_MCP'], '', '');
$tabs[] = array(
'mode' => 'viewlogs',
'title' => ($topic_id) ? $user->lang['VIEW_TOPIC_LOGS'] : $user->lang['VIEW_LOGS'],
'url' => $mcp_url . '&mode=viewlogs'
);
if ($forum_id && $forum_data[$forum_id]['forum_type'] == FORUM_POST && $auth->acl_get('m_', $forum_id))
{
$tabs[] = array(
'mode' => 'forum_view',
'title' => $user->lang['VIEW_FORUM'],
'url' => $mcp_url . '&mode=forum_view'
);
}
if ($auth->acl_get('m_info', $forum_id))
{
$tabs[] = array(
'mode' => 'forum_info',
'title' => $user->lang['FORUM_INFO'],
'url' => $mcp_url . '&mode=forum_info&f=' . $forum_id
);
}
if ($topic_id && $auth->acl_gets('m_delete', 'm_split', 'm_merge', 'm_approve', $forum_id))
{
$tabs[] = array(
'mode' => 'topic_view',
'title' => $user->lang['VIEW_TOPIC'],
'url' => $mcp_url . '&mode=topic_view'
);
}
if ($post_id && $auth->acl_gets('m_', $forum_id))
{
$tabs[] = array(
'mode' => 'post_details',
'title' => $user->lang['POST_DETAILS'],
'url' => $mcp_url . '&mode=post_details'
);
}
if (!$mode)
{
if ($post_id)
{
$mode = 'post_details';
}
elseif ($topic_id)
{
$mode = 'topic_view';
}
elseif ($forum_id && $forum_data[$forum_id]['forum_type'] == FORUM_POST)
{
$mode = 'forum_view';
}
else
{
$mode = 'front';
}
}
switch ($mode)
{
case 'select_topic':
if ($url_extra)
{
$tabs[] = array(
'mode' => 'merge',
'title' => $user->lang['MERGE_TOPIC'],
'url' => $mcp_url . '&mode=merge' . $url_extra
);
}
break;
case 'merge':
case 'split':
$tabs[] = array(
'mode' => $mode,
'title' => $user->lang[strtoupper($mode) . '_TOPIC'],
'url' => $mcp_url . '&mode=' . $mode . $url_extra
);
break;
}
foreach ($tabs as $tab)
{
$template->assign_block_vars('tab', array(
'S_IS_SELECTED' => ($tab['mode'] == $mode) ? TRUE : FALSE,
'NAME' => $tab['title'],
'U_LINK' => $tab['url'])
);
}
//
// Do major work ...
//
// Current modes:
// - make_* Change topic type
// - resync Resyncs topics
// - delete_posts Delete posts, displays confirmation if unconfirmed
// - delete_topic Delete topics, displays confirmation
// - select_topic Forward the user to forum view to select a destination topic for the merge
// - merge Topic view, only displays the Merge button
// - split Topic view, only displays the split buttons
// - delete Topic view, only displays the Delete button
// - topic_view Topic view, similar to viewtopic.php
// - forum_view Forum view, similar to viewforum.php
// - move Move selected topic(s), displays the forums list for confirmation. Used for quickmod as well
// - lock, unlock Lock or unlock topic(s). No confirmation. Used for quickmod.
// - merge_posts Actually merge posts to selected topic. Untested yet.
// - ip Displays poster's ip and other ips the user has posted from. (imported straight from 2.0.x)
// - split_all Actually split selected topic
// - split_beyond Actually split selected topic
// - mod_queue Displays a list or unapproved posts and/or topics. I haven't designed the interface yet but it will have to be able to filter/order them by type (posts/topics), by timestamp or by forum.
//
// TODO:
// - post_details Displays post details. Has quick links to (un)approve post.
// - post_reports Displays a list of reported posts. No interface yet, must be able to order them by priority(?), type, timestamp or forum. Action: view all (default), read, delete.
// - notes Displays moderators notes for current forum or for all forums the user is a moderator of. Actions: view all (default), read, add, delete, edit(?).
// - a hell lot of other things
//
switch ($mode)
{
case 'forum_info':
if (!$auth->acl_get('m_info', $forum_id))
{
trigger_error('NOT_MODERATOR');
}
if ($confirm)
{
$sql_ary = array(
'forum_name' => (string) (!empty($_POST['forum_name'])) ? $_POST['forum_name'] : $forum_info['forum_name'],
'forum_desc' => (string) $_POST['forum_desc'],
'forum_style' => (int) $_POST['forum_style'],
'forum_status' => (int) $_POST['forum_status']
);
$sql = 'UPDATE ' . FORUMS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE forum_id = ' . $forum_id;
$db->sql_query($sql);
$return_mcp = '
' . sprintf($user->lang['RETURN_FORUM'], "", '');
trigger_error($message);
break;
case 'disapprove':
// NOTE: what happens if the user disapproves the first post of the topic? Answer: the topic is deleted
$redirect_page = "mcp.$phpEx$SID&f=$forum_id";
$l_redirect = sprintf($user->lang['RETURN_MCP'], "", '');
if (!count($post_id_list))
{
trigger_error($user->lang['NO_POST_SELECTED'] . '
' . $l_redirect);
}
if ($confirm)
{
$topic_ids = $post_ids = array();
foreach ($post_id_list as $p_id)
{
if ($topic_data[$post_data[$p_id]['topic_id']]['topic_first_post_id'] == $p_id)
{
$topic_ids[] = $post_data[$p_id]['topic_id'];
}
else
{
$post_ids[] = $p_id;
}
}
foreach ($post_id_list as $p_id)
{
if (!in_array($topic_ids, $post_data[$p_id]['topic_id']))
{
$post_ids[] = $p_id;
}
}
if (count($topic_ids))
{
delete_topics('topic_id', $topic_ids);
}
if (count($post_ids))
{
delete_posts('post_id', $post_ids);
}
// TODO: warn the user when post is disapproved
meta_refresh(3, $redirect_page);
$msg = (count($post_id_list) == 1) ? $user->lang['POST_REMOVED'] : $user->lang['POSTS_REMOVED'];
trigger_error($msg . '
' . $l_redirect);
}
// Not confirmed, show confirmation message
$hidden_fields = '';
foreach ($post_id_list as $p_id)
{
$hidden_fields .= '';
}
// Set template files
mcp_header('confirm_body.html');
$template->assign_vars(array(
'MESSAGE_TITLE' => $user->lang['CONFIRM'],
'MESSAGE_TEXT' => (count($post_id_list) == 1) ? $user->lang['CONFIRM_DELETE_POST'] : $user->lang['CONFIRM_DELETE_POSTS'],
'S_CONFIRM_ACTION' => "mcp.$phpEx$SID&mode=disapprove",
'S_HIDDEN_FIELDS' => $hidden_fields)
);
break;
case 'approve':
case 'unapprove':
$user_posts = $resync_count = array();
$value = ($mode == 'approve') ? 1 : 0;
if (count($post_id_list))
{
$sql = 'UPDATE ' . POSTS_TABLE . "
SET post_approved = $value
WHERE post_id IN (" . implode(', ', $post_id_list) . ')';
$db->sql_query($sql);
if (count($post_id_list) == 1)
{
$lang_str = ($mode == 'approve') ? 'POST_APPROVED' : 'POST_UNAPPROVED';
}
else
{
$lang_str = ($mode == 'approve') ? 'POSTS_APPROVED' : 'POSTS_UNAPPROVED';
}
$redirect_page = "viewtopic.$phpEx$SID&f=$forum_id&t=$topic_id&start=$start";
$l_redirect = sprintf($user->lang['RETURN_TOPIC'], '', '');
foreach ($post_id_list as $post_id)
{
if ($post_id == $post_data[$post_id]['topic_first_post_id'])
{
$logm_mode = ($mode == 'approve') ? 'logm_approve_topic' : 'logm_unapprove_topic';
}
else
{
$logm_mode = ($mode == 'approve') ? 'logm_approve_post' : 'logm_unapprove_post';
}
add_log('mod', $forum_id, $post_data[$post_id]['topic_id'], $logm_mode, $post_id);
//NOTE: hey, who removed the enable_post_count field?! lol ^ ^
$forum_data[$post_data[$post_id]['forum_id']]['enable_post_count'] = 1;
if ($forum_data[$post_data[$post_id]['forum_id']]['enable_post_count'])
{
if (isset($user_posts[$post_data[$post_id]['poster_id']]))
{
++$user_posts[$post_data[$post_id]['poster_id']];
}
else
{
$user_posts[$post_data[$post_id]['poster_id']] = 1;
}
}
}
}
elseif (count($topic_id_list))
{
// TODO: 20030325 - I'm not sure we will ever use this mode, users won't approve whole topics at once, will they?
$sql = 'UPDATE ' . TOPICS_TABLE . "
SET topic_approved = $value
WHERE topic_id IN (" . implode(', ', $topic_id_list) . ')';
$db->sql_query($sql);
if (count($topic_id_list) == 1)
{
$lang_str = ($mode == 'approve') ? 'TOPIC_APPROVED' : 'TOPIC_UNAPPROVED';
}
else
{
$lang_str = ($mode == 'approve') ? 'TOPICS_APPROVED' : 'TOPICS_UNAPPROVED';
}
$redirect_page = "viewforum.$phpEx$SID&f=$forum_id&start=$start";
$l_redirect = sprintf($user->lang['RETURN_FORUM'], '', '');
$logm_mode = ($mode == 'approve') ? 'logm_approve_topic' : 'logm_unapprove_topic';
foreach ($topic_id_list as $topic_id)
{
add_log('mod', $forum_id, $topic_id, $logm_mode);
}
}
else
{
trigger_error($user->lang['NO_POST_SELECTED']);
}
// Resync last post infos, replies count et caetera
sync('topic', 'topic_id', $topic_id_list);
sync('topic_attachment', 'topic_id', $topic_id_list);
foreach ($user_posts as $user_id => $post_count)
{
if (isset($resync_count[$post_count]))
{
$resync_count[$post_count][] = $user_id;
}
else
{
$resync_count[$post_count] = array($user_id);
}
}
foreach ($resync_count as $post_count => $user_list)
{
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_posts = user_posts + $post_count
WHERE user_id IN (" . implode(', ', $user_list) . ')';
$db->sql_query($sql);
}
$template->assign_vars(array(
'META' => '')
);
$return_mcp = '
' . $l_redirect);
break;
case 'delete_moved':
if ($topic_id)
{
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE topic_moved_id = ' . $topic_d;
}
elseif ($forum_id)
{
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE topic_moved_id > 0
AND forum_id = ' . $forum_id;
}
$db->sql_query($sql);
$return = ($quickmod) ? sprintf($user->lang['RETURN_TOPIC'], '', '') : sprintf($user->lang['RETURN_MCP'], '', '');
trigger_error($user->lang['SHADOWS_REMOVED'] . '
' . $return);
break;
case 'delete_posts':
// NOTE: what happens if the user deletes the first post of the topic? The topic is resync'ed normally and topic time/topic author are updated by the new first post
$redirect_page = "mcp.$phpEx$SID&f=$forum_id";
$l_redirect = sprintf($user->lang['RETURN_MCP'], '', '');
if (!count($post_id_list))
{
trigger_error($user->lang['NO_POST_SELECTED'] . '