start();
$user->setup();
$auth->acl($user->data);
// End session management
/*
$s = explode(' ', microtime());
resync('forum');
$e = explode(' ', microtime());
echo $e[0] + $e[1] - $s[0] - $s[1];
echo $db->sql_report;
exit;
*/
// temp temp temp
very_temporary_lang_strings();
// temp temp temp
//
// Obtain initial var settings
//
$forum_id = (!empty($_REQUEST['f'])) ? intval($_REQUEST['f']) : '';
$topic_id = (!empty($_REQUEST['t'])) ? intval($_REQUEST['t']) : '';
$post_id = (!empty($_REQUEST['p'])) ? intval($_REQUEST['p']) : '';
$start = (!empty($_GET['start'])) ? intval($_GET['start']) : 0;
//
// Check if user did or did not confirm
// If they did not, forward them to the last page they were on
//
if (isset($_POST['cancel']))
{
if ($topic_id)
{
$redirect = "viewtopic.$phpEx$SID&t=$topic_id&start=$start";
}
elseif ($forum_id)
{
$redirect = "viewforum.$phpEx$SID&f=$forum_id&start=$start";
}
else
{
$redirect = "index.$phpEx$SID";
}
redirect($redirect);
}
// Continue var definitions
$forum_data = $topic_data = $post_data = array();
$topic_id_list = ($topic_id) ? array($topic_id) : array();
$post_id_list = ($post_id) ? array($post_id) : array();
$return_mcp = '
' . sprintf($user->lang['Click_return_mcp'], '', '');
$confirm = (!empty($_POST['confirm'])) ? TRUE : FALSE;
$mode = (!empty($_REQUEST['mode'])) ? $_REQUEST['mode'] : '';
$action = (!empty($_GET['action'])) ? $_GET['action'] : '';
$quickmod = (!empty($_REQUEST['quickmod'])) ? TRUE : FALSE;
$post_modes = array('move', 'delete', 'lock', 'unlock', 'merge_posts', 'delete_posts', 'split_all', 'split_beyond', 'select_topic', 'resync');
foreach ($post_modes as $post_mode)
{
if (isset($_POST[$post_mode]))
{
$mode = $post_mode;
break;
}
}
// Check destination forum or topic if applicable
$to_forum_id = (!empty($_REQUEST['to_forum_id'])) ? intval($_REQUEST['to_forum_id']) : 0;
$to_topic_id = (!empty($_REQUEST['to_topic_id'])) ? intval($_REQUEST['to_topic_id']) : 0;
if ($to_topic_id)
{
$result = $db->sql_query('SELECT * FROM ' . TOPICS_TABLE . ' WHERE topic_id = ' . $to_topic_id);
if (!$row = $db->sql_fetchrow($result))
{
trigger_error($user->lang['Topic_not_exist'] . $return_mcp);
}
if (!isset($topic_data[$to_topic_id]))
{
$topic_data[$to_topic_id] = $row;
}
$to_forum_id = $row['forum_id'];
}
if ($to_forum_id)
{
if (!$auth->acl_gets('f_list', 'm_', 'a_', $to_forum_id))
{
trigger_error($user->lang['FORUM_NOT_EXIST'] . $return_mcp);
}
if (!isset($forum_data[$to_forum_id]))
{
$result = $db->sql_query('SELECT * FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $to_forum_id);
if (!$row = $db->sql_fetchrow($result))
{
trigger_error($user->lang['FORUM_NOT_EXIST'] . $return_mcp);
}
$forum_data[$to_forum_id] = $row;
}
switch ($mode)
{
case 'move':
$is_auth = $auth->acl_gets('f_post', 'm_', 'a_', $to_forum_id);
break;
case 'merge':
$is_auth = $auth->acl_gets('f_post', 'f_reply', 'm_', 'a_', $to_forum_id);
break;
case 'split_all':
case 'split_beyond':
$is_auth = $auth->acl_gets('f_post', 'm_', 'a_', $to_forum_id);
break;
default:
trigger_error('Died here with mode ' . $mode);
}
// TODO: prevent moderators to move topics/posts to locked forums/topics?
if (!$is_auth || !$forum_data[$to_forum_id]['forum_postable'])
{
trigger_error($user->lang['User_cannot_post'] . $return_mcp);
}
}
// Cleanse inputted values then get permissions
foreach ($_POST['topic_id_list'] as $t_id)
{
if ($t_id = intval($t_id))
{
$topic_id_list[] = $t_id;
}
}
foreach ($_POST['post_id_list'] as $p_id)
{
if ($p_id = intval($p_id))
{
$post_id_list[] = $p_id;
}
}
$selected_post_ids = array();
if (!empty($_GET['post_id_list']))
{
$len = $_GET['post_id_list']{0};
for ($i = 1; $i < strlen($_GET['post_id_list']); $i += $len)
{
$short = substr($_GET['post_id_list'], $i, $len);
$selected_post_ids[] = (int) base_convert($short, 36, 10);
$post_id_list[] = base_convert($short, 36, 10);
}
}
$topic_id_sql = implode(', ', array_unique($topic_id_list));
$post_id_sql = implode(', ', array_unique($post_id_list));
// Reset id lists then rebuild them
$forum_id_list = $topic_id_list = $post_id_list = array();
$not_moderator = FALSE;
if ($forum_id)
{
if ($auth->acl_gets('m_', 'a_', $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('m_', 'a_', $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('m_', 'a_', $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
if (!$forum_id || count($forum_id_list) == 1)
{
$forum_id = $forum_id_list[0];
}
if (!$topic_id || count($topic_id_list) == 1)
{
$topic_id = $topic_id_list[0];
}
if (!$post_id || count($post_id_list) == 1)
{
$post_id = $post_id_list[0];
}
$forum_info = !empty($forum_data[$forum_id]) ? $forum_data[$forum_id] : array();
$topic_info = !empty($topic_data[$topic_id]) ? $topic_data[$topic_id] : array();
$post_info = !empty($post_data[$post_id]) ? $post_data[$post_id] : array();
}
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)
{
trigger_error('Not_Moderator');
}
else
{
$forumless_modes = array('', 'front', 'post_reports', 'mod_queue');
if (!in_array($mode, $forumless_modes))
{
// The user has submitted invalid post_ids or topic_ids
trigger_error($user->lang['Topic_post_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.
// Currently, this method may prevent moderators to merge topics if they do not have m_ or a_ access to both topics.
//
// Build links and tabs
$mcp_url = "mcp.$phpEx$SID";
$tabs = array(
'front' => $mcp_url,
'mod_queue' => $mcp_url . '&mode=mod_queue',
'post_reports' => $mcp_url . '&mode=post_reports'
);
$mcp_url .= ($forum_id) ? '&f=' . $forum_id : '';
$mcp_url .= ($topic_id) ? '&t=' . $topic_id : '';
$mcp_url .= ($post_id) ? '&p=' . $post_id : '';
$mcp_url .= ($start) ? '&start=' . $start : '';
$url_extra = (!empty($_GET['post_id_list'])) ? '&post_id_list=' . htmlspecialchars($_GET['post_id_list']) : '';
$return_mcp = '
' . sprintf($user->lang['Click_return_mcp'], '', '');
if ($forum_id)
{
$tabs['forum_view'] = $mcp_url . '&mode=forum_view' . $url_extra;
}
if ($topic_id)
{
$tabs['topic_view'] = $mcp_url . '&mode=topic_view' . $url_extra;
}
if ($post_id)
{
$tabs['post_view'] = $mcp_url . '&mode=post_view' . $url_extra;
}
if (!empty($_GET['post_id_list']))
{
$tabs['merge'] = $mcp_url . '&mode=merge' . $url_extra;
}
if (count($forum_id_list) == 1 && !$forum_info['forum_postable'])
{
trigger_error($user->lang['Forum_not_postable'] . $return_mcp);
}
if (!$mode)
{
if ($post_id)
{
$mode = 'post_view';
}
elseif ($topic_id)
{
$mode = 'topic_view';
}
elseif ($forum_id)
{
$mode = 'forum_view';
}
else
{
$mode = 'front';
}
}
// Get the current tab from the mode
$tabs_mode = array(
'mod_queue' => 'mod_queue',
'post_reports' => 'post_reports',
'split' => 'topic_view',
'merge' => (empty($_GET['post_id_list'])) ? 'topic_view' : 'merge',
'ip' => 'post_view',
'forum_view' => 'forum_view',
'topic_view' => 'topic_view',
'post_view' => 'post_view',
'front' => 'front'
);
foreach ($tabs as $tab_name => $tab_link)
{
$template->assign_block_vars('tab', array(
'S_IS_SELECTED' => (!empty($tabs_mode[$mode]) && $tab_name == $tabs_mode[$mode]) ? TRUE : FALSE,
'NAME' => $user->lang['mod_tabs'][$tab_name],
'U_LINK' => $tab_link
));
}
//
// Do major work ... (<= being the 1-billion dollars man)
//
// Current modes:
// - resync Resyncs topics
// - delete_posts Delete posts, displays confirmation if unconfirmed
// - delete 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
// - massdelete 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)
//
// TODO:
// - split_all Actually split selected topic
// - split_beyond Actually split selected topic
// - post_view Displays post details. Has quick links to (un)approve post.
// - 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.
// - 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.
// - approve/unapprove Actually un/approve selected topic(s) or post(s). NOTE: after some second thoughts we'll need three modes: (which names are still to be decided) the first to approve items, the second to set them back as "unapproved" and a third one to "disapprove" them. (IOW, delete them and eventually send a notification to the user)
// - 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
//
// TODO: add needed acl checks for each mode.
switch ($mode)
{
case 'resync':
resync('topic', 'topic_id', $topic_id_list);
$redirect_page = "mcp.$phpEx$SID&f=$forum_id";
$l_redirect = sprintf($user->lang['Click_return_mcp'], '', '');
$template->assign_vars(array(
'META' => '')
);
$msg = (count($topic_id_list) == 1) ? $user->lang['TOPIC_RESYNCHRONISED'] : $user->lang['TOPICS_RESYNCHRONISED'];
trigger_error($msg . '
' . $l_redirect);
break;
case 'delete_posts':
// TODO: what happens if the user deletes the first post of the topic? Currently, the topic is resync'ed normally and topic time/topic author are updated by the new first post
if (!count($post_id_list))
{
trigger_error($user->lang['None_selected']);
}
if ($confirm)
{
delete_posts('post_id', $post_id_list);
$redirect_page = "mcp.$phpEx$SID&f=$forum_id";
$l_redirect = sprintf($user->lang['Click_return_mcp'], '', '');
$template->assign_vars(array(
'META' => '')
);
$msg = (count($post_id_list) == 1) ? $user->lang['POST_REMOVED'] : $user->lang['POSTS_REMOVED'];
trigger_error($msg . '