acl_gets('a_forum', 'a_forumadd', 'a_forumdel'))
{
return;
}
$module['FORUM']['MANAGE'] = basename(__FILE__) . $SID;
return;
}
define('IN_PHPBB', 1);
// Include files
$phpbb_root_path = '../';
require($phpbb_root_path . 'extension.inc');
require('pagestart.' . $phpEx);
// Get mode
$mode = (isset($_REQUEST['mode'])) ? $_REQUEST['mode'] : '';
// Do we have permissions?
switch ($mode)
{
case 'add':
if (!$auth->acl_get('a_forumadd'))
{
trigger_error($user->lang['NO_ADMIN']);
}
case 'del':
if (!$auth->acl_get('a_forumdel'))
{
trigger_error($user->lang['NO_ADMIN']);
}
default:
if (!$auth->acl_get('a_forum'))
{
trigger_error($user->lang['NO_ADMIN']);
}
}
// Major routines
switch ($mode)
{
case 'move_up':
case 'move_down':
$show_index = TRUE;
$forum_id = intval($_GET['this_f']);
$result = $db->sql_query('SELECT parent_id, left_id, right_id FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id");
if (!$row = $db->sql_fetchrow($result))
{
trigger_error('Forum does not exist');
}
extract($row);
$forum_info = array($forum_id => $row);
//
// Get the adjacent forum
//
if ($mode == 'move_up')
{
$sql = 'SELECT forum_id, left_id, right_id
FROM ' . FORUMS_TABLE . "
WHERE parent_id = $parent_id AND right_id < $right_id
ORDER BY right_id DESC";
}
else
{
$sql = 'SELECT forum_id, left_id, right_id
FROM ' . FORUMS_TABLE . "
WHERE parent_id = $parent_id AND left_id > $left_id
ORDER BY left_id ASC";
}
$result = $db->sql_query_limit($sql, 1);
if (!$row = $db->sql_fetchrow($result))
{
//
// already on top or at bottom
//
break;
}
if ($mode == 'move_up')
{
$up_id = $forum_id;
$down_id = $row['forum_id'];
}
else
{
$up_id = $row['forum_id'];
$down_id = $forum_id;
}
$forum_info[$row['forum_id']] = $row;
$diff_up = $forum_info[$up_id]['right_id'] - $forum_info[$up_id]['left_id'];
$diff_down = $forum_info[$down_id]['right_id'] - $forum_info[$down_id]['left_id'];
//
// I should consider using transactions here
//
$forum_ids = array();
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE left_id > ' . $forum_info[$up_id]['left_id'] . ' AND right_id < ' . $forum_info[$up_id]['right_id'];
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$forum_ids[] = $row['forum_id'];
}
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET left_id = left_id + ' . ($diff_up + 1) . ', right_id = right_id + ' . ($diff_up + 1) . '
WHERE left_id > ' . $forum_info[$down_id]['left_id'] . ' AND right_id < ' . $forum_info[$down_id]['right_id'];
$db->sql_query($sql);
if (count($forum_ids))
{
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET left_id = left_id - ' . ($diff_down + 1) . ', right_id = right_id - ' . ($diff_down + 1) . '
WHERE forum_id IN (' . implode(', ', $forum_ids) . ')';
$db->sql_query($sql);
}
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET left_id = ' . $forum_info[$down_id]['left_id'] . ', right_id = ' . ($forum_info[$down_id]['left_id'] + $diff_up) . '
WHERE forum_id = ' . $up_id;
$db->sql_query($sql);
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET left_id = ' . ($forum_info[$up_id]['right_id'] - $diff_down) . ', right_id = ' . $forum_info[$up_id]['right_id'] . '
WHERE forum_id = ' . $down_id;
$db->sql_query($sql);
break;
case 'create':
if (!trim($_POST['forum_name']))
{
trigger_error('Cannot create a forum without a name');
}
$parent_id = (!empty($_POST['parent_id'])) ? intval($_POST['parent_id']) : 0;
if ($parent_id)
{
$result = $db->sql_query('SELECT left_id, right_id FROM ' . FORUMS_TABLE . " WHERE forum_id = $parent_id");
if (!$row = $db->sql_fetchrow($result))
{
trigger_error('Parent does not exist', E_USER_ERROR);
}
extract($row);
$db->sql_query('UPDATE ' . FORUMS_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 WHERE left_id > $right_id");
$db->sql_query('UPDATE ' . FORUMS_TABLE . " SET right_id = right_id + 2 WHERE $left_id BETWEEN left_id AND right_id");
$left_id = $right_id;
++$right_id;
}
else
{
$result = $db->sql_query('SELECT MAX(right_id) AS right_id FROM ' . FORUMS_TABLE);
$left_id = $db->sql_fetchfield('right_id', 0, $result) + 1;
$right_id = $left_id + 1;
}
$sql = array(
'parent_id' => $parent_id,
'left_id' => $left_id,
'right_id' => $right_id,
'forum_status' => intval($_POST['forum_status']),
'forum_postable' => (!empty($_POST['forum_postable'])) ? 1 : 0,
'forum_name' => $_POST['forum_name'],
'forum_desc' => $_POST['forum_desc'],
'forum_style' => (!empty($_POST['forum_style'])) ? intval($_POST['forum_style']) : 'NULL',
'enable_post_count' => (!empty($_POST['disable_post_count'])) ? 0 : 1,
'enable_icons' => (!empty($_POST['enable_icons'])) ? 1 : 0,
'enable_moderate' => (!empty($_POST['moderated'])) ? 1 : 0,
'enable_prune' => (!empty($_POST['prune_enable'])) ? 1 : 0,
'prune_days' => intval($_POST['prune_days']),
'prune_freq' => intval($_POST['prune_freq'])
);
$db->sql_query('INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql));
$forum_id = $db->sql_nextid();
// Redirect to permissions
redirect('admin/admin_permissions.' . $phpEx . $SID . '&mode=forums&f=' . $forum_id);
break;
case 'modify':
if (!$forum_id = intval($_POST['f']))
{
trigger_error('No forum specified');
}
$row = get_forum_info($forum_id);
$parent_id = intval($_POST['parent_id']);
$action = (!empty($_POST['action'])) ? $_POST['action'] : '';
if (($row['parent_id'] != $parent_id) && ($parent_id != -1))
{
move_forum($forum_id, $parent_id);
}
elseif ($row['forum_name'] != $_POST['forum_name'])
{
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET forum_parents = ""
WHERE left_id > ' . $row['left_id'] . ' AND right_id < ' . $row['right_id'];
$db->sql_query($sql);
}
$sql = array(
'parent_id' => $parent_id,
'forum_name' => (!empty($_POST['forum_name'])) ? $_POST['forum_name'] : $row['forum_name'],
'forum_desc' => (!empty($_POST['forum_desc'])) ? $_POST['forum_desc'] : $row['forum_desc'],
'forum_status' => intval($_POST['forum_status']),
'forum_postable' => (!empty($_POST['is_postable'])) ? 1 : 0,
'forum_style' => (!empty($_POST['forum_style'])) ? $_POST['forum_style'] : NULL,
'forum_image' => (!empty($_POST['forum_image'])) ? $_POST['forum_image'] : '',
'display_on_index' => (!empty($_POST['display_on_index'])) ? 1 : 0,
'enable_post_count' => (!empty($_POST['disable_post_count'])) ? 0 : 1,
'enable_icons' => (!empty($_POST['enable_icons'])) ? 1 : 0,
'enable_moderate' => (!empty($_POST['moderated'])) ? 1 : 0,
'enable_prune' => (!empty($_POST['prune_enable'])) ? 1 : 0,
'prune_days' => intval($_POST['prune_days']),
'prune_freq' => intval($_POST['prune_freq']),
);
if (!empty($_POST['set_nonpostable']) && $action)
{
if ($action == 'move' && $_POST['to_forum_id'])
{
move_forum_content($forum_id, $_POST['to_forum_id']);
}
elseif ($action == 'delete')
{
delete_forum_content($forum_id);
}
$sql['forum_posts'] = 0;
$sql['forum_topics'] = 0;
}
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql) . " WHERE forum_id = $forum_id");
$message = $user->lang['Forums_updated'] . "
" . sprintf($user->lang['Click_return_forumadmin'], '', '') . '
' . sprintf($user->lang['Click_return_admin_index'], '', '');
trigger_error($message);
break;
case 'remove':
if (empty($_POST['submit']))
{
//
// wasn't this form submitted? is anyone trying to remotely delete forums
//
// NOTE/TODO: this should not be possible because of session_id verification so this part can be removed
//
trigger_error('Did not submit', E_USER_ERROR);
}
$action_subforums = (!empty($_POST['action_subforums'])) ? $_POST['action_subforums'] : '';
$action_posts = (!empty($_POST['action_posts'])) ? $_POST['action_posts'] : '';
$row = get_forum_info($_GET['f']);
extract($row);
if ($action_posts == 'delete')
{
delete_forum_content($forum_id);
}
elseif ($action_posts == 'move')
{
if (empty($_POST['posts_to_id']))
{
$message = $user->lang['No_destination_forum'] . '
' . sprintf($user->lang['Click_return_forumadmin'], '', '');
trigger_error($message);
}
move_forum_content($forum_id, $_POST['posts_to_id']);
}
if ($action_subforums == 'delete')
{
$forum_ids = array($forum_id);
$rows = get_forum_branch($forum_id, 'children', 'descending', FALSE);
foreach ($rows as $row)
{
$forum_ids[] = $row['forum_id'];
delete_forum_content($row['forum_id']);
}
$diff = count($forum_ids) * 2;
$db->sql_query('DELETE FROM ' . FORUMS_TABLE . ' WHERE forum_id IN (' . implode(', ', $forum_ids) . ')');
}
elseif ($action_subforums == 'move')
{
if (empty($_POST['subforums_to_id']))
{
$message = $user->lang['No_destination_forum'] . '
' . sprintf($user->lang['Click_return_forumadmin'], '', '');
trigger_error($message);
}
$result = $db->sql_query('SELECT forum_id FROM ' . FORUMS_TABLE . " WHERE parent_id = $forum_id");
while ($row = $db->sql_fetchrow($result))
{
move_forum($row['forum_id'], $_POST['subforums_to_id']);
}
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET parent_id = ' . $_POST['subforums_to_id'] . " WHERE parent_id = $forum_id");
$diff = 2;
$db->sql_query('DELETE FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id");
}
else
{
$diff = 2;
$db->sql_query('DELETE FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id");
}
//
// Resync tree
//
$sql = 'UPDATE ' . FORUMS_TABLE . "
SET right_id = right_id - $diff
WHERE left_id < $right_id AND right_id > $right_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . FORUMS_TABLE . "
SET left_id = left_id - $diff, right_id = right_id - $diff
WHERE left_id > $right_id";
$db->sql_query($sql);
$return_id = (!empty($_POST['subforums_to_id'])) ? $_POST['subforums_to_id'] : $parent_id;
$message = $user->lang['Forum_deleted'] . '
' . sprintf($user->lang['Click_return_forumadmin'], '', '');
trigger_error($message);
break;
case 'sync':
sync('forum', intval($_GET['this_f']));
break;
case 'add':
case 'edit':
// Show form to create/modify a forum
if ($mode == 'edit')
{
$forum_id = intval($_GET['this_f']);
$row = get_forum_info($forum_id);
extract($row);
$subforums_id = array();
$subforums = get_forum_branch($forum_id, 'children');
foreach ($subforums as $row)
{
$subforums_id[] = $row['forum_id'];
}
$parents_list = make_forums_list('all', $parent_id, $subforums_id);
$l_title = $user->lang['Edit_forum'];
$newmode = 'modify';
$buttonvalue = $user->lang['Update'];
$prune_enabled = ($prune_enable) ? 'checked="checked" ' : '';
$forums_list = make_forums_list('forums', 0, $forum_id);
}
else
{
$parent_id = (!empty($_POST['parent_id'])) ? $_POST['parent_id'] : 0;
$parents_list = make_forums_list('all', $parent_id);
$l_title = $user->lang['Create_forum'];
$newmode = 'create';
$buttonvalue = $user->lang['Create_forum'];
$forum_id = $parent_id;
$forum_desc = '';
$forum_style = '';
$forum_status = ITEM_UNLOCKED;
$forum_name = (!empty($_POST['forum_name'])) ? htmlspecialchars($_POST['forum_name']) : '';
$post_count_inc = TRUE;
$moderated = FALSE;
$enable_icons = TRUE;
$prune_enabled = '';
$prune_days = 7;
$prune_freq = 1;
}
$styles_list = make_styles_list($forum_style);
$forumlocked = ($forum_status == ITEM_LOCKED) ? ' selected="selected"' : '';
$forumunlocked = ($forum_status == ITEM_UNLOCKED) ? ' selected="selected"' : '';
$postable_checked = ($forum_postable) ? 'checked="checked" ' : '';
$nonpostable_checked = (!$forum_postable) ? 'checked="checked" ' : '';
$statuslist = '\n";
$statuslist .= '\n";
page_header($l_title);
?>
lang['Forum_edit_delete_explain'] ?>
lang['Forum_delete_explain'] ?>
Forum Index'; $forums_nav = get_forum_branch($forum_id, 'parents', 'descending'); foreach ($forums_nav as $row) { if ($row['forum_id'] == $forum_id) { $navigation .= ' -> ' . htmlspecialchars($row['forum_name']); } else { $navigation .= ' -> ' . htmlspecialchars($row['forum_name']) . ''; } } } // Jumpbox $forum_box = make_forum_select($forum_id); // Front end page_header($user->lang['MANAGE']); ?>lang['Forum_admin_explain']; ?>
sql_query($sql); if (!$row = $db->sql_fetchrow($result)) { trigger_error("Forum #$forum_id does not exist", E_USER_ERROR); } return $row; } function make_forums_list($mode = 'all', $selected_id = 0, $exclude_id = array()) { global $db; if (!is_array($exclude_id)) { $exclude_id = array($exclude_id); } $sql = 'SELECT f2.* FROM ' . FORUMS_TABLE . ' f1, ' . FORUMS_TABLE . ' f2 WHERE f1.parent_id = 0 AND f2.left_id BETWEEN f1.left_id AND f1.right_id ORDER BY f2.left_id'; $result = $db->sql_query($sql); $list = ''; $indent = array(); $current_indent = 0; while ($row = $db->sql_fetchrow($result)) { if ($row['parent_id'] == 0) { $current_indent = 0; } elseif (!isset($indent[$row['parent_id']])) { ++$current_indent; $indent[$row['parent_id']] = $current_indent; } else { $current_indent = $indent[$row['parent_id']]; } if (($mode == 'forums' && !$row['forum_postable']) || ($mode == 'categories' && $row['forum_postable']) || (in_array($row['forum_id'], $exclude_id))) { continue; } if ($mode == 'all' && !$row['parent_id']) { $list .= "\n"; } $list .= '\n"; } return $list; } function make_styles_list($selected_id = 0) { global $db; $list = ''; $result = $db->sql_query('SELECT style_id, style_name FROM ' . STYLES_TABLE . ' ORDER BY style_name'); while ($row = $db->sql_fetchrow($result)) { $list .= '\n"; } return $list; } function move_forum($from_id, $to_id) { global $db; $moved_forums = get_forum_branch($from_id, 'children', 'descending'); $from_data = $moved_forums[0]; $diff = count($moved_forums) * 2; $moved_ids = array(); for ($i = 0; $i < count($moved_forums); ++$i) { $moved_ids[] = $moved_forums[$i]['forum_id']; } // Resync parents $sql = 'UPDATE ' . FORUMS_TABLE . " SET right_id = right_id - $diff, forum_parents = '' WHERE left_id < " . $from_data['right_id'] . " AND right_id > " . $from_data['right_id']; $db->sql_query($sql); // Resync righthand side of tree $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id - $diff, right_id = right_id - $diff, forum_parents = '' WHERE left_id > " . $from_data['right_id']; $db->sql_query($sql); if ($to_id > 0) { $to_data = get_forum_info($to_id); // Resync new parents $sql = 'UPDATE ' . FORUMS_TABLE . " SET right_id = right_id + $diff, forum_parents = '' WHERE " . $to_data['right_id'] . ' BETWEEN left_id AND right_id AND forum_id NOT IN (' . implode(', ', $moved_ids) . ')'; $db->sql_query($sql); // Resync the righthand side of the tree $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id + $diff, right_id = right_id + $diff, forum_parents = '' WHERE left_id > " . $to_data['right_id'] . ' AND forum_id NOT IN (' . implode(', ', $moved_ids) . ')'; $db->sql_query($sql); // Resync moved branch $to_data['right_id'] += $diff; if ($to_data['right_id'] > $from_data['right_id']) { $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1); } else { $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1); } } else { $result = $db->sql_query('SELECT MAX(right_id) AS right_id FROM ' . FORUMS_TABLE . ' WHERE forum_id NOT IN (' . implode(', ', $moved_ids) . ')'); $right_id = $db->sql_fetchfield('right_id', 0, $result); $diff = '+ ' . ($right_id - $from_data['left_id'] + 1); } $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id $diff, right_id = right_id $diff, forum_parents = '' WHERE forum_id IN (" . implode(', ', $moved_ids) . ')'; $db->sql_query($sql); } function move_forum_content($from_id, $to_id) { global $db; $db->sql_query('UPDATE ' . ACL_GROUPS_TABLE . " SET forum_id = $to_id WHERE forum_id = $from_id"); $db->sql_query('UPDATE ' . MODERATOR_TABLE . " SET forum_id = $to_id WHERE forum_id = $from_id"); $db->sql_query('UPDATE ' . LOG_MOD_TABLE . " SET forum_id = $to_id WHERE forum_id = $from_id"); $db->sql_query('UPDATE ' . POSTS_TABLE . " SET forum_id = $to_id WHERE forum_id = $from_id"); $db->sql_query('UPDATE ' . TOPICS_TABLE . " SET forum_id = $to_id WHERE forum_id = $from_id"); // // TODO: untested yet // $sql = 'SELECT t1.topic_id FROM ' .TOPICS_TABLE . ' t1 LEFT JOIN ' . TOPICS_TABLE . " t2 ON t1.topic_moved_id = t2.topic_id AND t1.forum_id = t2.forum_id WHERE t1.forum_id = $to_id"; $result = $db->sql_query($result); $topic_ids = array(); while ($row = $db->sql_fetchrow($result)) { $topic_ids[] = $row['topic_id']; } if (count($topic_ids)) { $db->sql_query('DELETE FROM ' . TOPICS_TABLE . ' WHERE topic_id IN (' . implode(', ', $topic_ids) . ')'); } sync('forum', $to_id); // // TODO: there might be conflicts in ACL tables =\ // make sure that the query that retrieves shadow topics uses the correct index (topic_type or topic_moved_id) // } function delete_forum_content($forum_id) { global $db; $db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . " WHERE forum_id = $forum_id"); $db->sql_query('DELETE FROM ' . MODERATOR_TABLE . " WHERE forum_id = $forum_id"); $db->sql_query('DELETE FROM ' . LOG_MOD_TABLE . " WHERE forum_id = $forum_id"); $db->sql_query('DELETE FROM ' . FORUMS_WATCH_TABLE . " WHERE forum_id = $forum_id"); $ids = array(); $result = $db->sql_query('SELECT post_id FROM ' . POSTS_TABLE . " WHERE forum_id = $forum_id"); while ($row = $db->sql_fetchrow($result)) { $ids[] = $row['post_id']; } $ids = implode(',', $ids); $db->sql_freeresult(); if ($ids) { $db->sql_query('DELETE FROM ' . SEARCH_MATCH_TABLE . " WHERE post_id IN ($ids)"); $db->sql_query('DELETE FROM ' . POSTS_TABLE . " WHERE forum_id = $forum_id"); $db->sql_query('DELETE FROM ' . POSTS_TEXT_TABLE . " WHERE post_id IN ($ids)"); } $ids = array(); $result = $db->sql_query('SELECT topic_id FROM ' . TOPICS_TABLE . " WHERE forum_id = $forum_id"); while ($row = $db->sql_fetchrow($result)) { $ids[] = $row['topic_id']; } $ids = implode(',', $ids); $db->sql_freeresult(); if ($ids) { $db->sql_query('DELETE FROM ' . TOPICS_WATCH_TABLE . " WHERE topic_id IN ($ids)"); $db->sql_query('DELETE FROM ' . TOPICS_TABLE . " WHERE forum_id = $forum_id"); $db->sql_query('DELETE FROM ' . TOPICS_TABLE . " WHERE topic_moved_id IN ($ids)"); } // // TODO: delete attachments // delete polls // OPTIMIZE / VACUUM table ? // } // // End function block // ------------------ ?>